views:

1224

answers:

6

Hello,

I am using the <cfinput type="datefield"> and I need to limit the dates that can be chosen. I cannot allow a date that can be selected in the past. Any help here?

Thanks!

A: 

AFAIK, there is no easy way to prevent the client from picking a day in the past. We have fields like that on a few of our forms that we check against the current date on the server side, though. Just remember to generate the date without the time for comparison, or you end up with [today's date] < now().

Ben Doom
A: 

You should use server side validation as well, but I believe you can use the "range" attribute of cfinput to limit the valid dates.

Sean Coyne
sorry, range only works for numeric values, not dates.Unless... you're not using "datefield", but 3 numeric textfields...
Henry
+1  A: 

Well you have two options validating it strictly server side or additionally adding a client side javascript check.

For the serverside, your cfm processing page could use the DateCompare function like so:

<cfif DateCompare(Date1,Date2) EQUAL -1>
<!--- Date 1 < Date 2 ---> 
<cfelseif DateCompare(Date1,Date2) EQUAL 0>
<!--- Date 1 = Date 2 ---> 
<cfelseif DateCompare(Date1,Date2) EQUAL 1>
<!--- Date 1 > Date 2 --->
</cfif>

Documentation and sample code is available for this function at: http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=functions_m-r_11.html

Another post suggested using the range functionality, however I was not able to get this to work because the Adobe documentation said it was only supported on type numeric.

Alternatively you can use javascript to check if the date is within range live on the page:

<html>
<head>
<script type="text/javascript">
function withinRange(submittedDate) {
    var start = Date.parse("08/10/2009");
    var end = Date.parse("09/11/2009");
    var userDate = Date.parse(document.getElementById('leaveDate').value);
    var previousDate = document.getElementById('calendarWorkaround').value;

    if (!isNaN(userDate) && ( previousDate != userDate)) {
     document.getElementById('calendarWorkaround').value = userDate;
     if (start <= userDate && end >= userDate) {
      alert("Your date is correct!");
     } else {
      alert("Date is incorrect.");
     }
    }
}
</script>
</head>
<body>
<cfform name="testing" id="vacationForm"action="testprocess">
    <cfinput name="date" type="datefield" id="leaveDate">
    <input type="hidden" name="workaround" id="calendarWorkaround" value="-1">
</cfform>

<!--- To get around onChange bug with cfinput type datefield --->
<cfajaxproxy bind="javaScript:withinRange({leaveDate})">

</body>
</html>

Now I would use the onChange attribute for cfinput on the datefield, however there is a bug that it does not call the javascript function that seems to be documented on a couple of other pages online. The workaround that I used was the cfajaxproxy call with the bind attribute. If you are using cfeclipse, it will give you an error that the syntax is not correct however it worked fine for me.

The hidden input type is necessary because with the cfajaxproxy tag, everytime you click the calendar icon it will call the javascript function which is not what we want. So I store the last value chosen by the user (or -1 on page load) so that the javascript to check if it is within range is only executed if the value changes. It is a bit of a hack, however the implementation of <cfinput type="datefield"> does not work as documented.

You can also modify this example so that coldfusion dynamical generates the start date and end date so it is not hard coded.

Just remember that whichever way you choose, you should always check the value server side just in case the user has javascript disabled.

adimitri
A: 

At first, I thought <cfcalendar> would help, but seems like the startrage and endrange is for disabled range.

I guess if you Really want to limit the range, use something else like jQuery UI Datepicker

Henry
A: 

Through experimentation, I was able to customize the supporting javascript files to restrict the selectable dates. However the jQuery option sounds good as well.

Leigh
A: 

I just added 100 years on to the endrange attribute for the cfcalendar component, thinking no one will sit and click through that far to beat your validation :

<cfset startRange = #dateformat(now(), 'dd/mm/yyyy')# >
<cfset endRange = dateadd("yyyy", 100, #Now()#)>
<cfset selectedDate = dateadd("d", -1, #Now()#)>

<cfcalendar name="start_period" mask="dd/mm/yyyy" selecteddate="#selectedDate#" startRange="#startRange#" endrange="#endRange#">

Simon.

Simon