Search code examples
javascriptjqueryjquery-chosen

jQuery-chosen - Push custom option attribute of selected option to list


I've an option list like bellow

<select data-placeholder="Choose users" style="width:350px;" multiple class="chosen-select" tabindex="8">
    <option data-user-id="1">User1</option>
    <option data-user-id="3">User2</option>
    <option data-user-id="6">User3</option>
    <option data-user-id="14">User4</option>
</select>

I can select multiple options using chosen plugin. Each selected value entered into new <li> element like the follow:

<li class="search-choice"><span>User</span><a class="search-choice-close" data-option-array-index="2"></a></li>

Is there any way to push data-user-id from the option to the above <li>.

Can I do it without hacking chosen plugin?

Below you will find my solution by changing a little bit chosen plugin


Solution

  • Inside with SelectParser.prototype.add_option I got my custom attribute using jquery and then I've pushed it as an option.

    The SelectParser.prototype.add_option looks like:

    SelectParser.prototype.add_option = function(option, group_position, group_disabled) {
      if (option.nodeName.toUpperCase() === "OPTION") {
        if (option.text !== "") {
          if (group_position != null) {
            this.parsed[group_position].children += 1;
          }
          this.parsed.push({
            user_id: $(option).attr('data-user-id'),
            array_index: this.parsed.length,
            options_index: this.options_index,
            value: option.value,
            text: option.text,
            html: option.innerHTML,
            title: option.title ? option.title : void 0,
            selected: option.selected,
            disabled: group_disabled === true ? group_disabled : option.disabled,
            group_array_index: group_position,
            group_label: group_position != null ? this.parsed[group_position].label : null,
            classes: option.className,
            style: option.style.cssText
          });
        } else {
          this.parsed.push({
            array_index: this.parsed.length,
            options_index: this.options_index,
            empty: true
          });
        }
        return this.options_index += 1;
      }
    };
    

    As you noticed I put only this user_id: $(option).attr('data-user-id'), line of code.

    Then to push the data-user-id to the <li> list I add this line 'data-user-id': item.user_id to Chosen.prototype.choice_build so at then end it looks like:

      Chosen.prototype.choice_build = function(item) {
          var choice, close_link,
            _this = this;
          choice = $('<li />', {
            "class": "search-choice"
          }).html("<span>" + (this.choice_label(item)) + "</span>");
          if (item.disabled) {
            choice.addClass('search-choice-disabled');
          } else {
            close_link = $('<a />', {
              "class": 'search-choice-close',
              'data-option-array-index': item.array_index,
              'data-user-id': item.user_id
            });
            close_link.bind('click.chosen', function(evt) {
              return _this.choice_destroy_link_click(evt);
            });
            choice.append(close_link);
          }
          return this.search_container.before(choice);
        };
    

    That's it! You can push as many custom attribute as you want with this way.