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

时间:2017-12-06 16:56:26

标签: jquery html css jquery-ui jquery-ui-selectmenu

我被赋予了一个创建下拉列表的任务,该列表由3列(每行)组成,如下图所示。

dropdown image

现在,我意识到jQuery UI的Selectmenu小部件将满足我的要求,因此,我使用了以下代码(如their official documentation page所示)。

<!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>

问题是我正在寻找创建3列而不是1默认列。因此,我尝试了两个选项来对齐选项标记内的文本内容。

  1. 将文本放在span标记内。
  2. 将文本放在由一行三列(单元格)组成的表中。
  3. 以下是我试过的代码。

    <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>
    

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

    wrong output

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

2 个答案:

答案 0 :(得分:3)

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

&#13;
&#13;
<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>
&#13;
&#13;
&#13;

这只是一个开始。你可以使用$("#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>

您在上面看到的内容有点像我们最先建立的内容。我添加了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;
}

我们将覆盖并扩展.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
  });
});

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

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

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

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

<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>

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>

然后,您可以更新<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;
}

JavaScript代码段

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

&nbsp;呈现非破坏空格字符。

  

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

     

不间断的空间是一个不会分成新线的空间。

     

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

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

答案 1 :(得分:0)

这是无效的HTML,我认为大多数浏览器会忽略它。

如果要更改渲染,请使用扩展点: http://api.jqueryui.com/selectmenu/#method-_renderItem