如何使用 jQuery UI selectMenu 小部件在下拉列表中创建 3 列?

The*_*der 1 html css jquery jquery-ui jquery-ui-selectmenu

我的任务是创建一个包含 3 列(每行)的下拉列表,如下图所示。

下拉图片

现在,我意识到 jQuery UI 的 Selectmenu 小部件将满足我的要求,因此,我使用了以下代码(在他们的官方文档页面上给出)。

<!doctype html>

<html lang="en">

<head>

<meta charset="utf-8">

<title>selectmenu demo</title>

<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css">

<style>

label { display: block; }

select { width: 200px; }

.overflow { height: 200px; }

</style>

<script src="//code.jquery.com/jquery-1.12.4.js"></script>

<script src="//code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

</head>

<body>

<label for="number">Select a number:</label>

<select name="number" id="number">

<option value="1">1</option>

<option value="2" selected>2</option>

<option value="3">3</option>

<option value="4">4</option>

<option value="5">5</option>

<option value="6">6</option>

<option value="7">7</option>

<option value="8">8</option>

<option value="9">9</option>

<option value="10">10</option>

<option value="11">11</option>

<option value="12">12</option>

<option value="13">13</option>

<option value="14">14</option>

<option value="15">15</option>

<option value="16">16</option>

<option value="17">17</option>

<option value="18">18</option>

<option value="19">19</option>

</select>

<script>

$( "#number" )

.selectmenu()

.selectmenu( "menuWidget" )

.addClass( "overflow" );

</script>

</body>

</html>
Run Code Online (Sandbox Code Playgroud)

问题是我希望创建 3 列而不是 1 个默认列。所以,我尝试了两个选项来对齐选项标签内的文本内容。

  1. 将文本放在 span 标签内。
  2. 将文本放入由一行三列(单元格)组成的表格中。

下面给出的是我尝试过的代码。

<option value="1">
        <span align="left">Apple</span>
        <span align="center">Mango</span>
        <span align="right">Orange</span>
        </option>
      <option value="2" selected>
      <table>
        <tr>
          <td align="left">1</td>
          <td align="center">2</td>
          <td align="right">3</td>
        </tr>
        </table>
      </option>
Run Code Online (Sandbox Code Playgroud)

但这并没有解决我的问题,因为我正在获得如下图所示的输出。

错误的输出

由于我是 HTML、CSS 和 jQuery 的初学者,因此,我不知道接下来要做什么来创建每行包含 3 列的下拉列表。请注意,我将选择由所有 3 列组成的整行(如下图所示),而不是任何特定列的任何单元格。任何人都可以建议如何解决此问题并创建下拉列表如第一张图片所示?

Twi*_*sty 5

首先,我们要创建一个合适的 HTML 结构。您需要了解一个 select 元素:<optgroup>. 这是一个基本的建议结构。

<label for="options">Select an Option:</label>
<select id="options">
  <optgroup label="PREFERRED OPTIONS">
    <option value="L">Standard Screw Adjustment</option>
  </optgroup>
  <optgroup label="STANDARD OPTIONS">
    <option value="C">Tamper Resistant - Factory Set</option>
    <option value="K">Handknob</option>
  </optgroup>
  <optgroup label="ADDITIONAL OPTIONS">
    <option value="F">Hex Head Screw with Locknut</option>
  </optgroup>
</select>
Run Code Online (Sandbox Code Playgroud)

这只是开始。你可以使用$("#options").selectmenu();,你会更接近你想要的。我们仍然需要添加更多元素并合并额外的数据。

selectmenu 小部件是用小部件工厂构建的,可以扩展。扩展小部件时,您可以覆盖或添加现有方法的行为。

这正是我们将要做的,以.autocomplete(). 在此处查看此示例:http : //jqueryui.com/autocomplete/#categories

我们将在.selectmenu(). 小部件工厂及其代码有时可能有点高级且难以理解,因此您必须自己深入研究。

HTML

<label for="options">Select an Option:</label>
<select id="options">
  <optgroup label="PREFERRED OPTIONS">
    <option data-short="L" data-price="$0.00" value="L">Standard Screw Adjustment</option>
  </optgroup>
  <optgroup label="STANDARD OPTIONS">
    <option data-short="C" data-price="$5.00" value="C">Tamper Resistant - Factory Set</option>
    <option data-short="K" data-price="$6.00" value="K">Handknob</option>
  </optgroup>
  <optgroup label="ADDITIONAL OPTIONS">
    <option data-short="F" data-price="-$4.00" value="F">Hex Head Screw with Locknut</option>
  </optgroup>
</select>
Run Code Online (Sandbox Code Playgroud)

您在上面看到的内容是从我们首先构建的内容扩展而来的。我添加了data属性。它们对我们的 HTML 没有多大意义,但它们对我们的 jQuery 很有用。这里的好处是,如果我们遇到不支持 JavaScript(因此无法加载 jQuery 库)的浏览器,代码将回退到基本的 HTML 标记,并且仍然为用户提供类似的体验。

