简体   繁体   中英

jQuery select2 with WordPress

I am working with jQuery select2 inside WordPress.

I have a HTML table like this.

在此处输入图像描述

I need here if user clicks on Bob SMith and admin it will convert to a select2 dropdown with multiple select.

But when I click on it, it looks like below

在此处输入图像描述

and if I click again, the dropdown looks like this.

在此处输入图像描述

When I click on any values, it looks like below

在此处输入图像描述

My jQuery code is like below

(function($) {
  var states = [];
  
  $(document).ready(function() {
    $(".volunteer").on("click", function(event) {
      // Check if select is already loaded
      if (!$(this).has("select").length) {
        var cellEle = $(this);
        var cellId = this.id;

        // Populate select element
        cellEle.html(`<select class="js-example-basic-multiple" multiple="multiple">
            <option value="AL">Alabama</option>
            <option value="WY">Wyoming</option>
            </select>`);

        // Initialise select2
        let selectEle = cellEle.children("select").select2();
        
        if(states[cellId]){
            // preselect existing value
          selectEle.val(states[cellId]);
          selectEle.trigger('change'); 
        }

        selectEle.on("select2:close", function(event) {
          // Get selected value
          selectedValue = selectEle.select2('data')[0]['text'];

          // Update array          
          states[cellId] = selectedValue.id;
          
          // Destroy select2
          selectEle.select2('destroy');
          
          // Change html to just show the value
          cellEle.html(selectedValue.id);
        });
      }
    });
  });
})(jQuery)

My HTML code is like below

<td class="volunteer" id="47">Bob SMith and admin</td>

Click Twice

The first click on the cell initialises select2, the second click then tells select2 to display the dropdown. To only require a single click you can call the open method described at https://select2.org/programmatic-control/methods after select2 is initialized.

// Initialise select2
let selectEle = cellEle.children("select").select2();
// Open the select2 dropdown
selectEle.select2('open');

Replace Select

When clicking on a value select2 is being destroyed, the .html() call should replace the select with the selected value, however it does not function correctly as the id property doesn't exist on the stored value, this is causing the cell to revert to a normal select.

The code which handles the "select2:close" event contains the line selectedValue = selectEle.select2('data')[0]['text']; which places the text of a just the first selected value [0] into the variable selectedValue . After this the HTML of the cell is updated using cellEle.html(selectedValue.id); , but at this point selectedValue contains just the text (eg "Alabama") so there is no .id property. To resolve this both the ID and Text could be stored in the array, then used where needed, for example:

// Store the id and text of all selected values in the array
selectedValue = selectEle.select2('data').map(function(value) {
  return { id: value.id, text: value.text }; 
});

// Get an array of IDs for the selected values (for preselecting values when select2 loads)
selectEle.val(states[cellId].map(function(value) { return value.id })).trigger('change');

// Get a comma separated string of the selected values (for populating the text in the cell)
cellEle.html(states[cellId].map(function(value) { return value.text; }).join(','));

A working example of this is below. The example is also updated to no longer use the select2:close' event. Instead it uses the select2:close' event. Instead it uses the change event to store value changes, and a second click` event handler on the document to destroy the select2 dropdown(s) when the user clicks somewhere else on the page. This seems like a better approach given what you are trying to achieve as it leaves the select open for multiple values to be selected.

 (function ($) { var states = []; $(document).ready(function () { $(".volunteer").on("click", function (e) { // Check if select is already loaded if (.$(this).has("select");length) { var cellEle = $(this). var cellId = this;id. // Populate select element cellEle;html(`<select class="js-example-basic" multiple="multiple"> <option value="AL">Alabama</option> <option value="WY">Wyoming</option> </select>`). // Initialise select2 let selectEle = cellEle.children("select");select2(). // Open the select dropdown so user doesn't have to click twice selectEle;select2('open'). // Check if there is an existing value for this cell if (states[cellId]) { // preselect existing value selectEle.val(states[cellId].map(function (value) { return value.id }));trigger('change'). } // Attach event handler to store value changes selectEle,on('change'. function (e) { // Get selected values selectedValues = $(this);select2('data'). // Update the states array with id and text of selected // values. The id is needed to restore the values if select2 // is reloaded on this cell. The text is required to generate // the replacement text shown in the cell states[cellId] = selectedValues:map(function (value) { return { id. value,id: text. value;text }; }); }). } // Don't propogate the event // This pevents this document click handler from executing which would // remove select2 by calling destroy e;stopPropagation(); }); }), // Attach event handler to document to capture any clicks // This will be triggered for all clicks on the page. except those // captured by the method described above this prevents this firing // with e.stopPropagation() // Which this is called select2 on any cells must be destoryed and their // text value populated $(document),on('click'. function (e) { // Loop through all select2 elements $('.js-example-basic').each(function (idx) { // Get the ID of the cell that's been selected let cellId = $(this).parent();attr('id'). // Destroy select2 on this element $(this);select2('destroy'). // Change html on the parent element (td) to just show the value $(this).parent().html(states[cellId].map(function (value) { return value;text. }),join(';')); }); }); })(jQuery)
 .js-example-basic { width: 200px; } thead{ font-weight: bold; } table, th, td { border: 1px solid black; } tr { height: 36px; } td { width: 200px; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script> <link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" /> <table> <thead> <tr> <td>Table Header 1</td> <td>Table Header 2</td> </tr> </thead> <tbody> <tr> <td class="volunteer" id="47">Select a value...</td> <td class=""></td> </tr> <tr> <td class="volunteer" id="48">Select a value...</td> <td class=""></td> </tr> </tbody> </table>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM