Search code examples
javascriptjquerybootstrap-multiselect

Dynamically add attributes as object properties


I'm working on bootstrap-multiselect, I'm trying to add data attributes in the dataprovider method.

Current

var options = [
        {label: 'Option 1', title: 'Option 1', value: '1', selected: true},
        {label: 'Option 2', title: 'Option 2', value: '2'}];

In the code it maps these an <option> tag like so:

$tag = $('<option/>').attr({
                        value: option.value,
                        label: option.label || option.value,
                        title: option.title,
                        selected: !!option.selected,
                        disabled: !!option.disabled
                      });

Desired

var options =[
  {
    "label": "Item 1",
    "value": 1,
    "selected": false,
    "attributes": [
      {
        "some-attribute": 10001
      },
      {
        "another-attribute": "false"
      }
    ]
  }
]

So it will render on the HTML element as data-some-attribute="10001" data-another-attribute="false".

I started out adding this to the code (which I know won't work):

$tag = $('<option/>').attr({
                        value: option.value,
                        label: option.label || option.value,
                        title: option.title,
                        selected: !!option.selected,
                        disabled: !!option.disabled,
                        forEach(option.attributes, function(attribute){

                        })
                    });

The problem of course is you can't add a loop as an objects properties. Once this is working I can add a pull request to the repository. I did ask a question on the repo but decided to try and tackle it myself Issue #592 Any ideas?


Solution

  • I would suggest changing attributes from an array to an object, since attribute names should be unique. It also simplifies how you would get the data attributes on the element.

    var attributes = {
      value: option.value,
      label: option.label || option.value,
      title: option.title,
      selected: !!option.selected,
      disabled: !!option.disabled
    };
    
    for (key in option.attributes) {
      attributes['data-' + key] = option.attributes[key];
    }
    
    $tag = $('<option/>').attr(attributes);
    

    If you wanted to keep it as an array, you can do the following:

    var attributes = {
      value: option.value,
      label: option.label || option.value,
      title: option.title,
      selected: !!option.selected,
      disabled: !!option.disabled
    };
    
    for (var i = 0; i < option.attributes.length; i++) {
      var key = Object.keys(option.attributes[i])[0],
          val = option.attributes[i][key];
    
      attributes['data-' + key] = val;
    }
    
    $tag = $('<option/>').attr(attributes);
    

    Doing this, however, provides no benefit and introduces complexity. If each object can have multiple keys, the code will need to change further.