web-dev-qa-db-fra.com

Liste d'options de mise à jour de Bootstrap Multiselect sur le flux

J'utilise bootstrap multi-select et je souhaite mettre à jour les options sur flow avec ajax

Pour renseigner sur mon multisélection je le fais

<select name="model" class="multiselect" multiple="multiple">
                <? foreach ($sel_models as $mod) { ?>
                    <option value="<?= $mod ?>" <?= ($mod == $params['model']) ? 'selected' : '' ?>><?= $mod ?></option>
                <? } ?>    
</select>  

puis sur l'événement, je voudrais mettre à jour ma liste d'options avec le ajax suivant

J'essayais d'utiliser la méthode de reconstruction mais je ne tire pas le menu déroulant après la création

 $.ajax({
        type: 'post',
        url: "helper/ajax_search.php",
        data: {models: decodeURIComponent(brands)},
        dataType: 'json',
        success: function(data) {
            $('select.multiselect').empty();
            $('select.multiselect').append(
                    $('<option></option>')
                    .text('alle')
                    .val('alle')
                    );

            $.each(data, function(index, html) {
                $('select.multiselect').append(
                        $('<option></option>')
                        .text(html.name)
                        .val(html.name)
                        );
            });

            $('.multiselect').multiselect('rebuild')
        },
        error: function(error) {
            console.log("Error:");
            console.log(error);
        }
    });

Avec firebug je peux voir que la liste est générée mais sur select ne sera pas affiché

8
fefe

Dans la doc, je peux lire:

.multiselect ('setOptions', options) Utilisé pour changer la configuration après l'initialisation du multiselect. Cela peut être utile en combinaison avec .multiselect ('rebuild').

Peut-être que vous ne pouvez pas modifier les données de votre widget par votre chemin initial. De manière correcte, vous devriez utiliser la méthode setOptions

Sinon: avec votre chemin, peut-être devriez-vous penser à détruire votre widget .multiselect('destroy') et à le recréer après.

Mise à jour après commentaire:

Dans la doc: (vous avez lié)

Fournit des données pour construire les options de la manière suivante:

var data = [
    {label: "ACNP", value: "ACNP"},
    {label: "test", value: "test"}
];
$("#multiselect").multiselect('dataprovider', data);

Donc: Lorsque vous recevez des données de votre appel ajax, vous devez créer un tableau d'objets (ce sont les options de la sélection que vous souhaitez avoir) avec le format suivant: 

var data = 
[
    {label: 'option1Label', value: 'option1Value'},
    {label: 'option2Label', value: 'option2Value'},
    ...
]

Lorsque votre tableau d'objets est créé, il vous suffit d'appeler la méthode 

$("#multiselect").multiselect('dataprovider', data);

Où données est votre tableau d'objets.

J'espère que je suis clair: /

21
Pimento Web

Au lieu de multisélectionner ('fournisseur de données', données), vous pouvez créer la liste avec jquery append exactement comme vous l'avez fait dans votre question. Le seul changement à effectuer consiste à retarder la reconstruction après la fin de la demande ajax.

var buildDrivers = $.getJSON('resources/orders/drivers.json', function(data) { 
   $.each(data, function(i, driver) {
      $('#toolbar select[name="drivers"]').append('<option>'+driver+'</option>');
   });
});
buildDrivers.complete(function() {
    $('.multiselect').multiselect('rebuild');
});

voir http://api.jquery.com/jquery.getjson/ pour la documentation

9
tbradley22

La fonctionnalité de mise à jour des options a été ajoutée après filtrage et obtention du côté serveur. Cette solution repose sur le concept d'injection de nouvelles options, de destruction de la sélection et de son initialisation.

J'ai pris en compte:

  1. Considérant les options sélectionnées existantes, qui doivent rester.
  2. Suppression des options en double (il peut s’agir d’un conflit qui a déjà été sélectionné et de la nouvelle provenant du serveur).
  3. Garder le bac d'options ouvert après la mise à jour.
  4. Réattribuez le texte précédent dans la zone de texte de recherche et concentrez-le.

Ajoutez simplement 'updateOptions' en tant que fonction après la fonction 'refresh' avec les deux fonctions d'assistance, comme suit:

updateOptions: function (options) {
        var select = this.$select;
        options += this.getSelectedOptionsString();
        var selectedIds = select.val(),
            btnGroup = select.next('.btn-group'),
            searchInput = btnGroup.find('.multiselect-search'),
            inputVal = searchInput.val();

        options = this.removeOptionsDuplications(options);
        if (!options) {
            options = '<option disabled></option>';
        }

        // 1) Replacing the options with new & already selected options
        select.html(options);

        // 2) Destroyng the select
        select.multiselect('destroy');

        // 3) Reselecting the previously selected values
        if (selectedIds) {
            select.val(selectedIds);
        }

        // 4) Initialize the select again after destroying it
        select.multiselect(this.options);

        btnGroup = select.next('.btn-group');
        searchInput = btnGroup.find('.multiselect-search');

        // 5) Keep the tray options open
        btnGroup.addClass('open');

        // 6) Setting the search input again & focusing it
        searchInput.val(inputVal);
        searchInput.focus();
    },
    getSelectedOptionsString: function () { // Helper
        var result = '',
            select = this.$select,
            options = select.find('option:selected');

        if (options && options.length) {
            $.each(options, function (index, value) {
                if (value) {
                    result += value.outerHTML;
                }
            });
        }

        return result;
    },
    removeOptionsDuplications: function (options) { // Helper
        var result = '',
            ids = new Object();

        if (options && options.length) {
            options = $(options);
            $.each(options, function (index, value) {
                var option = $(value),
                    optionId = option.attr('value');

                if (optionId) {
                    if (!ids[optionId]) {
                        result += option[0].outerHTML;
                        ids[optionId] = true;
                    }
                }
            });
        }
        return result;
    },

Démo:

Etat:

"Option 1"

$('#select').multiselect('updateOptions', '<option value="2">Option 2</option>');

Etat:

"Option 2"

"Option 1"

0
Jacob