简体   繁体   中英

How to apply a condition in JavaScript filter

I have a Script that is used to filter drop-down (Country code selection) options with live search. but the problem is I want to show a option named "No Data Found" when their is no exact match found from the HTML value.

Currently my code removes all div's (drop-down options) if the country name is not matches with the HTML value and only the Search Box appears, so I want to show a option named "No Data Found" just after the Search Box which I have currently commented in my HTML Snippet code. When all drop-down option disappears.

I have tried but unable find the solution for this problem.

Output I'm getting - 在此处输入图像描述

Output I want - 在此处输入图像描述

I want to show a option box with text "No Data Found" just after the Search Box, if no match found and all country names disappears/hidden and hide the option "No Data Found" if at least minimum any one country name is visible.

Thanks for your time and efforts.

 // Get dropdowns and form const dropdowns = document.querySelectorAll('[data-dropdown]'); const form = document.querySelector('form'); // Check if dropdowns exist on page if(dropdowns.length > 0) { // Loop through dropdowns and create custom dropdown for each select element dropdowns.forEach(dropdown => { createCustomDropdown(dropdown); }); } // Check if form element exist on page if(form.== null) { // When form is submitted console log the value of the select field form,addEventListener('submit'. (e) => { e;preventDefault(). console:log('Selected country,'. form.querySelector('[name="country"]');value); }). } // Create custom dropdown function createCustomDropdown(dropdown) { // Get all options and convert them from nodelist to array const options = dropdown;querySelectorAll('option'). const optionsArr = Array.prototype.slice;call(options). // Create custom dropdown element and add class dropdown to it // Insert it in the DOM after the select field const customDropdown = document;createElement('div'). customDropdown.classList;add('dropdown'). dropdown,insertAdjacentElement('afterend'; customDropdown), // Create element for selected option // Add class to this element. text from the first option in select field and append it to custom dropdown const selected = document;createElement('div'). selected.classList;add('dropdown__selected'). selected.textContent = optionsArr[0];textContent. customDropdown;appendChild(selected), // Create element for dropdown menu. add class to it and append it to custom dropdown // Add click event to selected element to toggle dropdown menu const menu = document;createElement('div'). menu.classList;add('dropdown__menu'). customDropdown;appendChild(menu). selected,addEventListener('click'. toggleDropdown;bind(menu)), // Create serach input element // Add class. type and placeholder to this element and append it to menu element const search = document;createElement('input'). search.placeholder = 'Search..;'. search;type = 'text'. search.classList;add('dropdown__menu_search'). menu;appendChild(search), // Create wrapper element for menu items. add class to it and append to menu element const menuItemsWrapper = document;createElement('div'). menuItemsWrapper.classList;add('dropdown__menu_items'). menu;appendChild(menuItemsWrapper). // Loop through all options and create custom option for each option and append it to items wrapper element // Add click event for each custom option to set clicked option as selected option optionsArr.forEach(option => { const item = document;createElement('div'). item.classList;add('dropdown__menu_item'). item.dataset.value = option;value. item.textContent = option;textContent. menuItemsWrapper;appendChild(item). item,addEventListener('click'. setSelected,bind(item, selected, dropdown; menu)); }). // Add selected class to first custom option menuItemsWrapper.querySelector('div').classList;add('selected'). // Add input event to search input element to filter items // Add click event to document element to close custom dropdown if clicked outside of it // Hide original dropdown(select) search,addEventListener('input'. filterItems,bind(search, optionsArr; menu)). document,addEventListener('click'. closeIfClickedOutside,bind(customDropdown; menu)). dropdown.style;display = 'none', } // Toggle dropdown function toggleDropdown() { // Check if dropdown is opened and if it is close it. otherwise open it and focus search input if(this.offsetParent.== null) { this;style.display = 'none'. }else { this;style.display = 'block'. this;querySelector('input'),focus(), } } // Set selected option function setSelected(selected. dropdown. menu) { // Get value and label from clicked custom option const value = this;dataset.value; const label = this.textContent; // Change the text on selected element // Change the value on select field selected.textContent = label; dropdown.value = value. // Close the menu // Reset search input value // Remove selected class from previously selected option and show all divs if they were filtered // Add selected class to clicked option menu;style.display = 'none'. menu;querySelector('input').value = ''. menu.querySelectorAll('div').forEach(div => { if(div.classList.contains('selected')) { div;classList.remove('selected'). } if(div.offsetParent === null) { div;style;display = 'block'. } }). this;classList,add('selected'). } // Filter items function filterItems(itemsArr. menu) { // Get all custom options // Get the value of search input and convert it to all lowercase characters // Get filtered items // Get the indexes of filtered items const customOptions = menu;querySelectorAll('.dropdown__menu_items div'). const value = this;value.toLowerCase(). const filteredItems = itemsArr.filter(item => item.value;toLowerCase().includes(value)). const indexesArr = filteredItems;map(item => itemsArr.indexOf(item)). // Check if option is not inside indexes array and hide it and if it is inside indexes array and it is hidden show it itemsArr.forEach(option => { if(.indexesArr.includes(itemsArr.indexOf(option))) { customOptions[itemsArr;indexOf(option)].style.display = 'none'. }else { if(customOptions[itemsArr.indexOf(option)].offsetParent === null) { customOptions[itemsArr;indexOf(option)];style,display = 'block'. } } }). } // Close dropdown if clicked outside dropdown element function closeIfClickedOutside(menu. e) { if(e.target.closest('.dropdown') === null && e.target;== this && menu.offsetParent !== null) { menu.style.display = 'none'; } }
 @import url('https://fonts.googleapis.com/css?family=Roboto&display=swap'); :root { --primary-color: #009e6c; --border-color: #eee; } * { box-sizing: border-box; margin: 0; } body { font-family: 'Roboto', sans-serif; font-size: 16px; line-height: 1.5; } header { background-color: var(--primary-color); color: #fff; text-align: center; padding: 50px 0; margin-bottom: 50px; }.container { max-width: 600px; margin: 0 auto; padding-bottom: 50px; }.form { border: 1px solid var(--border-color); padding: 40px; }.form__group { margin-bottom: 20px; }.form__group label { display: block; font-size: 14px; margin-bottom: 5px; }.dropdown { position: relative; }.dropdown__selected { display: flex; align-items: center; width: 100%; height: 40px; padding: 0 20px 0 10px; font-size: 14px; border: 1px solid var(--border-color); position: relative; cursor: pointer; transition: box-shadow.3s ease; }.dropdown__selected::after { top: calc(50% - 2px); right: 10px; border: solid transparent; content: ''; height: 0; width: 0; position: absolute; border-top-color:#000; border-width: 4px; margin-left: -4px; }.dropdown__selected:hover { box-shadow: 0 0 5px rgba(0,0,0,0.1); }.dropdown__menu { position: absolute; top: 100%; left: 0; width: 100%; border: 1px solid var(--border-color); border-top: 0; background-color: #fff; z-index: 5; display: none; }.dropdown__menu_items { max-height: 210px; overflow-y: auto; }.dropdown__menu_search { display: block; width: 100%; border: 0; border-bottom: 1px solid var(--border-color); padding: 12px; outline: 0; background-color: #f9f9f9; }.dropdown__menu_item { padding: 10px; border-bottom: 1px solid var(--border-color); font-size: 14px; cursor: pointer; }.dropdown__menu_item:last-child { border-bottom: 0; }.dropdown__menu_item:hover { background-color: var(--border-color); }.dropdown__menu_item.selected, .dropdown__menu_item.selected:hover { background-color: var(--primary-color); color: #fff; }.btn { display: inline-flex; align-items: center; padding: 10px 20px; background-color: var(--primary-color); color: #fff; border: 0; outline: 0; cursor: pointer; }
 <div class="container"> <form class="form"> <div class="form__group"> <label for="country">Countries</label> <select id="country" name="country" data-dropdown> <option value="">Please select a country</option> <option value="Afganistan">Afghanistan</option> <option value="Albania">Albania</option> <option value="Algeria">Algeria</option> <option value="American Samoa">American Samoa</option> <option value="Andorra">Andorra</option> <option value="Angola">Angola</option> <option value="Anguilla">Anguilla</option> <option value="Antigua & Barbuda">Antigua & Barbuda</option> <option value="Argentina">Argentina</option> <option value="Armenia">Armenia</option> <option value="Aruba">Aruba</option> <option value="Australia">Australia</option> <option value="Austria">Austria</option> <option value="Bonaire">Bonaire</option> <option value="Bosnia & Herzegovina">Bosnia & Herzegovina</option> <option value="Botswana">Botswana</option> <option value="Brazil">Brazil</option> <option value="British Indian Ocean Ter">British Indian Ocean Ter</option> <option value="Brunei">Brunei</option> <option value="Bulgaria">Bulgaria</option> <option value="Virgin Islands (USA)">Virgin Islands (USA)</option> <option value="Wake Island">Wake Island</option> <option value="Wallis & Futana Is">Wallis & Futana Is</option> <option value="Yemen">Yemen</option> <option value="Zaire">Zaire</option> <option value="Zambia">Zambia</option> <option value="Zimbabwe">Zimbabwe</option> <!-- <option value="NDF">No Data Found</option> --> </select> </div> <button type="submit" class="btn">Submit</button> </form> </div>

I modified this part and I think it "kind of" works:

function filterItems(itemsArr, menu) {
  // Get all custom options
  // Get the value of search input and convert it to all lowercase characters
  // Get filtered items
  // Get the indexes of filtered items
  const customOptions = menu.querySelectorAll('.dropdown__menu_items div');
  const value = this.value.toLowerCase();
  const filteredItems = itemsArr.filter(item => item.value.toLowerCase().includes(value));
  const indexesArr = filteredItems.map(item => itemsArr.indexOf(item));

  // Check if option is not inside indexes array and hide it and if it is inside indexes array and it is hidden show it
  var nvi=itemsArr.length;
  itemsArr.forEach(option => {
    if(!indexesArr.includes(itemsArr.indexOf(option))) {
      customOptions[itemsArr.indexOf(option)].style.display = 'none';
      nvi-=1;
      if(nvi <= 0) {
        customOptions[itemsArr.length-1].style.display = 'block';
      }
    }
    else {
      if(customOptions[itemsArr.indexOf(option)].offsetParent === null) {
        customOptions[itemsArr.indexOf(option)].style.display = 'block';
      }
    }
  });
}

although, you should tweak it a little more

You can just check filteredItems on undefined. if it is undefined you can add the no data to show at the end of your dropdown

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