Tuesday, May 19, 2015

How to pass multiple checkbox (checked and unchecked) values to server side?

 In the W3C HTML 4, it has something like this:
Checkboxes (and radio buttons) are on/off switches that may be toggled by the user. A switch is "on" when the control element's checked attribute is set. When a form is submitted, only "on" checkbox controls can become successful.

This means the value is only sent if the checkbox is checked. So we need to have a way of remembering what checkboxes you are expecting on the server side since not all the data comes back from the form.


In my case, I have same checkbox names in different rows. The HTML code is like this.

 <c:forEach items="${classes}" var="class">  
      <tr>  
           <td  
                class="hidden-xs hidden-sm hidden-md hidden-lg ui-state-default">  
                <input type="hidden" id="classid" name="classid[]"  
                value='<c:out value="${class.configClassId}"/>'></input> <input  
                type="hidden" id="displayOrder" name="displayOrder[]"  
                class="form-control"  
                value='<c:out value="${class.displayOrder}"/>'></input>  
           </td>  
           <td><input type="text" id="internalClassName"  
                name="internalClassName[]" class="form-control"  
                placeholder="Class Internal Name"  
                value='<c:out value="${class.internalClassName}"/>'></td>  
           <td><input type="text" id="displayName"  
                name="displayName[]" class="form-control"  
                placeholder="Display Name"  
                value='<c:out value="${class.displayName}"/>' /></td>  
           <td>  
                <div class="checkbox">  
                     <c:if test="${class.enable!=null && class.enable=='Y'}">  
                          <input type="checkbox" name="enabled[]"  
                               class="form-control chk" value="Y" checked="checked">  
                     </c:if>  
                     <c:if test="${class.enable==null || class.enable!='Y'}">  
                          <input type="checkbox" name="enabled[]"  
                               class="form-control chk" value="Y">  
                          <input type="hidden" name="enabled[]" class="chk" value="N">  
                     </c:if>  
                </div>  
           </td>  
           <td><input type="text" id="searchWeight[]"  
                name="searchWeight[]" class="form-control"  
                value='<c:out value="${class.searchWeight}"/>'></td>  
           <td><input type="hidden" id="fileid" name="fileid[]"  
                class="form-control"  
                value='<c:out value="${class.fileStore.fileId}"/>'><img  
                src="${pageContext.request.contextPath}/download/${class.fileStore.fileId}"></td>  
           <td>  
                <div class="input-group">  
                     <span class="input-group-btn"> <span  
                          class="btn btn-default btn-file active">  
                               Browse&hellip; <input type="file" id="uploadimage"  
                               name="uploadimage[]" class="form-control" multiple />  
                     </span>  
                     </span> <input type="text" class="form-control" readonly>  
                </div>  
           </td>  
           <td><button type="button" class="removebutton"  
                     title="Remove this class">  
                     <span class="glyphicon glyphicon-remove "></span>  
                </button></td>  
      </tr>  
 </c:forEach>  


Since it only sends the checked values, I couldn't find out which checkbox value match to which row.
In order to work around this, you can see in the html code, I added hidden input to set a value if the value from server side is not 'Y'.  (See highlighted code above.)

For checkbox is changed after the page is loaded, I added some javascript code to set the right value in. The javascript code is as below.


  .on("click", ".chk",function() {  
    var v = $(this).attr('checked') == 'checked'?'Y':'N';  
    if (v=='Y')  
     {  
     $(this).removeAttr('checked');   
     $(this).after('<input type="hidden" name="enabled[]" value="N" />');  
     }  
    if (v=='N')  
     {  
          $(this).attr('checked');   
          $(this).val( "Y" );  
          if ($(this).next().attr('class')=='chk')  
               $(this).next().attr('disabled', true);       
     }  
 }  


There must be some other ways to do this. But the code above works fine for me. It sent checked and unchecked values correctly to the server side.







No comments:

Post a Comment