Hello Every one. In this blog we are going to implement the multi level cascade drop down in SharePoint new and edit forms with the help of Rest Api.
We no need to create multiple list to store the source data. We can keep all the hierarchy of the data in a single list as shown below.
We have a master list in which we are storing the Country, State, City and District as a lookup column from the above list.
Now add the following code in the default new form and edit form.
<script type="text/javascript" src="jquery-1.12.0.min.js"></script>
<script type="text/javascript" src="cascadeDropdownPlugin.js"></script>
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery.fn.cascadeDropdownPlugin.Methods._init({
parentListTitle: "Custom Cascade",
sourceFields: "Title,State,City,District",
destinationFields: ["Country lookup", "State lookup", "City lookup", "District lookup Required Field"]
});
});
</script>
In the above code
jQuery.fn.cascadeDropdownPlugin.Methods._init({
parentListTitle: Source List title
sourceFields: <<Internal Name>>. These are the columns which we are going to lookup in the master list. Basically these are the columns that is in the Source List. This field should be in comma separated,
destinationFields: <<Display Name>>.These are the fields that is in the master list. This should be in an array format.
});
If there is any required field then we have to append "Required Field" in the end of the display name. For example "District lookup" is a column in the master list. If we made the field required then the name should became "District lookup Required Field" while passing into the function.
With this code we can use 'n' number of cascade drop-downs.
The source field sequence and the destination field sequence should be in the same order. For example
The destinationFields should maintain the same order as in the sourceFields.
The result will be looking like the below image.
Please find the code below for the cascadeDropdownPlugin.js
We no need to create multiple list to store the source data. We can keep all the hierarchy of the data in a single list as shown below.
We have a master list in which we are storing the Country, State, City and District as a lookup column from the above list.
<script type="text/javascript" src="jquery-1.12.0.min.js"></script>
<script type="text/javascript" src="cascadeDropdownPlugin.js"></script>
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery.fn.cascadeDropdownPlugin.Methods._init({
parentListTitle: "Custom Cascade",
sourceFields: "Title,State,City,District",
destinationFields: ["Country lookup", "State lookup", "City lookup", "District lookup Required Field"]
});
});
</script>
In the above code
jQuery.fn.cascadeDropdownPlugin.Methods._init({
parentListTitle: Source List title
sourceFields: <<Internal Name>>. These are the columns which we are going to lookup in the master list. Basically these are the columns that is in the Source List. This field should be in comma separated,
destinationFields: <<Display Name>>.These are the fields that is in the master list. This should be in an array format.
});
If there is any required field then we have to append "Required Field" in the end of the display name. For example "District lookup" is a column in the master list. If we made the field required then the name should became "District lookup Required Field" while passing into the function.
With this code we can use 'n' number of cascade drop-downs.
The source field sequence and the destination field sequence should be in the same order. For example
The result will be looking like the below image.
Please find the code below for the cascadeDropdownPlugin.js
(function ($) {
jQuery.fn.cascadeDropdownPlugin = jQuery.fn.cascadeDropdownPlugin || {};
var sourceData = [];
var input = [];
jQuery.fn.cascadeDropdownPlugin.ServiceCalls = {
getSourceFieldsValues: function (options) {
if (options.parentListTitle == undefined || options.sourceFields == undefined || options.destinationFields == undefined)
alert("Message from cascade plugin : The Input JSON is not in correct format");
else {
input = options;
jQuery.ajax({
url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/GetByTitle('" + options.parentListTitle + "')/items?$select=Id," + options.sourceFields,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
if (data.d.results != undefined) {
sourceData = data.d.results;
jQuery.fn.cascadeDropdownPlugin.logic.removeOptions(options.destinationFields);
jQuery.fn.cascadeDropdownPlugin.logic.addCustomAttribute(options.destinationFields);
jQuery.fn.cascadeDropdownPlugin.logic.addOptions(sourceData, options);
jQuery.fn.cascadeDropdownPlugin.logic.bindChangeEvent(options.destinationFields);
}
},
error: function (msg) {
alert("Message from cascade plugin : " + JSON.parse(msg.responseText).error.message.value);
}
});
}
}
}
jQuery.fn.cascadeDropdownPlugin.logic = {
addOptions: function (sourceData, options) {
var template = "<option value='[val]'>[display]</option>";
var sourceFields = options.sourceFields.split(',');
var firstElement = jQuery("select[title='" + options.destinationFields[0] + "']");
var lookup = {};
var items = sourceData;
var temp = [];
for (var item, i = 0; item = items[i++];) {
var name = item[sourceFields[0]]
if (!(name in lookup)) {
lookup[name] = 1;
jQuery(template.replace('[val]', item.Id).replace('[display]', name)).appendTo(firstElement);
}
}
},
removeOptions: function (fields) {
var destinationFields = fields;
for (var i = 0; i < destinationFields.length; i++) {
jQuery("select[title='" + destinationFields[i] + "'] option").remove();
jQuery("<option value='0'>None</option>").appendTo(jQuery("select[title='" + destinationFields[i] + "']"));
}
},
addCustomAttribute: function (fields) {
var destinationFields = fields;
for (var i = 0; i < destinationFields.length; i++) {
jQuery("select[title='" + destinationFields[i] + "']").attr('data-cascade', i);
}
},
changeEvent: function (e) {
var selectedText = e.target.selectedOptions[0].text;
var selectedValue = e.target.selectedOptions[0].value;
var ctrlNo = Number(e.target.getAttribute("data-cascade"));
var ctrls = input.destinationFields;
if (ctrls.length - 1 == ctrlNo) {
for (var i = 0; i < ctrls.length - 1; i++) {
jQuery("select[title='" + ctrls[i] + "'] option:selected").val(selectedValue);
}
}
else {
var template = "<option value='[val]'>[display]</option>";
var sourceFields = input.sourceFields.split(',');
var nthElement = jQuery("select[title='" + ctrls[ctrlNo + 1] + "']");
for (var k = ctrlNo + 1; k < ctrls.length; k++) {
jQuery("select[title='" + ctrls[k] + "'] option").remove();
jQuery("<option value='0'>None</option>").appendTo(jQuery("select[title='" + ctrls[k] + "']"));
}
var lookup = {};
var items = sourceData;
var temp = [];
for (var item, i = 0; item = items[i++];) {
if (item[sourceFields[ctrlNo]] == selectedText) {
var name = item[sourceFields[ctrlNo + 1]]
if (!(name in lookup)) {
if (name != undefined) {
lookup[name] = 1;
jQuery(template.replace('[val]', item.Id).replace('[display]', name)).appendTo(nthElement);
}
else
break;
}
}
}
}
},
bindChangeEvent: function (fields) {
var destinationFields = fields;
for (var i = 0; i < destinationFields.length; i++) {
jQuery("select[title='" + destinationFields[i] + "']").change(this.changeEvent);
}
}
}
jQuery.fn.cascadeDropdownPlugin.Methods = {
_init: function (options) {
jQuery.fn.cascadeDropdownPlugin.ServiceCalls.getSourceFieldsValues(options);
}
}
})(jQuery);