-1
\$\begingroup\$

The table has 4 search types and 4 radio buttons; when one radio button is clicked, other fields should be disabled. The JavaScript code seems repetitive. How can I improve it?

Wireframe diagram

JavaScript

function Init_RadioButtonList() {
    $(function () {
        TRShow($("input:radio[id='RadioButton1']:checked").val());

        $('#RadioButton1 input').change(function () {
            TRShow($('#RadioButton1 input').val());
        });

        TRShow($("input:radio[id='RadioButton2']:checked").val());

        $('#RadioButton2 input').change(function () {
            TRShow($('#RadioButton2 input').val());
        });

        TRShow($("input:radio[id='RadioButton3']:checked").val());

        $('#RadioButton3 input').change(function () {
            TRShow($('#RadioButton3 input').val());
        });

        TRShow($("input:radio[id='RadioButton4']:checked").val());

        $('#RadioButton4 input').change(function () {
            TRShow($('#RadioButton4 input').val());
        });      
    });
}

function TRShow(value) {
    switch (value) {
        case "1":
            $("#Name").attr('disabled', 'disabled');
            $("#Product_Price").attr('disabled', 'disabled');
            $("#Year").attr('disabled', 'disabled');
            $("#Product_Type").attr('disabled', 'disabled');
            $("#M_START_NUMB_IV").attr('disabled', 'disabled');
            $("#M_END_NUMB_IV").attr('disabled', 'disabled');
            $("#M_START_CDATE_AS").attr('disabled', 'disabled');
            $("#M_END_CDATE_AS").attr('disabled', 'disabled');
            break;
        case "2":
            $("#Year").attr('disabled', 'disabled');
            $("#Product_Type").attr('disabled', 'disabled');
            $("#M_START_NUMB_IV").attr('disabled', 'disabled');
            $("#M_END_NUMB_IV").attr('disabled', 'disabled');

            $("#M_START_CDATE_AS").attr('disabled', 'disabled');
            $("#M_END_CDATE_AS").attr('disabled', 'disabled');

            $("#DropDownList1").attr('disabled', 'disabled');
            $("#Product_Price_NEW").attr('disabled', 'disabled');
            $("#Product_Type_NEW").attr('disabled', 'disabled');
            break;
        case "3":
            $("#Name").attr('disabled', 'disabled');

            $("#M_START_CDATE_AS").attr('disabled', 'disabled');
            $("#M_END_CDATE_AS").attr('disabled', 'disabled');

            $("#DropDownList1").attr('disabled', 'disabled');
            $("#Product_Price_NEW").attr('disabled', 'disabled');
            $("#Product_Type_NEW").attr('disabled', 'disabled');
            break;
        case "4":
            $("#Name").attr('disabled', 'disabled');
            $("#Product_Price").attr('disabled', 'disabled');
            $("#Year").attr('disabled', 'disabled');
            $("#Product_Type").attr('disabled', 'disabled');
            $("#M_START_NUMB_IV").attr('disabled', 'disabled');
            $("#M_END_NUMB_IV").attr('disabled', 'disabled');

            $("#DropDownList1").attr('disabled', 'disabled');
            $("#Product_Price_NEW").attr('disabled', 'disabled');
            $("#Product_Type_NEW").attr('disabled', 'disabled');
            break;
    }
}

HTML (ASP.NET)

