Wednesday, October 10, 2007

Add JavaScript Date Validation into List Item forms

Another undocumented piece of SharePoint.

I want to validate two fields on a new list item form by invoking JavaScript custom function. They are two date fields and I want to ensure that the end date can't happen before the start date. My first idea was to attach a validation function on the onclick event of the Submit button.

I started by inspecting the generated HTML of the form. The Submit button already has a onclick() code which is:

if (!PreSaveItem()_) return false;WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("ctl00$ctl13$g_740c1963_b0da_4b45_9b71_0dcca5d082b0$ctl00$toolBarTbl$RightRptControls$ctl00$ctl00$diidIOSaveItem", "", true, "", "", false, true))

Searching in the SharePoint JavaScript files in the LAYOUT folder, I found the definition of PreSaveItem function in FORMS.JS file. It simply invokes PreSaveAction function, if defined.

Finally, it was just a matter of inserting a custom function named PreSaveAction in a <SCRIPT> block of the NewForm.aspx (and EditForm.aspx). I also used the date parse code from this forum.

The code I put in NewItem.aspx is like this (note that I use getTagFromIdentifierAndTItle function from my older blog entry):

function PreSaveAction()
{
    var date1 = getTagFromIdentifierAndTitle("INPUT","DateTimeFieldDate","Contract Date"); 
    var date2 = getTagFromIdentifierAndTitle("INPUT","DateTimeFieldDate","Contract End Date");
    var arrDate1 = date1.value.split("/");
    var useDate1 = new Date(arrDate1[2], arrDate1[1]-1, arrDate1[0]);
    var arrDate2 = date2.value.split("/");
    var useDate2 = new Date(arrDate2[2], arrDate2[1]-1, arrDate2[0]);
    if(useDate1 > useDate2)
    {
        alert("The end date cannot happen earlier than the start date");
        return false; // Cancel the item save process
    }
    return true;  // OK to proceed with the save item
}

39 comentarios:

Ben said...

great post Res, i had this exact issue albeit for different field types but i can modify your code. cool cheers for this, will be sure to give you props - unfortunately its on an intranet

Ben said...

hi me again,

I am trying to validate on empty fields - they want javascript validation not just serverside .net, any idea what a single line of text would be identified as in your javascript getTagFromIdentifierAndTitle? e.g. "INPUT", "", "fieldname" my code is


var stringExplain = getTagFromIdentifierAndTitle("INPUT","string","explain");
if (stringExplain.value.length==0)||(explain.value==null)
{
alert("please enter a explanation");
return false;
}
return true;

but i have a feeling string is not the answer?

Pramod said...

I couldn't work out it for me, actually i got lost in which Newform.aspx i have to add code.
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\SiteTemplates

under various sub dir of this dir i found 12 NewForm.aspx files.

Can you please suggest on this?

bfalchi said...

Hi, great post, thanks.
Have you got any suggestion to validate a user and group field?

Murali Kannan said...

Hi Can you help in more detailed. I can't find any script blok on the newforms.aspx

I am using wss 3.0 sp1

Justin said...

This could also be done with an item event handler attached to the list. If you're able to customize your site with custom features, do a Google search for the ItemAdding event and you can whip one up pretty quickly.

Here's some code to chew on:
http://forums.microsoft.com/TechNet/ShowPost.aspx?PostID=3119964&SiteID=17&mode=1

Edin said...

To pramod and murali kanaan:
You have to use SharePoint Designer in order to add JavaScript code to the list maintenance ASPX pages.

To justin:
An EventHandler won't do because it's a server-side component, not client-side.

To bfalchi:
I'm also investigating it. I will share my discoveries, don't worry.

kalyan93 said...

How can I know the field names of the html fields? And where should I have to add this function in the NewForm.aspx or EditForm.aspx? Please help me. Its really very helpfull for me.

Edin said...

Hi, kalyan93

You can put this code either in NewForm.aspx or in EditForm.aspx, in a SCRIPT tag that you create, editing the ASPX files from SharePoint Designer.

The HTML fields codes you are referring to are just the field names that SharePoint uses (such as "Contract Date"). The second parameter in the function is field type, you can find more information about that in this blog post.

I hope it helps.

kalyan93 said...

Hi I got the information that how to get the field name. I think it would be helpfull for some other.

Go to List / Document Library Settings, click on the name of the column to modify it and in URL find the last parameter value.

May be usefull.

kalyan93 said...

@Edin

getTagFromIdentifierAndTitle("INPUT","DateTimeFieldDate","Contract Date"); is this function already existing in the sharepoint code or we need to write the definition of that function as you gave in your older blog entry. Because when I m trying to use this in my newForm.aspx page it is throughing an error like "object expected" at that corresponding line. Please help me....

Edin said...

Hi kalyan93,

this function is not provided by SharePoint, so you must copy-paste it to the ASPX markup code or reference an external JS file from the ASPX.

kalyan93 said...

I added this "getTagFromIdentifierAndTitle(tagName, identifier, title) " also in the Newform.aspx, but after adding this control is not going to the "PreSaveAction " function. I dont know where it is goint.. no single alert is working in both the functions.. any clue??

Edin said...

Kalyan93, can't help you much without seeing the code, but please double-check that you have correctly copied both of the functions (PreSaveAction and GetTagFromIdentifierAndTitle).

Any progress?

