Home > Net >  Disable a textarea in a for loop of textareas using JQuery/Typescript and KnockoutJS
Disable a textarea in a for loop of textareas using JQuery/Typescript and KnockoutJS

Time:12-10

So I have a for loop that will display a list of textareas. Each has a unique id using the KO data-binding attribute, but they all have the same name. What I want to do is use Jquery to either check if all the textareas in the list are empty, in which case it will disable every text area except for the first, or if one of the textareas is filled, the ones with an empty string value will be disabled. Currently, my code looks something like this:

Typescript/Jquery

thisMethod(): any {
    this.check.subscribe(val => {
        if (val === true) {
            $("textarea[name='text']").each((i, element) => {
                 if ($(element).val() === "") {
                     if (i !== 0) {
                         $(element).prop('disabled', true);
                     };
                 }
                 else {
                      // some check for populated textbox to disable unpopulated checkboxes
                 }
            }
        }
    }
}

HTML

<div data-bind="foreach: choice">
    <-- ko if: hasData($data) -->
    <div>
        <textarea  name="text" data-bind="attr: {id: $data   '-choice-text'}, event: {change: $root.anonClass.thisMethod}"></textarea>
    </div>
</div>

I think my confusion mainly stems from not understanding jquery. With .each(), does it first validate each element before moving to the next condition or is it iterative like a normal for loop?

Upon testing just the first if block, nothing seems to happen. This could be completely unrelated to Jquery and could possibly be the result of the knockout change event not firing, but I'm not sure.

CodePudding user response:

.each() just loops through the whole set. Have you tried console logging all the elements inside .each() to check if they are correctly selected?

Your code almost works, but it always leaves the first one enabled, even if another one has a value.

I would probably do something like this instead as it's a bit clearer in my opinion:

  • Find all empty textareas and disable them
  • If all textareas are empty, re-enable only the first one

$('#check').click(() => {
  const $areas = $('textarea');
  
  /*
  // your code does work, but leaves the first one enabled, even if another one has a value
  $areas.each((i, element) => {
     if ($(element).val() === "") {
         if (i !== 0) {
             $(element).prop('disabled', true);
         };
     }
     else {
          // some check for populated textbox to disable unpopulated checkboxes
     }
   });
   */
                 
                   
  const $emptyAreas = $areas.filter((i,t) => !t.value);
  $emptyAreas.prop('disabled', true);
  
  if ($emptyAreas.length === $areas.length) {
    // all empty
    $areas.first().prop('disabled', false);
  }

});

$('#reset').click(() => $('textarea').prop('disabled', false).val(''));
textarea {
display:block;
margin-bottom:1rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea></textarea>
<textarea></textarea>
<textarea></textarea>
<textarea></textarea>
<button id="check">check</button>
<button id="reset">reset</button>

  • Related