如果没有任何内容,请禁用选择

时间:2019-05-28 17:24:29

标签: javascript css

我制作了具有多个选项的过滤器。如您所见,有时没有结果。我说:“没有结果。”作为用户反馈,将其反馈给访问者。

现在我要说的是,如果某些组合是由过滤器(某些值)构成的,则只有在实际有值的情况下才可以使用过滤器(因此,如果页面上没有值,请隐藏一个选项)。这样,我就避免了用户必须进行无穷尽的过滤器组合才能找到正确的结果。有人可以帮我吗?

$("select.filterby").change(function() {
  var filters = $.map($("select.filterby").toArray(), function(e) {
    return $(e).val();
  }).join(".");
  $("div#FilterContainer").find("div.job-offer-card").hide();
  if ($("div#FilterContainer").find("div.job-offer-card." + filters).length) {
    $("div#FilterContainer").find("div.job-offer-card." + filters).show();

  } else {
    $("div#FilterContainer").find("div.noresults").show();
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span> View by:</span>


    <label for="location">Location</label>
    <select id="location" class="filterby">
       <option value="all">Show All</option>
       <option value="australia">Australia</option>
       <option value="singapore">Singapore</option>
       <option value="newzealand">New Zealand</option>
       <option value="usa">USA</option>
       <option value="uk">UK</option>
       <option value="vietnam">Vietnam</option>
       <option value="global">Global</option>
       <option value="othercountry">Other</option>
    </select>


    <label for="type">Type</label>
    <select id="type" class="filterby">
       <option value="all">Show All</option>
       <option value="accommodation">Accommodation</option>
       <option value="app">App/Technology</option>
       <option value="business">Business</option>
       <option value="health">Health</option>
       <option value="hospitality">Hospitality</option>
       <option value="education">Education</option>
       <option value="retail">Retail</option>
       <option value="services">Services</option>
       <option value="travel">Travel</option>
    </select>

    <label for="code">Code</label>
    <select id="code" class="filterby">
       <option value="all">Show All</option>
       <option value="001">001</option>
       <option value="002">002</option>
       <option value="003">003</option>
       <option value="004">004</option>
    </select>

<div id="FilterContainer">
  <div class="job-offer-card noresults">
    <p>no results</p>
  </div>
  <div class="job-offer-card all vietnam accommodation travel 004">
    <p>1 all vietnam accommodation travel</p>
  </div>
  <div class="job-offer-card all vietnam  travel 003">
    <p>2 all vietnam travel</p>
  </div>
  <div class="job-offer-card all vietnam accommodation travel">
    <p>3 all vietnam accommodation travel</p>
  </div>
  <div class="job-offer-card all australia accommodation travel 003">
    <p>4 all australia accommodation travel</p>
  </div>
  <div class="job-offer-card all australia education">
    <p>5 all australia</p>
  </div>
  <div class="job-offer-card all vietnam newzealand usa accommodation">
    <p>6 all vietnam accommodation</p>
  </div>
  <div class="job-offer-card all vietnam accommodation travel">
    <p>7 all vietnam accommodation travel</p>
  </div>
  <div class="job-offer-card all vietnam  travel">
    <p>8 all vietnam travel</p>
  </div>
  <div class="job-offer-card all vietnam accommodation travel">
    <p>9 all vietnam accommodation travel</p>
  </div>
  <div class="job-offer-card all australia accommodation travel">
    <p>10 all australia accommodation travel</p>
  </div>
  <div class="job-offer-card all australia health 001">
    <p>11 all australia</p>
  </div>
  <div class="job-offer-card all vietnam accommodation 002">
    <p>12 all vietnam accommodation</p>
  </div>
</div>

2 个答案:

答案 0 :(得分:1)

具有动态选择和动态FilterContainer元素的解决方案。

备注:类名001 ... 004应该更改为_001 ..._ 004,因为它们不是有效的类名 参见=> Which characters are valid in CSS class names/selectors?
或者使用数据集=> https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset

更清晰

false
const
    Selects = document.querySelectorAll('select')                      // 3 selects in this story
  , mainFC  = document.querySelector('#FilterContainer')               // result part
  , all_FC  = document.querySelectorAll('#FilterContainer div')        // details result part
  , zeroFC  = document.querySelector('#FilterContainer div.noresults') // when there is nothing
;

var PossibleOptions = new Set();  // set for all options feet in #FilterContainer div

all_FC.forEach(d=>{d.className.split(' ').forEach(c=>{PossibleOptions.add(c)})}) // first attempt

// for the start : set only options availables + onchange listener
Selects.forEach(s=>{                                // for each Select 
  s.querySelectorAll('option').forEach(o=>{         // and for each option, in
    o.disabled = !PossibleOptions.has(o.value);     // is there 1 a result div using this class ?.
    if (o.value==='all') o.selected=true;           // start the select at position for all
  })
  s.onchange = SelecChange;                         // give listener 'change' to function named 'SelecChange'
})



function SelecChange(e)              // for every select action...
{
  //  e.target.value 
  let                               // prepare ;
    List_Selects = []               // - array for all selects value
  , no_FC        = true             // - flag to know if there is no FS as result
  ;
  PossibleOptions.clear();          // new start

  Selects.forEach(s=>{              // make List_Selects
    if(s.value!='all')              // everything is nothing
    { List_Selects.push(s.value) }  // add select value
  });
 
  all_FC.forEach(d=>{               // for each FilterContainer <div> as 'd'
    let ok = true;
    for(let cLS of List_Selects)    // for each option choosed in a select
    { ok = ok && d.classList.contains(cLS) } // check if in class list of the <div>

    if (ok){
      d.classList.remove('noShow');   // so this div will be shown
      d.className.split(' ').forEach(c=>{ PossibleOptions.add(c) }); 
                                      // and all the div class item be added on the set
      no_FC = false;                  // one is enough
    }
    else {
      d.classList.add('noShow');    // soory guy, your not in the team for this time
    }
  })

  // now we have disable all options witch as no reality in FilterContainer
  Selects.forEach(s=>{ 
    s.querySelectorAll('option').forEach(o=>{
      o.disabled = !PossibleOptions.has(o.value);   // PossibleOptions know
    })
  })

  // last things: is there results ?
  if (no_FC) { zeroFC.classList.remove('noShow') }  // there is none
  else       { zeroFC.classList.add('noShow')    }  // there is one (or more)
}
.noShow { display: none }

相同的解决方案,但使用数据选项
=> <h4> View by:</h4> <label for="location">Location</label> <select id="location" class="filterby"> <option value="all">Show All</option> <option value="australia">Australia</option> <option value="singapore">Singapore</option> <option value="newzealand">New Zealand</option> <option value="usa">USA</option> <option value="uk">UK</option> <option value="vietnam">Vietnam</option> <option value="global">Global</option> <option value="othercountry">Other</option> </select> <label for="type">Type</label> <select id="type" class="filterby"> <option value="all">Show All</option> <option value="accommodation">Accommodation</option> <option value="app">App/Technology</option> <option value="business">Business</option> <option value="health">Health</option> <option value="hospitality">Hospitality</option> <option value="education">Education</option> <option value="retail">Retail</option> <option value="services">Services</option> <option value="travel">Travel</option> </select> <label for="code">Code</label> <select id="code" class="filterby"> <option value="all">Show All</option> <option value="001">001</option> <option value="002">002</option> <option value="003">003</option> <option value="004">004</option> </select> <hr> <div id="FilterContainer"> <div class="job-offer-card noresults noShow"> <p>no results</p> </div> <div class="job-offer-card all vietnam accommodation travel 004"> <p>1 all vietnam accommodation travel _004</p> </div> <div class="job-offer-card all vietnam travel _003"> <p>2 all vietnam travel _003</p> </div> <div class="job-offer-card all vietnam accommodation travel"> <p>3 all vietnam accommodation travel</p> </div> <div class="job-offer-card all australia accommodation travel 003"> <p>4 all australia accommodation travel 003</p> </div> <div class="job-offer-card all australia education"> <p>5 all australia education</p> </div> <div class="job-offer-card all vietnam newzealand usa accommodation"> <p>6 all vietnam newzealand usa accommodation</p> </div> <div class="job-offer-card all vietnam accommodation travel"> <p>7 all vietnam accommodation travel</p> </div> <div class="job-offer-card all vietnam travel"> <p>8 all vietnam travel</p> </div> <div class="job-offer-card all vietnam accommodation travel"> <p>9 all vietnam accommodation travel</p> </div> <div class="job-offer-card all australia accommodation travel"> <p>10 all australia accommodation travel</p> </div> <div class="job-offer-card all australia health 001"> <p>11 all australia health _001</p> </div> <div class="job-offer-card all vietnam accommodation 002"> <p>12 all vietnam accommodation _002</p> </div> </div>
(JS => element.dataset.options

<div class="job-offer-card" data-options="all vietnam accommodation 002">
const
    Selects = document.querySelectorAll('select')                      // 3 selects in this story
  , mainFC  = document.querySelector('#FilterContainer')               // result part
  , all_FC  = document.querySelectorAll('#FilterContainer div')        // details result part
  , zeroFC  = document.querySelector('#FilterContainer div.noresults') // when there is nothing
;

var PossibleOptions = new Set();  // set for all options feet in #FilterContainer div

all_FC.forEach(d=>{ d.dataset.options.split(' ').forEach(c=>{PossibleOptions.add(c)})}) // first attempt

// for the start : set only options availables + onchange listener
Selects.forEach(s=>{                                // for each Select 
  s.querySelectorAll('option').forEach(o=>{         // and for each option, in
    o.disabled = !PossibleOptions.has(o.value);     // is there 1 a result div using this class ?.
    if (o.value==='all') o.selected=true;           // start the select at position for all
  })
  s.onchange = SelecChange;                         // give listener 'change' to function named 'SelecChange'
})

function SelecChange(e)              // for every select action...
{
  //  e.target.value 
  let                               // prepare ;
    List_Selects = []               // - array for all selects value
  , no_FC        = true             // - flag to know if there is no FS as result
  ;
  PossibleOptions.clear();          // new start

  Selects.forEach(s=>{              // make List_Selects
    if(s.value!='all')              // everything is nothing
    { List_Selects.push(s.value) }  // add select value
  });
 
  all_FC.forEach(d=>{               // for each FilterContainer <div> as 'd'
    let
      ok  = true,
      opt = d.dataset.options.split(' ');
 
    for(let cLS of List_Selects)    // for each option choosed in a select
    { ok = ok && opt.includes(cLS) } // check if in class list of the <div>

    if (ok){
      opt.forEach(c=>{ PossibleOptions.add(c) }); // all the data-options item  be added on the set
      d.classList.remove('noShow');              // so this div will be shown
      no_FC = false;                            // one is enough
    }
    else {
      d.classList.add('noShow');    // soory guy, your not in the team for this time
    }
  })

  // now we have disable all options witch as no reality in FilterContainer
  Selects.forEach(s=>{ 
    s.querySelectorAll('option').forEach(o=>{
      o.disabled = !PossibleOptions.has(o.value);   // PossibleOptions know
    })
  })

  // last things: is there results ?
  if (no_FC) { zeroFC.classList.remove('noShow') }  // there is none
  else       { zeroFC.classList.add('noShow')    }  // there is one (or more)
}
.noShow { display: none }

答案 1 :(得分:0)

所以,如果我正确检查了您的问题:

const
  All_Select          = document.querySelectorAll('select')
, All_FilterContainer = document.querySelectorAll('#FilterContainer div')
;

var List_of_everthing   = new Set();
All_FilterContainer.forEach(d=>{
  d.className.split(' ').forEach(c=>{List_of_everthing.add(c.toLowerCase())});
})

All_Select.forEach(s=>{
  s.querySelectorAll('option').forEach(o=>{
    o.disabled = !List_of_everthing.has(o.value);
  })
})