2012-04-15 56 views
4

我需要jQuery插件,这将改变我简单与文本输入选项的Jquery selectmenu插件

<select> 
    <option>text</option> 
</select> 

在完全可定制的名单就像一个<lu>列表或<div>列表中,我发现了很多这样的的插件,但他们都没有选择键入的东西,并将其设置为一个选项。

可以说我有一种名单:

<select> 
    <option value="text">text</option> 
    <option value="other">other</option> 
</select> 

现在我想其他选择转化为<input type="text" />,我敢肯定,必须有插件,它做到了这一点。

我已经做了一个例子它应该怎么看,左边是我目前的插件,右边是我需要的,我知道我可以编辑我当前的插件,但它只是对我来说很大的方式,它会采取到很多时间。

enter image description here

+0

你的意思是你要选择列表转换成输入列表? – GillesC 2012-04-15 09:11:05

+0

不是所有人都只有他们其中的一些其他可以是任何东西,我只需要输入时,我想设置选项“其他”,这意味着用户将能够键入他想要的任何东西。 – Linas 2012-04-15 09:16:10

回答

5

没有完全相同的jQuery插件。但是,有一个jQuery UI selectmenu plugin,它将select元素转换为html表示,以便您可以设置选择菜单的样式。这个插件还提供了格式化文本的回调,在我们的例子中,我们可以将我们的“其他”选项格式化为输入框。

假设我们有以下选择:

<select name="otherselect" id="otherselect"> 
     <option value="united-states">United States</option> 
     <option value="latvia" selected="selected">Latvia</option> 
     <option value="france">France</option> 
     <option>Other</option> 
    </select> 

我们可以创建一个selectmenu使用这个插件:

$(function(){ 
     selectMenu = $('select#otherselect').selectmenu({ 
      style:'popup', 
      width: 300, 
      format: otherFormatting 
     }); 
    }); 

在这里的功能otherFormatting是将格式化我们的其他选项的功能。这是我们的功能:

var otherFormatting = function(text){ 

    // if text contains 'Other' format into Other input box... 
     if (text == "Other") { 
     var button = $('<input type="submit" onclick="selectOther(this)" value="select"/>'); 
     var input = $('<input class="other" type="text" value="Other..."/>'); 


      return $('<span/>') 
      .append(input) 
      .append(button)[0].outerHTML; 
    } 

     return text; 
    } 

selectOther功能按钮被点击时调用,是我们将与扩展插件的功能。这个函数,当点击按钮时激活,将设置我们的select的值,以便我们可以使用表单轻松地提交它。而且,请设置新选择菜单中显示的值(而不是在选择框中显示输入框)。

我们需要扩展这个插件,这基本上是一个jQuery UI widget。但是,由于该插件绑定了一些使我们无法获得输入字段和按钮的事件,因此我们需要解除其中一些事件。我们在打开选择菜单时执行此操作。为此,我们需要重写窗口小部件的打开函数,调用我们的函数来取消绑定某些事件,然后使用原始打开函数打开菜单。

把所有这些组合起来:

<!DOCTYPE html> 
<html> 
    <head> 
    <title>Demo Page for jQuery UI selectmenu</title> 

    <link type="text/css" href="../../themes/base/jquery.ui.all.css" rel="stylesheet" /> 
    <link type="text/css" href="../../themes/base/jquery.ui.selectmenu.css" rel="stylesheet" /> 
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> 
    <script type="text/javascript" src="../../ui/jquery.ui.core.js"></script> 
    <script type="text/javascript" src="../../ui/jquery.ui.widget.js"></script> 
    <script type="text/javascript" src="../../ui/jquery.ui.position.js"></script> 
    <script type="text/javascript" src="../../ui/jquery.ui.selectmenu.js"></script> 
    <style type="text/css"> 
     body {font-size: 62.5%; font-family: "Verdana",sans-serif; } 
     fieldset { border: 0; } 
     label, select, .ui-select-menu { float: left; margin-right: 10px; } 
     select { width: 200px; } 
    </style> 
    <script type="text/javascript"> 
     // We need to able to call the original open method, save intoIf you need to call original method 
     var fn_open = $.ui.selectmenu.prototype.open; 
     $.widget("ui.selectmenu", $.extend({}, $.ui.selectmenu.prototype, { 
      open : function() { 
       // Every the selectmenu is opened, unbind some events... 
       this._unbindEvents(); 
       fn_open.apply(this, arguments); 
      }, 
      _unbindEvents : function() { 
       var el = $(this.list).find('li:has(input.other)').eq(0); 
       // unbind events, we need a different event here... 
       el.unbind('mouseup'); 
       el.unbind('mousedown'); 
       el.bind('mousedown', function() { 
        // We need to call focus here explicitly 
        $(this).find('input.other').eq(0).focus(); 

        // Empty field on click... 
        if ($(this).find('input.other').eq(0).val() == 'Other...') 
         $(this).find('input.other').eq(0).val(""); 
       }); 
       // Unbind keydown, because otherwise we cannot type in our textfield.... 
       this.list.unbind('keydown'); 
       // We only need to return false on the mousedown event. 
       this.list.unbind('mousedown.selectmenu mouseup.selectmenu'); 
       this.list.bind('mousedown', function() { 
         return false; 
       }); 
      }, 
      selectOther : function(el) { 
       var button = $(el); 

       // li item contains the index 
       var itemIndex = button.parent().parent().parent().data('index'); 
       var changed = itemIndex != this._selectedIndex(); 

       // Get the value of the input field 
       var newVal = button.prev().val(); 
       this.index(itemIndex); 
       // Update the display value in the styled select menu. 
       this.newelement.find('.' + this.widgetBaseClass + '-status').html(newVal); 

       // Update the value and html of the option in the original select. 
       $(this.element[0].options[itemIndex]).val(newVal).html(newVal); 

       // Call the select, change and close methods 
       var e = jQuery.Event("mouseup"); 
       this.select(e); 
       if (changed) 
        this.change(e); 
       this.close(e); 
      } 
     })); 

     var selectMenu; 
     $(function(){ 
      selectMenu = $('select#otherselect').selectmenu({ 
       style:'popup', 
       width: 300, 
       format: otherFormatting 
      }); 
     }); 

     function selectOther(el) { 
      // Call our self defined selectOther function. 
      selectMenu.selectmenu('selectOther', el); 
     } 

     //a custom format option callback 
     var otherFormatting = function(text){ 

      // if text contains 'Other' format into Other input box... 
      if (text == "Other") { 
       var button = $('<input type="submit" onclick="selectOther(this)" value="select"/>'); 
       var input = $('<input class="other" type="text" value="Other..."/>'); 


       return $('<span/>') 
        .append(input) 
        .append(button)[0].outerHTML; 
      } 

      return text; 
     } 
    </script> 
