jharrell jharrell - 5 months ago 17
Javascript Question

Using jQuery to hide parent elements based on Input

I am trying to remove the items from printing using .addClass() and .removeClass(). The ul.gform_fields contains the entire section and a title for each area and li.gfield contain the input areas.

The basic idea is to mark them all as hidden on document load (@media print) and then remove the hidden value from any that are selected including the parent container ul item. The end goal is to have items removed and if all the items of one category are removed then remove the category as well.

I can get the list items to work but I can't seem to get the parent UL to toggle visibility.

jQuery(document).ready(function($) {
$("#gform_print_button").click( function()
{

$("ul.gform_fields").each(function () {
$(this).addClass("noPrint");
});

$("input.ginput_quantity").each(function () {
if (this.value == "")
$(this).parent().parent().addClass("noPrint");
else
$(this).parent().parent().parent().removeClass("noPrint");
$(this).parent().parent().removeClass("noPrint");
});
//javascript:window.print();
}
);
})


Here is the HTML:

<ul class="gform_fields">
<li>
<h4>Cart &amp; Dollies</h4>
</li>
<li class="">
<span>Daily Rate</span>
<span>Quantity</span>
</li>
<li class="">
<label for="input_1_31_1">
</label>
<div class="ginput_container">
<input type="hidden" name="input_31.1" value="Furniture Dolly" />
<span >Price:</span>
<span id="input_1_31">$6.00</span>
<input type="hidden" name="input_31.2" id="ginput_base_price_1_31" value="$6.00" />
<span>Quantity:</span>
<input type="text" name="input_31.3" value="" id="ginput_quantity_1_31" class="ginput_quantity" size="10"
tabindex="24" /></div>
</li>
<li class="">
<label for="input_1_32_1">
</label>
<div class="ginput_container">
<input type="hidden" name="input_32.1" value="Gorilla Cart" class="gform_hidden" />
<span>Price:</span>
<span id="input_1_32">$10.00</span>
<input type="hidden" name="input_32.2" id="ginput_base_price_1_32" value="$10.00" />
<span>Quantity:</span>
<input type="text" name="input_32.3" value="" id="ginput_quantity_1_32" class="ginput_quantity" size="10"
tabindex="25" /></div>
</li>
<li class="">
<label class="gfield_label" for="input_1_33_1">
</label>
<div class="ginput_container ginput_container_singleproduct">
<input type="hidden" name="input_33.1" value="Magliner / Jr." class="gform_hidden" />
<span>Price:</span>
<span id="input_1_33">$15.00</span>
<input type="hidden" name="input_33.2" id="ginput_base_price_1_33" value="$15.00" />
<span>Quantity:</span>
<input type="text" name="input_33.3" value="" id="ginput_quantity_1_33" class="ginput_quantity" size="10"
tabindex="26" /></div>
</li>
</ul>
<ul>
<li class="">
<input type="button" id="gform_print_button" class="gform_button button printbtn" value="Print" />
</li>
</ul>


http://jsfiddle.net/zy87g0Lz/1/

Answer

If I understand correctly you're after something like this? http://jsfiddle.net/mickatron/zy87g0Lz/6/

Try to avoid DOM traversal, actually try to pretend those parent, sibling etc methods don't even exist. Your code will be more readable, modular and slightly faster in most all cases.

I've included some other tips in the answers comments.

jQuery(document).ready(function($) {
  // cache selectors that you reuse
  var $gFormFields = $("ul.gform_fields");
  // hide the whole ul on doc load
  $gFormFields.addClass("noPrint");

    var clickHandler = function(){
    $gFormFields.addClass("noPrint");
    // loop all the li's in the gFormFields
    // superior to looping the input as you don't have to use DOM traversal 
    $("li", $gFormFields).each(function () {
        var $this = $(this);
      var $inputValue = $("input.ginput_quantity", $this).val();
      if ($inputValue){             
        $gFormFields.removeClass("noPrint");
        $this.removeClass("noPrint");
      }else {           
        $this.addClass("noPrint");
      }
    });
  };

  // Use .on() and .off() for all events. In later version of jQ even delegates have been moved to .on();
  // assigning the handler to a function expression allows you to remove that specific handler with .off().
  $("#gform_print_button").on('click', clickHandler);
});