Here I'd like to demonstrate the most popular cases you may face during implementation of SharePoint forms with complex logic. Most likely you will need to combine the cases described below to cover your requirements but it's quite easy if you have enough samples. To accomplish the tasks below I used SharePoint Forms Designer 2.8.10. All samples work properly for all editions of SharePoint 2010/2013 including Foundations and Office 365.
First of all, I'd like to make an important notice which is common for all the cases. fd.field() method of JavaScript framework expects an internal name of a field you want to retrieve. As you might know, it's not easy enough to obtain an internal name of a field in SharePoint, so we included this property into field properties in Forms Designer 2.8.10:
Now you can just copy and paste it into your code in a much simpler way even without closing Forms Designer. OK, let me start.
Prepopulate field and disable/enable it based on condition
Let's say we have a task form and we need to set the Percent Complete to 100% and disable it when the user turns the Status field into Completed:
We should place the following code into JS-editor of Forms Designer:
function setPercentComplete() { if (fd.field('Status').value() == 'Completed') { // Setting the Percent Complete to 100 fd.field('PercentComplete').value('100'); // Getting JQuery-object of the field and disable it fd.field('PercentComplete').readonly(true); } else { // Getting JQuery-object of the field and enable it fd.field('PercentComplete').readonly(false); } } // Calling setPercentComplete when the user changes the status fd.field('Status').change(setPercentComplete); // Calling setPercentComplete on form loading setPercentComplete(); // Enabling fields before the submission fd.onsubmit(function () { fd.field('PercentComplete').readonly(false); return true; });
Please, pay attention to the last part of the code:
// Enabling fields before the submission fd.onsubmit(function () { fd.field('PercentComplete').readonly(false); return true; });
Most browsers don’t send values of disabled fields to the server during the submission, so they will be lost. Therefore, we need to enable all fields that we need to save right before the submission in onsubmit handler.
Hide/show field or set of fields conditionally
Now I will modify the script from the previous section so that it will hide the Percent Complete field. First, we should assign a CSS-class to the field to use it in JQuery-selector:
OK, now we can use it to retrieve the field container by the following way: $('.percent-complete'). Here is the modified code:
function setPercentComplete() { if (fd.field('Status').value() == 'Completed') { // Setting the Percent Complete to 100 fd.field('PercentComplete').value('100'); // Getting JQuery-object of the field container and hide it $('.percent-complete').hide(); } else { // Getting JQuery-object of the field container and show it $('.percent-complete').show(); } } // Calling setPercentComplete when the user changes the status. fd.field('Status').change(setPercentComplete); // Calling setPercentComplete on form loading setPercentComplete();
Please, notice that I've removed the last part from the code because values of hidden fields are passed to the server properly.
What if we need to hide multiple fields? There are several approaches. You can either put them into a single table and assign CSS-class to the table:
Next, use that class in JQuery-selector to retrieve the table and hide or show it:
// Hide the table $('.fields-to-hide').hide(); // Show the table $('.fields-to-hide').show();
Or if your fields are scattered about the form and you cannot put them into a single table, you can assign the same CSS-class to all fields that you need to hide e.g. 'field-to-hide' and use it in the selector to make all of them disappear:
$('.field-to-hide').hide();
Require field based on condition
At this section I'd like to demonstrate how to make some fields mandatory based on other field values. Let's go back to the original task form and say that we need to make the Due Date field required if the task is assigned to someone (the Assigned To field is not empty).
Here is the sample:
function setRequiredFields() { if (fd.field('AssignedTo').value().dictionaryEntries.length != 0) { // Add asterisks fd.field('DueDate').titleRequired(true); } else { // Remove asterisks fd.field('DueDate').titleRequired(false); } } // Calling setRequiredFields when the user changes the assignment fd.field('AssignedTo').change(setRequiredFields); // Calling setRequiredFields on form loading setRequiredFields(); // Custom validation fd.onsubmit(function () { if (fd.field('AssignedTo').value().dictionaryEntries.length != 0) { if (!fd.field('DueDate').value()) { alert('Please, fill in the Due Date field.'); return false; } } return true; });
As you can see, I've added the custom validation into onsubmit handler, whereas fd.field().titleRequired() just adds or removes the asterisk near the title.
Get values on display forms
Finally, I'd like to focus your attention on differences between display and edit or new forms. Display forms don't contain controls, so you can retrieve only the text representation of field values like you see them on a form. The samples above work on new and edit forms only. You should use the following syntax to obtain a text representation of values on a display form:
fd.field('Status').control()._el().text()
Get information on how to get or set values of different types of fields from the following article: http://formsdesigner.blogspot.com/2013/04/getting-and-setting-sharepoint-form.html
Please, feel free to ask your questions in comments.
Thank you for posting this article. I appreciate the foundational nature of it and the additional examples. Adding the internal name field to the designer is a great addition and will come in handy. I would love to see more foundational based blog posts that help give more detail about the Forms Designer API.
ReplyDeletethanks
-schuess
I have a Choice field with allowed 'Fill-in' choices. What would be the code to make it required and validate? I tried code in a sample but it doesn't work for 'Fill-in' values.
ReplyDeleteYou can make a field mandatory in the field settings. But you can retrieve its value via JavaScript as well. Please, specify what kind of choice you use: drop-down, checkboxes or radio buttons.
DeleteIt becomes mandatory only under certain conditions so I can't use field settings. I'm using drop-down.
ReplyDeleteOk, thanks. Please, try the following code:
Deletefd.onsubmit(function() {
if (
fd.field('Choice').control()._el().find('input[type="radio"]:eq(0)').prop("checked") && !fd.field('Choice').value() ||
fd.field('Choice').control()._el().find('input[type="radio"]:eq(1)').prop("checked") && !fd.field('Choice').control()._el().find('input[type="text"]').val()
) {
alert('Please, fill-in the Choice field.');
return false;
}
return true;
});
This comment has been removed by the author.
ReplyDeleteHi Dmitry,
ReplyDeleteWe have a field that we want editable (Progress on a task) only if the current user is equal to the "Assigned To" field (Render is set to Client). What is the javascript code that we can use? Many thanks in advance.
I'd recommend to use our groups functionality to create separate forms for assignees based on the condition:
DeleteContainsCurrentUser([Assigned To])
http://spform.com/documentation/groups
But if you still want to use JavaScript, you need to get the current user's login as demonstrated in the following post:
http://formsdesigner.blogspot.com/2013/03/how-to-create-dynamic-forms-with-forms.html
And compare it with the 'Assigned To' field value:
http://formsdesigner.blogspot.com/2013/04/getting-and-setting-sharepoint-form.html
Hi Dmitry,
DeleteMust have been a typo on my end but the ContainsCurrentUser works now for us, so agreed, that it is the easier approach to go with groups.
Hey Dmitry,
ReplyDeleteIs there any way to conditionally make a lookup field mandatory? In my case, I have a lookup field that by default is "(None)" (no default value). I want the user to choose an option from the lookup drop-down, validating that "(None)" is not selected.
I cannot simply make the field mandatory as I have some JavaScript in place for cascading drop-downs on these lookup fields, making them mandatory breaks the cascading code.
Any help would be appreciated.
Hi Mitch,
DeleteSure, you can check a field value in the onsubmit handler and require a user fill in it:
fd.onsubmit(function() {
if (fd.field('LookupField').value() == 0) {
alert('Please, fill-in the lookup field');
return false;
}
return true;
});
That worked, thanks!
Deletewhere in the cascading script does this new script go? Thanks
DeleteHI - I have the same scenario as Mitch Gates where I need to add another condition to make a look up mandatory if an option is selected, the above existed, I am using a similar script as below:
DeleteIn the below example, how can I add another condition under on submit condition:
function setRequiredFields() {
if (fd.field('AssignedTo').value().dictionaryEntries.length != 0) {
// Add asterisks
fd.field('DueDate').titleRequired(true);
} else {
// Remove asterisks
fd.field('DueDate').titleRequired(false);
}
}
// Calling setRequiredFields when the user changes the assignment
fd.field('AssignedTo').change(setRequiredFields);
// Calling setRequiredFields on form loading
setRequiredFields();
// Custom validation
fd.onsubmit(function () {
if (fd.field('AssignedTo').value().dictionaryEntries.length != 0) {
if (!fd.field('DueDate').value()) {
alert('Please, fill in the Due Date field.');
return false;
}
}
return true;
});
Hello Dimity,
ReplyDeleteDo we use the same syntax fd.field('DueDate').show()/hide() for display forms or do we use fd.field? thank you
Hey Dmitry,
ReplyDeleteHow about looking up to see if a date field is populated (any value) on a display form? I'd like to hide the field on display form if no date is populated.
This comment has been removed by the author.
ReplyDeleteHi,
ReplyDeleteI checked this with this Look Up field.
My look up field name is Cases.
When alert the valueof look field , it displays the ID not the value in the look up.
alert(fd.field('Cases1').value());
it prints Value as 1. But my exact value is Accident. 1 is its ID. How can I get the text?
alert(fd.field('Cases1').text()); I tried this also. But it returns an error
Hi,
DeletePlease, read the post
Its working ...
ReplyDeleteThank You Dmitry :)
Hi !
ReplyDeleteOne of my required fields is managed metadata. Can you please help me with syntax? I was trying to use
fd.field('FieldName').control()._el().find('.ms-taxonomy').value()
fd.field('FieldName').control()._el().find('.ms-taxonomy').value() == ""
fd.field('FieldName').control()._el().find('.ms-taxonomy').length !=0
but the check is not done for this field.
I entered the code, and it is working properly. However, Both the starting field and the conditional fields are displayed in a tab. When I add the Jaascript, the tabs on the form are no longer appearing. Do I need to add something to have the tabs re-appear on the form again?
ReplyDeleteHi, is it possible to hide a related items field while a lookup is empty, and then display the related items when the lookup if filled? The related items don't have a place for an internal name.
ReplyDeleteThanks.