0
\$\begingroup\$

I have a model with a number of complex/simple properties that has a corresponding strongly typed view, that calls EditorFor to a custom editor template view for the model.

One of the form's requirements is to auto fill the form based on a choose of values from a database.

Previously, I had the selectors on the selection popup do a post back to an action with the additional value needed to prepopulate the model, and then the model is bound like normal.

I wanted to see if I could alter the form to do the prefill with Ajax:

I have a JsonResult Action that accepts a unique Id, and returns the JSON version of the model.

When you click the selection button this action is invoked via jQuery $.ajax post.

Each input on the form has an Id in the form Id="ModelName_PropertyName" so parse the keys in the JSON object, using the keys to look up the field in a given selector, and set the values from JSON.

Here is how I invoke from Ajax in CoffeeScript (I can post the JavaScript if requested):

$.ajax
    type: "POST"
    url: $("#SelectFromPolicyContainer").data "url"
    data: vin
    success: (response) ->
        $("#PropertyInfo").bindFormToJson response.Data.Vehicle, true
        $("#SelectFromPolicyResponse").dialog "close"

The Action looks like this:

[HttpPost]
public JsonResult VehicleByVIN(string VinNumber)
{
    return AjaxJsonResponse.Create(UserNotice.NoNotice, new 
    { 
        Vehicle = Policy.Vehicles.SingleOrDefault(p=>p.Info.Vin.Number==VinNumber)
    });
}

And the definition of bindFormToJson:

$ -> $.fn.bindFormToJson = (JsonObject, OverwritePopulatedFields) ->

    selector = $(this).selector

    iterateJson = (JSonObject, FullKey, Seperator, func) ->
        for key, value of JSonObject
            newKey = ""
            if FullKey == ""
                newKey = key
            else
                newKey = FullKey + Seperator + key

            if typeof(value) == "object" 
                iterateJson value, newKey, Seperator, func  
            else 
                func newKey, value

    iterateJson JsonObject, "", "_", (key,value) -> 
        field = $(selector + " #" + key)
        currentValue = field.val()
        if (currentValue and OverwritePopulatedFields) or not currentValue
            field.val(value)

Any tips, or things I may have missed or potential problems I might have overlooked would be wonderful. In my test environment right now though, this is working beautifully.

\$\endgroup\$
1
\$\begingroup\$

Not a JavaScript pitfall per se, but I'd stay away from using two variable names that are only differentiated by the case of the second letter in a single lexical scope like that. (JsonObject vs JSonObject)

Also, the bindFormToJson function is re-defining the iterateJson function every time it is called, which a waste of cycles (not egregious, but less than ideal). Using coffeescripts do notation is a handy way to create a closure and return a value from it:

$ -> $.fn.bindFormToJson = do ->

    iterateJson = (Source, FullKey, Seperator, func) ->
        for key, value of Source
            newKey = ""
            if FullKey == ""
                newKey = key
            else
                newKey = FullKey + Seperator + key

            if typeof(value) == "object" 
                iterateJson value, newKey, Seperator, func  
            else 
                func newKey, value

    return (JsonObject, OverwritePopulatedFields) ->
        selector = $(this).selector
        iterateJson JsonObject, "", "_", (key, value) -> 
            field = $(selector + " #" + key)
            currentValue = field.val()
            if (currentValue and OverwritePopulatedFields) or not currentValue
                field.val(value)

The return is unnecessary, but I figured it can't hurt to be explicit about what's happening there.

\$\endgroup\$
1
  • \$\begingroup\$ Thank you for the feedback, and I have made the suggested changes. I hadn't use do before, that is very useful. \$\endgroup\$ – asawyer Jan 23 '12 at 13:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.