3

How do I select the last has-errors div below?

<section class="form-block">
    <div class="form-group has-errors">
          ERROR!
    </div>
    <div class="form-group has-errors">
          ERROR!
    </div>
    <div class="form-group">
          stuff
    </div>
</section>

I can select the first has-errors using:

.form-block .form-group.has-errors:first-child {
  background-color: blue;
}

But last-child does not work above. How do I select the last instance of .form-group.has-errors?

jsfiddle

Nick B
  • 9,267
  • 17
  • 64
  • 105
  • Possible duplicate of [How do I select the "last child" with a specific class name in CSS?](https://stackoverflow.com/questions/6401268/how-do-i-select-the-last-child-with-a-specific-class-name-in-css) – Heretic Monkey Jun 27 '17 at 22:22
  • The solution is much different in the question linked above. The solution in the linked answer in inapplicable to my use case. The answer below is a method applicable to my problem. – Nick B Jun 28 '17 at 16:30

2 Answers2

2

With CSS it will be tough unless there are some specific rules - like it's always the 2nd from last. In short what you're asking for is like last-of-class, which doesn't exist. There is last-of-type but that only applies to element type (div, p, etc), not to classes.

The next best option is some vanilla JS to grab the last element with the .form-group.has-error class.

const hasErrors = document.querySelectorAll('.form-group.has-errors');
hasErrors[hasErrors.length -1].style.color = 'red';
<section class="form-block">
    <div class="form-group has-errors">
          ERROR!
    </div>
    <div class="form-group has-errors">
          ERROR!
    </div>
    <div class="form-group">
          stuff
    </div>
</section>

To make this useful for multiple form blocks on a page it could be modified to:

const formGroups = Array.from(document.querySelectorAll('.form-block'));


formGroups.forEach(function(block) {
  const hasErrors = block.querySelectorAll('.form-group.has-errors');
  hasErrors[hasErrors.length -1].style.color = 'red';
});
Form Block 1
<section class="form-block">
    <div class="form-group has-errors">
          ERROR!
    </div>
    <div class="form-group has-errors">
          ERROR!
    </div>
    <div class="form-group">
          stuff
    </div>
</section>

Form Block 2
<section class="form-block">
    <div class="form-group has-errors">
          ERROR!
    </div>
    <div class="form-group has-errors">
          ERROR!
    </div>
    <div class="form-group">
          stuff
    </div>
</section>
Brett DeWoody
  • 59,771
  • 29
  • 135
  • 184
  • Use `for()` instead of `forEach()`. It's [`a lot faster`](https://jsperf.com/ktest23) and works in IE11. – tao Jun 28 '17 at 02:07
-1

Sorry, I can't see nesting in your code.

Nested elements should be disposed like this

<div class="form-group">
    stuff
    <div class="form-group">
        stuff
        <div class="form-group">
              stuff
        </div>
    </div>
</div>

no answer to my problem here. maybe the title not to be exact

calterras
  • 308
  • 2
  • 4