Link to home
Start Free TrialLog in
Avatar of kgarnto
kgarnto

asked on

How to limit the number of Checkboxes Selected?

Thanks to some help from mrichmon, I now have a Withdrawal form that does a query for CRNs for a student for the current term.  The form returns the CRNs and also some drop down grade boxes and date input text boxes for the instructor to submit Withdrawal Information for each CRN that is returned.  When a student withdrawals from the school, they are removed from all classes.

I then needed to kind of duplicate the withdrawal form for dropping (1) or more classes (but not all classes), and I have done it by using dynamically created checkboxes that are associated with each CRN that is returned from the query and then appending the same grade drop down boxes and date input boxes to each CRN that is returned.  The instructor can then get all the CRNs that are for the student, and then just select the CRN that they are dropping.  They could submit (1) CRN or multiple CRNs, but we don't want them to be able to check all the CRNs.

My problem is that I don't know how to limit the instructor from being able to check all the checkboxes, because if they do that they really need to be submitting the withdrawal form instead of the drop form.

Does anyone know how I might go about doing this?  My checkboxes are created dynamically from the query, and on my processing page, I want to be able to loop through the CRNs that are processed and allow the instructor to be able to select each CRN checkbox that they need to select.  If the instructor tries to submit all the CRNs, I think I want a pop-up window or an error message to display saying that they can't submit all CRNs from the drop class form, they must use the withdrawal form.

This may not be the best way to handle this, and I'm open to another suggestion.  The main thing is that we need to have seperate forms because we ask for different information in each circumstance.

Thanks in advance for any help that you can offer.

Here is the code for the drop form:
<cfset CrnList = ValueList(get_classes.crn)>
<CFOUTPUT query="get_classes">
     <tr>
     <td><div align="center"><input type="Checkbox" name="class#currentrow#" value="#get_classes.crn#" <cfif ListFind(CrnList, get_classes.crn)>unchecked</cfif>>#get_classes.class#</div></td>
                  <td><div align="center">
                    <select name="grd#currentrow#" id="grd">
                      <option value="A">A</option>
                      <option value="B">B</option>
                      <option value="C">C</option>
                      <option value="D">D</option>
                      <option value="F">F</option>
                      <option value="W" selected>W</option>
                      <option value="WF">WF</option>
                      <option value="WP">WP</option>
                    </select>
                  </div></td>
                  <td><div align="center">
                    <select name="wegrd#currentrow#" id="wegrd">
                      <option value="1" selected>1</option>
                      <option value="2">2</option>
                      <option value="3">3</option>
                      <option value="4">4</option>
                    </select>
                  </div></td>
                  <td><div align="center"><CF_DCCOM controlNumber="#currentrow#" component="calendarControl" dateFormat="dd-%b-%y" showTime="no" startdate="#DateFormat(now(),"DD-MMM-YYYY")#" name="ldoa#currentrow#"></CF_DCCOM></div></td>
  <td><div align="center"><input type="text" name="reason#currentrow#" id="reason"></div></td>
                </tr>
       </cfoutput>
<input type= "hidden" name="counter" value="<cfoutput>#get_classes.recordcount#</cfoutput>">
              </table>

Here is the code for processing the dropped CRNs:
<cfloop index="i" from="1" to="#form.counter#">
<CFOUTPUT>
   <tr>
     <td>#Form['class' & i]#</td>
     <td>#FORM['GRD' & i]#</td>
     <td>#FORM['WEGRD' & i]#</td>
     <td>#FORM['ldoa' & i]#</td>
     <td>#FORM['reason' & i]#</td>
    </tr>
</CFOUTPUT></cfloop>
Avatar of James Rodgers
James Rodgers
Flag of Canada image

rather than use check boxes can you use radio buttons?
Hi kgarnto,
this is example of the javascript where you can limit the checkbox select. Original source is also include due to copy right reasons.
<html>
<head>
<!--
This file retrieved from the JS-Examples archives
http://www.js-x.com
1000s of free ready to use scripts, tutorials, forums.
Author: JS-Examples - http://www.js-examples.com/
-->


</head>
<body>

This script only allows 2 items to be selected. it does not matter which 2.
<script>
var MAX_ALLOWED=2;
var clickedData=new Array(false,false,false,false);
function itemsClicked(){var i=0;for(var j=0;j<clickedData.length;j++)i+=clickedData[j]?1:0;return(i);}
function itemClicked(_v)
{
  var ALLOW_THIS=true;
  var x=itemsClicked();
  if (x>=MAX_ALLOWED && !clickedData[_v])
  {
    ALLOW_THIS=false;
  }
  else
  {
    clickedData[_v]=clickedData[_v]?false:true;
    eval("document.exf1.r"+_v+".clicked=false;");
  }
  document.showit.s1.value=x; /* comment out */
  return (ALLOW_THIS); /* kill the event handler */
}


</script>

<form name=exf1>
<INPUT name=r1 type=checkbox value=Charity_profile onclick="return itemClicked(1)">Item 1<BR>
<INPUT name=r2 type=checkbox value=lost_found      onclick="return itemClicked(2)">Item 2<BR>
<INPUT name=r3 type=checkbox value=fun_section     onclick="return itemClicked(3)">Item 3<BR>
<INPUT name=r4 type=checkbox value=contacts        onclick="return itemClicked(4)">Item 4<BR>
</form>

<!-- the following form is just to show off how many is selected -->
<form name=showit>
<input type=text name=s1 value=0>
</form>

<BR><center><a href='http://www.js-x.com'>JS-X.com</a></center>
</body>
</html>


Regards,
---Pinal
Avatar of kgarnto
kgarnto

ASKER

I really appreciate the quick responses.

I don't think I can use radio buttons, because I need to be able to either select (1) CRN or multiple CRNs, without selecting all of them.

Each student could have anywhere from 1-10 CRNs returned for them each term.

I like the Javascript approach, but I'm concerned about being limited to only (2) checked CRNs.  In some cases, you might have an Instructor dropping more than 2 courses.  The student might be enrolled for 5 classes, and dropping all but (1) of them, in which case they would use the drop form.
Hi kgarnto,
you can change them to more if you wish.. just change the variable from 2 to anything you want if 5 then like this...
var MAX_ALLOWED=5;

Regards,
---Pinal
Hi kgarnto. I like your form and the way you've set it up - it will help a lot, actually.

Remember that a checkbox exists on the "action" page ONLY if the user has checked it. Otherwise, it will not exist at all. You need to be careful with this when evaluating #Form['class' & i]#.

For SERVER-SIDE validation, try this:

<!--- start of code --->
<cfset variables.numDropped = 0>
<cfloop index="i" from="1" to="#form.counter#">
      <cfif StructKeyExists(form, "class" & i)>
            <cfset variables.numDropped = variables.numDropped + 0>
       </cfif>
</cfloop>

<cfif variables.numDropped eq form.counter>
      <div style="color:red">
            <strong>You cannot use this form to drop all CRNs. If you want to withdraw this student, use the withdrawal form.</strong>
      </div>
</cfif>
<!--- end of code --->

Repost if you need a client-side solution.
Try this for a JavaScript solution. Place this code block between the <HEAD></HEAD> tags on your page:

<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">
<!--
checkCRNs(objCheckbox) {
      var objForm = objCheckbox.form;
      var i, counter;

      for (i = 1; i <= <cfoutput>#get_classes.recordcount#</cfoutput>; i++) {
            if (objForm["class" + i].checked) {
                  counter++;
            }
      }
      if (counter == <cfoutput>#get_classes.recordcount#</cfoutput>) {
            alert('You cannot use this form to drop all CRNs.\nIf you want to withdraw this student, use the withdrawal form.')
            return false;
      } else {
            return true;
      }

}
//-->
</SCRIPT>

Then change the code of your checkbox to this:

<input type="Checkbox" name="class#currentrow#" value="#get_classes.crn#" <cfif ListFind(CrnList, get_classes.crn)>unchecked</cfif> onchange="return checkCRNs(this);">

If the user attempts to check all checkboxes, the JavaScript will alert a message and then return false, meaning that the checkbox won't be checked. I recommend combining this with server-side validation, in case the end use has JavaScript turned off.
Avatar of kgarnto

ASKER

Thanks lxdev, I like the idea of using both javascript and the validation, and I think that will work for me.   I put your recommended code in the script, and right now I'm getting some javascript runtime errors on the page, and I'm working to debug those.  On the results page, it is processing the first CRN that I select, but then I get this error:

Element class2 is undefined in a Java object of type class coldfusion.filter.FormScope referenced as

Could I still not have my checkboxes setup properly with the checked/unchecked attributes?  

Avatar of kgarnto

ASKER

I'm no longer getting javascript errors when I try to access the form.  However, it doesn't seem to be working either.  I'm able to select all of the checkboxes and I don't get an error message.

Also, on the results page, the server-side validation doesn't seem to be catching either.  I have the code at the top of the page, thinking it would catch that first.  Then I have my loop through the crns to output the selected crns.  Do I need to have both of those together?

I'm missing something simple I know, but I can't seem to get it.  It also seems to only return the results correctly if all the CRNs are selected.  If I've only selected 1 or 2 CRNs, then I get an error message stating that it can find the form element.  This leads me to believe that I don't have my checkboxes set up properly and that it doens't know what to do when it gets to the record that isn't checked.
ASKER CERTIFIED SOLUTION
Avatar of lxdev
lxdev

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of kgarnto

ASKER

Thanks so much lxdev.  I really appreciate you taking the time to really explain it to me and show me the code.

I understand so much better now, and my initial test scripts seem to be working.  I'll work on incorporating it all into my original code now.