<table width="100%" border="0" cellpadding="3" cellspacing="0" bordercolor="#3366CC"
       bordercolordark="#FFFFFF" class="dataTable">
  <tr>
    <td align='right' nowrap class="dataColor01">
      <asp:RadioButton ID="RadioButton1" runat="server"  GroupName="choose" 
                       AutoPostBack="True" Value="1" Checked="True" />
      <span id="Span1" runat="server">ProductLevel</span>
    </td>
    <td  id="condition1_1" class="dataColor02"  style="width:40%">
      <asp:DropDownList ID="DropDownList1" runat="server">
        <asp:ListItem Text="1" Value="1"></asp:ListItem>
      </asp:DropDownList>
    </td>
    <td align='right' nowrap class="dataColor01">
      <span id="Span4" ml="NEW PriceType" runat="server">NEW PriceType</span>
      <asp:Label ID="H_PROC_PROG_GRP" runat="server" Text="" Visible="false"></asp:Label>
    </td>
    <td  id="condition1_2" class='dataColor02' >
      <asp:TextBox ID="Product_Price_NEW" runat="server"  ValidationGroup="NotNull" />
      <asp:DropDownList ID="Product_Type_NEW" runat="server"  ValidationGroup="NotNull">
      </asp:DropDownList>
    </td>
  </tr>
  <tr>
    <td align='right' nowrap class="dataColor01">
      <asp:RadioButton ID="RadioButton2" Value="2" runat="server"  GroupName="choose" AutoPostBack="True"/>
      <span id="Span7" ml="PL_Name" runat="server">Name</span>
    </td>
    <td class='dataColor02' colspan="3">
      <asp:TextBox ID='Name' CssClass='select' runat='server' ValidationGroup="EQ" Width="65px" />
    </td>
  </tr>
  <tr>
    <td align='right' class="dataColor01">
      <asp:RadioButton ID="RadioButton3" Value="3" runat="server"  GroupName="choose" AutoPostBack="True"/>
      <span id="Span8" ml="PL_quickSearch" runat="server">quickSearch</span>
    </td>
    <td class="dataColor02" colspan="3">
      <asp:TextBox ID='Year' CssClass='select' runat='server' Width="60px"/>
      <asp:Label ID="Label3" runat="server" Text="年"></asp:Label>
      <asp:TextBox ID="Product_Price" runat="server" CssClass="select"   Width="60px"/>
      <asp:DropDownList ID="Product_Type" runat="server">
      </asp:DropDownList>
      <asp:Label ID="Label1" runat="server" Text=" Product Serial Number"></asp:Label>
      <asp:Label ID="Label4" runat="server" Text=""></asp:Label>
      <asp:TextBox ID='M_START_NUMB_IV' CssClass='select' runat='server'  Width="65px" />
      <asp:Label ID="Label8" runat="server" Text="~"></asp:Label>
      <asp:TextBox ID='M_END_NUMB_IV' CssClass='select' runat='server' Width="65px" />
    </td>
  </tr>
  <tr>
    <td align='right' class="dataColor01">
      <asp:RadioButton ID="RadioButton4" Value="4" runat="server" GroupName="choose" AutoPostBack="True"/>
      <span id="Span9" ml="PL_Dates" runat="server">Dates</span>
    </td>
    <td class="dataColor02" colspan="3">
      <asp:TextBox ID='M_START_CDATE_AS' CssClass='select' runat='server'  Width="65px" />
      <asp:Label ID="Label6" runat="server" Text="~"></asp:Label>
      <asp:TextBox ID='M_END_CDATE_AS' CssClass='select' runat='server' Width="65px" />
    </td>
  </tr>
</table>
\$\endgroup\$
  • \$\begingroup\$ You only ever disable input elements; you never re-enable anything. That seems wrong to me. \$\endgroup\$ – 200_success Nov 13 '14 at 7:56
2
\$\begingroup\$

Bugs

You only ever disable input elements; you never re-enable anything. That seems wrong to me. I'm going to assume that you mean to re-enable all input elements that are not explicitly disabled for the selected radio button.

In the live example below, I've converted your ASP.NET markup to HTML elements as best I could. I'm puzzled by a discrepancy, though. In the excerpt below, the first line implies that the element with ID RadioButton1 is an <input type="radio" …> element. However, in the following lines, the selectors are saying that the element with ID RadioButton1 contains the radio button. For this review, I'll assume that with the former is true.

TRShow($("input:radio[id='RadioButton1']:checked").val());

$('#RadioButton1 input').change(function () {
    TRShow($('#RadioButton1 input').val());
});

Simplification

At first glance, it appears that enable just the input elements on the same table row, and disable the rest. However, there are exceptions: selecting the second radio button causes the Product_Price field in the third row to be enabled. Assuming that that is intentional, the solution will need to be more flexible to accommodate such exceptions. (Consider redesigning the UI — perhaps even having two product price text fields — to make things more consistent.)

