简体   繁体   中英

Making ul li dropdown filter

I have a dropdown menu, now trying to use it as a filter. pass a value when I click the menu item start filtering But I am a bit confused at Jquery part. How to pass "name" & "value" and start filtering. And the important issue is when I click one item and filter. After that when I click next item, I don't want it to start over. I want to keep old history of search. and add it to new filter.

  var allOptions = $(".init").children('li'); $("ul").on("click", function() { allOptions.removeClass('selected'); $(this).addClass('selected'); $("ul").children('.init').html($(this).html()); allOptions.slideUp(); }); 
 #filter-wrapper { margin-top:15px } #filter-wrapper ul { list-style:none; position:relative; float:left; margin:0; padding:0 } #filter-wrapper ul a { display:block; color:#333; text-decoration:none; font-weight:700; font-size:12px; line-height:32px; padding:0 15px; font-family:"HelveticaNeue","Helvetica Neue",Helvetica,Arial,sans-serif } #filter-wrapper ul li { position:relative; float:left; margin:0; padding:0 } #filter-wrapper ul li.current-menu-item { background:#ddd } #filter-wrapper ul li:hover { background:#f6f6f6 } #filter-wrapper ul ul { display:none; position:absolute; top:100%; left:0; background:#fff; padding:0 } #filter-wrapper ul ul li { float:none; width:200px } #filter-wrapper ul ul a { line-height:120%; padding:10px 15px } #filter-wrapper ul ul ul { top:0; left:100% } #filter-wrapper ul li:hover > ul { display:block } 
 <script src="https://code.jquery.com/jquery-3.3.1.js"></script> <div id="filter-wrapper"> <ul> <li name="sortbyprice" class="current-menu-item"><a href="#">Cheapest Cars</a></li> <li name="sortbyprice" class="current-menu-item"><a href="#">Newest Cars</a></li> <li><a href="#">Car Color</a> <ul class="init" name="sortbycolor"> <li data-value="red"><a href="#">Red</a></li> <li data-value="black"><a href="#">Black</a></li> <li data-value="silver"><a href="#">Silver</a></li> </ul> </li> </ul> </div> 

For example, when I select Red then Car Color changed with the Red.

PS: And by the way the name="" that I gave, it comes from Laravel controller. It contains the data.

And this is the old filter of mine. It's working with this. I can filter the data.

   <form>
     <select name="sortbyprice" class="custom-select custom-select-md" style="width: 100px;">
       <option value="asc">cheapest</option>
       <option value="desc">Expensive</option>
     </select>
     <select id="cars" name="cars" class="custom-select custom-select-md" style="width: 100px;">
      <option value="" disabled selected>car colors</option>
      <option value="red">red</option>
      <option value="blue">blue</option>
      <option value="black">black</option>
    </select>
    <button type="submit" name="button" class="btn btn-success" id="filter-btn">Filter</button>
  </form>

