Toggle Form ELEMENTS With Javascript

October 2016


Toggle Form Elements Enabled / Disabled With Javascript

Recently I was tasked with creating a form to Track Technicians Productive time, along with Non-Productive time on Tickets worked. Some times, when working on a project, the technnician will perform other duties, that may or may not be billable back to the customer that they are working with.

These times are things like breaks, gathering material, even driving to the job. All of which are part of the overall time, be are non-productive, and therefore hard to bill for. My proposal was to break each ticket into 5 Segments, and labeling each segment with a "Work Type", "Start Time", and "End Time". Internally to our organization, they have become "Segments".


So now when we look at billable time, we only have to track the work time. We do not have to take into consideration for breaks, or driving, as the technician has identified how much of his ticket time is used to work. The attached picture is the front end form I have come up with. This How-To is an example of how to customize each "segment", and making it possible to reduce the back end server processsing when the form is submitted.

The back server process would go nuts looking at each ticket, for each technician, and check for the 5 segments. So in order to reduce that processing, I have disabled the Check box that cuts the technicians times into segments. So the Beginning and end times are always the whole work time, unless the technician has identified other Non-productive tasks that he HAD TO COMPLETE in order to close out his work ticket. The back server side logic now only has to look to see if the Segment is ENABLED, and if it is, then process it.

In this example, we will concentrate on the User Front end, and the Client Javascript that the server pushes to the client to determine if the Segment is enabled.

Our Tickets now, have checkboxes, that control segment work types, and start and stop times. The work types and start and stop times are not enabled unless the Checkbox for that segment becomes enabled. This example will explain how I accomplished such interaction with a few short commands in Javascript.

The following code is an example of how to create an HTML FORM in a web page. This is not the complete code, but it shows how the form Elements are Programmitcally set up and named, to allow control in Javscript.


The code:

Total Work for (Date mm/dd/yyyy): <input type="text" name="segmentdate" id="segmentdate" value="<%=date()-1%>">
<hr>
<% for seg_count = 0 to 4%>
<div style="display:inline;width:75px;">
Segment <%=seg_count+1%> <input type=checkbox name="segment<%=seg_count+1%>" onclick="javascript:makeusable('<%=seg_count+1%>',segment<%=seg_count+1%>.checked);">
<br>
Segment <%=seg_count+1%> Worktype:
<select name="S<%=seg_count+1%>work" disabled=true>
<option value="select">Select Type</option>
<option value="Break">Break</option>
<option value="Lunch">Lunch</option>
<option value="Demo">Demo/Removal</option>
<option value="Underground">Underground</option>
<option value="Rough">Rough</option>
<option value="Tubset">Tubset</option>
<option value="Trim">Trim</option>
<option value="Service">Service</option>
<option value="Mat/Warehouse">Mat.Warehouse</option>
<option value="Mat/Supplier">Mat.Supplier</option>
<option value="Delivery">Deliver Materials</option>
<option value="Design">Design Consult</option>
<option value="Estimate">Estimate</option>
<option value="Drive">Drive</option>
<option value="Cust Education">Cust. Education</option>
<option value="Training">Training</option>
</select>
Start Time: <select name="S<%=seg_count+1%>_starttime" disabled=true onchange="javascript:updatesegment('<%=seg_count+1%>');">
<%for segment=seg_count+0 to 14%>
<option value="<%=6+segment%>:00"><%=6+segment%>:00</option>
<option value="<%=6+segment%>:15"><%=6+segment%>:15</option>
<option value="<%=6+segment%>:30"><%=6+segment%>:30</option>
<option value="<%=6+segment%>:45"><%=6+segment%>:45</option>
<%next%>
</select>
<br>
End Time: <select name="S<%=seg_count+1%>_endtime" disabled=true>
<%for segment=seg_count+1 to 14%>
<option value="<%=6+segment%>:00"><%=6+segment%>:00</option>
<option value="<%=6+segment%>:15"><%=6+segment%>:15</option>
<option value="<%=6+segment%>:30"><%=6+segment%>:30</option>
<option value="<%=6+segment%>:45"><%=6+segment%>:45</option>
<%next%>
</select>