To eliminate the nasty switch block from your JavaScript, you should push the complexity into HTML so that jQuery and the browser do the hard work for you. You just have to mark the HTML elements with the right classes and craft your jQuery selectors intelligently. As you can see in enableDisableInputs(), I disable all elements with the enabledfor class, then re-enable just the ones with the choice2 (or whatever) class.

function enableDisableInputs() {
    var checkedRadioValue = $('input:radio[name="choose"]:checked').val();
    $('.enabledfor').attr('disabled', 'disabled');
    $('.enabledfor.choice' + checkedRadioValue).removeAttr('disabled');
}

$(function() {
    $('input:radio[name="choose"]').change(enableDisableInputs);
    enableDisableInputs();

    clarifyElementIdsJustForThisDemo();
});

function clarifyElementIdsJustForThisDemo() {
    $('input[type="text"].enabledfor').each(function() {
        $(this).attr('placeholder', $(this).attr('id'));
    });
    $('select.enabledfor').each(function() {
        $(this).append('<option>' + $(this).attr('id') + '</option>');
    });
}
/* To emphasize the table rows for the demo */
tr:nth-child(odd)  { background-color: #eeffee; }
tr:nth-child(even) { background-color: #eeeeff; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table width="100%" border="0" cellpadding="3" cellspacing="0" bordercolor="#3366CC" bordercolordark="#FFFFFF" class="dataTable">

  <tr>
    <td align='right' nowrap class="dataColor01">
      <input type="radio" ID="RadioButton1" name="choose" Value="1"  Checked="True" />   <span id="Span1" runat="server">ProductLevel</span>
    </td>
    <td id="condition1_1" class="dataColor02"  style="width:40%">
      <select ID="DropDownList1" class="enabledfor choice1">
        <option Value="1">1</option>
      </select>
    </td>
    <td align='right' nowrap class="dataColor01">
      <span id="Span4">NEW PriceType</span><label ID="H_PROC_PROG_GRP" style="visibility: hidden;"></label>
    </td>
    <td  id="condition1_2" class='dataColor02'>
      <input type="text" ID="Product_Price_NEW" class="enabledfor choice1">
      <select ID="Product_Type_NEW" class="enabledfor choice1"></select>
    </td>
  </tr>
  <tr>
    <td align='right' nowrap class="dataColor01">
      <input type="radio" ID="RadioButton2" Value="2" name="choose"> <span id="Span7">Name</span>
    </td>
    <td class='dataColor02' colspan="3">
      <input type="text" ID='Name' class='select enabledfor choice2' Width="65px">
    </td>
  </tr>
  <tr>
    <td align='right' class="dataColor01">
      <input type="radio" ID="RadioButton3" Value="3" name="choose">  <span id="Span8">quickSearch</span>
    </td>
    <td class="dataColor02" colspan="3">
      <input type="text" ID='Year' class='select enabledfor choice3' Width="60px">
      <label ID="Label3">年</label>
      <input type="text" ID="Product_Price" class="select enabledfor choice2 choice3" Width="60px">
      <select ID="Product_Type" class="enabledfor choice3"></select>
      <label ID="Label1"> Product Serial Number</label>
      <label ID="Label4"></label>
      <input type="text" ID='M_START_NUMB_IV' class='select enabledfor choice3' Width="65px">
      <label ID="Label8">~</label>
      <input type="text" ID='M_END_NUMB_IV' class='select enabledfor choice3'  Width="65px">
    </td>
  </tr>
  <tr>
    <td align='right' class="dataColor01">
      <input type="radio" ID="RadioButton4" Value="4" name="choose">  <span id="Span9">Dates</span>
    </td>
    <td class="dataColor02" colspan="3">
      <input type="text" ID='M_START_CDATE_AS' class='select enabledfor choice4' Width="65px" />

      <label ID="Label6">~</label>
      <input type="text" ID='M_END_CDATE_AS' class='select enabledfor choice4' Width="65px">
    </td>
  </tr>
</table>

HTML

The quality of the HTML code is not up to modern standards. Attributes related to the presentation of the content, such as align='right' and nowrap, are now supposed to be specified using CSS instead. <label> elements should be fixed such that clicking on the word "quickSearch" will cause the corresponding radio button to be selected.

I suggest that you run your HTML output through a validator to improve the markup.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.