Ask a Jedi: ColdFusion datefield/change question

This post is more than 2 years old.

Curt Danceswithformfields asked:

I am trying to get a form to submit onchange with cfinput type="datefield" and it won't fire my onchange event if the change is made using the popup calendar.

Consider the following...
<cfinput type="datefield" id="duedate" name="duedate" value="#NOW()#" onchange="javascript: ItemsDueForm.submit();">

Have you ever run into anything like this before. Do you know of a quick workaround?

As much as I've played around with ColdFusion 8, I really haven't done much with the date controls. What's interesting is that the onchange runs just fine if you manually change the value, but the little calendar icon won't fire onchange when you change the value. So what can we do?

My first thought was - let's try a bind command with cfajaxproxy:

<cfajaxproxy bind="javaScript:doSubmit({duedate})">

Unfortunately this fired the second you clicked the calendar. Even though - visibly - nothing changed the doSubmit function was firing immediately for me. When I switched from a form submit to just a console.log('twinkies'), I noticed quite a few log messages when using the control. I figured the only way to make this work would be to store the original value, and compare that in my JavaScript. This is what I ended up with:

<head> <script> var origDate;

function setOrig() { origDate = document.getElementById('duedate').value; }

function doSubmit(duedate) { //submit if we really changed if(duedate != origDate) document.getElementById('ItemsDueForm').submit(); } </script> </head>

<body> <cfif isDefined("form.duedate")>

  &lt;cfdump var="#form#"&gt;

<cfelse>

  &lt;cfform id="ItemsDueForm" action="#cgi.SCRIPT_NAME#" method="post"&gt;

        &lt;cfinput type="datefield" id="duedate" name="duedate" value="#NOW()#"&gt;

  &lt;/cfform&gt;

&lt;cfajaxproxy bind="javaScript:doSubmit({duedate})"&gt;
&lt;cfset ajaxOnLoad('setOrig')&gt;

</cfif>

</body> </html>

As you can see, I added an ajaxOnLoad. This will fetch the current value of the field and store it. Now when doSubmit is fired, it will only do the form submission when the value is changed.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Andy Sandefer posted on 10/2/2008 at 1:39 AM

You could also try experimenting with onMouseUp but I've never had to do this before so I'm not sure if any of the standard events will help you.

Comment 2 by David posted on 8/1/2009 at 2:55 AM

Ray,

I am having a problem with the CF datepicker and FF 3.5.1.

http://www.neale.ca/test.cfm

The datepicker will popup in IE but nothing happens in FF?

Any ideas?

Comment 3 by David posted on 8/1/2009 at 3:40 AM

Ray this has been fixed. The cfform tags must reside outside the table tags for FF.

Comment 4 by Scott Dyer posted on 12/2/2009 at 9:12 PM

Thank you for the cfform outside of the table tags tip. I have spent 3 days with this problem and I could not figure out why it was not working.

Comment 5 by FALCONSEYE posted on 2/10/2010 at 9:11 PM

While searching the intrAWeb for a solution to utilize jquery validation plug-in with cfinput datefield and found this entry.

This is what I have:

<script>
...
isValid = function() {
$("#popUpForm").validate({
rules: { header: "required",
startDate: { required: true, date : true } ,
endDate: { required: true, date : true }
},
messages: { header: "<br/> <span style='color:red;'>Header is required!</span>",
startDate: "<br/> <span style='color:red;'>Start Date is required (MM/DD/YYYY)!</span>",
endDate: "<br/> <span style='color:red;'>End Date is required (MM/DD/YYYY)!</span>"
},
errorPlacement: function(error, element) {
if (element.attr("name") == "startDate") {
error.appendTo("#err-startDate");
} else if (element.attr("name") == "endDate") {
error.appendTo("#err-endDate");
} else {
error.insertAfter(element);
}
}
}).form();
if ($("#popUpForm").valid()) {
return true;
} else {
return false;
}
}

I run isValid() method when the user clicks on the form's submit button. Say, user didn't enter a date or entered something that is an invalid date format. The validation displays the error message. If the user hits the little datefield clicky, picks a date, the date field is populated with a correct date (format) and therefore the error message should go away. Well, it didn't go away. As you mentioned, the clicky does not trigger the onChange() event. So, this is how i get it to work. If you view the page source, you will see that ColdFusion created an image (startDatepopUpForm_cf_button) for the clicky. So, I addded this:

$("#startDatepopUpForm_cf_button").click(function() {
$("#err-startDate").html('');
});

Of course, if the user closes the pop-up without picking up a date, then the next click to save button is going to catch the error.

I think the clicky functions are handled by /CFIDE/scripts/ajax/ext/build/util/Date-min.js. I guess the ultimate solution will be to put an onChange function somewhere here.

Hope this helps to others.

Comment 6 by Nick posted on 8/29/2013 at 4:12 AM

BEAUTIFUL! Thanks a ton.

Comment 7 by dwayne anderson posted on 4/12/2014 at 4:17 AM

I have a cf div bound to a CF datefield with native date picker. When I press the icon, the cfdiv reloads, AND when I select the date, the cfdiv reloads.

The problem is there is a lot of data loading in the cfdiv.

Seems like the same type of problem...hoping someone knows of a better solution as I can't imagine writing JS to replace my bound cfdiv.

<cfinput class="form-control cfdatefield" readonly="yes" type="#ftype#" id="dpStart" name="dpStart" value="#cookie.dpStart#"><cfinput class="form-control cfdatefield" readonly="yes" type="#ftype#" id="dpEnd" name="dpEnd" value="#cookie.dpEnd#">

<cfdiv bind="url:jobs_table.cfm?user=#getAuthUser()#&dpStart={dpStart.value}&dpEnd={dpEnd.value}&search=#url.search#" ID="theDiv" ></cfdiv>

Comment 8 by Raymond Camden posted on 4/12/2014 at 7:47 PM

The UI control CF is using must be sending a change event even when you just click the control. Nothing you can do that about that as far as I know. I recommend *not* using cfdiv and cfinput nowadays - and yes - that means writing JavaScript.