0

My from elements are written in Object. I need to populate HTML form elements from that. Problem is that Object contains different input types, structure, custom rules etc. For example, there will be text input, image type input, select box, radio, checkbox etc. So, I don't understand looping over the object will be good idea (I started this, but couldn't complete by myself :( ). I could write the html tag element in html file too. But, I must take the value from that object. So, what's the best solution for it?

Sample Object:

var formObj = {
    username: {
    value: null,
    type: 'text',
    placeholder: 'Enter username'
  },
  password: {
    value: null,
    type: 'password',
    placeholder: 'enter password'
  },
  country: {
    value: null,
    type: 'select',
    defaultText: 'Choose here',
    option: [
        {
            value: '1',
        label: 'Australia'
        },
      {
            value: '2',
        label: 'USA'
        },
      {
            value: '3',
        label: 'UK'
        }
    ]
  },
  gender: {
    value: null,
    type: 'select',
    defaultText: null,
    option: [
        {
            value: 'male',
        label: 'Male'
        },
      {
            value: 'female',
        label: 'Female'
        },
      {
            value: 'other',
        label: 'Other'
        }
    ]
  }
}

jsfiddle demo

2 Answers 2

1

your jsfiddle demo revised

Added some comments to your demo. I'd also look into template strings. They'll make your life easier and code cleaner :) and the single responsibility principle for breaking your code into easier to manage/read pieces.

var html = ''; // <-- Initialize as empty string for `+=`
$.each(formObj, function(key, value) {
  if (value.value === null) {
    value.value = '';
  }

  // Add label
  html += '<label for="' + key + '">' + key + '</label>';

  // Add input
  if (value.type === 'select') {
    // Type is select
    html += '<select class="form-control">' + generateOptionPlaceholder(value.defaultText) + generateOptionMarkup(value.option) + '</select>';
  } else {
    html += '<input name="' + key + '" type="' + value.type + '" value="' + value.value + '" placeholder="' + value.placeholder + '" class="form-control" />';
  }

  console.log(html);
});
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, I can now proceed with this concept. Can you please help me with one more step? I have added additionalAttr i.e. disabled, checked and additionalClass in some property of the object. I don't understand how to get all the <input /> those additional attr/class when those are available. Here is the fiddle: jsfiddle.net/learner73/71h6xkbq/71
@user1896653 From your example: jsfiddle. The more you start to add, the more it is important to break each thing into specific actions. "DRY" is another principle that will help with maintenance and writing your programs. Your code is already starting to look better when you refactored the radio/checkbox into a separate function :). jQuery also has many methods that would be useful for your scenario, for example: addClass(). Keep it up!
0

You could use a strategy pattern for this sort of thing. For any variance, used a dictionary where the keys are based off of the variant, and the values are a function to call for that variant.

For example, if your object with form data had a structure like this:

var form = {
    "field1": {
        type: "text"
        value: "foo",
        attrs: {...}
    },
    ...
}

You can use a strategy to handle different field types. Your strategy dictionary might start our like this:

var FIELD_STRATEGY = {
    "input": function (name, value, attrs) {
        // General purpose method for <input>
        // Needs type included in attrs
    "text": function (name, value, attrs) {
        // Constructs an <input type="text">
        attrs.type = "text";
        return FIELD_STRATEGY.input(name, value, attrs);
    },
    "option": function (value, label, attrs) {
        // Constructs an <option>
    },
    "select": function (name, options, attrs {
        // Constructs a <select>
        var opts = options.map(function(opt) {
            return FIELD_STRATEGY.option(
                null,
                opt.value,
                opt.label);
            }).join("");
        var attr_str = Object.keys(attrs).map(function(attr) {
            var value = attrs[attr];
            return name + '="' + value '"';
        }).join(" ");
        return '<select name="' + name + '" ' + attr_str + '>' +
            opts + '</select>';
    }
};

To use it, loop over the field names and invoke strategies based on type:

var fields = Object.keys(form).map(function (name) {
    var conf = form[name] || {};
    var strategy = FIELD_STRATEGY[conf.type];
    var rendered = "";

    if (strategy) {
        rendered = strategy(name, conf.value, conf.attrs);
    }

    return rendered;
});

This will give you a final fields list containing rendered strings based on the strategy for each field type.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.