Reputation: 2867
So I have this form on my Index.cshtml view (Some data removed to shorten length), I want to be able to submit it to the action "/Estimate/Index" defined as,
public ActionResult CreateEstimate(Estimate Est);
It creates the object just fine by serializing the data and submitting, my problem is that sub-object data is not inserted (and I understand that it doesn't cause it doesn't know how), I was curious if there was a way to tell it how to correctly create the objects in a simple/automated manner.
I've tried giving the NetUplift a different name,
Ex. name="NetUplift.Value"
but this results in an internal server error (code 500).
Form in razor view - Index.cshtml
<form id="form-create-estimate">
<table id="table-create-estimate" class="table">
<tbody>
<tr>
<td class="td-header">ID</td>
<td id="td-id"><input name="ID" type="text" value="" /></td>
</tr>
<tr>
<td class="td-header">Name</td>
<td id="td-name"><input name="Name" type="text" value="" /></td>
</tr>
<tr>
<td class="td-header">Job Difficulty</td>
<td id="td-jobdifficulty"><input name="JobDifficulty" type="text" value="" /></td>
</tr>
<tr>
<td class="td-header">Type</td>
<td id="td-type"><input name="Type" type="text" value="" /></td>
</tr>
<tr>
<td class="td-header Unit">Net Uplift</td>
<td id="td-netuplift">
<input name="NetUplift" class="Unit" title="in PSF" type="number" value="" />
@*<input name="NetUplift.DataType" type="hidden" value="System.Int32" />
<input name="NetUplift.UnitOfMeasure" type="hidden" value="psf" />*@
</td>
</tr>
<tr>
<td class="td-header Unit">Joist Spacing</td>
<td id="td-joistspacing"><input name="JoistSpacing" class="FeetInch" title="in Feet' Inch''" type="text" value="" /></td>
</tr>
</tr>
<tr>
<td class="td-header">Drawing Location</td>
<td id="td-drawinglocation"><input name="DrawingLocation" type="text" value="" /></td>
</tr>
<tr>
<td><input id="button-submit-estimate" type="button" value="Create" /></td>
<td><input id="button-cancel-estimate" type="button" value="Cancel" /></td>
</tr>
</tbody>
</table>
</form>
Ajax Submit Script
// Do an Ajax Post to Submit the newly created Estimate.
function CreateEstimate() {
// Serialize the Form.
var Estimate = $("#form-create-estimate").serialize();
// Send the Serialized Form to the Server to be processed and returned
// as an updated page to asynchronously update this page.
// I guess instead of returning this entire page we could make the action
// return just a table row with the Estimate's Data, then append it to the table
// of estimates. It'll be saved to the list of estimates too so there won't be
// a chance to the lists on the Client and list on the server to be different.
$.ajax({
url: "/Estimate/CreateEstimate/",
datatype: "json",
data: Estimate,
contenttype: "application/json",
success: function (Data, Success) {
if (Data.Estimate !== undefined) {
// Create a Html Table Row from the Estimate.
// Append the Row to the Table.
// Hide the Dialog.
} else {
alert("No Error Occured; however, the Creation of the Estimate was unsuccessful. Please Try Again.");
}
},
error: function (xhr, ajaxOptions, thrownError) {
alert("An Error Occured. \n" + thrownError + "\n" + xhr.status);
}
});
}
Estimate Class
public class Estimate
{
public Int32 ID { get; set; }
public String JobDifficulty { get; set; }
public String Type { get; set; }
public String Name { get; set; }
public Unit NetUplift { get; set; }
public Unit JoistSpacing { get; set; }
public String DrawingLocation { get; set; }
}
Unit Class
public class Unit
{
public String Value { get; set; }
public Type DataType { get; set; }
public String UnitOfMeasure { get; set; }
public Unit(Type DataType, String Value, String UnitOfMeasure)
{
this.Value = Value;
this.DataType = DataType;
this.UnitOfMeasure = UnitOfMeasure;
}
}
Currently the action CreateEstimate(Estimate Est)
recieves the data submitted except for sub-object values such as Unit
(Estimate.NetUplift
). How do I tell it to map NetUplift to Estimate.NetUplift.Value
, and the two commented out input fields to NetUplift.DataType
/NetUplift.UnitOfMeasure
?
Is there a way to have the server just know that it should be mapped that way or do I have to do it before sending the form to the server?
Upvotes: 0
Views: 313
Reputation: 50493
You could try this:
$.fn.serializeToObject = function () {
var o = {};
var a = this.serializeArray();
$.each(a, function () {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
var estimate = $("#form-create-estimate").serializeToObject();
Upvotes: 2