I was asked to add additional columns to a SharePoint “Out Of The Box (OOTB) calendar list with the aim of allowing the end user to complete each field in an orderly fashion.
The default field allows the user to reveal child fields based on the value of the previous field.
The fields in essence have a hierarchical structure. I decided to use a dropdown field (at least at the first two levels) to allow the user to jump from one selection to another. The last level can be any type of field. Before writing code, I executed the following steps,
- Create a “.html” file.
- Create a list (any type). In this case, I’m working with a Calendar list.
- In this list, I created four columns using the list settings. The column names are;
- “Type of Events”
- “Festivals”
- “Parties”
- “Galas”
- Add a Content Editor Web Part (CEWP) to the NewForm.aspx and EditForm.aspx files of your list.
- Edit each page, by editing the CEWP and inserting a link to your html file in the “Content Link” part of the Content Editor box and Click the “OK” or “Apply” button.
Note
You’ll require some experience with JavaScript to get through this article.
As far as the contents of the html file, I am not going to describe the css part of the code as it is not the scope of this article. You can take a look at that part of the file in more detail. The JavaScript part of the file is the most important. This is the part of the file that performs the magic. Within the <script> tag, at the top I declared my global variables as follows,
-
-
-
- var txtTypesOfEvents = "Type of Events";
- var txtFestivals = "Festivals";
- var txtParties = "Parties";
- var txtGalas = "Galas";
-
-
- var fldLocation = {}
- var fldTypesOfEvents = {}
- var fldFestivals = {}
- var fldParties = {}
- var fldGalas = {}
-
-
- var inputLocation = {}
- var selectTypesOfEvents = {}
- var selectFestivals = {}
- var selectParties = {}
- var selectGalas = {}
Now, I will use the document-ready method to execute my jQuery. The document ready event fires before all images etc. are loaded, but after the whole DOM itself is ready. The ready event occurs when the DOM (document object model) has been loaded. Because this event occurs after the document is ready, it is a good place to have all other jQuery events and functions. The ready() method specifies what happens when a ready event occurs. The ready() method should not be used together with <body onload="">.
- $(document).ready(function(){
-
- selectTypesOfEvents = $("select[title='" + txtTypesOfEvents + "']");
-
- selectFestivals = $("select[title='" + txtFestivals + "']");
-
- selectParties = $("select[title='" + txtParties + "']");
-
- inputGalas = $("input[title='" + txtGalas + "']");
-
-
- fldTypesOfEvents = selectTypesOfEvents.closest('tr');
-
- fldFestivals = selectFestivals.closest('tr');
-
- fldParties = selectParties.closest('tr');
-
- fldGalas = inputGalas.closest('tr');
-
-
- if (selectFestivals.val() == "" || selectFestivals.val() == 0) {
- fldFestivals.hide();
- }
- if (selectParties.val() == "" || selectParties.val() == 0) {
- fldParties.hide();
- }
- if (inputGalas.val() == "") {
- fldGalas.hide();
- }
-
-
- selectTypesOfEvents.change(function() {
-
- if ($(this).val() == txtFestivals) {
- fldFestivals.show();
- fldParties.hide();
- fldGalas.hide();
- }
- if ($(this).val() == txtParties) {
- fldFestivals.hide();
- fldParties.show();
- fldGalas.hide();
- }
- if ($(this).val() == txtGalas) {
- fldFestivals.hide();
- fldParties.hide();
- fldGalas.show();
- }
-
- });
-
- selectFestivals.change(function() {
- if ($(this).val() == "Wireless") {
- alert("This is an outdoor event, please come early and bring your umbrella in case it rains!");
- }
-
- });
-
- });
Note
If you select Yes to “Require that this column contains information:” in the list settings, for OOTB field validation, i.e. making that field mandatory – your jQuery will not work. You will have to implement custom validation through JavaScript.
Implementing custom validation was more tricky than expected. I searched Google and read a few articles and blog posts, and tried a few things until I got it to work. The best way, perhaps the only way I know how to achieve custom validation using JavaScript is to make use the “PreSaveAction()” method in the form’s newform.aspx or editform.aspx form. This works on SharePoint Online, 2016, 2013.
In the below code, firstly I got the value of the “Title” field – by SharePoint field value id. That is the really long string of characters starting with the “#” symbol. You can find this id using your browser developer tool.
-
- function PreSaveAction() {
- console.log('PreSaveAction loaded');
-
-
- var fldTitleNew = $('#ctl00_ctl41_g_98d75819_9fcb_451b_87d4_c513b39997e4_ctl00_ctl05_ctl00_ctl00_ctl00_ctl05_ctl00_ctl00_TextField').val();
- console.log('Title field on new', fldTitleNew);
-
-
- var fldTitleEdit = $('#ctl00_ctl41_g_fda4b637_35d6_4a94_b15e_205d2e23e04a_ctl00_ctl05_ctl00_ctl00_ctl00_ctl05_ctl00_ctl00_TextField').val();
- console.log('Title field on Edit', fldTitleEdit);
-
-
- if ((fldTitleNew == "") || (fldTitleEdit != undefined && fldTitleEdit == "")) {
- alert("A value for 'Title' is required!");
- $("p").text("A value for 'Title' is required!");
- $('#ctl00_ctl41_g_98d75819_9fcb_451b_87d4_c513b39997e4_ctl00_ctl05_ctl00_ctl00_ctl00_ctl05_ctl00_ctl00_TextField').parent().append("<p class='error-msg'>A value for 'Title' is required!</p>");
- $('#ctl00_ctl41_g_98d75819_9fcb_451b_87d4_c513b39997e4_ctl00_ctl05_ctl00_ctl00_ctl00_ctl05_ctl00_ctl00_TextField').focus();
- console.log("A value for 'Title' is required!");
- return false;
- }
-
-
- if (selectTypesOfEvents.val() == "" || selectTypesOfEvents.val() == 0) {
- alert("A value for 'Type of Event' is required!");
- $('#ctl00_ctl41_g_98d75819_9fcb_451b_87d4_c513b39997e4_ctl00_ctl05_ctl08_ctl00_ctl00_ctl05_ctl00_DropDownChoice').parent().append("<p class='error-msg'>A value for 'Type of Event' is required!</p>");
- $('#ctl00_ctl41_g_98d75819_9fcb_451b_87d4_c513b39997e4_ctl00_ctl05_ctl08_ctl00_ctl00_ctl05_ctl00_DropDownChoice').focus();
- console.log("A value for 'Type of Event' is required!");
- return false;
-
-
- } else if (selectTypesOfEvents.val() == txtFestivals && selectFestivals.val() == "") {
- alert("A value for 'Festivals' is required!");
-
- $('#ctl00_ctl41_g_98d75819_9fcb_451b_87d4_c513b39997e4_ctl00_ctl05_ctl09_ctl00_ctl00_ctl05_ctl00_DropDownChoice').parent().append("<p class='error-msg'>A value for 'Festivals' is required!</p>");
- $('#ctl00_ctl41_g_98d75819_9fcb_451b_87d4_c513b39997e4_ctl00_ctl05_ctl09_ctl00_ctl00_ctl05_ctl00_DropDownChoice').focus();
- console.log("A value for 'Festivals' is required!");
- return false;
-
-
- } else {
- if (selectTypesOfEvents.val() == txtParties && selectParties.val() == "") {
- alert("A value for 'Parties' is required!'");
- $('#ctl00_ctl41_g_98d75819_9fcb_451b_87d4_c513b39997e4_ctl00_ctl05_ctl10_ctl00_ctl00_ctl05_ctl00_DropDownChoice').parent().append("<p class='error-msg'>A value for 'Parties' is required!</p>");
- $('#ctl00_ctl41_g_98d75819_9fcb_451b_87d4_c513b39997e4_ctl00_ctl05_ctl10_ctl00_ctl00_ctl05_ctl00_DropDownChoice').focus();
- console.log("A value for 'Parties' is required!");
- return false;
-
-
- } else if (selectTypesOfEvents.val() == txtGalas && inputGalas.val() == "") {
- alert("A value for 'Galas' is required!");
- $('#ctl00_ctl41_g_98d75819_9fcb_451b_87d4_c513b39997e4_ctl00_ctl05_ctl11_ctl00_ctl00_ctl05_ctl00_ctl00_TextField').parent().append("<p class='error-msg'>A value for 'Galas' is required!</p>");
- $('#ctl00_ctl41_g_98d75819_9fcb_451b_87d4_c513b39997e4_ctl00_ctl05_ctl11_ctl00_ctl00_ctl05_ctl00_ctl00_TextField').focus();
- console.log("A value for 'Galas' is required!");
- return false;
- }
- }
-
- return true;
- }
In the above code, I’ve commented the code to explain what is going on. As you can see, I am using both an alert and text on the page to warn the user but both aren’t necessary. My preference is using just text (which fade out). When the user Click the “Save” button, and any of the fields are blank, the user will be alerted as shown in the below images.
Figure 1: Validate “Title” field – warning text appended to it
Figure 2: Validate “Festivals” field – warning text appended to it and alert text