20

I'm customizing the NewForm of a list item and need to trigger the default form validation from my JavaScript, but I don't want the form to be submitted, since I'm doing that in a callback later on.

Is this possible to do? I've tried searching on the SPClientForms object and in particular SPClientForms.ClientValidation and SPClientForms.ClientFormManager but I can't find out if I can trigger it.

8

At least two options are available when it comes to client side validation in SharePoint 2013:

  • Client-Side Rendering (CSR) Validation
  • Override Save handler using PreSaveAction function

Assume the scenario where we need to add client side validation for Email column in the Contacts list.

Client-Side Rendering (CSR) Validation in SharePoint 2013

CSR is a default rendering mode in SharePoint 2013. SPClientForms.ClientValidation namespace contains Validation API and includes common . Below is demonstrated how to override default Text Field client validation and add custom validator for Email field:

CustomClientValidation = {};
CustomClientValidation.EmailValidator = function() {
};
CustomClientValidation.EmailValidator.prototype.Validate = function(value) {
    value = SPClientTemplates.Utility.Trim(value);

    var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    var hasError = !re.test(value);
    var errorMsg = hasError ? 'Invalid email address' : '';

    return new SPClientForms.ClientValidation.ValidationResult(hasError, errorMsg);
};


function EmailField_Edit(rCtx) {
    if (rCtx == null)
        return '';
    var formCtx = SPClientTemplates.Utility.GetFormContextForCurrentField(rCtx);

    if (formCtx == null || formCtx.fieldSchema == null)
        return '';

    var _value = formCtx.fieldValue != null ? formCtx.fieldValue : '';      

    if (_value.length > 0) {
        var validators = new SPClientForms.ClientValidation.ValidatorSet();
        validators.RegisterValidator(new CustomClientValidation.EmailValidator());
        formCtx.registerClientValidator(formCtx.fieldName, validators);
    }

    return SPFieldText_Edit(rCtx); //default renderer for Text field
}


(function () {
    var emailFieldCtx = {};
    emailFieldCtx.Templates = {};
    emailFieldCtx.Templates.Fields = {
        'Email': {
            'NewForm': EmailField_Edit,
            'EditForm': EmailField_Edit
        }
    };

    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(emailFieldCtx);
})();

CustomClientValidation.js

Usage:

Specify JavaScript file location using JSLink property

Override Save handler using PreSaveAction function

PreSaveAction function from another hand, allows to override behavior for a Save button.

Below is demonstrated how to add Email validation for Email field:

function validateEmail(email) { 
    var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return re.test(email);
} 


function PreSaveAction(){

    var email = $('[id ^=Email_][id $=TextField]');
    if (!validateEmail(email.val())) {
        var errorHtml = '<span class="ms-formvalidation"><span role="alert">Invalid email address<br></span></span>';
        email.after(errorHtml);
        return false;
    }
    return true;
};

Usage:

JavaScript file could referenced in New/Edit form page using Content Editor web part.

Results

New/Edit form page enter image description here

  • 4
    Thanks for the answer, but this isn't what I wanted either. I know I could always write the validation myself, but I just wanted to know if it was possible to trigger the default one, but I guess not – stinaq Mar 14 '14 at 15:26
7

You can't trigger the form validation through javascript, however you can do something else.

In both the New form and the Edit form the Save button has onclick which triggers PreSaveItem() which is a function in FORMS.js that invokes a function called PreSaveAction which is a user defined function, meaning it is a function you define and decide what should do. Preferably placed inside the New/Edit form directly to perform validation in the specific form.

It's manual, yes, but at least you don't need to bind a click event to a button. It's already there, all you have to do is supply the logic.

Update
To get the correct fields using this method, you can use the function getTagFromIdentifierAndTitle which takes 3 arguments; Type ("input", "select" etc), FieldType ("DateTimeFieldDate" etc - may be left blank), Display name ("Title", "My Column" etc)

Example:

