Bootstrap-select: Support for removing <options> from <select> element

Created on 11 Feb 2013  路  19Comments  路  Source: snapappointments/bootstrap-select

When I remove an option element from a select, the bootstrap-select doesn't update. I tried removing the full $('.bootstrap-select') group and re-initializing by calling .selectpicker(), but it won't update and recreate the dropdown.

$("#select_list option[value='New Test List']").remove();

Any suggestions?

Thanks!

All 19 comments

I will fix this to @kayzee

Thanks so much @silviomoreto! This one is a must for me (more than the other issue I posted). I am currently trying manually remove the ".ul .li" element from the boostrap-select group, but this is obviously a work-around hack. A proper refresh on delete (similar to the refresh on insert) would be awesome!

PS. Other than these 2 minor issues that I reported, I love this custom select that you created. I replaced every select2 and upgraded all of the standard selects throughout my whole project with your bootstrap-select!

Currently the select is only updated when there is an insertion to the DOM. A temporary workaround is to append an empty option at the same time as the removal:

$('.remove').click(function() {
    $(".selectpicker option").eq(0).remove();
    $(".selectpicker").append('<option class="hidden"></option>');
});

.hidden {display: none;}

To fix this, cant we just listen for dom node removal as well...

change

 this.$element.bind('DOMNodeInserted', $.proxy(this.reloadLi, this));

to

 this.$element.bind('DOMNodeInserted DOMNodeRemoved', $.proxy(this.reloadLi, this));

m

We could add it in there. However, browser support for DOMNodeRemoved can vary (IE _cough_ IE) , so I would still think it would be better to always use/recommend the render method any time you're modifying the select via javascript. We could possibly remove that line altogether, just to get people in the habit of using render? This is how jQuery mobile handles the modification of form elements (with their refresh method), so I don't think people will think it's that big of an issue. Perhaps we could just update the documentation to make that more clear?

Just a comment about the render. I attempted to use render in IE8 after adding an element and the bootstrap list wouldn't update. I ended up calling reloadLi, which calls render() inside. Any reason why reloadLi works but render doesn't (in the wonderful world of IE that is. Chrome and Firefox work fine when adding new elements).

Yeah, its the same issue with IE 8 support for DOMNodeRemoved

the render method doesn't actually re build the list, it just updates the state - selected values, disabled items etc etc.

Adding and removing elements requires a rebuild - reloadLi

It works on other browsers as they support the DOMNodeInserted event, which the plugin listens for and triggers a reloadLi.

So...

We should probably add a refresh method, that will fire reloadLi and render.

This way, you can call render (less overhead) if you are just manually changing values / states. Or refresh if you modify the underlying structure.

That sounds like a good idea..if you guys don't beat me to it, I'll submit a pull request sometime next week.

As discussed in #31, we need to move the size logic into its own size method which can be called at init and refresh

m.

Hey everyone,

I'm working with the awesome Bootstrap Select, but experienced a weird behavior which you might be able to help me with. It's within a Bootstrap modal dialog where the first paragraph holds the item selector and whenever that selector is changed, the selected option's detail data (manufacturer, color, etc.) is loaded via AJAX.

The relevant JavaScript code:

$(document).ready(function () {
  var deleteItem = $('#delete-item');
  var itemManufacturer = $('#item-manufacturer');
  var itemSelector = $('#item-selector');
  var itemSelectorOption = $('#item-selector option'); // also tried: $('#item-selector option:selected');
  // ... code left out for terse reasons ...    

  deleteItem.click(function () {
    var itemID = itemSelector.val();

    $.ajax({
      // ... code left out for terse reasons ...
    }).done(function (response) {
      if (response > 0) {
        itemSelectorOption.eq(0).remove();
        itemSelector.append('<option class="hidden"></option>');
        itemSelector.selectpicker('refresh');

        itemManufacturer.selectpicker('deselectAll');
        // ... several more lines, resetting other input fields ...
      }
        // ... else left out for terse reasons as well ...
    });
  });
});