</div>
<%next%>
</TD>


You will notice the presence of codes enclosed by <% and %>, they are ASP codes that programmatically loop through each of the required elements, thus eliminating the need to duplicate the code for each of the 5 segments of program. Do not get held up by the ASP code in the <%%>, as they create the HTML, and the HTML and JAVASCRIPT are what we are focusing on in this example.

You also must notice that each Segment WORK TYPE, Start time, and End time, is DISABLED, thus making it impossible for the user to manipulate the times, unless they activate it by clicking on the appropriate segment checkbox.

We are going to break down the code that allows for the enabling and disabling of form elments, based on the interaction of other ELEMENTS in the form.



Take a look at the code below:

<% for seg_count = 0 to 4%>
<div style="display:inline;width:75px;">
Segment <%=seg_count+1%> <input type=checkbox name="segment<%=seg_count+1%>" onclick="javascript:makeusable('<%=seg_count+1%>',segment<%=seg_count+1%>.checked);">



In the line starting with <%, you will notice that we set a variable for a "FOR...NEXT" Loop. This variable is identified as "seg_count", and is initialized with a value of 0. If we start the loop at zero, and continue to increment by 1 until we reach 4, then we will have 5 different segments; without having to write the code 5 times. Got it? Good!

Now take a look at he the variable of "seg_count". It is going to be used over and over again during this loop, anywhere we want the current segment number (variable) to be used in the FORM ELEMENT name.


<input type=checkbox name="segment<%=seg_count+1%>" onclick="javascript:makeusable('<%=seg_count+1%>',segment<%=seg_count+1%>.checked);">


As in the above code, we make a FORM ELEMENT of a CHECKBOX. This checkbox, has a dynamic name, comprised of the STRING "segment", and the variable of "seg_count". When combined programatically, it produces UNIQUE names of "segment1", "segment2", "segment3", and so on. You will notice, there is no "segment0", as in each name, we add 1 to the variable of "seg_count", to produce a "valid" segment to the user.

Now, notice the EVENT attached to the CHECKBOX ELEMENT:


onclick=""


This is the action that triggers the call to the javascript that enables the other FORM ELEMENTS. In this case, we call a JAVASCRIPT, named "makeusable(what_index,boolean)". This Script is expecting two variables to be passed to it; the first one:what_index. This is the segment number to manipulate, as the FORM elements are all identifed by the segment number it is in. The second variable: boolean. This is the True or False statement of if the CHECK BOX is CHECKED OR NOT.

Because of the way the mouse interacts with the rest of the page, the ACTUAL mouse click, isn't really performed until the MOUSE IS UP. So in this case, the Javascript will FIRE on the click GOING down, and it will not wait until the up click. Because of this interaction (normal), If we are clicking the checkbox for the first time, the check box is going to report the current status, which in this case , would be false, as the check is placed in the box on the UP CLICK. We will deal with tricking the javascript later. Let us look into the javascript of MAKEUSABLE().


function makeusable(elementidcount,whatvalue) {
////***********************************************************
////Working example AC3MARK not to be distributed or published beyond scope of this example
////*******************************************************************************************************
var segwork, elementid, elementidX
var whatelem, whatelemX, whatseg;
whatvalue = !whatvalue;
elementid='S'+elementidcount+'_starttime';
elementidX='S'+elementidcount+'_endtime';
segwork='S'+elementidcount+'work';
whatelem = document.getElementById(elementid);
whatelemX = document.getElementById(elementidX);
whatseg = document.getElementById(segwork);
whatseg.disabled=whatvalue;
whatelem.disabled=whatvalue;
whatelemX.disabled=whatvalue;
}


OK, now we are going to break down the nuts and bolts of the SCRIPT, that does the work for us.


