Question

I have some code in my PreSaveItem event that checks to see if there is a conflict on the calendar with the item being created. The code itself executes just fine and properly checks the calendar for conflicts. Where the problem occurs is when there is no conflict - the success happens, but then it does not submit the form, just returns you to the open form.

function PreSaveItem(){

var d = new Date(startDate);
startDate=d.toISOString();
startMinute = handleMinute(startMinute);
d.setHours(startHour);
d.setMinutes(startMinute);
startDate=d.toISOString();

var e = new Date(endDate);
endDate=e.toISOString();
endMinute = handleMinute(endMinute);
e.setHours(endHour);
e.setMinutes(endMinute);
endDate=e.toISOString();
conflictFlag = false;
var calendarUrl = theCalendarURL;
    $.getJSON(calendarUrl,function(data,status,xhr){
            if(data.value.length>0){ 
                 for (var i = 0; i < data.value.length;i++){
                    var b= new Date(data.value[i].EventDate);               
                    var s= new Date(data.value[i].EndDate); 
                    b=b.toISOString();
                    s=s.toISOString();
                    //if ( b.getFullYear()==d.getFullYear() && b.getMonth()==d.getMonth() && b.getDate() == d.getDate() ){              
                        if(b<startDate && s>startDate){ conflictFlag=true; }
                        if(b<endDate && s>startDate){ conflictFlag=true; }
                        if(b>startDate && s<startDate){ conflictFlag=true; }
                    //}
                 }
            }
            if (conflictFlag==true){
                    alert("You have selected a date/time/line that is already in use. Please select a different date/time or line."); 
                    return false;
                } else { 
                    alert("Congrats!");         
                    return true;
            }
    }); 

}

(I have removed some code in the name of efficiency here, but the missing variables are populating properly)

Was it helpful?

Solution

The problem here, I suspect, is that after your validation check, when you are trying to return true; to tell the SharePoint form that it's ok to submit, you're not really returning out of your PreSaveAction function. You are returning out of your anonymous $.getJSON callback function, which is returning true back out into the inner scope of the PreSaveAction function, which by that time has finished executing anyway.

Also, please see this answer on the difference between PreSaveItem and PreSaveAction - it's probably better to name your function PreSaveAction rather than overriding the default PreSaveItem function.

Now, here's an example of how you can handle needing to complete some async work before you can tell if the form should be submitted or not:

var MyNamespace = MyNamespace || {};

// set up some global variables that exist
// outside the scope of any function
MyNamespace.StartedValidation = false;
MyNamespace.PassedValidation = false;

function PreSaveAction() {
    if (!MyNamespace.StartedValidation) {
        // you might want to consider disabling the submit button
        // while the async stuff goes on so that they don't click
        // it again if it takes a sec to get the data from the server.

        // start your async process
        MyNamespace.DoAsyncStuff();

        // prevent the form from submitting
        // while the async stuff is happening
        return false;

    } else {
        if (MyNamespace.PassedValidation) {
            alert('Congrats!');
            return true;
        } else {
            // reset the flag that checks if validation
            // is happening, so they can make changes
            // and try to resubmit
            MyNamespace.StartedValidation = false;

            alert('Sorry, conflicting.');
            return false;
        }
    }
}

MyNamespace.DoAsyncStuff = function doAsyncStuff() {
    // turn on the flag that will tell
    // the PreSaveAction that you are doing the validation
    MyNamespace.StartedValidation = true;

    // do all the major work you were
    // doing in the PreSaveAction function
    // here, ending with
    $.getJSON(calendarUrl, function (data, status, xhr) {
        // do your validation...

        // set the global validation flag
        if (conflictFlag === true) {
            MyNamespace.PassedValidation = false;
        } else {
            MyNamespace.PassedValidation = true;
        }

        // now, here's the tricky part.
        // if you had disabled the submit button,
        // enable it now.  and whether you did or
        // didn't disable it, the next thing to do is
        // "re-click" it from code, which will 
        // re-trigger the PreSaveAction function
        // firing, and allow you to return from that
        // properly to control the form behavior
        $('selector-for-submit-button').click();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top