breezertwo
breezertwo

Reputation: 585

Toggle selector CSS with multiple values

This is what I have:

A SVG with several lines. These have types as CSS classes. For example: .pen1 .pen2 .pen3 .pen4. and .special

Every line has one of the first four and can have .spcial! There are also some .special only lines.

It's possible do activate and deactivate each of these classes with buttons.

My problem is:

(Line A has .pen1, Line B has .pen1 .special, Line C has .pen2, Line D has .pen2 .special)

Following procedure:

But I need both to disappear in 2) and after that both should reappear in 3).

My current solution is, If I press the button for .pen1 i set a flag that it was pressed and test this flag when I press .special --> This works, but only if only one class has its own and the .special class

This is my code right now:

for special toggling:

if (this._pen1|| this._pen2|| this.pen3|| this.pen4 ){
      if (this.special) {
        if (this.pen1) {
          [...].find('svg .' + _PENSTYLES.special).not('.' + _PENSTYLES.pen1).hide(0);
        }
        if (this.pen2) {
          [...].find('svg .' + _PENSTYLES.special).not('.' + _PENSTYLES.pen2).hide(0);
        }
        if (this.pen3) {
          [...].find('svg .' + _PENSTYLES.special).not('.' + _PENSTYLES.pen3).hide(0);
        }
        if (this.pen4) {
          [...].find('svg .' + _PENSTYLES.special).not('.' + _PENSTYLES.pen4).hide(0);
        }
      } else {
        if (this.pen1) {
          [...].find('svg .' + _PENSTYLES.special).not('.' + _PENSTYLES.pen1).show(0);
        }
        if (this.pen2) {
          [...].find('svg .' + _PENSTYLES.special).not('.' + _PENSTYLES.pen2).show(0);
        }
        if (this.pen3) {
          [...].find('svg .' + _PENSTYLES.special).not('.' + _PENSTYLES.pen3).show(0);
        }
        if (this.pen4) {
          [...].find('svg .' + _PENSTYLES.special).not('.' + _PENSTYLES.pen4).show(0);
        }
      }
    } else {
      [...].find('svg .' + _PENSTYLES.special).toggle(0);
    }
    this.special= !this.special;

for pen1-4 toggling:

    if (this.special) {
      [...].find('svg .' + _PENSTYLES.pen1).not('.' + _PENSTYLES.special).toggle(0);
    } else {
      [...].find('svg .' + _PENSTYLES.pen1).toggle(0);
    }
    this.pen1= !this.pen1;  

I hope someone can help me how I do it for my problem with multiple lines. Because right now they pen2 overrides pen1 and show/hides everything which was excluded in the others.

Upvotes: 0

Views: 521

Answers (2)

Ted
Ted

Reputation: 14927

Here's a simplification of what I think you're looking for to get you started. Run the snippet to see it work.

var hidden = [];

function toggle(classname) {
  if (hidden.indexOf(classname) > -1) {
    hidden.splice(hidden.indexOf(classname), 1);
    getElements(classname).forEach(function(ele) {
      ele.classList.remove("hidden");
    });
  } else {
    hidden.push(classname);
  }
  hidden.forEach(function(hide) {
    getElements(hide).forEach(function(ele) {
      ele.classList.add("hidden")
    });
  })
}

function getElements(classname) {
  return Array.from(document.getElementsByClassName(classname));
}
html {
  font-family: sans-serif;
}

.root {
  display: flex;
}

.root>div {
  flex: 0 0 80px;
}
button{
 width: 70px;
}

svg line {
  stroke-width: 2;
}

.special {
  stroke: red;
  stroke-dasharray: 5;
}

.pen1 {
  stroke: blue;
}

.pen2 {
  stroke: green;
}

.pen3 {
  stroke: goldenrod;
}

.pen4 {
  stroke: DarkOrchid;
}

text {
  font-size: 14px;
}

.hidden {
  display: none;
}
<div class="root">
  <div>
    <button onclick="toggle('pen1')">.pen1</button>
    <button onclick="toggle('pen2')">.pen2</button>
    <button onclick="toggle('pen3')">.pen3</button>
    <button onclick="toggle('pen4')">.pen4</button>
    <button onclick="toggle('special')">.special</button>
  </div>

  <svg width="400" height="200" viewBox="0 0 400 200">
  <rect width="400" height="200" fill="#efefef" />
  <line class="pen1" y1="20" y2="20" x1="0" x2="300" />
  <line class="pen2" y1="40" y2="40" x1="0" x2="300" />
  <line class="pen3" y1="60" y2="60" x1="0" x2="300" />
  <line class="pen4" y1="80" y2="80" x1="0" x2="300" />
  <line class="pen1 special" y1="100" y2="100" x1="0" x2="300" />
  <line class="pen2 special" y1="120" y2="120" x1="0" x2="300" />
  <line class="pen3 special" y1="140" y2="140" x1="0" x2="300" />
  <line class="pen4 special" y1="160" y2="160" x1="0" x2="300" />
  <line class="special" y1="180" y2="180" x1="0" x2="300" />
  <text x="310" y="20" alignment-baseline="middle">.pen1</text>
  <text x="310" y="40" alignment-baseline="middle">.pen2</text>
  <text x="310" y="60" alignment-baseline="middle">.pen3</text>
  <text x="310" y="80" alignment-baseline="middle">.pen4</text>
  <text x="310" y="100" alignment-baseline="middle">.pen1 .special</text>
  <text x="310" y="120" alignment-baseline="middle">.pen2 .special</text>
  <text x="310" y="140" alignment-baseline="middle">.pen3 .special</text>
  <text x="310" y="160" alignment-baseline="middle">.pen4 .special</text>
  <text x="310" y="180" alignment-baseline="middle">.special</text>
</svg>
</div>

Upvotes: 1

Bojan Kolano
Bojan Kolano

Reputation: 283

I will give you a hint. You can always add another , Same named , class for elements that you want to toggle. .pen1 and .pen2 can both have class "hidden" with some attributes in it. Hope it helps :)

Upvotes: 1

Related Questions