Search code examples
ajaxjsonasp.net-mvc-4razor-2

How can I automatically map a json object to fields based off a viewmodel mapped to fields?


I have a view that is loaded with a blank viewmodel initially. I want to populate that already rendered view with a json object (obtained view ajax post) that was based off the viewmodel for that view.

Is there a way of automatically doing this?
Is there a way of doing it in reverse? (fields to matching viewmodel json object)


Solution

  • Ok it looks like this will suit my needs. I need to follow a convention of naming containers the same name as their respective properties as well as putting a class on them to indicate that they contain subfields.

    function MapJsonObjectToForm(obj, $container) {
        for (var key in obj) {
            if (obj.hasOwnProperty(key)) {
                var $field = $container.find('#' + key);
                if ($field.is('div')) {
                    MapJsonObjectToForm(obj[key], $field);
                } else {
                    if (obj[key] == null) {
                        if ($field.hasClass('select2-offscreen')) {
                            $field.select2('val', '');
                            $field.select2().trigger('change');
                        } else {
                            $field.val("");
                        }
                    } else {
                        if ($field.hasClass('select2-offscreen')) {
                            $field.select2('val', obj[key]);
                            $field.select2().trigger('change');
                        } else {
                            $field.val(obj[key]);
                        }
                    }
                }
            }
        }
    }
    
    function MapFormToJsonObject(containerid) {
        var obj = {};
        $('.dataitem').each(function () {
            var exclude = "s2id";
            if ($(this).attr("ID").substring(0, exclude.length) !== exclude) {
                var parents = $(this).parents(".has-sub-fields");
                if (parents.length > 0) {
                    obj = FindParents(obj, parents.get(), $(this).attr("ID"), $(this).val());
                } else {
                    obj[$(this).attr("ID")] = $(this).val();
                }
            }
        });
        return obj;
    }
    
    function FindParents(obj, arr, id, value) {
        if (arr.length == 0) {
            obj[id] = value;
            return obj;
        }
        var parentID = $(arr[arr.length - 1]).attr("ID");
        arr.pop();
        if (obj[parentID] == null) {
            obj[parentID] = {};
        }
        obj[parentID] = FindParents(obj[parentID], arr, id, value);
        return obj;
    }