CSS

.ui-selectmenu-category {
  color: #5F5F5F;
  padding: .5em .25em;
}
.ui-menu-item {
}
.ui-menu-item .ui-menu-item-wrapper {
  display: inline-block;
  padding: 1em 2px;
}

.ui-menu-item .ui-menu-item-wrapper.ui-state-active {
  border-width: 1px 0 1px 0;
  border-color: #CCCCCC;
  background-color: #E4EBF1;
  color: #000;
}

.ui-menu-item .ui-menu-item-wrapper.ui-state-active.short {
  color: #2E6D99;
}

.ui-menu-item div.ui-menu-item-wrapper {
  width: 295px;
}

.ui-menu-item .short {
  color: #2E6D99;
  font-weight: strong;
  width: 30px;
  padding-left: .5em;
}

.ui-menu-item .price {
  font-weight: strong;
  width: 75px;
  margin-right: -6px;
}
Run Code Online (Sandbox Code Playgroud)

我们将覆盖和扩展.selectmenu(). 这一切只是为了帮助使其符合所需的外观和感觉。

JavaScript

$(function() {
  $.widget("custom.mySelectMenu", $.ui.selectmenu, {
    _renderMenu: function(ul, items) {
      var that = this,
        currentCategory = "";
      $.each(items, function(index, item) {
        var li, name, short, price;
        if (item.optgroup != currentCategory) {
          ul.append("<li class='ui-selectmenu-category'>" + item.optgroup + "</li>");
          currentCategory = item.optgroup;
        }
        li = that._renderItemData(ul, item);
        console.log(ul);
        name = li.text();
        short = item.element.data("short");
        price = item.element.data("price");
        console.log(li, short, price);
        li.prepend($("<span>", {
          class: "short"
        }).html(short));
        li.append($("<span>", {
          class: "price"
        }).html(price));
        if (item.optgroup) {
          li.attr("aria-label", item.optgroup + " : " + item.label);
        }
      });
    }
  });
  $("#options").mySelectMenu({
    width: 400
  });
});
Run Code Online (Sandbox Code Playgroud)

工作示例: https : //jsfiddle.net/Twisty/sn1z5vzn/7/

这是我们将其$.ui.selectmenu扩展到我们自己使用的地方。您可以看到我们只是为_renderMenu扩展点编写了一个函数。关于选择菜单的所有其他内容都将原封不动地进行。

这很重要,因为我们需要定义一个width选项。我们需要知道宽度,以便我们可以创建适当的列,本质上。

这将遍历每个items和 createli元素以与ul由 selectmenu 创建的一起使用。结果项目将如下所示:

<li aria-label="PREFERRED OPTIONS : Standard Screw Adjustment" class="ui-menu-item">
  <span class="short ui-menu-item-wrapper ui-state-active" id="ui-id-1" tabindex="-1" role="option">L</span>
  <div id="ui-id-2" tabindex="-1" role="option" class="ui-menu-item-wrapper ui-state-active">Standard Screw Adjustment</div>
  <span class="price ui-menu-item-wrapper ui-state-active" id="ui-id-3" tabindex="-1" role="option">$0.00</span>
</li>
Run Code Online (Sandbox Code Playgroud)

jQuery UI 为我们做了很多额外的工作,分配唯一的 ID 和应用悬停类等。我们的添加允许我们为每个项目的不同部分设置样式和主题。

类别项目不想玩好。到目前为止,我发现如果我尝试将任何 HTML 元素添加到它的li,它无法正确呈现菜单的其余部分。我可能会回去看看是否_renderItem会在这里有所帮助。

容易吧!?如果您有问题,请发表评论。

参考


更新

如果你像这样改变你的选项:

<option data-icon-url="https://www.gravatar.com/avatar/b3e04a46e85ad3e165d66f5d927eb609?d=monsterid&r=g&s=16" data-price="$0.00" value="L">Standard Screw Adjustment</option>
Run Code Online (Sandbox Code Playgroud)

然后您可以更新<span>以将其用作背景。

CSS 片段

.ui-menu-item .icon {
  background-repeat: no-repeat;
  background-size: 30px;
  background-position: center center; 
  color: #2E6D99;
  font-weight: strong;
  width: 30px;
  padding-left: .5em;
}
Run Code Online (Sandbox Code Playgroud)

JavaScript 代码段

    li.prepend($("<span>", {
      class: "icon",
      style: "background-image: url('" + iconUrl + "')"
    }).html("&nbsp;"));
Run Code Online (Sandbox Code Playgroud)

&nbsp;呈现一个不可间断的空格字符。

HTML 中常用的字符实体是不间断空格: &nbsp;

不间断空格是不会换行的空格。

由不间断空格分隔的两个单词会粘在一起(不会换行)。这在打破单词可能具有破坏性时很方便。

工作示例:https : //jsfiddle.net/Twisty/sn1z5vzn/12/