Rohit416 Rohit416 - 4 months ago 22
jQuery Question

Disable customized radio buttons by jQuery conditionaly

I am using this plugin to customize check boxes and radio buttons on a page.

These radio buttons are in a container

div
which comprise of some other elements also. I need to disable everything in this
div
on a button click. For this i have the following code,

<script type="text/javascript">
$(function(){
$('#DisableElements').click(function(){
$('#Main').find('*').attr('disabled', 'disabled');
});
});
</script>

<!-- HTML Section -->

<input type="button" id="DisableElements" value="Disable elements" />

<div id="Main">
<input type="radio" class="styled" name="reg-all"/>
<input type="radio" class="styled" name="reg-all"/>

<select id="MyList">
<option value="1">Choice-1</option>
<option value="2">Choice-2</option>
</select>

<textarea id="Comments" rows="4" cols="5"></textarea>
</div>


Problem: Everything getting disabled correctly except the radio buttons.

Behind the scenes, what the plugin doing is it hides the actual radio buttons and put a span over the radio buttons like a blanket. This span has got a background image. On radio button selection this background image (a sprite image containing the radio button on and off states) gets updated according to the current state of radio button. This was the working of this plugin.

What makes senese here is that i should use the inbuilt API method of the plugin probably to disable/destroy the functionality like we have in
jQuery UI
themes. But i can't find any such method for this plugin or else.

Any advise/clue would be helpful.

Answer

The solution i made can be thought of as a patch but works nice (for my scenario at least). What should have been the right approach for this would be using some existing API method to reflect the change, something like disable() or similar but i did not find such method or something like this.

Solution: Making the radio buttons appear like disable (non clickable).

Because i do not want to dig into the plugin js file. For this i made a transparent div with some width and height enough to cover the radio buttons and place it over them like a layer between radio buttons and cursor. This div is hidden by default and show this while making controls disable. keeping it short and sweet, here are the code changes.

HTML

<input type="button" id="DisableElements" value="Disable elements" />

<div id="Main">
  <div id="Blanket"></div>
  <input type="radio" class="styled" name="reg-all"/>
  <input type="radio" class="styled" name="reg-all"/>

  <select id="MyList">
    <option value="1">Choice-1</option>
    <option value="2">Choice-2</option>
  </select>

  <textarea id="Comments" rows="4" cols="5"></textarea>
</div>

CSS - for blanket div

#Blanket
{
  position:absolute;  /*Imp: otherwise it will disturb the UI*/
  width:100px;
  height:100px;
  display:none;
  /* top/left adjustments, if required! */
}

Script

$(function(){
   $('#DisableElements').click(function(){
      $('#Blanket').show();
      $('#Main').find('*').attr('disabled', 'disabled');
   });
});

This solution however needed to drop the fear of what if someone using developer tools to out smart the application but that does not matter any way. Besides, you can-not 100% block the user from using such tools.

Another solution which worked and looks more appropriate: Placing invisible blanket over input controls sounds like a patch and can be easily snapped. The plugin script adds a CSS class named styled and requires to add following styles to achieve customized look and feel.

input.styled
{
    display: none;  // hides the parent input element
}

Because of this, even if we switch button states to disable, the changes did not reflect because the parent element was hidden making the other listeners difficult to attach. By changing the styles to following, everything worked.

input.styled
{
    position: absolute;
    opacity: 0;
}

It makes the parent input element invisible but completely active on DOM behind the scenes.