Validation on SharePoint Forms – Part Four

2 minute read

Trolling the MSDN SharePoint – Design and Customization forum is proving to be a great learning experience all around.  I see questions I can’t answer which cause me to research them, and hopefully, I’m providing some answers which help others.

One of the things I saw over the last few days was a link to a post which explained how to use the PreSaveAction() JavaScript function to validate form data before it is saved.  (Check out my recent previous posts about validation in SharePoint forms: Parts One, Two, and Three.  I’ve posted about many other bits and pieces of this over time as well.)  Greg Osimowicz explains this in a post entitled SharePoint Forms date validation using JavaScript with reference to Edin Kapić‘s post entitled Add JavaScript Date Validation into List Item forms.  Read through both posts if you want to see how this holds together.

The cool thing is that there is a JavaScript function called PreSaveAction() which is called by FORMS.JS if it is defined in the form (NewForm.aspx or EditForm.aspx).  I had always converted the default List Form Web Part (LFWP) on forms to a Data View Web Part (DVWP) in order to “hook in” my JavaScript into the submit button for validation but it turns out that you don’t necessarily need to do that if you use the PreSaveAction function instead.

So, for example, if you want to validate that a Start Date is before an End Date (as shown in the posts above), you’d add this JavaScript to your page:

<script language="javascript" type="text/javascript">
function PreSaveAction() {
    var date1 = getTagFromIdentifierAndTitle("INPUT","DateTimeFieldDate","Start Time");
    var date2 = getTagFromIdentifierAndTitle("INPUT","DateTimeFieldDate","End Time");
    var arrDate1 = date1.value.split("/");
    var useDate1 = new Date(arrDate1[2], arrDate1[0]-1, arrDate1[1]);
    var arrDate2 = date2.value.split("/");
    var useDate2 = new Date(arrDate2[2], arrDate2[0]-1, arrDate2[1]);
    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
}

// getTagFromIdentifierAndTitle: Find a form field object using its tagName, identifier, and title to find it in the page
// Arguments:
//                            tagName:            The type of input field (input, select, etc.)
//                            identifier:            The identifier for the instance of the fieldName (ff1, ff2, etc.)
//                            title:                       The title of the list column
//
function getTagFromIdentifierAndTitle(tagName, identifier, title) {
    var len = identifier.length;
    var tags = document.getElementsByTagName(tagName);

    for (var i=0; i < tags.length; i++) {
        var tempString = tags[i].id;
        if (tags[i].title == title && (identifier == "" || tempString.indexOf(identifier) == tempString.length - len)) {
            return tags[i];
        }
    }
    return null;
}

</script>
Advertisements

64 Comments

  1. Hi Marc, that was wierd, but looks like some text was removed. Could’ve been my thumbs too.

    Anyway as per your date function above, I understand your example, however, I don’t have two date fields to draw from. I only have an input date field and todays date to compare between.

    var arrDate1 = date1.split(“/”);
    var useDate1 = new Date(arrDate1[2], arrDate1[1]-1, arrDate1[0]);

    if(useDate1 > new Date()) {
    alert (alertText);
    var fieldConc = $(“:input[title=’dateTitle’]”);
    fieldConc.focus();

    //the save has been stopped

    return false;
    }
    blah blah..

    So in comparison, my arrDate2 would need to be todays date.

    The problem is my code works ok for June 15 being > June 8, but it alerts if I enter May 31.?????? I suspect it could be the different formatting of the two date references where dtae field is MM/dd/yy and New Date() is yy,MM,dd. I beeleive I Ssould I create an arrDate2 = new Date() ? But unsure of syntax and beleive me I’ve searched and searched. All examples only show the two date fields.

    Any ideas please??

    Cheers

    Carl

    Reply
    • Carl:

      If you alert a new Date(), you’ll see that the format is something like “Thu Jun 9 19:20:19 CDT 2011”. so you’ll need to reformat both dates to do the comparison reliably. If you convert both to YYYYMMDD format, you should be all set. I think any successful comparisons you’re seeing are just lucky!

      M.

      Reply
  2. Hi Marc,

    We try you code and it is working fine on staging environment, but on production the PreSaveAction function is not called. Another strange behavior which I see is I cant see the PreSaveAction function on view source of firefox and can see it in view source of IE. In both browser PreSaveAction function is not fired.

    Any suggestions?

    Thanks,
    Deepesh Verma

    Reply
    • Deepesh:

      PreSaveAction works the same, regardless the environment. I’d do some debugging. Is it possible that someone has altered the core JavaScript files in your production environment?

      M.

      Reply
  3. Hi Marc,
    My client is having requirment which is related to this article..could you pls help me on this…For example in custom list form (new form,edit form ) am having 5 fields like
    1:Yes/No field
    2: Text Field
    3: Date field
    4: people or group Field
    in this i require validation like if i click the field 1 to yes other fields should require value entered( like require field validator dynamically) or else value is not required… Pls show me the way how to do it..
    Thanks,
    Surya

    Reply
    • Surya:

      You can definitely add this type of behavior using script. You’ll want to bind to whichever event makes sense and then change the visibility or settings of the other columns appropriately.

      M.

      Reply
      • Marc thanks for quick reply….Am trying this from 2 days ..i have tried using spservices and also using jquery but no use…..So can u please send me on which way be can do this and it will be good if you send me some code by taking any examples…Thanks

        Reply
        • Surya:

          There are plenty of examples on the Web showing how to use script to change the behavior of forms. It’s one of those things where there’s no generic answer, though. You’ll need to figure out the code for your own situation.

          M.

          Reply
  4. Thanks for the great post Mark,

    I have a small question though. If instead of

    alert(“The End Date cannot happen earlier than the Start Date”);

    i wish to show the error message as in the case of a required filed validation for the NewForm.aspx, how should i achieve that ?
    I could not find a span in which i could insert my message and display it just below my date time control. Any help will be appreciated.

    Reply
    • Binit:

      You’ll have to decide where in the page you want to place your message and come up with an appropriate selector to do it. I can’t really tell you what it might be from afar.

      M.

      Reply
  5. Marc
    the code is workking to a point , it catches the error, but it still saves the info. Do you know how to get the code to not save and to stop once the error is caught?

    Reply
      • Marc-
        I figured out what was wrong.
        We are using this Button Click.
        Submit
        But the code and PreSaveAction is looking for the native SaveButton.
        I was wondering, where could I put in this code a Link to the WR_Submission_Success.aspx page?

        Reply
  6. Hi, Is there anyway possible to give a error notification if say a user selects a date 1 month ahead of the current date. So if they submit anything less than a month from the current date the error is shown.

    Reply
  7. Hi Marc,

    Is there any function that is similar to the PreSaveAction() but executes after a successful save? Something like PostSaveAction() ….

    I want to execute a piece of javascript code after the item has successfully been created unlike presaveaction().

    Any advice would be a great help.

    Thanks,
    Charan

    Reply
    • Charan:

      Sadly, no. By the time the asynchronous write is done, the page is long gone (in computer time).

      You can use a workflow or play some games with the redirect like I do in SPRedirectWithID in SPServices.

      M.

      Reply
  8. Thank you for your reply Marc.
    I’ve always benefited from your articles.

    That is really sad. I thought you might have come across a situation like this and may have solved it. Can you post an example of how you play around with SPRedirectWithID?

    Thanks,
    Charan

    Reply
    • Charan:

      You can take a look in SPServices yourself to see how the function works.

      I’d think a little more about what you’re trying to do, though, and there may be a different approach that works better.

      M.

      Reply

Have a thought or opinion?