</head> 
<body> 
    <h2>Select with Other option input field</h2> 
    <fieldset> 
     <label for="otherselect">Select a value:</label> 
     <select name="otherselect" id="otherselect"> 
      <option value="united-states">United States</option> 
      <option value="latvia" selected="selected">Latvia</option> 
      <option value="france">France</option> 
      <option>Other</option> 
     </select> 
    </fieldset> 
    <button onclick="console.log($('#otherselect').val());">Test</button> 
</body> 
</html> 

要试试这个,download the plugin here并确保网址的JS/CSS文件是正确的。 (我已经把这个html文件放到了demo/selectmenu文件夹中,它可以工作...)。当然,你可以用图像替换按钮。

+0

这是最接近正确的答案,而不必从头开始写所有东西。 – Christian 2012-04-30 12:44:17

+0

真棒,我试图解开这些事件我自己,因为我试图让这个插件做我的自己有一段时间去一次,但我失败了:/反正现在试试你的解决方案。 – Linas 2012-05-01 10:57:31

+0

它完美的工作!非常感谢你我有这个问题一个多月了,现在终于完成了^^我现在需要的是将它实现到我的网站 – Linas 2012-05-01 11:27:52

3

试试这个,这个小脚本将一个选择框后,创建一个文本输入,如果选择框值等。新的文本输入与选择相同的名称,以便它的值覆盖由select所设置的值(因为它是其他的)

如果值是别的东西,我们只检查文本输入的存在并删除它(因此它不会覆盖选择值)

http://jsfiddle.net/cW725/1/

HTML

<form> 

    <p> 
     <select> 
      <option value="text">text</option> 
      <option value="text">text</option> 
      <option value="text">text</option> 
      <option value="other">other</option> 
     </select> 
    </p> 

    <p> 
     <select> 
      <option value="text">text</option> 
      <option value="text">text</option> 
      <option value="text">text</option> 
      <option value="other">other</option> 
     </select> 
    </p> 

</form> 
​ 

jQuery的

$(function() { 

    // bind all select on change 
    $('select').on('change', function() { 

     // if value is other 
     if ($(this).val() == 'other') { 

      // add a text input we match the name so that this input overwrite the select one as after in the form 
      $(this).after('<input type="text" name="' + $(this).attr('name') + '" class="otherInput" />'); 

     } else { 

      if ($(this).next().is('input.otherInput')) { 
       $(this).next().remove(); 
      }; 
     }; 
    }); 
});​ 
+0

他的解决方案非常有意义,这是最简单的方法。您可以通过将原始HTML转换为假选择(删除实际的选择标记并用大量的div和输入替换它)来解决问题;或者你可以做他做的事情:让“其他”选项在* select后面追加一个文本输入*(不是* in *,正如你声称的那样)。当然,如果你选择别的东西,它必须被删除。试试他的小提琴。 – Armatus 2012-04-28 08:56:12

0

您可能会检出chosen.js - 它可能适合您的需求。从头开始制作一些东西可能会更容易些。祝你好运。

2

我正在寻找一个jQuery的“选择或编辑”解决方案,并发现这可以在select2 plugin的帮助下完成。

原来是非常简单的解决方案,正是我想要的。

HTML:

<select name="otherselect" id="otherselect"> 
    <option value="united-states">United States</option> 
    <option value="latvia" selected="selected">Latvia</option> 
    <option value="france">France</option> 
</select> 

JS:

$('#otherselect').select2({tags: true}); 

例子: https://jsfiddle.net/h0qp37jk/