For this specific case, I based myself on one of our client's requests, which was "to create some sort of validation, when a user submits an item in a booking list".
There was a list indicating the stock of each item available for booking, so the approach was to request the number of items available (via ajax call) in the mentioned list and if that number was greater than "0", then the user should be able to make a booking.
Details:
Material field name : Material
Item availability list name : Item Availability
Booking list name: Material Bookings
Solution:
After the JSLink file being referenced in the list definition (Schema.xml), we can start developing our business logic.
- Adding the callback handler to the new form.
- In the "AddCallbackHandler" function we will have to:
- Get form context for current field
- Create a validator set to register the required validator and our custom validator
- Register our error callback
- Return the field default html (choice in this case) and a <span> tag which will contain our custom error message to be displayed when saving a new item is not allowed.
- Now let's define our custom validation
![]() |
I developed a separate function to get the results, just because we needed to make more than one call. Note: "async" was set to false, otherwise it would have to be promisified. |
- To finish, we just have to define what happens when an error occurs.
Find the full code below:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Add callback handler to new form | |
(function () { | |
var MaterialFieldCtx = {}; | |
MaterialFieldCtx.Templates = {}; | |
MaterialFieldCtx.Templates.Fields = { | |
"Material": { | |
"NewForm": AddCallbackHandler | |
} | |
}; | |
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(MaterialFieldCtx); | |
})(); | |
//Define handler | |
function AddCallbackHandler(ctx) { | |
var _materialField = SPClientTemplates.Utility.GetFormContextForCurrentField(ctx); | |
var fieldValidators = new SPClientForms.ClientValidation.ValidatorSet(); | |
if (_materialField.fieldSchema.Required) { | |
fieldValidators.RegisterValidator(new SPClientForms.ClientValidation.RequiredValidator()); | |
} | |
fieldValidators.RegisterValidator(new MyCustomFieldValidator()); | |
_materialField.registerValidationErrorCallback(_materialField.fieldName, onError); | |
_materialField.registerClientValidator(_materialField.fieldName, fieldValidators); | |
var returnHtml = SPFieldChoice_Edit(ctx) | |
returnHtml += "<span id='MyCustomFieldError' class='ms-formvalidation ms-csrformvalidation'></span>"; | |
return returnHtml; | |
} | |
//Custom validator logic | |
MyCustomFieldValidator = function () { | |
MyCustomFieldValidator.prototype.Validate = function (value) { | |
var availabilityListTitle = "Item Availability"; | |
var BookingListTitle = "Material Bookings"; | |
var initialStock = 0; | |
var isError = true; | |
//Initial Stock | |
var urlQueryStock = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('" + availabilityListTitle + "')/Items?$filter=Title eq '" + value + "'"; | |
var results = getResults(urlQueryStock); | |
initialStock = results[0].Number; | |
if(initialStock > 0 ) | |
{ | |
isError = false; | |
} | |
else | |
{ | |
isError = true; | |
} | |
var errorMessage = "There are no stock specified for the selected item. Item: " + value; | |
return new SPClientForms.ClientValidation.ValidationResult(isError, errorMessage); | |
}; | |
}; | |
//Get results array from ajax call | |
function getResults(qry){ | |
var result; | |
$.ajax({ | |
url: qry, | |
async: false, | |
method: "GET", | |
headers: { "Accept": "application/json; odata=verbose" }, | |
success: function (data) { | |
// parse the results | |
result = data.d.results; | |
}, | |
error: function (data) { | |
// an error occured. For this example I'm using an alert. | |
alert("An error has occured"); | |
} | |
}); | |
return result; | |
} | |
//On error | |
function onError(error) { | |
$("#MyCustomFieldError") | |
.html("<span role='alert'>" + error.errorMessage + "</span>"); | |
}; | |
Hope you find it useful ;)
No comments:
Post a Comment