2015-07-21 35 views
0

我試圖創建過濾器定製的選擇菜單,如演示頁:jQuery Mobile的可篩選選擇一長串

http://demos.jquerymobile.com/1.4.5/selectmenu-custom-filter/

它工作正常的短名單:

http://jsfiddle.net/dw1c1439/

但它不適用於長列表:

https://jsfiddle.net/pppzLbfu/

我不斷收到錯誤:

SCRIPT5007:無法獲取的未定義或空引用屬性「jqmData」

我完整的代碼

<!DOCTYPE html> 
<html> 
<head> 
<meta charset="utf-8"> 
<meta name="viewport" content="width=device-width, initial-scale=1"> 
<title>Filterable inside custom select - jQuery Mobile Demos</title> 
<link rel="shortcut icon" href="../favicon.ico"> 
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Open+Sans:300,400,700"> 
<link rel="stylesheet" href="jquery.mobile/css/themes/default/jquery.mobile-1.4.5.min.css"> 
<link rel="stylesheet" href="jquery.mobile/_assets/css/jqm-demos.css"> 
<script src="jquery.mobile/js/jquery.js"></script> 
<script src="jquery.mobile/_assets/js/index.js"></script> 
<script src="jquery.mobile/js/jquery.mobile-1.4.5.min.js"></script> 

<script> 
(function($) { 
function pageIsSelectmenuDialog(page) { 
    var isDialog = false, 
     id = page && page.attr("id"); 
    $(".filterable-select").each(function() { 
     if ($(this).attr("id") + "-dialog" === id) { 
      isDialog = true; 
      return false; 
     } 
    }); 
    return isDialog; 
} 
$.mobile.document 
    // Upon creation of the select menu, we want to make use of the fact that the ID of the 
    // listview it generates starts with the ID of the select menu itself, plus the suffix "-menu". 
    // We retrieve the listview and insert a search input before it. 
    .on("selectmenucreate", ".filterable-select", function(event) { 
     var input, 
      selectmenu = $(event.target), 
      list = $("#" + selectmenu.attr("id") + "-menu"), 
      form = list.jqmData("filter-form"); 
     // We store the generated form in a variable attached to the popup so we avoid creating a 
     // second form/input field when the listview is destroyed/rebuilt during a refresh. 
     if (!form) { 
      input = $("<input data-type='search'></input>"); 
      form = $("<form></form>").append(input); 
      input.textinput(); 
      list 
       .before(form) 
       .jqmData("filter-form", form) ; 
      form.jqmData("listview", list); 
     } 
     // Instantiate a filterable widget on the newly created selectmenu widget and indicate that 
     // the generated input form element is to be used for the filtering. 
     selectmenu 
      .filterable({ 
       input: input, 
       children: "> option[value]" 
      }) 
      // Rebuild the custom select menu's list items to reflect the results of the filtering 
      // done on the select menu. 
      .on("filterablefilter", function() { 
       selectmenu.selectmenu("refresh"); 
      }); 
    }) 
    // The custom select list may show up as either a popup or a dialog, depending on how much 
    // vertical room there is on the screen. If it shows up as a dialog, then the form containing 
    // the filter input field must be transferred to the dialog so that the user can continue to 
    // use it for filtering list items. 
    .on("pagecontainerbeforeshow", function(event, data) { 
     var listview, form; 
     // We only handle the appearance of a dialog generated by a filterable selectmenu 
     if (!pageIsSelectmenuDialog(data.toPage)) { 
      return; 
     } 
     listview = data.toPage.find("ul"); 
     form = listview.jqmData("filter-form"); 
     // Attach a reference to the listview as a data item to the dialog, because during the 
     // pagecontainerhide handler below the selectmenu widget will already have returned the 
     // listview to the popup, so we won't be able to find it inside the dialog with a selector. 
     data.toPage.jqmData("listview", listview); 
     // Place the form before the listview in the dialog. 
     listview.before(form); 
    }) 
    // After the dialog is closed, the form containing the filter input is returned to the popup. 
    .on("pagecontainerhide", function(event, data) { 
     var listview, form; 
     // We only handle the disappearance of a dialog generated by a filterable selectmenu 
     if (!pageIsSelectmenuDialog(data.toPage)) { 
      return; 
     } 
     listview = data.prevPage.jqmData("listview"), 
     form = listview.jqmData("filter-form"); 
     // Put the form back in the popup. It goes ahead of the listview. 
     listview.before(form); 
    }); 
})(jQuery); 

