real
real

Reputation: 491

Mithril.js multiple css class

I'm new at mithril.js. I have a div, I want to add class "invalid" if ctrl.invalid()==true, and "hidden" if ctrl.hidden()==true.

If I use m('div', {class: ctrl.invalid() ? 'invalid' : '', class: ctrl.hidden()? 'hidden' : ''}), they override each other.

I can use m('div', {class: [ctrl.invalid()?'invalid':'', ctrl.focused()?'focused':''].join(' ')}), and it'll work, but it looks messy.

Is there an elegant solution for this? Thanks.

Upvotes: 6

Views: 2697

Answers (3)

Thomas Jørgensen
Thomas Jørgensen

Reputation: 1122

Very late to the game, but as an inspiration for others ending up here, I often do something like the following, just because it is:

  • simple to implement
  • easy to extend
  • easy to understand
view(): {
    const classes = 
        `${ctrl.invalid() ? '.invalid' : ''}` +
        `${ctrl.hidden()? '.hidden' : ''}`;
    return m(`div${classes}`);
}

Upvotes: 1

Matias Kinnunen
Matias Kinnunen

Reputation: 8540

You can add a helper method to your Mithril component:

const myComponent = {
    css() {
        // Add some logic

        return 'class1 class2';
    },
    view() {
        return m('div', { class: this.css() });
    },
};

Or to the controller:

const ctrl = {
    css() {
        // Add some logic

        return 'class3';
    },
};

const myComponent = {
    view() {
        return m('div', { class: ctrl.css() });
    },
};

Choose whichever suits your case better.

You can also use the classnames utility, as suggested by Ross Khanas in his answer:

const myComponent = {
    css() {
        return classNames({
            invalid: ctrl.invalid(), 
            focused: ctrl.focused(),
        });
    },
    view() {
        return m('div', { class: this.css() });
    },
};

Or:

const ctrl = {
    css() {
        return classNames({
            invalid: this.invalid(), 
            focused: this.focused(),
        });
    },
    invalid() { /* ... */ },
    focused() { /* ... */ },
};

const myComponent = {
    view() {
        return m('div', { class: ctrl.css() });
    },
};

Upvotes: 0

Ross Khanas
Ross Khanas

Reputation: 1501

I recommend you to use classnames - a simple utility for that. You can define your classes in a nice way and it will merge everything for you. In your case it will be:

const myMergedClasses = classNames({
    invalid: ctrl.invalid(), 
    focused: ctrl.focused()
});
m('div', { class: myMergedClasses })

Beautiful?!

Upvotes: 5

Related Questions