From 21a7149486495756850e0d152448111f1c49e3ee Mon Sep 17 00:00:00 2001 From: root Date: Mon, 29 Dec 2025 09:43:23 +0000 Subject: [PATCH] Switch Ajax transport to JSON with proper Content-Type Migrate $name from Form_Field to input components Refactor form inputs: $name moves from Form_Field to input components MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../Core/Ajax/Ajax_Batch_Controller.php | 10 +- app/RSpade/Core/Js/Ajax.js | 6 +- app/RSpade/man/crud.txt | 14 +-- app/RSpade/man/datetime_inputs.txt | 20 ++-- app/RSpade/man/form_conventions.txt | 15 +-- app/RSpade/man/forms_and_widgets.txt | 93 ++++++++-------- app/RSpade/man/modals.txt | 12 +-- .../form_input_abstract_12_29_2.txt | 100 ++++++++++++++++++ docs/CLAUDE.dist.md | 3 +- docs/skills/crud-patterns/SKILL.md | 8 +- docs/skills/forms/SKILL.md | 12 +-- 11 files changed, 197 insertions(+), 96 deletions(-) create mode 100755 app/RSpade/upstream_changes/form_input_abstract_12_29_2.txt diff --git a/app/RSpade/Core/Ajax/Ajax_Batch_Controller.php b/app/RSpade/Core/Ajax/Ajax_Batch_Controller.php index f96936f02..22319174d 100644 --- a/app/RSpade/Core/Ajax/Ajax_Batch_Controller.php +++ b/app/RSpade/Core/Ajax/Ajax_Batch_Controller.php @@ -46,20 +46,18 @@ class Ajax_Batch_Controller extends Rsx_Controller_Abstract \App\RSpade\Core\Debug\Debugger::disable_console_html_output(); // Get batch calls from request - $batch_calls_json = $request->input('batch_calls'); + // With JSON Content-Type, Laravel auto-decodes the body + $batch_calls = $request->input('batch_calls'); - if (empty($batch_calls_json)) { + if (empty($batch_calls)) { return response()->json([ 'error' => 'Missing batch_calls parameter' ], 400); } - // Parse batch calls - $batch_calls = json_decode($batch_calls_json, true); - if (!is_array($batch_calls)) { return response()->json([ - 'error' => 'Invalid batch_calls format - must be JSON array' + 'error' => 'Invalid batch_calls format - must be array' ], 400); } diff --git a/app/RSpade/Core/Js/Ajax.js b/app/RSpade/Core/Js/Ajax.js index 26896a855..6ab0735c1 100755 --- a/app/RSpade/Core/Js/Ajax.js +++ b/app/RSpade/Core/Js/Ajax.js @@ -195,7 +195,8 @@ class Ajax { $.ajax({ url: url, method: 'POST', - data: params, + contentType: 'application/json', + data: JSON.stringify(params), dataType: 'json', __local_integration: true, // Bypass $.ajax override success: (response) => { @@ -364,7 +365,8 @@ class Ajax { const response = await $.ajax({ url: '/_ajax/_batch', method: 'POST', - data: { batch_calls: JSON.stringify(calls_to_send) }, + contentType: 'application/json', + data: JSON.stringify({ batch_calls: calls_to_send }), dataType: 'json', __local_integration: true, // Bypass $.ajax override }); diff --git a/app/RSpade/man/crud.txt b/app/RSpade/man/crud.txt index be47a8ed9..4da4d21b4 100755 --- a/app/RSpade/man/crud.txt +++ b/app/RSpade/man/crud.txt @@ -455,12 +455,12 @@ EDIT PAGE (ADD/EDIT COMBINED) <% } %> - - + + - - + + @@ -479,11 +479,11 @@ RSX_FORM $method - Ajax endpoint method name Form Fields - - + + - The $name must match: + The $name on the input component must match: - The key in $data JSON - The key in server-side $params - The key in validation $errors array diff --git a/app/RSpade/man/datetime_inputs.txt b/app/RSpade/man/datetime_inputs.txt index 44b7d160a..9bdd90ec8 100755 --- a/app/RSpade/man/datetime_inputs.txt +++ b/app/RSpade/man/datetime_inputs.txt @@ -5,8 +5,8 @@ NAME SYNOPSIS Client-side (template): - - + + Server-side: @@ -42,8 +42,8 @@ DESCRIPTION Schedule_Input combines all scheduling fields into one component: - - + + Submits as JSON: @@ -90,8 +90,8 @@ SCHEDULE_INPUT COMPONENT Template Usage Basic usage: - - + + Without timezone picker: @@ -334,12 +334,12 @@ COMPLETE EXAMPLE Template - - + + - - + + diff --git a/app/RSpade/man/form_conventions.txt b/app/RSpade/man/form_conventions.txt index eac65d8de..1df88dfee 100755 --- a/app/RSpade/man/form_conventions.txt +++ b/app/RSpade/man/form_conventions.txt @@ -116,16 +116,16 @@ TEMPLATE PATTERN <% } %> - - + + - - + + - - + @@ -350,7 +350,8 @@ COMMON MISTAKES this.data.form_data = { name: 'Test' }; // Template uses 'title' - VALUE WILL BE EMPTY - + + SEE ALSO forms_and_widgets(3), jqhtml(3), ajax(3) diff --git a/app/RSpade/man/forms_and_widgets.txt b/app/RSpade/man/forms_and_widgets.txt index ee00eede6..340242b3f 100755 --- a/app/RSpade/man/forms_and_widgets.txt +++ b/app/RSpade/man/forms_and_widgets.txt @@ -8,12 +8,12 @@ SYNOPSIS - - + + - - + + @@ -69,12 +69,12 @@ RSX_FORM COMPONENT Example - Basic Form: - - + + - - + + @@ -119,39 +119,38 @@ FORM_FIELD WRAPPER Responsibilities: - Display label with optional required indicator - - Set data-name attribute on child widget + - Read data-name from child widget (set by Form_Input_Abstract) - Display validation errors returned from server - Provide consistent spacing and styling Example - Basic Field: - - + + Example - Required Field with Help Text: - - + Example - Field with HTML in Label: - - + + Form_Field_Abstract: Use Form_Field_Abstract directly when you need field functionality - without visual formatting (e.g., for hidden fields or custom layouts). + without visual formatting (e.g., for custom layouts). Example - Unformatted Field: - - + + Form_Hidden_Field: @@ -388,14 +387,14 @@ DISABLED STATE Example - Disable Individual Fields: - - + + Example - Conditional Disable: - - + @@ -465,31 +464,31 @@ MULTI-COLUMN LAYOUTS
- - + +
- - + +
- - + +
- - + +
- - + +
@@ -547,8 +546,8 @@ CREATING CUSTOM WIDGETS Usage: - - + + EXAMPLES @@ -573,34 +572,34 @@ EXAMPLES @endif - - + +
- - + +
- - + +
- - + - - + + - - + +