</script> 
<style> 
.ui-selectmenu.ui-popup .ui-input-search { 
    margin-left: .5em; 
    margin-right: .5em; 
} 
.ui-selectmenu.ui-dialog .ui-content { 
    padding-top: 0; 
} 
.ui-selectmenu.ui-dialog .ui-selectmenu-list { 
    margin-top: 0; 
} 
.ui-selectmenu.ui-popup .ui-selectmenu-list li.ui-first-child .ui-btn { 
    border-top-width: 1px; 
    -webkit-border-radius: 0; 
    border-radius: 0; 
} 
.ui-selectmenu.ui-dialog .ui-header { 
    border-bottom-width: 1px; 
} 
</style> 

</head> 
<body> 
<div data-role="page" class="jqm-demos" id="pageMainForm"> 

    <div data-role="header" class="jqm-header"> 
     <h2><a href="../" title="jQuery Mobile Demos home"><img src="../_assets/img/jquery-logo.png" alt="jQuery Mobile"></a></h2> 
     <p>Demos <span class="jqm-version"></span></p> 
     <a href="#" class="jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left">Menu</a> 
     <a href="#" class="jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-search ui-nodisc-icon ui-alt-icon ui-btn-right">Search</a> 
    </div><!-- /header --> 

    <div data-role="content" class="ui-content jqm-content"> 

    <h1>Filterable inside custom select</h1> 

     <div data-demo-html="true" data-demo-js="true" data-demo-css="true"> 
      <form> 
       <select id="filter-menu" class="filterable-select" data-native-menu="false"> 
        <option value="Option 1">Option 1</option> 
        <option value="Option 2">Option 2</option> 
        <option value="Option 3">Option 3</option> 
        <option value="Option 4">Option 4</option> 
        <option value="Option 5">Option 5</option> 
        <option value="Option 6">Option 6</option> 
        <option value="Option 7">Option 7</option> 
        <option value="Option 8">Option 8</option> 
        <option value="Option 9">Option 9</option> 
        <option value="Option 10">Option 10</option> 
        <option value="Option 11">Option 11</option> 
        <option value="Option 12">Option 12</option> 
        <option value="Option 13">Option 13</option> 
        <option value="Option 14">Option 14</option> 
        <option value="Option 15">Option 15</option> 
        <option value="Option 16">Option 16</option> 
        <option value="Option 17">Option 17</option> 
        <option value="Option 18">Option 18</option> 
        <option value="Option 19">Option 19</option> 
        <option value="Option 20">Option 20</option> 
        <option value="Option 21">Option 21</option> 
        <option value="Option 22">Option 22</option> 
       </select> 
      </form> 
     </div> 

    </div><!-- /content --> 

</div><!-- /page --> 
</body> 
</html> 
+0

找到答案? –

+0

還沒有。即使是JqueryMobile演示頁面上的長列表示例也不起作用(在IE,Firefox或Chrome中)。 – Dion

回答

2

這裏的解決方案,如果你仍然需要它: 演示本身有一些錯誤。下面是一個方法來做到這一點:

//演示的對話框是由JQM時動態創建自定義selectmenu

$(document).on("pagecreate", "#demo-dialog", function (e) { 
    var form = $("<form><input data-type='search'/></form>"), 
    page = $(this); 

$(".ui-content", this) 
    .prepend(form); 

form.enhanceWithin() 
    .on("keyup", "input", function() { 
    var data = $(this).val().toLowerCase(); 
    $("li", page).addClass("ui-screen-hidden") 
     .filter(function (i, v) { 
     return $(this).text().toLowerCase().indexOf(data) > -1; 
    }).removeClass("ui-screen-hidden"); 
}); 

$(document).on("pagecontainerhide", function() { 
    $("#demo-menu li").removeClass("ui-screen-hidden"); 
    $("input", form).val(""); 
}); 

加入 // selectmenu(演示)+( - 對話)的ID });

參考: https://forum.jquery.com/topic/cannot-read-property-jqmdata-of-undefined

+0

@victor:非常感謝。作品一種享受。 – Dion

0

這似乎解決它,我 - 在「pagecontainerhide」處理程序,從「data.toPage」到「data.prevPage」作爲更改 pageIsSelectmenuDialog函數的參數在:

if (!pageIsSelectmenuDialog(data.prevPage)) { 
       return; 
}