How to label jQuery mobile select-menu after adding of input-search in sub menu

Viewed 220

I am rather new to jquery and ran into the following problem:

I have a main menu and a click on the main menu opens a sub menu with multiple items. Originally, the button that opens the submenu was labeled with the first <option> that has an empty value. And this first <option> (Countries in my case) with empty value was not listed in the submenu. So far so good.

     <script src="mbo_master/javascript/jquery-2.1.3.js"></script>
     <script src="mbo_master/javascript/jquery.mobile-1.4.5.js"></script>
$(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("");
    }); 

});                                             
.ui-selectmenu.ui-popup .ui-input-search {
    margin-left: .5em;
    margin-right: .5em;
}

.ui-selectmenu.ui-dialog .ui-content {
    padding-top: 0;
    max-height: 85vh;
    overflow-y: scroll;
}
.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;
    padding-left: 50px;
}

    <label for="demo" id="label">Long list:</label>   
    <select name="demo" id="demo" multiple="multiple" data-native-menu="false" class="select">

        <option data-placeholder="true" value="">Countries</option>
        <option value="AL">Alabama</option>
        <option value="AK">Alaska</option>
        <option value="AZ">Arizona</option>
        <option value="AR">Arkansas</option>
        <option value="CA">California</option>
        <option value="CO">Colorado</option>
        <option value="CT">Connecticut</option>
        <option value="DE">Delaware</option>
        <option value="FL">Florida</option>
        <option value="GA">Georgia</option>
        <option value="HI">Hawaii</option>
        <option value="ID">Idaho</option>
        <option value="IL">Illinois</option>
        <option value="IN">Indiana</option>
        <option value="IA">Iowa</option>
        <option value="KS">Kansas</option>
        <option value="KY">Kentucky</option>
        <option value="LA">Louisiana</option>
        <option value="ME">Maine</option>
        <option value="MD">Maryland</option>
        <option value="MA">Massachusetts</option>
        <option value="MI">Michigan</option>
        <option value="MN">Minnesota</option>
        <option value="MS">Mississippi</option>
        <option value="MO">Missouri</option>
        <option value="MT">Montana</option>
        <option value="NE">Nebraska</option>
        <option value="NV">Nevada</option>
        <option value="NH">New Hampshire</option>
        <option value="NJ">New Jersey</option>
        <option value="NM">New Mexico</option>
        <option value="NY">New York</option>
        <option value="NC">North Carolina</option>
        <option value="ND">North Dakota</option>
        <option value="OH">Ohio</option>
        <option value="OK">Oklahoma</option>
        <option value="OR">Oregon</option>
        <option value="PA">Pennsylvania</option>
        <option value="RI">Rhode Island</option>
        <option value="SC">South Carolina</option>
        <option value="SD">South Dakota</option>
        <option value="TN">Tennessee</option>
        <option value="TX">Texas</option>
        <option value="UT">Utah</option>
        <option value="VT">Vermont</option>
        <option value="VA">Virginia</option>
        <option value="WA">Washington</option>
        <option value="WV">West Virginia</option>
        <option value="WI">Wisconsin</option>
        <option value="WY">Wyoming</option>

    </select>

After having added a jquery search field on top of the submenu, the first <option> with empty value appears in the submenu, what I don´t want.

I can remove it with $("#demo option[value='']").remove(); but then the label of the button disappears, too. data-placeholder="true" didn´t work as well.

I found that the problem is the line $("#demo-menu li").removeClass("ui-screen-hidden"); in the search-function. When it is removed, button-labeling and listing of options work as it should, however, the search function doesn´t work properly, of course.

Is there any possibility that allows labeling of the select-button in the main-menu and listing of items with value only in the submenu? Thanks!

1 Answers

JQM has its own naming convention.

For instance: the popup which will be created to show a short list of options, will get its own id that is composed by concatenating the "id" of the select followed by the keyword "listbox-popup".

the dialog-page which will be created to show a long list of options exceeding the page height, will get its own id that is composed by concatenating the "id" of the select followed by the keyword "dialog".

So, after thinking about it, I believe the filterable is needed only when a dialog-page will be displayed, as the choice between popup and dialog-page is made dynamically, every time the select is opening.

Therefore the code is even simpler, as the JQM built-in data-filter option can be used here:

HTML:

  <div data-role="page" id="page-select-country">
    <div data-role="content">
      <div class="ui-field-contain">
        <label for="country-select">Long list:</label>
        <select name="country-select" id="country-select" data-native-menu="false">
          <!-- option empty value will be used as data-placeholder -->
          <option>Choose Your Country</option>
          <option value="AL">Alabama</option>
          <option value="AK">Alaska</option>
          ... other oprions...
          <option value="WY">Wyoming</option>
        </select>
      </div>
    </div>
  </div>

JavaScript:

$(document).on("selectmenucreate", "#country-select", function(e, ui) {
  var data = $(this).data("mobile-selectmenu"), hide = {"display": "none"};
  data.list
    .attr("data-filter", "true")
    .find("li[data-placeholder='true']").css(hide);
  $(this).on("change", function () {
    var cases = {"page": data.menuPageClose, "overlay": data.headerClose},
        btnClose = cases[data.menuType];
    if ($("option:selected", this).length === 0) {
      btnClose
        .addClass("ui-icon-delete")
        .removeClass("ui-icon-check")
        .css("backgroundColor", "initial");      
    } else {
      btnClose
        .addClass("ui-icon-check")
        .removeClass("ui-icon-delete")
        .css("backgroundColor", "#90ee90");
    }
  });
});

$(document).on("pagecontainerbeforeshow", function(e, ui) {
  var data = $("#country-select").data("mobile-selectmenu");
  if(ui.toPage.attr("id") == data["dialogId"]) {
    if(!ui.toPage.find(".ui-filterable").length) {
      ui.toPage.find(".ui-content").enhanceWithin();
    }
  }
});

$(document).on("pagecontainershow", function(e, ui) {
  var data = $("#country-select").data("mobile-selectmenu");
  if(ui.toPage.attr("id") == data["dialogId"]) {
    ui.toPage.find(".ui-filterable input").focus();
  }
});

$(document).on("pagecontainerhide", function(e, ui) {
  var data = $("#country-select").data("mobile-selectmenu");
  if(ui.prevPage.attr("id") == data["dialogId"]) {
    data["list"].find("li").removeClass("ui-screen-hidden");
    ui.prevPage.find(".ui-filterable input").val("");
  }
});
Related