kalyan93 said...

Edin

Hi Your post is really helpfull for me. There is a syntax error in the function "getTagFromIdentifierAndTitle" unclosed for loop. Because of that only the error is coming. Thanks a lot Edin.

Thanks
Kalyan

Edin said...

You're welcome! I'm glad I've been helpful, that's the purpose of sharing my knowledge on this blog in the first place.

Happy coding!

kalyan said...

@Edin
Hi I have one another question that how could I pre-populate the form fields with database values? Eg:- like first name, last name, address kind of details.
Please help me in getting this..

Thanks in advance..

Kalyan

Edin said...

Hi Kalyan,

Sorry for the delay.

I think you can populate it using Data View Web Part from SharePoint Designer. It can display data from SQL source and then you can use java script / XSLT to get it into the fields.

gpollock said...

Hey Edin,

This was great and really helped me. One think I am noticing though, if you Cancel from the form, and get prompted 'Do you definitely want to leave without saving changes, etc', and then click Ok to save changes.... I don't think PreSaveAction gets called!?

Cheers
Gavin

Anonymous said...

does this test check the time (hours and minutes)?
how can I change the time of such a control?

Anonymous said...

How to validate start Time before end time?

Ma Zhe said...
This post has been removed by the author.
Ma Zhe said...
This post has been removed by the author.
Ma Zhe said...

Hi Edin,
I copied your code and paste it in Content Editor Web Part in newform.aspx by sharepoint designer, but i get the error message when i testing the page:

Webpage Script Errors
Message: Object expected
Message: Object doesn't support this property or method

here is the code i used:

[script language="javascript" type="text/javascript"]
function PreSaveAction()
{
var date1 = getTagFromIdentifierAndTitle("INPUT","DateTimeFieldDate","Start Date");
var date2 = getTagFromIdentifierAndTitle("INPUT","DateTimeFieldDate","End Date");
var arrDate1 = date1.value.split("/");
var useDate1 = new Date(arrDate1[2], arrDate1[1]-1, arrDate1[0]);
var arrDate2 = date2.value.split("/");
var useDate2 = new Date(arrDate2[2], arrDate2[1]-1, arrDate2[0]);
if(useDate1 > useDate2)
{
alert("The end date cannot happen earlier than the start date");
return false; // Cancel the item save process
}
return true; // OK to proceed with the save item
}
[/script]

Can you please suggest on this?
Thanks in advance..

Edin said...

Hi Ma Zhe,


It seems that you haven't included the necessary function "getTagFromIndentifierAndTitle". You can find the code at http://edinkapic.blogspot.com/2007/08/hide-field-from-newformaspx.html

Ma Zhe said...
This post has been removed by the author.
Ma Zhe said...
This post has been removed by the author.
Edin said...

The code seems correct, check that the field names ("Start Date" and "End Date") are well written.

Ma Zhe said...

Hi Edin,

thank you very much, as you said i lost the function "getTagFromIndentifierAndTitle". it is work correctly now!!

thank you again!!

Ma Zhe said...
This post has been removed by the author.
Ma Zhe said...

Hi Edin,

new problem with me and need your help,
how can I get this new result:
if(useDate1 < (((((((today))))))) alert("The start date cannot earlier than now")

sharepointapplied said...

Great post - the script works perfectly. Just blogged about it at http://sharepointapplied.wordpress.com/2009/01/08/sharepoint-forms-date-validation-using-javascript/

Keep them coming!
Greg

Amitabh said...

Hi
I want to hide some fields based on drop down values selected?
can this be doone?

Anonymous said...

Great post. This helped me a lot.

Many thanks for sharing this.

Anonymous said...

hi ,
is your code working for sharepoint control i.e date picker control. if so, how can i call the function

Edin said...

Hi,

It should work because the validation function is called for the form, not for the individual items. Your main concern should be how to access the control value with JavaScript.

Regards,

Anonymous said...

Hi,

If my "start date" & "end date" inclulded the time value. how to control the time validation in this javascript?

thx

Anonymous said...

Hi Edin,

But it seems dosen't work. I've try to select the start time > end time. It can be saved. On the other hand, if I select the start date > end date, it' work. It cannot be saved and prompt message !!

thx

Tony said...

Hi Edin. I've been using the PreSaveAction function on my new and edit forms for some time now. Works great, except I am not able to come up with a clean way of checking a date/time against another date/time, since SharePoint breaks that out into an input and two selects. There's no good tags to grab for the two selects for the hours and minutes.

Example of minutes select:

select name="ctl00$m$g_b6d12889_a442_4619_a490_ad2198622376$ctl00$ctl04$ctl11$ctl00$ctl00$ctl04$ctl00$ctl00$DateTimeField$DateTimeFieldDateMinutes" id="ctl00_m_g_b6d12889_a442_4619_a490_ad2198622376_ctl00_ctl04_ctl11_ctl00_ctl00_ctl04_ctl00_ctl00_DateTimeField_DateTimeFieldDateMinutes" dir="ltr"

No title tag on these selects. Seems Microsoft should have used a title attribute on these that just appended 'Hours' and 'Minutes' so they could be easily matched up with the proper input tag that makes up the date. And they even went to the trouble to add a label tag for the hours and minutes and hide those. Looks like the td tag that the two selects are within won't work either, since it just has a generic class. Ideas?

Post a Comment