2

I have a small app weather app that displays some basic info from public API and based on that info I add a certain icon (e.g. sun, cloudy) to the App. User can check another city after the first, and I'd like to change that icon every time conditions changes. I could do it with clearing all classes, adding basic classes and then adding right icon class, or just changing every if to "classList(all relevant classes) but I'd rather do that with RegEx. Here is how the App works:

cityButton.addEventListener("click", function() {
    if (mainIcon.classList.contains(new RegExp(/^wi-.+$/))) {
        console.log("Icon contains wi-");
    }
    fetch(api + "q=" + cityInput.value + "&APPID=" + key + "&units=metric")
    .then((resp) => resp.json())
    .then((data) => {
        let date = new Date();
        let currentTime = date.getHours();
        if (currentTime >= 6 && currentTime <= 18 && data.clouds.all < "25") {;
            mainIcon.classList.add("wi-day-sunny");
        } else if (currentTime >= 18 && currentTime <= 6 && data.clouds.all < "25") {
            mainIcon.classList.add("wi-night-clear");
        } else if (currentTime >= 6 && currentTime <= 18 && data.clouds.all >= "25" && data.clouds.all < "50") {
            mainIcon.classList.add("wi-day-cloudy");
        } else if (currentTime >= 18 && currentTime <= 6 && data.clouds.all >= "25" && data.clouds.all < "50") {
            mainIcon.classList.add("wi-night-alt-cloudy");
        } else if (currentTime >= 6 && currentTime <= 18 && data.clouds.all >= "50" && data.clouds.all < "75") {
            mainIcon.classList.add("wi-day-cloudy-high");
        } else if (currentTime >= 18 && currentTime <= 6 && data.clouds.all >= "50" && data.clouds.all < "75") {
            mainIcon.classList.add("wi-night-alt-cloudy-high");
        } else if (data.clouds.all >= "75") {
            mainIcon.classList.add("wi-cloudy");
        }
        temperature.innerHTML = data.main.temp;
        tempMin.textContent = data.main.temp_min;
        tempMax.textContent = data.main.temp_max;
        pressure.textContent = data.main.pressure + " hPa";
        humidity.textContent = data.main.humidity + " %";
        wind.textContent = data.wind.speed + " m/s";
        clouds.textContent = data.clouds.all + " %";
        windDir.textContent = data.wind.deg;
        city.textContent = data.name;
        if (data.rain !== undefined) {
            rain.textContent = data.rain + " %";
        }
    })
    .catch(function(error) {
        console.log(error);
    })
});

As you can see, user puts city name in the input, click search and then the app should check if the span "mainIcon" contains a class with name that starts with "wi-". RegEx is correct, I've tested it using https://regexr.com/, but in the console there is nothing showing up. i've tried also:

const wiClass = new RegExp(/^wi-.+$/);
    if (mainIcon.classList.contains(wiClass)) {
        console.log("Icon contains wi-");
    }

But again, no luck. What I want to do is something like this:

if (mainIcon.classList.contains(wiClass)) {
        mainIcon.classList.remove(wiClass);
    } else {
        return;
    }

Why doesn't that work? I'll appreciate all of your answers, as long as there is no jQuery involved (I like it, but I want to do it in vanilla JS).

2
  • contains doesn't work with regular expressions. Commented Nov 29, 2017 at 8:34
  • use className.match(wiClass) or wiClass.exec(className). if there is no match this functions will return null Commented Nov 29, 2017 at 8:41

1 Answer 1

9

You should not use classList with regular expression, contains method works with string parameter, not regex. You could just use plain old className property with match method:

const wiClass = new RegExp(/\bwi-.+?\b/, 'g');

if (mainIcon.className.match(wiClass)) {
    console.log("Icon contains wi-");
}

To remove class with regular expression you would again use className

if (mainIcon.className.match(wiClass)) {
    console.log("Icon contains wi-");
    mainIcon.className = mainIcon.className.replace(wiClass, '')
}

Note, g global flag in regular expression necessary to remove all wi- classes.

Sign up to request clarification or add additional context in comments.

6 Comments

Unfortunately, not working. Even if the mainIcon has wi-clody and wi-day-sunny it doesn't work. if (mainIcon.className.match(wiClass)) { console.log("Icon contains wi-"); } else { console.log("Icon does not contains wi-"); }
Probably because you regular expression is not very unreliable. I would use something like this /\bwi-.+?\b/. But in any case it works for me for usecase you posted. jsfiddle.net/vbjzxzz4
It works when wi-something is the only class, but if there is any other there seems to be a problem. Here is updated fiddle: jsfiddle.net/vbjzxzz4/3
UPDATE: I've changed my RegEx to yours and now it works properly. So there is first problem gone. Another one is - how do I remove a class using RegEx? classList.remove also accepts only strings - so how could I do it?
Thank you very much, now it works like a charm :) Additionaly I've changed your RegEx to "/\bwi-.+\b/" beacuse this class can be wi-something or wi-something-something - updated fiddle - jsfiddle.net/vbjzxzz4/10
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.