TransWikia.com

How to properly call a function with the condition of input values

Stack Overflow Asked by Miloš Jeknić on November 12, 2021

I have been recently working on a website, which will mainly be used as a medium where various tourist agencies could post their travel offers.

The index page contains a functional filters area, where the user could perform an offer search based on multiple conditions.

            <div id="offer-filters">
            <h2>Filter search</h2>
            <div id="filter-bars">
                <ul id="filter-list">
                    <li>
                        <label for="searchagency">Agency</label>
                        <input list="agencies" id="searchagency" name="searchagency"
                            onclick="dataListFromOriginAgency('agencies', 'searchagency')">
                    </li>
                    <datalist id="agencies"></datalist>
                    <li>
                        <label for="searchdepart">Departure</label>
                        <input list="departures" id="searchdepart" name="searchdepart"
                            onclick="dataListFromOriginOffersDeparture('departures', 'searchdepart')">
                    </li>
                    <datalist id="departures"></datalist>
                    <li>
                        <label for="searchdestination">Destination</label>
                        <input list="destinations" id="searchdestination" name="searchdestination"
                            onclick="dataListFromOriginOffersDestination('destinations', 'searchdestination')">
                    </li>
                    <datalist id="destinations"></datalist>
                    <li>
                        <label for="searchpricerangefrom">Price below</label>
                        <input type="number" id="searchpricerangefrom" name="searchpricerangefrom" min="1"
                            max="1000000">
                        <label for="searchpricerangeto">over</label>
                        <input type="number" id="searchpricerangeto" name="searchpricerangeto" min="1"
                            max="1000000">
                    </li>
                    <li>
                        <label for="searchtransport">Transport</label>
                        <input list="transport" id="searchtransport" name="searchtransport"
                            onclick="dataListFromOriginOffersTransportation('transport', 'searchtransport')">
                    </li>
                    <datalist id="transport"></datalist>
                    <li>
                        <label for="searchstartdate">Start date</label>
                        <input type="date" name="searchstartdate" id="searchstartdate"></li>
                    <li>
                        <label for="searchenddate">Return date</label>
                        <input type="date" name="searchenddate" id="searchenddate">
                    </li>
                </ul>
            </div>
            <button class="search-filter">Search</button>
        </div>

The key idea is that the button present at the bottom would return functions based on how many inputs contain values, that saying how many inputs are not empty. I.e. an user performs a search of offers based on a certain agency, passing the agency name into the first input, and a destination which would be entered into the third one.

When i define a function that will return different results based on input conditions, some functions would never be called as the previous condition already evaulated.