function PreSaveAction(){
    var col = getTagFromIdentifierAndTitle('input', '', 'Title');
    if (col == '') {
        alert(col.value + " is required!");
        return false;
    }
    return true;
};
  • 2
    I haven't tried it yet, but I'm guessing that this means I have to for example check required input boxes for myself? The problem with that is that the markup is full of guid-ids = I have trouble finding the elements, and even more trouble checking which ones are required (plus the complexity of different types of inputs, such as select, textbox and radiobutton) and I need a dynamic checking since the fileds are not always the same. What I need is the default check so I don't have to find all the elements! – stinaq Mar 13 '14 at 12:56
  • @stinaq You could make some javascript which iterates through the DOM of the form and combine it with my update. – user2536 Mar 13 '14 at 13:16
  • 1
    Yes, but this also means that I have to write the validation myself, so I guess it's not possible to do what I want. – stinaq Mar 14 '14 at 15:24
2

If you are using SharePoint 2013 with new standard rendering (CSR) call the following method to trigger default validation: SPClientForms.ClientFormManager.SubmitClientForm('WPQ2').

I'm not sure if the WPQ2 is constant. Such suffix is added to the many elements in DOM, so it won't be hard to check. For example: id="MSOZoneCell_WebPartWPQ2".

2

Late to the party, I found the following solution that appears to do the trick

// force PostBackRequired to true in the context, otherwise it won't work if you open it into a modal
WPQ2FormCtx.PostBackRequired=true;
// we override SPClientForms.ClientFormManager.SubmitClientForm
SPClientForms.ClientFormManager.SubmitClientForm=function(b){
  var a=SPClientForms.ClientFormManager.GetClientForm(b);
  var res = (a!=null&&a.SubmitClientForm());
  // if the form is not valid, then res===true
  if (res === true) {
    return true;
  } else {
    // Do your custom things here
    // Send the form to the server
    WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions($get(WPQ2FormCtx.SubmitButtonID).name, "", true, "", "", false, true));
  }
  // to make sure the form won't be submitted yet
  return true;
};

From https://blog.kodono.info/wordpress/2016/11/18/execute-action-before-saving-a-form-and-after-form-validation-sharepoint/

  • Really like this solution. Unfortunately the SubmitClientForm() validations are only for required fields? Column validations and data type don't seem to be handled at this step. – Rothrock May 3 at 20:00
1

SP behaviour is little bit strange. If you change value of some field, SP invoke validation, but no message is displayed. Problem is that SP has in file clientforms.js:

this.NotifyControlEvent = function(eventName, fldName, eventArg) { ...
  case SPClientForms.FormManagerEvents.Event_OnControlValueChanged:
    UpdateAndValidateControlValue(fldName, eventArg, false);
  ...
}

function UpdateAndValidateControlValue(fName, fVal, bDisplayError) {
  ...
  ValidateControlValue(fName, fVal, bDisplayError);
}

So when value is changing function UpdateAndValidateControlValue(fldName, eventArg, false); is called, but no validation message is displayed.

But when the form is submiting, this function is called with true parameter and valiadation messages is displayed.

I wasn't able to inject this script to change this weird behaviour.

But if you have access to clientforms.js in file system, you can easily change it. To change all SP behaviour you can simply change false to true in function NotifyControlEvent. But I would recomend you to use some input parameter, so you can specify which field will have onchanged validation.

this.NotifyControlEvent = function(eventName, fldName, eventArg) {
  ...
  case SPClientForms.FormManagerEvents.Event_OnControlValueChanged:
      //this.customFieldSettings is custom property of  SPClientForms.ClientForm, which you have to fill
      if (this.customFieldSettings !== undefined &&
          this.customFieldSettings[fldName] != undefined && 
          this.customFieldSettings[fldName].onchangeValidation == true) 
      {
          UpdateAndValidateControlValue(fldName, eventArg, true);
      } else {
          UpdateAndValidateControlValue(fldName, eventArg, false);
      }
  return;

I Hope it will help and lead to simpler solution.

0

Try

if (SPClientForms.ClientFormManager.SubmitClientForm('WPQ2')) return false;

i didn't got a chance to look what 'WPQ2' means...but this worked for me...

  • 2
    SPClientForms.ClientFormManager.SubmitClientForm('WPQ2') always returns true, how can this be of any help? And also "WPQ2" is the form unique id which you can get at ctx.FormUniqueId – Memphis335 Feb 8 '17 at 12:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.