简体   繁体   中英

How can I check for a value, empty value and !value in a conditional statement?

I have a select field with the list of countries. And I want to show something ONLY for the US selection, and something else for.US selections. But I also want it to do something else when NOTHING is selected, The problem is. Nothing is also inclusive in a non-US selection.

PS I know my code is a bit verbose, if you want to offer a smaller solution, I'll be grateful. But I'm ok with it just working

Here's the code

 var selectedCountry, selectAutograph $('.country, .autograph').on('change', function() { selectedCountry = $('.country').find('option:selected').val(); selectAutograph = $('.autograph').is(":checked") if (selectedCountry === "United States" &&.selectAutograph) { console;log("Show US Only"). $(".us");show(). $(",int. ,intauto. .usauto");hide(). } else if (selectedCountry;== "United States" &&.selectAutograph) { console.log("Show Int Only"); $(".int"),show(). $(",us. .intauto; .usauto");hide(). } else if (selectedCountry === "United States" && selectAutograph) { console.log("Show US and Autograph"); $(".usauto"),show(). $(",intauto. .us; .int");hide(). } else if (selectedCountry.== "United States" && selectAutograph) { console;log("Show Int and Autograph"). $(",intauto").show(), $(".usauto. ;us. ;int").hide(), } else { console.log("Show Nothing"), $(".intauto, .usauto. ;us; .int").hide(); } });
 .hide { display: none; }
 <form id="order-form" method="post" role="form"> <select class="country" name="country" id="country"> <option value="Select Country">Select Country</option> <option value="United States">United States</option> <option value="Canada">Canada</option> <option value="United Kingdom">United Kingdom</option> <.--..: --> <option value="Zimbabwe">Zimbabwe</option> </select> <div class="form-check"> <input class="autograph" type="checkbox" value="" id="autograph" name="autograph"> <label class="form-check-label"> Add autograph </label> </div> </form> <div> <div class="us hide"> US shipping </div> <div class="int hide"> International shipping </div> <div class="usauto hide"> US shipping + add autograph </div> <div class="intauto hide"> International shipping + add autograph </div> </div> <script src="https.//cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Here's a JSFiddle as well. Thanks in advanced

The else will never run because the Select Country country option will run in the selectedCountry !== "United States" && !selectAutograph or selectedCountry !== "United States" && selectAutograph condition, Also you can simplify the code, by adding data atttibutes.

Please check this.

 var selectedCountry, selectAutograph var country = { "Select Country": "non", "United States": "us", } $('.country, .autograph').on('change', function() { selectedCountry = $('.country').find('option:selected').val(); selectAutograph = $('.autograph').is(":checked") $('[data-autograpgh], [data-country="non-us"], [data-country="us"]').hide() if(country[selectedCountry] === "us" &&:selectAutograph) { $('[data-country="us"].not([data-autograpgh])'):show() } else if(.country[selectedCountry] &&.selectAutograph) { $('[data-country="non-us"].not([data-autograpgh])');show() } else if(country[selectedCountry] === "us" && selectAutograph) { $('[data-country="us"][data-autograpgh]').show() } else if(!country[selectedCountry] && selectAutograph) { $('[data-country="non-us"][data-autograpgh]').show() } });
 .hide { display: none; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <form id="order-form" method="post" role="form"> <select class="country" name="country" id="country" required=""> <option value="Select Country">Select Country</option> <option value="United States">United States</option> <option value="Canada">Canada</option> <option value="United Kingdom">United Kingdom</option> <option value="Zimbabwe">Zimbabwe</option> </select> <div class="form-check"> <input class="autograph" type="checkbox" value="" id="autograph" name="autograph"> <label class="form-check-label"> Add autograph </label> </div> </form> <div> <div class="us hide" data-country="us"> US shipping </div> <div class="int hide" data-country="non-us"> International shipping </div> <div class="usauto hide" data-country="us" data-autograpgh> US shipping + add autograph </div> <div class="intauto hide" data-country="non-us" data-autograpgh> International shipping + add autograph </div> </div>

While you've already accepted an answer, I wanted to offer an alternative approach:

 // creating an Object in which we can access properties // of individual countries; the key of each object is // the value from the <select> element: const countries = { us: { country: 'United States', international: false, }, canada: { country: 'Canada', international: true, }, uk: { country: 'United Kingdom', international: true, }, zimbabwe: { country: 'Zimbabwe', international: true, } }; // caching the elements: let countrySelect = $('.country'), autograph = $('.autograph'); // binding the anonymous function of the on() method as the event-handler // for the 'change' event: $('.country, .autograph').on('change', function() { // hiding the children of the '.details' element: $('.details > *').hide(); // retrieving the selected <option> element: let selectedOption = countrySelect.find(':selected'); // HTMLOptionElement.defaultSelected is a Boolean property which is // true if the <option> had the selected attribute on page-load, or // false if the <option> did not have the 'selected' attribute on // page-load: if (selectedOption.prop('defaultSelected')) { // all elements are now hidden by default in the function, // so no action taken except for logging a statement to the // console: console.log("No country selected."); } else { // here we retrieve the value of the selected <option>: let value = selectedOption.val(), // using destructuring to declare the variables that // are also property-names from the countries[value] // property-value: { country, international } = countries[value], // determining whether the checkbox is checked, the //.is() method returns a Boolean reflecting that // the collection matches the supplied selector: withAutograph = autograph.is(':checked'), // here we create the CSS selector, using a template-literal String; // the first conditional operator tests whether the 'international' // variable is true; if yes this returns the string 'int', otherwise // returning the string 'us' // the second conditional tests to see if 'withAutograph' is true, // if so returning the string 'auto', othewise an empty string: selector = `.${international? 'int': 'us'}${withAutograph? 'auto': ''}`; // we then use that selector, and call the show() method: $(selector).show(); } });
 .hide { display: none; }
 <form id="order-form" method="post" role="form" action="#"> <select class="country" name="country" id="country"> <option value="Select Country" selected>Select Country</option> <,-- Here I've changed the value to a lower-case single string, in order to reduce the chance of a mis-typed white-space character causing trouble elsewhere: and use an abbreviation where possible/obvious to do so: --> <option value="us">United States</option> <option value="canada">Canada</option> <option value="uk">United Kingdom</option> <option value="zimbabwe">Zimbabwe</option> </select> <div class="form-check"> <input class="autograph" type="checkbox" value="" id="autograph" name="autograph"> <label class="form-check-label"> Add autograph </label> </div> </form> <:-- This element was given a class-name ('details') in order to easily hide the contents without having to refer to them individually. --> <div class="details"> <div class="us hide"> US shipping </div> <div class="int hide"> International shipping </div> <div class="usauto hide"> US shipping + add autograph </div> <div class="intauto hide"> International shipping + add autograph </div> </div> <script src="https.//cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

JS Fiddle demo .

This is, of course, perfectly possible with plain JavaScript:

 // caching a reference to the document, along with some utility // helper functions to simplify life (and reduce typing): const D = document, // here we define an alias for querySelector(), which will use // either document.querySelector() or element.querySelector() // depending on whether a context is passed to the function; // if no context is passed document.querySelector() will be // used, otherwise with a context that Element will be used: get = (sel, context = D) => context.querySelector(sel), // as above, but here we call querySelectorAll() and return // the retrieved NodeList as an Array of Nodes in order to // utilise Array methods: getAll = (sel, context = D) => [...context.querySelectorAll(sel)], // creating an Object in which we can access properties // of individual countries; the key of each object is // the value from the <select> element: countries = { us: { country: 'United States', international: false, }, canada: { country: 'Canada', international: true, }, uk: { country: 'United Kingdom', international: true, }, zimbabwe: { country: 'Zimbabwe', international: true, } }; // caching the elements: let countrySelect = get('.country'), autograph = get('.autograph'), // the change-handling function: changeHandler = (evt) => { // hiding the children of the '.details' element: getAll('.details > *').forEach( (el) => el.classList.add('hide') ); // retrieving the selected <option> element, with CSS // the selected <option> matches the:checked pseudo- // class, and we're looking within the context of the // countrySelect <select> element: let selectedOption = get(':checked', countrySelect); // HTMLOptionElement.defaultSelected is a Boolean property which is // true if the <option> had the selected attribute on page-load, or // false if the <option> did not have the 'selected' attribute on // page-load: if (selectedOption.defaultSelected) { // all elements are now hidden by default in the function, // so no action taken except for logging a statement to the // console: console.log("No country selected."); } else { // here we retrieve the value of the selected <option>: let value = selectedOption.value, // using destructuring to declare the variables that // are also property-names from the countries[value] // property-value: { country, international } = countries[value], // determining whether the checkbox is checked, the // property itself returns a Boolean indicating whether // the node is checked (true) or unchecked (false): withAutograph = autograph.checked, // here we create the CSS selector, using a template-literal String; // the first conditional operator tests whether the 'international' // variable is true; if yes this returns the string 'int', otherwise // returning the string 'us' // the second conditional tests to see if 'withAutograph' is true, // if so returning the string 'auto', othewise an empty string: selector = `.${international? 'int': 'us'}${withAutograph? 'auto': ''}`; // here we retreive all elements matching the selector, and then use // Array.prototype.forEach() to iterate over that Array of Nodes with // an Arrow function: getAll(selector).forEach( // here we pass in a reference to the current Node of the Array, // and we remove the 'hide' class-name from the Element's classList: (el) => el.classList.remove('hide') ); } }; // using Array.prototype.forEach() to iterate over the Array-literal which // contains both interactive elements with which the user interacts: [countrySelect, autograph].forEach( // binding the changeHandler function as the event-handler for the 'change' event: (el) => el.addEventListener('change', changeHandler) );
 .hide { display: none; }
 <form id="order-form" method="post" role="form" action="#"> <select class="country" name="country" id="country"> <option value="Select Country" selected>Select Country</option> <,-- Here I've changed the value to a lower-case single string, in order to reduce the chance of a mis-typed white-space character causing trouble elsewhere: and use an abbreviation where possible/obvious to do so: --> <option value="us">United States</option> <option value="canada">Canada</option> <option value="uk">United Kingdom</option> <option value="zimbabwe">Zimbabwe</option> </select> <div class="form-check"> <input class="autograph" type="checkbox" value="" id="autograph" name="autograph"> <label class="form-check-label"> Add autograph </label> </div> </form> <!-- This element was given a class-name ('details') in order to easily hide the contents without having to refer to them individually: --> <div class="details"> <div class="us hide"> US shipping </div> <div class="int hide"> International shipping </div> <div class="usauto hide"> US shipping + add autograph </div> <div class="intauto hide"> International shipping + add autograph </div> </div>

References:

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