jQuery выбор меню onchange

Я хочу сделать меню выбора с иконками, а текст, который вы выбрали, должен отображаться в тексте сверху (или иконке). Моя проблема в том, что метод изменения не работает.

Что не так?

$(function() {
  $.widget("custom.iconselectmenu", $.ui.selectmenu, {
    _renderItem: function(ul, item) {
      var li = $("<li>"),
        wrapper = $("<div>", {
          text: item.label
        });

      if (item.disabled) {
        li.addClass("ui-state-disabled");
      }

      $("<span>", {
        style: item.element.attr("data-style"),
        "class": "ui-icon " + item.element.attr("data-class")
      }).appendTo(wrapper);

      return li.append(wrapper).appendTo(ul);
    },
    select: function(event, ui) {
      console.log("test")
    }
  });

  $("#icons_id")
    .iconselectmenu()
    .iconselectmenu("menuWidget")
    .addClass("ui-menu-icons avatar");

});

var select = document.getElementById("icons_id");

var options = ["Aufgabe", "Gruppe", "Schritt", "Werkzeug", "Dokument"];

for (var i = 0; i < options.length; i++) {

  var opt = options[i];

  var el = document.createElement("option");

  var icon = opt;

  el.style

  el.textContent = opt;

  el.value = opt;


  select.appendChild(el);

}

function myFunction() {

  var x = document.getElementById("icons_id").value;

  document.getElementById("demo_text").innerHTML = "You selected: " + x;

}
option.avatar {
  background-repeat: no-repeat !important;
  padding-left: 20px;
}

.avatar .ui-icon {
  background-position: left top;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link href="https://code.jquery.com/ui/1.12.0/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>


<h2 id="test">Dropdown Menu</h2>

<p id="demo_text">You selected: </p>

<select name="icons_name" id="icons_id" onchange="myFunction()">

  <option data-class="avatar" data-style="background-image: url(&apos;http://www.gravatar.com/avatar/b3e04a46e85ad3e165d66f5d927eb609?d=monsterid&amp;r=g&amp;s=16&apos;);">1</option>

  <option data-class="avatar" data-style="background-image: url(&apos;http://www.gravatar.com/avatar/e42b1e5c7cfd2be0933e696e292a4d5f?d=monsterid&amp;r=g&amp;s=16&apos;);">2</option>

  <option data-class="avatar" data-style="background-image: url(&apos;http://www.gravatar.com/avatar/bdeaec11dd663f26fa58ced0eb7facc8?d=monsterid&amp;r=g&amp;s=16&apos;);">3</option>

</select>

3 ответа

change событие оригинала <select> элемент не сработает, так как вы управляете элементами виджета Selectmenu, а не <select>, Вы можете вручную вызвать change на оригинальный элемент, например .trigger("change"), но вместо этого вы можете рассмотреть возможность использования виджета Selectmenu change событие, чтобы запустить вашу функцию.

В приведенном ниже фрагменте я переместил change событие из настройки виджета и в iconselectmenu инициализация.

Как это:

.iconselectmenu({
  change: myFunction
})

(Также см . Ответ Тома Махера для другого способа определения select обработчик события.)

Рабочий пример:

$(function() {
  $.widget("custom.iconselectmenu", $.ui.selectmenu, {
    _renderItem: function(ul, item) {
      var li = $("<li>"),
        wrapper = $("<div>", {
          text: item.label
        });

      if (item.disabled) {
        li.addClass("ui-state-disabled");
      }

      $("<span>", {
        style: item.element.attr("data-style"),
        "class": "ui-icon " + item.element.attr("data-class")
      }).appendTo(wrapper);

      return li.append(wrapper).appendTo(ul);
    }
  });

  $("#icons_id")
    .iconselectmenu({
      change: myFunction
    })
    .iconselectmenu("menuWidget")
    .addClass("ui-menu-icons avatar");

});


var select = document.getElementById("icons_id");
var options = ["Aufgabe", "Gruppe", "Schritt", "Werkzeug", "Dokument"];

for (var i = 0; i < options.length; i++) {
  var opt = options[i];
  var el = document.createElement("option");
  var icon = opt;
  el.textContent = opt;
  el.value = opt;
  select.appendChild(el);
}

function myFunction() {
  var x = document.getElementById("icons_id").value;
  document.getElementById("demo_text").innerHTML = "You selected: " + x;
}
option.avatar {
  background-repeat: no-repeat !important;
  padding-left: 20px;
}

.avatar .ui-icon {
  background-position: left top;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link href="https://code.jquery.com/ui/1.12.0/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>


<h2 id="test">Dropdown Menu</h2>
<p id="demo_text">You selected: </p>

<select name="icons_name" id="icons_id" onchange="myFunction()">
  <option data-class="avatar" data-style="background-image: url(&apos;http://www.gravatar.com/avatar/b3e04a46e85ad3e165d66f5d927eb609?d=monsterid&amp;r=g&amp;s=16&apos;);">1</option>
  <option data-class="avatar" data-style="background-image: url(&apos;http://www.gravatar.com/avatar/e42b1e5c7cfd2be0933e696e292a4d5f?d=monsterid&amp;r=g&amp;s=16&apos;);">2</option>
  <option data-class="avatar" data-style="background-image: url(&apos;http://www.gravatar.com/avatar/bdeaec11dd663f26fa58ced0eb7facc8?d=monsterid&amp;r=g&amp;s=16&apos;);">3</option>
</select>


Редактировать:

Один из способов добавить значок в #demo_text это ссылаться на то же самое data-style атрибут, который вы используете при рендеринге виджета. В пределах change обработчик событий, я беру фоновое изображение и создаю элемент значка для добавления к #demo_text вместе со значением выбранного параметра.

Кроме того, поскольку вы используете jQuery, я решил написать код в jQuery, а не ванильный JavaScript.

$(function() {
  $.widget("custom.iconselectmenu", $.ui.selectmenu, {
    _renderItem: function(ul, item) {

      var li = $("<li>");

      var wrapper = $("<div>", {
        "text": item.label,
      });

      if (item.disabled) {
        li.addClass("ui-state-disabled");
      }

      $("<span>", {
        "style": item.element.attr("data-style"),
        "class": "ui-icon " + item.element.attr("data-class")
      }).appendTo(wrapper);

      return li.append(wrapper).appendTo(ul);

    }
  });

  $("#icons_id")
    .iconselectmenu({
      change: myFunction
    })
    .iconselectmenu("menuWidget")
    .addClass("ui-menu-icons avatar");

});


var options = ["Aufgabe", "Gruppe", "Schritt", "Werkzeug", "Dokument"];
var $select = $('#icons_id');
var $display = $('#demo_text');

$.each(options, function() {
  var $option = $('<option>', {
    "value": this,
    "text": this
  });
  $select.append($option);
});

function myFunction(e, ui) {
  var $value = $("<span>", {
    "text": $select.val()
  });
  var $icon = $("<span>", {
    "style": ui.item.element.data("style"),
    "class": "ui-icon "
  });
  $display.text('You selected: ').append($icon, $value);
}
option.avatar {
  background-repeat: no-repeat !important;
  padding-left: 20px;
}

.avatar .ui-icon {
  background-position: left top;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link href="https://code.jquery.com/ui/1.12.0/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>


<h2 id="test">Dropdown Menu</h2>
<p id="demo_text">You selected: </p>

<select name="icons_name" id="icons_id" onchange="myFunction()">
  <option data-class="avatar" data-style="background-image: url(&apos;http://www.gravatar.com/avatar/b3e04a46e85ad3e165d66f5d927eb609?d=monsterid&amp;r=g&amp;s=16&apos;);">1</option>
  <option data-class="avatar" data-style="background-image: url(&apos;http://www.gravatar.com/avatar/e42b1e5c7cfd2be0933e696e292a4d5f?d=monsterid&amp;r=g&amp;s=16&apos;);">2</option>
  <option data-class="avatar" data-style="background-image: url(&apos;http://www.gravatar.com/avatar/bdeaec11dd663f26fa58ced0eb7facc8?d=monsterid&amp;r=g&amp;s=16&apos;);">3</option>
</select>


Редактировать:

Вот пример того, как заполнить <select> элемент исключительно из массива объектов, так что вы можете указать значок для каждого <option>,

Я также использовал код из этого поста, чтобы показать "заполнитель" для выпадающего списка до выбора пользователя.

Я также перешел с change событие в select событие. Первый вариант выбран по умолчанию (даже если отображается заполнитель), поэтому change не срабатывает, если вы выберете его снова.

$(function() {

  /* Customize Widget */

  $.widget("custom.iconselectmenu", $.ui.selectmenu, {
    _drawButton: function() {
      this._super();
      var selected = this.element
        .find('[selected]')
        .length,
        placeholder = this.options.placeholder;

      if (!selected && placeholder) {
        this.buttonItem.text(placeholder);
      }
    },
    _renderItem: function(ul, item) {

      var style = "background-image:url('" + item.element.attr("data-icon") + "')";

      var li = $("<li>");

      var wrapper = $("<div>", {
        "text": item.label,
      });

      if (item.disabled) {
        li.addClass("ui-state-disabled");
      }

      $("<span>", {
        "style": style,
        "class": "ui-icon"
      }).appendTo(wrapper);

      return li.append(wrapper).appendTo(ul);

    }
  });

  /* Define Select Handler */

  function chooseOption(e, ui) {
    var style = "background-image:url('" + options[ui.item.index]['data-icon'] + "')";
    var $value = $("<span>", {
      "text": $select.val()
    });
    var $icon = $("<span>", {
      "style": style,
      "class": "ui-icon"
    });
    $display.text('You selected:').append($icon, $value);
  }

  /* Define Select Options */

  var options = [{
      'value': 'Aufgabe',
      'text': 'Aufgabe',
      'data-icon': 'http://www.gravatar.com/avatar/b3e04a46e85ad3e165d66f5d927eb609?d=monsterid&r=g&s=16'
    },
    {
      'value': 'Gruppe',
      'text': 'Gruppe',
      'data-icon': 'http://www.gravatar.com/avatar/e42b1e5c7cfd2be0933e696e292a4d5f?d=monsterid&r=g&s=16'
    },
    {
      'value': 'Schritt',
      'text': 'Schritt',
      'data-icon': 'http://www.gravatar.com/avatar/bdeaec11dd663f26fa58ced0eb7facc8?d=monsterid&r=g&s=16'
    },
    {
      'value': 'Werkzeug',
      'text': 'Werkzeug',
      'data-icon': 'https://picsum.photos/30/30/?image=2'
    },
    {
      'value': 'Dokument',
      'text': 'Dokument',
      'data-icon': 'https://picsum.photos/30/30/?image=12'
    }
  ];

  /* Generate Select Options */

  var $select = $('#icons_id');
  var $display = $('#demo_text');

  $.each(options, function() {
    var $option = $('<option>', this);
    $select.append($option);
  });

  /* Initialize SelectMenu */

  $("#icons_id")
    .iconselectmenu({
      placeholder: 'Select an Option',
      select: chooseOption
    })
    .iconselectmenu("menuWidget")
    .addClass("ui-menu-icons");

});
.ui-icon {
  background-position: left center;
}

#demo_text .ui-icon {
  margin: 0 .5em;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link href="https://code.jquery.com/ui/1.12.0/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>

<p id="demo_text"></p>
<select name="icons_name" id="icons_id"></select>

Думаю, проблема в том, что вы добавляете метод select в свой виджет, а не устанавливаете метод select в базовом виджете (selectmenu) для использования в качестве обработчика событий.

Следующее должно работать:

$(function() {
  $.widget("custom.iconselectmenu", $.ui.selectmenu, {
    _create: function(){
        this.element.on("selectmenuselect", function( event, ui ) {
            console.log("test");
        } ););
    }

    _renderItem: function(ul, item) {
      var li = $("<li>"),
        wrapper = $("<div>", {
          text: item.label
        });

      if (item.disabled) {
        li.addClass("ui-state-disabled");
      }

      $("<span>", {
        style: item.element.attr("data-style"),
        "class": "ui-icon " + item.element.attr("data-class")
      }).appendTo(wrapper);

      return li.append(wrapper).appendTo(ul);
    }
  });

Вы упускаете значение для опций

    function myFunction() {
      var x = document.getElementById("icons_id").value;    
      document.getElementById("demo_text").innerHTML = "You selected: " + x;    
    }
    <h2 id="test">Dropdown Menu</h2>

    <p id="demo_text">You selected: </p>

    <select name="icons_name" id="icons_id" onchange="myFunction()">

      <option value="1" data-class="avatar" data-style="background-image: url(&apos;http://www.gravatar.com/avatar/b3e04a46e85ad3e165d66f5d927eb609?d=monsterid&amp;r=g&amp;s=16&apos;);">1</option>

      <option value="2" data-class="avatar" data-style="background-image: url(&apos;http://www.gravatar.com/avatar/e42b1e5c7cfd2be0933e696e292a4d5f?d=monsterid&amp;r=g&amp;s=16&apos;);">2</option>

      <option value="3" data-class="avatar" data-style="background-image: url(&apos;http://www.gravatar.com/avatar/bdeaec11dd663f26fa58ced0eb7facc8?d=monsterid&amp;r=g&amp;s=16&apos;);">3</option>

    </select>

Другие вопросы по тегам