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