HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Toggling buttons on click

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
togglingclickbuttons

Problem

Whenever a button is clicked, the following need to be performed:

  • All siblings of the clicked button get toggled



  • All edit_button get toggled, except for the edit_button within the same span as the clicked button (note: the excluded edit_button can be the same as the clicked button)



The JavaScript is working in the way I want it to, but I am curious if there's another better way to achieve the second requirement.

Note: save_button and cancel_button are hidden when first loaded.



$(function() {
$('.edit_button, .save_button, .cancel_button').click(function() {
$(this).toggle();
$(this).siblings('button').toggle();
$('div#personal_info').find('button.edit_button').not($(this).parent().find('button.edit_button')).toggle();
});
});



EditCancelSave Changes


EditCancelSave Changes


EditCancelSave Changes

Solution

The selector for all edit_buttons can be expressed as a single selector $('div#personal_info button.edit_button').

I am tempted to rewrite the code to use closure scope to cache the selector values e.g.

// Iterate using each to define cached values for selectors within a 
// closure scope 
$('.edit_button, .save_button, .cancel_button').each(function() {
  var button = $(this);
  // select all elements that need be toggled on click
  var toggled = $([
    button,
    button.siblings('button'),
    $('div#personal_info button.edit_button').
       not(button.parent().find('button.edit_button'))
  ]);
  // toggle each element separetely on click as the first element in a selector
  // defines the target visiblity of a no parameter .toggle()
  button.click(function() {
    toggled.each(
      function() {
        $(this).toggle();
      });
    });
});


The benefit of it is that less traversing is needed. Unfortunately the toggle method didn't work quite as I imagined it would when there are both hidden and shown elements in the selector when using jQuery 1.6.2.

The above code is available through jsFiddle

From a maintenance/cleanliness point of view I'm a bit wary how this piece of code merges the concerns of

  • Hiding all edit actions



  • Showing all edit actions



  • Displaying save and cancel actions for a specific edit action



  • Hiding save and cancel actions for a specific edit action



The result of all these goals leads to astonishment that is higher than the least possible. I don't really know what a good name for that function would be?

Also how and where are the event handlers for onclick events of .save_button and .cancel_button defined?

Code Snippets

// Iterate using each to define cached values for selectors within a 
// closure scope 
$('.edit_button, .save_button, .cancel_button').each(function() {
  var button = $(this);
  // select all elements that need be toggled on click
  var toggled = $([
    button,
    button.siblings('button'),
    $('div#personal_info button.edit_button').
       not(button.parent().find('button.edit_button'))
  ]);
  // toggle each element separetely on click as the first element in a selector
  // defines the target visiblity of a no parameter .toggle()
  button.click(function() {
    toggled.each(
      function() {
        $(this).toggle();
      });
    });
});

Context

StackExchange Code Review Q#3634, answer score: 2

Revisions (0)

No revisions yet.