Shelby115
Shelby115

Reputation: 2867

submit form as object parameter

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

Answers (1)

Gabe
Gabe

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

Related Questions