Rohit416 Rohit416 - 4 months ago 9
Javascript Question

Why customized radio buttons are not getting disabled?

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

These radio buttons are in a

div#Main
element which comprise of some other HTML elements also. I need to disable everything in this
div
on a button click (I am using jQuery). For this I have the following code,

HTML

<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>


Script

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





Issue: Everything got disabled correctly except the radio buttons.


Behind the scenes, the plugin script hides the actual radio button and
put a
span
over the radio buttons like a blanket. This
span
has
got a background image sprite with different states (on and off) which
gets updated accordingly on radio button selection. This was the
working of this plugin.


I could have used the inbuilt method of the plugin to disable/destroy the functionality but I did not find any method for this.

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.