Not sure whether this is what you want, but you can try the code below and tell me what you think

 var mockData = [ { make: 'a', color: 'red', price: 1000 }, { make: 'a', color: 'black', price: 2000 }, { make: 'b', color: 'red', price: 1 }, { make: 'a', color: 'silver', price: 3000 }, { make: 'c', color: 'black', price: 1500 }, { make: 'a', color: 'red', price: 1500 } ]; var allOptions = $('.init').children('li'); // use an object to store the filter options selected by the user // you can then use the information in this object to do the filtering // by sending an AJAX request or just filter the already fetched data var filterOptions = { sortbycolor: '', sortbymake: '', sortbyprice: '' }; $(allOptions).on('click', function () { // get the items' data-value var value = $(this)[0].dataset.value; // select the corresponding <a> tag var button = $(this).parent()[0].previousElementSibling; // get the corresponding name attribute, eg sortbycolor var type = $($(this).parent()[0]).attr('name'); // set the filterOptions filterOptions[type] = value; // change the displayed text of the filter when the user select something $(button).text(function (idx, content) { // here I choose using a colon ':' as the separator, // you can use whatever you want var colonIndex = content.indexOf(':'); // example for baseContent is 'Car Color' var baseContent = content; if (colonIndex > -1) { baseContent = content.slice(0, colonIndex); } // eg 'Car Color: red return baseContent + ': ' + value; }); allOptions.slideUp(); console.log('update filterOptions: ', filterOptions); // filter the already fetched data var filteredData = mockData.filter(function (val) { var isValid = true; if (isValid && filterOptions.sortbycolor) { isValid = val.color === filterOptions.sortbycolor; } if (isValid && filterOptions.sortbymake) { isValid = val.make === filterOptions.sortbymake; } return isValid; }); // sort the data by price // hard-code the sorting direction here for simplicity, // you can set this dynamically with the onclick event filterOptions.sortbyprice = 'asc'; if (filterOptions.sortbyprice === 'asc') { filteredData.sort(function (a, b) { return a.price - b.price; }); } else if (filterOptions.sortbyprice === 'desc') { filteredData.sort(function (a, b) { return b.price - a.price; }); } console.log('filteredData: ', filteredData); // or you can send an ajax request to the server, // and let the server handle the filtering for you // you have to set the keys and values inside // the 'data' youself, below is just an example // as I don't know what your server's API looks like $.get({ url: 'url-to-your-server', data: { color: filterOptions.sortbycolor, make: filterOptions.sortbymake }, success: function (response) { // do something with the response, // maybe it contains the filtered result // however, I am not sure how does your API look like } }); }); // to deal with the left over css style(display: none) introduced by .slideUp() $('.dropdown').on('mouseenter', function () { allOptions.css('display', 'block'); }); console.log('initial filterOptions: ', filterOptions); 
 #filter-wrapper { margin-top: 15px } #filter-wrapper ul { list-style: none; position: relative; float: left; margin: 0; padding: 0 } #filter-wrapper ul a { display: block; color: #333; text-decoration: none; font-weight: 700; font-size: 12px; line-height: 32px; padding: 0 15px; font-family: "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif } #filter-wrapper ul li { position: relative; float: left; margin: 0; padding: 0 } #filter-wrapper ul li.current-menu-item { background: #ddd } #filter-wrapper ul li:hover { background: #f6f6f6 } #filter-wrapper ul ul { display: none; position: absolute; top: 100%; left: 0; background: #fff; padding: 0 } #filter-wrapper ul ul li { float: none; width: 200px } #filter-wrapper ul ul a { line-height: 120%; padding: 10px 15px } #filter-wrapper ul ul ul { top: 0; left: 100% } #filter-wrapper ul li:hover>ul { display: block } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="filter-wrapper"> <ul> <li name="sortbyprice" class="current-menu-item"><a href="#">Cheapest Cars</a></li> <li name="sortbyprice" class="current-menu-item"><a href="#">Newest Cars</a></li> <li class="dropdown"> <a href="#" id="car-color">Car Color</a> <ul class="init" name="sortbycolor"> <li data-value="red"><a href="#">Red</a></li> <li data-value="black"><a href="#">Black</a></li> <li data-value="silver"><a href="#">Silver</a></li> </ul> </li> <li class="dropdown"> <a href="#" id="make">Make</a> <ul class="init" name="sortbymake"> <li data-value="a"><a href="#">A</a></li> <li data-value="b"><a href="#">B</a></li> <li data-value="c"><a href="#">C</a></li> </ul> </li> </ul> </div> 

I eliminated your css, you are just interested in the color value - correct ?

<div id="filter-wrapper">
    <ul>
        <li name="sortbyprice" class="current-menu-item"><a href="#">Cheapest Cars</a></li>
        <li name="sortbyprice" class="current-menu-item"><a href="#">Newest Cars</a></li>

        <li><a href="#">Car Color</a>
            <ul class="init" name="sortbycolor">
                <li><a href="#" data-value="red">Red</a></li>
                <li><a href="#" data-value="black">Black</a></li>
                <li><a href="#" data-value="silver">Silver</a></li>
            </ul>
        </li>
    </ul>
</div>

<script>
    var allOptions = $(".init").children('li');

    // I think you are only interested in the html content of the a (anchor)

    $("li[data-value] > a").on("click", function(e) {
        e.preventDefault();

        allOptions.removeClass('selected');
        $(this).addClass('selected');

        let filterVal = $(this).data('value'); // do something with this ...
        let li = $('<li />').html( filterVal);
        $("ul.init").html('').append( li); // ul.init just has the value of the filter

        // allOptions.slideUp(); // superfluos
    });
</script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM