Solved

How to limit the number of Checkboxes Selected?

Posted on 2004-08-24
10
226 Views
Last Modified: 2013-12-24
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>
0
Comment
Question by:kgarnto
  • 4
  • 3
  • 2
  • +1
10 Comments
 
LVL 25

Expert Comment

by:James Rodgers
ID: 11883841
rather than use check boxes can you use radio buttons?
0
 
LVL 21

Expert Comment

by:pinaldave
ID: 11883856
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
0
 

Author Comment

by:kgarnto
ID: 11883965
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.
0
 
LVL 21

Expert Comment

by:pinaldave
ID: 11883987
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
0
 
LVL 1

Expert Comment

by:lxdev
ID: 11884001
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.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 1

Expert Comment

by:lxdev
ID: 11884093
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.
0
 

Author Comment

by:kgarnto
ID: 11884333
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?  

0
 

Author Comment

by:kgarnto
ID: 11885745
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.
0
 
LVL 1

Accepted Solution

by:
lxdev earned 250 total points
ID: 11936652
Hi kgarnto,

I've put all this together into an example with a simplified form. I'm also using a <cfscript> block to create a query object in lieu of using a <cfquery>, <cfstoredproc>, or a CFC.

To test the server side validation, turn JavaScript off in your browser.

Hope this helps.

<!--- start of code --->
<cfscript>
// obviously, you would run a query instead of creating one...
get_classes = QueryNew("crn,class");
QueryAddRow(get_classes, 4);
QuerySetCell(get_classes, "crn", "crn1", 1);
QuerySetCell(get_classes, "class", "Class 1", 1);
QuerySetCell(get_classes, "crn", "crn2", 2);
QuerySetCell(get_classes, "class", "Class 2", 2);
QuerySetCell(get_classes, "crn", "crn3", 3);
QuerySetCell(get_classes, "class", "Class 3", 3);
QuerySetCell(get_classes, "crn", "crn4", 4);
QuerySetCell(get_classes, "class", "Class 4", 4);
</cfscript>
<cfset CrnList = ValueList(get_classes.crn)>

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


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>
      <title>Test CRN</title>

<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">
<!--
function checkCRNs(objCheckbox) {
     var objForm = objCheckbox.form;
     var i;
       var counter = 0;
     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>
</head>

<body>

<cfif IsDefined("form.counter")>
      <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>
</cfif>

<form action="<cfoutput>#cgi.query_string#</cfoutput>" method="post">
<table border="1">
<tr align="center">
      <th>Delete?</th>
      <th>Class Name</th>
</tr>
<cfoutput query="get_classes">
<tr align="center">
      <td><input type="Checkbox" name="class#currentrow#" id="class#currentrow#" value="#get_classes.crn#" onclick="return checkCRNs(this)"></td>
      <td><label for="class#currentrow#">#get_classes.class#</label></td>
</tr>
</cfoutput>
</table>
<input type="hidden" name="counter" value="<cfoutput>#get_classes.recordcount#</cfoutput>"><br>
<input type="submit" value="Delete Checked">
</form>

</body>
</html>
<!--- end of code --->
0
 

Author Comment

by:kgarnto
ID: 11946157
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.
0

Featured Post

Complete Microsoft Windows PC® & Mac Backup

Backup and recovery solutions to protect all your PCs & Mac– on-premises or in remote locations. Acronis backs up entire PC or Mac with patented reliable disk imaging technology and you will be able to restore workstations to a new, dissimilar hardware in minutes.

Join & Write a Comment

One of the typical problems I have experienced is when you have to move a web server from one hosting site to another. You normally prepare all on the new host, transfer the site, change DNS and cross your fingers hoping all will be ok on new server…
Periodically we have to update or add SSL certificates for customers. Depending upon your hosting plan you may be responsible for the installation and/or key generation. In the wake of Heartbleed many sites were forced to re-key. We will concen…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now