I'm trying to create a DynamicForm subclass to implement custom handling of a "multiple=true" field in my datasource.
application.ds.xml
vehicle.ds.xml
Let me explain what I'm trying to accomplish.
I want a form that has two buttons "Add Vehicle" and "Remove Vehicle" and when clicked will either show / hide the corresponding nested form of (year,make,model) [see attachment].
This showing / hiding is not a problem and is working as expected.
Validation is not a problem either - overriding DynamicForm.validate() and delegating to the nested forms works like a charm.
The problem is aggregating the nested form values by override DynamicForm.getValues(). Using Firebug, the getValues() is not getting called as a part of the ValuesManager.saveData() - the validate() function does get called and aborts saving if a nested form is visible and invalid (i.e. incomplete).
getValues() should be expecting a JS Object like...
...for correct unmarshalling on the server-side.
Anyone have any ideas on what I'm doing wrong?
Thanks,
--mgbowman
-----
Here's the code for my two forms:
VehiclesForm.js
VehicleForm.js
application.ds.xml
Code:
<DataSource ...> <serverObject ... /> <fields> <field name="vehicles" type="vehicle" multiple="true" /> </fields> </DataSource>
Code:
<DataSource ...> <serverObject ... /> <fields> <field name="year" type="integer" /> <field name="make" type="text" /> <field name="model" type="text" /> </fields> </DataSource>
I want a form that has two buttons "Add Vehicle" and "Remove Vehicle" and when clicked will either show / hide the corresponding nested form of (year,make,model) [see attachment].
This showing / hiding is not a problem and is working as expected.
Validation is not a problem either - overriding DynamicForm.validate() and delegating to the nested forms works like a charm.
The problem is aggregating the nested form values by override DynamicForm.getValues(). Using Firebug, the getValues() is not getting called as a part of the ValuesManager.saveData() - the validate() function does get called and aborts saving if a nested form is visible and invalid (i.e. incomplete).
getValues() should be expecting a JS Object like...
Code:
{ vehicles:[{ year: x1, make: "y2", model: "z2" },{ year: x2, make: "y2", model: "z2" }] }
Anyone have any ideas on what I'm doing wrong?
Thanks,
--mgbowman
-----
Here's the code for my two forms:
VehiclesForm.js
Code:
isc.defineClass("VehiclesForm", "DynamicForm").addProperties({ count: 0, max: 5, initWidget: function(config) { this.numCols = 4; this.fields = [{ name: "add", title: "Add Vehicle", type: "button", click: this.getID() + ".addVehicle()", endRow: false },{ name: "remove", title: "Remove Vehicle", type: "button", click: this.getID() + ".removeVehicle()", startRow: false, disabled: true }]; this.vehicleForms = []; for (var i = 0; i < this.max; i++) { this.vehicleForms.add(isc.VehicleForm.create({ requiredIf: this.getID() + ".count > " + i })); this.fields.add({ name: "vehicles", title: "Vehicle #" + (i + 1), type: "nestedEditor", editor: this.vehicleForms[i], showIf: this.getID() + ".count > " + i, }); } this.Super("initWidget", arguments); }, validate: function(validateHiddenFields) { var valid = true; for (var i = 0; i < this.count; i++) { valid &= this.vehicleForms[i].validate(validateHiddenFields); } return valid; }, getValues: function() { var vehicles = []; for (var i = 0; i < this.count; i++) { vehicles.add(this.vehicleForms[i].getValues()); } return { vehicles: vehicles } }, addVehicle: function() { if (this.count < this.max) { this.count++; this.markForRedraw(); } if (this.count == this.max) { this.getField("add").disable(); } this.getField("remove").enable(); }, removeVehicle: function() { if (this.count > 0) { this.count--; this.markForRedraw(); } if (this.count == 0) { this.getField("remove").disable(); } this.getField("add").enable(); } });
Code:
isc.defineClass("VehicleForm", "DynamicForm").addProperties({ initWidget: function(config) { this.fields = [{ name: "year", title: "Year", editorType:"select", optionDataSource:vehicleYears, changed: function() { var make = this.form.getField('make'); var model = this.form.getField('model'); make.clearValue(); model.clearValue(); make.enable(); model.disable(); make.fetchData(); }, validators: [{ type: "requiredIf", expression: config.requiredIf }] }, { name: "make", title: "Make", editorType: "select", optionDataSource: vehicleMakes, autoFetchData: false, disabled: true, changed: function() { var model = this.form.getField('model'); model.clearValue(); model.fetchData(); model.enable(); }, getPickListFilterCriteria: function() { var year = this.form.getValue("year"); return {year:year}; }, validators: [{ type: "requiredIf", expression: config.requiredIf }] }, { name: "model", title: "Model", editorType: "select", optionDataSource: vehicleModels, autoFetchData: false, disabled: true, getPickListFilterCriteria: function() { var year = this.form.getValue("year"); var make = this.form.getValue("make"); return {year: year, make: make}; }, validators: [{ type: "requiredIf", expression: config.requiredIf }] }]; this.Super("initWidget", arguments); } });
Comment