As you can see, I've tried to incorporate the solution suggested by @caseyjhol in https://github.com/silviomoreto/bootstrap-select/issues/52#issuecomment-13754729, but didn't have any luck after the first removal. Also, since I use the title attribute, .eq(0) gives me that "placeholder" text, but even .eq(1). only removes the option the first time I click the delete button.

Now, the HTML "template":

<select id="item-selector" class="selectpicker show-menu-arrow show-tick" data-id="' . $item["itemID"] . '" data-width="479px" title="Please select an item">
{PHP code which loops the following line for each item}
  <option value="' . $item["ItemID"] . '">' . $item["ItemConcatName"] . '</option>
{PHP code which loops the above line for each item}
</select>

So, my problem is: the deleteItem button only works the first time it's clicked. Each consecutive click resets the other input fields, but not itemSelector.

What am I doing wrong and how can I fix that? And is there maybe a better approach to resetting itemManufacturer than by using .selectpicker('deselectAll')? Because it's a dropdown menu where only one item can be selected at a time.
Would it be possible to enhance Bootstrap Select in order to offer add/delete methods?

Regards,
Martin

This may happen because of the query for the itemSelectorOption was made outside the scope of the request action. try to move the line var itemSelectorOption = $('#item-selector option'); before the itemSelectorOption.eq(0).remove();, so you will update the selector for the options

Well, that makes the delete button working and the select menu resetting its text to the title attribute's value. But unfortunately, no entry is removed from the dropdown menu this way.

Nevermind, I've fixed it myself. So, in essence, the correct lines (for deleting the currently selected option) read like this:

var itemSelectorOption = $('#item-selector option:selected');
itemSelectorOption.remove();
itemSelector.selectpicker('refresh');

Thanks for your help, @silviomoreto! :)

Sorry, but I have to come back one more time: how to raise the changed.bs.select event manually?
Because prior to deleting the currently selected option, I set the next sibling as being selected by calling:

var itemSelectorOption = $('#item-selector option:selected');
itemSelector.selectpicker('val', itemSelectorOption.next().val());
itemSelectorOption.remove();
itemSelector.selectpicker('refresh');

But this doesn't raise the changed event which therefore prevents the itemManufacturerSelector from being changed appropriately (i. e. new item means new manufacturer).

itemSelector.trigger('changed.bs.select');

Well, I overlooked that "Option" suffix and for about 2 hours, I've triggered itemSelectorOption instead of itemSelector. I'm so sorry, @caseyjhol. I want to curl up and die. -.-
But thanks a bunch for pointing me into the right direction! :+1:

@Eagle3386 do not worry! the important thing is that you solved your problem! hope bootstrap-select helped you in your project

It does tremendously! :)

However, as an improvement, I'd like to suggest a better approach for the default text by implementing support for a placeholder value - much like native HTML5 input elements already offer.

Currently, the title attribute is somewhat used for that. But this gave me many headaches, because I'm in a scenario where I do need both, as placeholder (e. g. when a selected option is removed or simply deselected) and at the same time as the default value (e. g. when the page gets loaded or the modal dialog received the content after being rendered by PHP and transfered via AJAX).

As a feature request, I'd like to ask for native AJAX support of the data source, as, to put it simple, Ajax-Bootstrap-Select sucks. Right now, I have to use this code to achieve AJAX loading:

itemManufacturer.selectpicker()
  .on('loaded.bs.select', function (event, clickedIndex, newValue, oldValue) {
    $.getJSON('/path/to/item-manufacturers.php', function (response) {
      itemManufacturer.html('');
      $.each(response, function (key, value) {
        itemManufacturer.append('<option value="' + value.ID + '">' + value.Name + '</option>');
      });
    }).done(function () {
      itemManufacturer.selectpicker('refresh');
      itemManufacturer.selectpicker('val', itemManufacturer.data('initial-manufacturer'));
    });
  });

So, it would be really awesome, to just give the JSON-url as a settings property and also have a placeholder option. :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ddinchev picture ddinchev  路  3Comments

edwolfe807 picture edwolfe807  路  3Comments

Cruyjun picture Cruyjun  路  3Comments

james-yun picture james-yun  路  3Comments

EmilMoe picture EmilMoe  路  4Comments