Home > Software design >  jQuery find items with each
jQuery find items with each

Time:11-22

I have multiple elements of the same class and I want to customize them, I can separate my input values, but I have no idea how to customize my span values.

jQuery('.qty').each(function(){

    if( jQuery(this).val() == jQuery(this).attr("max") ){
        jQuery(this).find('plus').text("Max Value");
    }
    else if( jQuery(this).val() == jQuery(this).attr("min") ){
            jQuery(this).find('min').text("Min Value");
    }
});
input{
  line-height:25px;
  width:150px;
  margin:10px 0;
}
input[type=number]::-webkit-inner-spin-button, 
input[type=number]::-webkit-outer-spin-button {  
   opacity: 1;
}
span{
  font-size:15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class="minus"></span>
<input type="number" class="qty" value="1" min="1" max="4">
<span class="plus"></span>
<br>
<span class="minus"></span>
<input type="number" class="qty" value="1" min="1" max="2">
<span class="plus"></span>
<br>
<span class="minus"></span>
<input type="number" class="qty" value="1" min="1" max="3">
<span class="plus"></span>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

Thanks in advance.

CodePudding user response:

There's a few issues in your code.

Firstly, you need to check the value of each .qty element when the user interacts with it, not on load of the page. To do this hook your logic to an input event handler.

From there you need to use prev() and next() to get the span elements as they are siblings to the input. find() is intended to search for child elements, so is not applicable in this case. You also need to include the . prefix on the classnames in your selectors.

Taking this a step further you can add an else clause to your if statement which removes the text labels when the min/max value is not selected.

Finally, the correct class for the first span in each set is .minus, not .min.

jQuery($ => {
  $('.qty').on('input', function() {
    let $el = $(this);    
    
    if ($el.val() == $el.attr("max")) {
      $el.next('.plus').text("Max Value");
    } else if ($el.val() == $el.attr("min")) {
      $el.prev('.minus').text("Min Value");
    } else {
      $el.next('.plus').text("");
      $el.prev('.minus').text("");
    }
  });
});
input {
  line-height: 25px;
  width: 150px;
  margin: 10px 0;
}

input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
  opacity: 1;
}

span {
  font-size: 15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class="minus"></span>
<input type="number" class="qty" value="1" min="1" max="4">
<span class="plus"></span>

<br />

<span class="minus"></span>
<input type="number" class="qty" value="1" min="1" max="2">
<span class="plus"></span>

<br />

<span class="minus"></span>
<input type="number" class="qty" value="1" min="1" max="3">
<span class="plus"></span>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

Also note that you can make your code far more succinct by alisasing jQuery within your document.ready handler, as I've done in the example above to give you access to the $ variable again.

In addition it's good practice to 'cache' the jQuery objects, as accessing the DOM and building jQuery objects are (relatively) slow operations so you want to aim to do it as little as possible. In the example above you can see I accessed $(this) only once and stored its value in a variable within each event handler.

CodePudding user response:

With your current HTML, you'd use prev to get the minus span and next to get the plus span (but keep reading). You probably also want to clear the span when the condition isn't true, and update when the value changes:

function update() {
    jQuery('.qty').each(function() {
        const input = jQuery(this);
        const val = input.val();
        input.next().text(
            val == input.attr("max")
            ? "Max value"
            : ""
        );
        input.prev().text(
            val == input.attr("min")
            ? "Min value"
            : ""
        );
    });
}
update();
jQuery(".qty").on("input", update);

Live Example:

Show code snippet

function update() {
    jQuery('.qty').each(function() {
        const input = jQuery(this);
        const val = input.val();
        input.next().text(
            val == input.attr("max")
            ? "Max value"
            : ""
        );
        input.prev().text(
            val == input.attr("min")
            ? "Min value"
            : ""
        );
    });
}
update();
jQuery(".qty").on("input", update);
input{
  line-height:25px;
  width:150px;
  margin:10px 0;
}
input[type=number]::-webkit-inner-spin-button, 
input[type=number]::-webkit-outer-spin-button {  
   opacity: 1;
}
span{
  font-size:15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class="minus"></span>
<input type="number" class="qty" value="1" min="1" max="4">
<span class="plus"></span>
<br>
<span class="minus"></span>
<input type="number" class="qty" value="1" min="1" max="2">
<span class="plus"></span>
<br>
<span class="minus"></span>
<input type="number" class="qty" value="1" min="1" max="3">
<span class="plus"></span>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

But to me, that's fragile. I'd instead wrap each set of elements in a div, like this:

<div>
    <span class="minus"></span>
    <input type="number" class="qty" value="1" min="1" max="4">
    <span class="plus"></span>
</div>

...and then use jQuery(this).closest("div").find(/*...*/) to find the plus and minus elements:

function update() {
    jQuery('.qty').each(function() {
        const input = jQuery(this);
        const val = input.val();
        const div = input.closest("div");
        div.find(".plus").text(
            val == input.attr("max")
            ? "Max value"
            : ""
        );
        div.find(".minus").text(
            val == input.attr("min")
            ? "Min value"
            : ""
        );
    });
}
update();
jQuery(".qty").on("input", update);

(Note that I've looked for .minus, not .min, to find the span.)

Live Example:

Show code snippet

function update() {
    jQuery('.qty').each(function() {
        const input = jQuery(this);
        const val = input.val();
        const div = input.closest("div");
        div.find(".plus").text(
            val == input.attr("max")
            ? "Max value"
            : ""
        );
        div.find(".minus").text(
            val == input.attr("min")
            ? "Min value"
            : ""
        );
    });
}
update();
jQuery(".qty").on("input", update);
input{
  line-height:25px;
  width:150px;
  margin:10px 0;
}
input[type=number]::-webkit-inner-spin-button, 
input[type=number]::-webkit-outer-spin-button {  
   opacity: 1;
}
span{
  font-size:15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
    <span class="minus"></span>
    <input type="number" class="qty" value="1" min="1" max="4">
    <span class="plus"></span>
</div>
<div>
    <span class="minus"></span>
    <input type="number" class="qty" value="1" min="1" max="2">
    <span class="plus"></span>
</div>
<div>
    <span class="minus"></span>
    <input type="number" class="qty" value="1" min="1" max="3">
    <span class="plus"></span>
</div>
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related