function makeusable(elementidcount,whatvalue) {

This Javascript is looking, once again, for two variables to be passed to it; "elementidcount", and "whatvalue".

The next couple of lines, free up memory for the javascirpt to use during the process.


var segwork, elementid, elementidX
var whatelem, whatelemX, whatseg;


Do you remeber me mentioning we were going to trick the Javascript into thinking something else is going on? The next step does that:

whatvalue = !whatvalue;


Because we passed the variable of "whatvalue" as a boolean variable, it can only be in one of two states, TRUE or FALSE. In Javascript, you can use LOGIC STATEMENTS to set, or test certain variables. In this case, we take the value of "whatvalue", and make it the opposite with the OPERATOR OF "!" (in front of the the second "whatvalue"). This line is actualy saying, take the variable of "whatvalue", and make it the opposite of "whatvalue". If you are stuck with this, please read more about LOGIC operators.

So, if the varaible set was False before, we have just made the change to True, with one little character ("!").

Now let us look at how to "hook" into the correct FORM ELEMENTS:

elementid='S'+elementidcount+'_starttime';
elementidX='S'+elementidcount+'_endtime';
segwork='S'+elementidcount+'work';


Remember, we initilized the variables of elementid, elementidX, and segwork. On our form, these are the ELEMENTS of "Start Time", "End Time", and "Work Type".

Because the FORM ELEMENTS we created by code, we have to build them in our Javascript to match and find the ELEMENTS. That is why we the build each variable STRING NAME with the below statement:

elementid='S'+elementidcount+'_starttime';


If "elementidcount" was passed to our Javascript in the onlclick EVENT, we can then build the element name with that information that is passed, with the populating the variable of "elementid" with COMBINED STRINGS of "S" plus the value passed (example -1), plus the string of "_starttime". If you go back to each FORM ELEMENT in the first code pasting, you will see each ELEMENTS NAME is constructed with a number in it. A working ELEMENT name that will be constructed will be "S1_starttime". You wils see, we do this with all three ELEMENTS we wish to interact with ("SX_starttime", SX_endtime", and "SX_work"-where X is the variable passed by the onlcik event). Still with me?


whatelem = document.getElementById(elementid);
whatelemX = document.getElementById(elementidX);
whatseg = document.getElementById(segwork);


The Javascript method of document.getElementById(whatelement), is the only way I have found to be completly certain to hook into each element, regardless of browser type. I would like to hear of other ways to be 100% certain your code will find the ELEMENTS!

So, we then "hook" into each element, by initializing OBJECT Variables of "whatelem", "whatelemX", and "whatseg", with each appropriate ELEMENT NAME, as constructed in the previous variable constructors.

Now, before we go on, please take a look at each FORM ELEMENT in HTML:

Start Time: <select name="S<%=seg_count+1%>_starttime" disabled=true onchange="javascript:updatesegment('<%=seg_count+1%>');">

Notice how we start each ELEMENT with the "disabled=true", value. So, when we click on the CHECKBOX, it is then going to report to the JAVASCRIPT, that is True. Remember the line of code, we called a trick (the "!" operator)?

whatvalue = !whatvalue;


That is where we take the FALSE passed by the onclick event, and "flip it" to a TRUE. So whatvalue is now the opposite of what it once was. Get it?
Let's see how we flip the ELEMENTS to enabled, and therfore can be interacted with by the user:

whatseg.disabled=whatvalue;
whatelem.disabled=whatvalue;
whatelemX.disabled=whatvalue;



I will revisit the second call event of "updatesegment()" attached to the START TIME ELEMENT, in another How-To at a later date. All this javascript does, is finds out what the Start Time ELEMENT IS, and moves the DROP DOWN SELECT to an Hour later. I also want to have it eventually check to see what type of WORK TYPE is set, and automatically adjust the END TIME elelent for the appopriate time. SO, if Segment 1 Time, was Break, Upon setting the Start Time (Example:11:00), it checks to see what type of work is was, and if it finds BREAK, then make END TIME automatically set for 11:15, as breaks are 15 minutes. (I already have the code for this, so please do not post suggestion on how to make it, I already have it, and it works).

I hope this has made everyone interested in the interaction of FORM ELEMENTS and JAVASCRIPT!
Until the next one, HAVE FUN!

All thanks to ac3mark for this tip,

Related :

This document entitled « Toggle Form ELEMENTS With Javascript » from CCM (ccm.net) is made available under the Creative Commons license. You can copy, modify copies of this page, under the conditions stipulated by the license, as this note appears clearly.