function triggerFuncByScenario() {
if (!(document.querySelector("#searchagency").value === "")) {
    getOffersByName();
}

else if (!(document.querySelector("#searchagency").value === "" && document.querySelector("#searchdestination").value === "")) {
    getOffersByDestinationName();
}

Taken as an example, the first function normally occurs on button click, while the second one doesn’t work because the first part of the condition is already evaluated, leading to the constant call of the first one.

Is there any solution so that every filter combination could be assigned to different functions?

The functions also use an AJAX request for obtaining the data.

function prepareOffers(type, route, objectJSON) {

var offer = document.getElementsByClassName("offer");

while (offer[0]) {
    offer[0].parentNode.removeChild(offer[0]);
}

while (!(document.getElementById("offers-nav").innerHTML == "")) {
    var nav = document.getElementById("offers-nav");
    nav.innerHTML = "";
}

var httpRequest = new XMLHttpRequest();

httpRequest.onreadystatechange = function () {

    if (httpRequest.readyState == 4) {
        var response = httpRequest.responseText;
        var respArray = response.split(",");
        var arrayParsed = JSON.parse(respArray);
        for (let i = 0; i < arrayParsed.length; i++) {

            var offer = document.createElement("div");
            offer.className = "offer";
            document.getElementById("offers-list").appendChild(offer);

            var offerFlex = document.createElement("div");
            offerFlex.className = "offer-flex";
            document.getElementsByClassName("offer")[i].appendChild(offerFlex);

            var image = document.createElement("img");
            image.setAttribute("alt", "Image description of an given agency offer destination");
            image.setAttribute("src", ("img/" + arrayParsed[i].destination + ".jpg"));
            image.setAttribute("class", "destination-image");

            var image2 = document.createElement("img");
            image2.setAttribute("alt", "Logo of an agency that provided the offer");
            image2.setAttribute("src", ("img/" + arrayParsed[i].tourism_agency + ".png"));
            image2.setAttribute("class", "agency-logo");


            var markAsFavourite = document.createElement("a");
            markAsFavourite.setAttribute("class", "favourite");
            markAsFavourite.setAttribute("href", "#a");
            markAsFavourite.setAttribute("onclick", "addToFavourites()");
            markAsFavourite.innerHTML = "<i class='fas fa-star'></i> Add to favourites";

            var list = document.createElement("ul");
            document.getElementsByClassName("offer-flex")[i].appendChild(markAsFavourite);
            document.getElementsByClassName("offer-flex")[i].insertBefore(list, markAsFavourite);
            document.getElementsByClassName("offer-flex")[i].insertBefore(image2, list);
            document.getElementsByClassName("offer-flex")[i].insertBefore(image, image2);

            var element1 = list.appendChild(document.createElement("li"));
            element1.setAttribute("class", "destination");

            var element2 = list.appendChild(document.createElement("li"));
            element2.setAttribute("class", "start");

            var element3 = list.appendChild(document.createElement("li"));
            element3.setAttribute("class", "end");

            var element4 = list.appendChild(document.createElement("li"));
            element4.setAttribute("class", "price");

            var element5 = list.appendChild(document.createElement("li"));
            element5.setAttribute("class", "transportation");

            var element6 = list.appendChild(document.createElement("li"));
            element6.setAttribute("class", "more-info");

            document.getElementsByClassName("destination")[i].innerHTML = "Destination: " + arrayParsed[i].destination;

            document.getElementsByClassName("start")[i].innerHTML = "Start date: " + arrayParsed[i].start;

            document.getElementsByClassName("end")[i].innerHTML = "Return date: " + arrayParsed[i].end;

            document.getElementsByClassName("price")[i].innerHTML = "Price: " + arrayParsed[i].price + " €";

            document.getElementsByClassName("transportation")[i].innerHTML = "Transport: " + arrayParsed[i].transportation;

            document.getElementsByClassName("more-info")[i].innerHTML = "For more info please click <a href='#offers-page' onClick='displayMoreInfo()'>here</a>";

            document.getElementById("offers-count").innerHTML = "Showing " + document.querySelectorAll(".offer").length + " from " + arrayParsed.length + " offer(s):";
        }

        if (arrayParsed.length == 0) {
            var noOffers = document.createElement("h2");
            noOffers.setAttribute("id", "no-offers");
            document.querySelectorAll(".show-offers")[0].insertBefore(noOffers, document.querySelector("#offers-list"));
            document.querySelector("#no-offers").innerHTML = "No offers found!";
        } else {
            var noOffers = document.createElement("h2");
            noOffers.setAttribute("id", "no-offers");
            document.querySelectorAll(".show-offers")[0].insertBefore(noOffers, document.querySelector("#offers-list"));
            document.querySelector("#no-offers").remove();
        }
    }
}

httpRequest.open(type, route, true);

if (!(objectJSON == "" || objectJSON == null)) {
    httpRequest.setRequestHeader("Content-type", "application/json");
    httpRequest.send(objectJSON);
} else {
    httpRequest.send();
}

Thank you in advance.

3 Answers

While simply changing the order in which you evaluate your conditions could get the result you want, a more verbose solution can make very clear what is happening at each step.

Here, the evaluateSearchFields function reports a single value representing which combination of fields the user filled in. With this information, you can be confident about which action to take.

I wouldn't bother with this level of detail in most cases, but sometimes clarity is what we need so we can proceed from a solid foundation.

function triggerFuncByScenario() {
  const
    searchAgency =      document.getElementById("searchagency"),
    searchDestination = document.getElementById("searchdestination"),

    agencyEmpty = (searchAgency.value === ""),
    destinationEmpty = (searchDestination.value === "");

  if( evaluateSearchFields() == "agencyOnly" ){ getOffersByName(); }
  else if( evaluateSearchFields() == "both"  ){ getOffersByDestinationName(); }
}

function evaluateSearchFields(){
  if(!agencyEmpty && !destinationEmpty){ return "both";            }
  if(!agencyEmpty &&  destinationEmpty){ return "agencyOnly";      }
  if( agencyEmpty && !destinationEmpty){ return "destinationOnly"; }
  if( agencyEmpty &&  destinationEmpty){ return "neither";         }
  else { return "this is impossible"; }
}

Answered by Cat on November 12, 2021

So I've been looking it over and just a thought, have you tried to nest your if-else statements?

function triggetFuncByScenario(){
    if(!(document.querySelector("#searchagency").value === "")){
        if(!(document.querySelector("#searchdestination").value === "")){
            getOffersByDestinationName();
        }else{
            getOffersByName();
        }
    }
}

To me, it looks like that little oversight is what is causing your problem. By nesting this you are getting a certain check of all the given conditions.

Hope it is helpful and good luck with your project.

Answered by TikkyDev on November 12, 2021

For this part removing else will evaluate both conditions and execute.

Also try to use getElementById if you need to get only one element by ID

function triggerFuncByScenario() {
    var searchAgency = document.getElementById("searchagency");

   if (!(searchAgency.value === "")) {
         getOffersByName();
   }


  if (!(searchAgency.value === "" && 
    document.querySelector("#searchdestination").value === "")) {
        getOffersByDestinationName();
     }
  }

Answered by Velu S Gautam on November 12, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP