This week I had an interesting (email) conversation with a reader. Jason is a .Net developer using jQuery to build a simple form. On his page he had a UI feature where one of two DIVs were displayed. He had no problem with handling the logic of showing one div or another on the client side, but he was interested in how he could persist that change when he submitted his form. I worked up a simple demo of one way that this could be handled.
I began by creating a very simple form.
<form id="myform" method="post">
name: <input type="text" name="name"><br/>
email: <input type="text" name="email"><br/>
<input type="submit">
</form>
Instead of using two divs, I went with div that could be hidden or shown. The idea is that the div could be used for instructions.
<input type="button" id="toggleinstructions" value="Toggle Instructions">
<div id="instructions" style="display:none">These are the instructions for the slow people.</div>
Next I whipped up some quick jQuery to support the toggle:
$("#toggleinstructions").click(function() {
$("#instructions").toggle()
})
So far so good. How can we help persist the state of the instructions? Well one way would be with cookies. We could modify the click event handler to set a cookie every time the status changed. My problem with this though is that it seems a bit overkill to use a cookie just to remember the status of a UI item on the form. I decided to take another approach. What if we passed the status of the div when the form is submitted?
The first thing I did was to add a new hidden form field to the form:
<input type="hidden" name="instruction_status" id="instruction_status">
I then added a form submit handler:
$("#myform").submit(function() {
status = $("#instructions").is(":visible")
$("#instruction_status").val(status)
})
This was my first time making use of the jQuery IS operator. This was a new one for me. As you can guess, it allows you to run a simple check on the currently selected item. In this case I'm checking for the visible property. This will return a boolean that then gets passed to the hidden form field.
Here is the complete template. You can see that I've added some server side logic to check for the hidden field and set the visibility accordingly.
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$("#toggleinstructions").click(function() {
$("#instructions").toggle()
})
$("#myform").submit(function() {
status = $("#instructions").is(":visible")
console.log(status)
$("#instruction_status").val(status)
})
})
</script>
</head>
<body>
<cfparam name="form.instruction_status" default="false">
<input type="button" id="toggleinstructions" value="Toggle Instructions">
<div id="instructions" <cfif form.instruction_status is false>style="display:none"</cfif>>These are the instructions for the slow people.</div>
<form id="myform" method="post">
<input type="hidden" name="instruction_status" id="instruction_status">
name: <input type="text" name="name"><br/>
email: <input type="text" name="email"><br/>
<input type="submit">
</form>
</body>
</html>
<cfdump var="#form#">
Does it make sense for me to use a hidden form field for this? I don't know. It kind of feels like I'm cluttering up the form with non-essential data. Then again, I do think I prefer this over the cookie approach. Either way - it's just one more way to solve a problem in jQuery!
Archived Comments
It seems that using a hidden form field would be the only way you could submit the status in the post. I suppose you could experiment with using a textarea field with an alternate style to be the display object. Probably wouldn't work though.
With a single flag value like that, you could instead tack the value/state of the flag onto the post as a URL variable in the "action" attribute of the form. So when the submit event runs, the action attribute value is change from "submit.cfm" to "submit.cfm?instruct=true" or "submit.cfm?instruct=false", and then base your conditional on the URL variable value.
I have gone through same problem but different is need to maintain multiple divs hidden/visible. Applied same login but rather than different hidden variable use single one and at time of form submission build JSON string with id and current visibility status (like {'div1':'true','div2':'false'....} and on load of page go through all structure element and show/hide as per value
I think I'd go with the hidden field as well but there is a pretty nice Cookie plugin for jQuery (http://plugins.jquery.com/p... in case anyone wants to explore the cookie route ... the plugin makes reading and writing basic cookies quite simple.
I'm curious as to why this is needed in the first place. It smells like a display preference issue. Ideally state for that should be persisted using the session and/or database and/or framework. Or am I missing something?
Other than that, this works well enough. It just doesn't feel like the long term, elegant solution. Then again, how often is the elegant solution the best one?
I done this before for form elements. I disabled the element while hiding. So I won't get that form element after post. While loading I checked isDefined(form.element).
@Craig, It sounds good. I will update my code.
My 2 cents: first of all,remember that users can have coockies disabled; often i change the action url string of a form at submit, depending of any parameter, what button is pressed ecc, i like Brian's solution as we have not another field form field not direclty related to the form.