Sometimes there is a requirement to fetch the SharePoint taxonomy term sets programmatically. So, how to get SharePoint taxonomy terms programmatically using JSOM ?
Here is a way to fetch SharePoint taxonomy terms using JavaScript code:
$(document).ready(function () {
ExecuteOrDelayUntilScriptLoaded(function () {
SP.SOD.registerSod('sp.taxonomy.js', "/_layouts/15/sp.taxonomy.js");
SP.SOD.executeFunc('sp.taxonomy.js', false, Function.createDelegate(this, function () {
var context = SP.ClientContext.get_current();
var taxonomySession = SP.Taxonomy.TaxonomySession.getTaxonomySession(context);
var termStore = taxonomySession.get_termStores().getByName("Taxonomy_qeFlDdEX32yZ3Q7EpEIeMQ==");
var termSet = termStore.getTermSet("ed6d3beb-6a49-4444-bc5d-456f747e139d");
var terms = termSet.getAllTerms();
context.load(terms);
context.executeQueryAsync(Function.createDelegate(this, function (sender, args) {
var termsEnumerator = terms.getEnumerator();
var menuItems = new Array();
while (termsEnumerator.moveNext()) {
var currentTerm = termsEnumerator.get_current();
var targetGroups = document.getElementById("selectTaxonomy");
var taxoGroup = document.createElement("option");
taxoGroup.text = currentTerm.get_name();
targetGroups.add(taxoGroup);
}
}), Function.createDelegate(this, function (sender, args) {
alert('The error has occured: ' + args.get_message());
}));
}));
},"sp.js")
});
Related
I am trying to push values into an array as follows, but it is showing as an empty array. Alerting works. I am sure I am missing something obvious. Any clues? I have included the code with the just the array push attempt and another entry of code that has working alerts.
$scope.termsArray = [];
execOperation();
function execOperation() {
//Current Context
var context = SP.ClientContext.get_current();
//Current Taxonomy Session
var taxSession = SP.Taxonomy.TaxonomySession.getTaxonomySession(context);
//Term Stores
var termStores = taxSession.get_termStores();
//Name of the Term Store from which to get the Terms.
var termStore = termStores.getByName("Taxonomy_111111111111");
//GUID of Term Set from which to get the Terms.
var termSet = termStore.getTermSet("12345-55-689");
var terms = termSet.getAllTerms();
context.load(terms);
context.executeQueryAsync(function () {
var termEnumerator = terms.getEnumerator();
while (termEnumerator.moveNext()) {
var currentTerm = termEnumerator.get_current();
$scope.termsArray.push({
termName: currentTerm.get_name(),
termGUID: currentTerm.get_id(),
termSynonyms: 'Coming Soon'
});
}
}, function (sender, args) {
console.log(args.get_message());
});
}
Here is the code with working alerts:
function execOperation() {
//Current Context
var context = SP.ClientContext.get_current();
//Current Taxonomy Session
var taxSession = SP.Taxonomy.TaxonomySession.getTaxonomySession(context);
//Term Stores
var termStores = taxSession.get_termStores();
//Name of the Term Store from which to get the Terms.
var termStore = termStores.getByName("Taxonomy_111111111111");
//GUID of Term Set from which to get the Terms.
var termSet = termStore.getTermSet("12345-55-689");
var terms = termSet.getAllTerms();
context.load(terms);
context.executeQueryAsync(function () {
var termEnumerator = terms.getEnumerator();
var termList = "Terms: \n";
while (termEnumerator.moveNext()) {
var currentTerm = termEnumerator.get_current();
$scope.termsArray.push({
termName: currentTerm.get_name(),
termGUID: currentTerm.get_id(),
termSynonyms: 'Coming Soon'
});
termList += currentTerm.get_id() + currentTerm.get_name() + "\n";
}
alert(termList);
}, function (sender, args) {
console.log(args.get_message());
});
}
Here is the HTML output:
<div> {{termsArray}}</div>
It returns []
Update: If I click in an input box and back out, or click an alert and hit ok, it then loads the array instead of loading on page load.
I was able to track the issue down. It appears that Angular doesn't respect non-Angular functions on load, so I needed to wrap the $scoped array in a $scope.apply. Please see here for details: Execute SharePoint Function On Page Load in AngularJS Application ($scope issue???)
I'm creating a sharepoint hosted app which is based on javascript only. I wanted to update a multivalue taxonomy field in a list so I wrote this function which didn't work. there is a very little support for javascript csom online.
var list = context.get_web().get_lists().getByTitle('Company');
var item = list.getItemById(2);
var field = list.get_fields().getByInternalNameOrTitle("Departments");
var taxField = context.castTo(field, SP.Taxonomy.TaxonomyField);
var terms = new SP.Taxonomy.TaxonomyFieldValueCollection(context,
'Unit 1|5bf47d1f-d890-49d1-a844-85628ca508fd;#Unit 4|334ad23d-d2d8-4acb-ab09-38d2bacb97d4',
taxField);
taxField.setFieldValueByValueCollection(item, terms);
item.update();
context.load(taxField);
context.executeQueryAsync(
function() {
console.log('field updated');
});
I also used this code
var list = context.get_web().get_lists().getByTitle('Company');
var item = list.getItemById(2);
item.set_item('Departments', 'Unit 1|5bf47d1f-d890-49d1-a844-85628ca508fd;Unit 4|334ad23d-d2d8-4acb-ab09-38d2bacb97d4');
item.update();
context.executeQueryAsync(
function() {
console.log('field updated');
});
You must include a fake wssid (lookup id) prefix to the value. Below is a code I use to set a multiple value term field from jsom in the app model. This works.
function SetManagedMetaDataField() {
appweburl = decodeURIComponent(getQueryStringParameter('SPAppWebUrl'));
hostweburl = decodeURIComponent(getQueryStringParameter('SPHostUrl'));
context = new SP.ClientContext(appweburl);
factory = new SP.ProxyWebRequestExecutorFactory(appweburl);
context.set_webRequestExecutorFactory(factory);
appContextSite = new SP.AppContextSite(context, hostweburl);
var list = appContextSite.get_web().get_lists().getByTitle('Documents');
var item = list.getItemById(5);
var field = list.get_fields().getByInternalNameOrTitle("Cars");
var taxField = context.castTo(field, SP.Taxonomy.TaxonomyField);
var terms = new SP.Taxonomy.TaxonomyFieldValueCollection(context,
'-1;#ATS|9f3e8e20-593b-471d-a145-81ff8664fd96;#-1;#CTS|8b18f6df-22be-4548-92b4-8f240d8fbfe5',
taxField);
taxField.setFieldValueByValueCollection(item, terms);
item.update();
context.load(taxField);
context.executeQueryAsync(
function () {
alert('field updated');
}, function (sender,args) {
alert(args.get_message() + '\n' + args.get_stackTrace());
});
}
I am trying to create one function that can handle all the data that is sent to the page to build google charts in different points on the page. The first think that I am doing is properly setting up the data array that the chart will use. That is ok. The issue that I am having is when the prdocess gets to the "google.visualization.arrayToDataTable([data])" the error I receive is "google.visualization is undefined". Any help with what I may be doing wrong will be appreciated.
//$(document).ready(function () {
var chart_pie = $('.chart-pie');
var dataObj = [];
var Chart = {} || [];
//console.log(chart_pie);
google.load('visualization', '1.0', {'packages':['corechart']});
// Set a callback to run when the Google Visualization API is loaded.
// google.setOnLoadCallback(Chart.draw_chart);
var chartColors = ['#f0ca41','#c97038', '#14425c', '#3d799d', '#625e79'];
var pieHeight = 300;
var pieWidth = 400;
var columnHeight = 230;
var columnWidth = 775;
Chart = {
init: function () {
this.pie_chart();
},
pie_chart: function () {
chart_pie.each(function () {
var chartID = $(this).attr('id');
chartID = chartID.replace('chart-', '');
console.log(chartID +': '+ JSON.stringify(chart_data[chartID]));
Chart.populate_object(chart_data[chartID], chartID);
google.setOnLoadCallback(Chart.draw_chart(dataObj[chartID]));
// console.log(JSON.stringify(chart_data[chartID]));
});
},
populate_object: function (obj, chartID) {
for (var i=0;i<obj.length;i++) {
dataObj[obj.chartID] = [obj[i].Label, obj[i].Value];
}
},
draw_chart: function (data) {
var chartData = google.visualization.arrayToDataTable([data]);
var options = {'title':chart_data[chartID].title,
'width':pieWidth,
'height':pieWidth,
borderColor: '#ffffff',
'colors': chartColors};
var chart = new google.visualization.PieChart(document.getElementById('chart-' + chartID));
chart.draw(chartData, options);
}
};
Chart.init();
// });
If some one has a function that they created to handle this type of operation for google charts please share.
Your callback is not valid:
google.setOnLoadCallback(Chart.draw_chart(dataObj[chartID]));
Is actually invoking your draw_chart method, so its being called before onLoad has been triggered. You would need to do something like this:
google.setOnLoadCallback(function () {
Chart.draw_chart(dataObj[chartID]);
});
I am having a lot of trouble with this. Essentially, I am trying to count the number of times Decommission appears in a particular list column. From what I can tell, the javascript is correct, but it doesn't work. Can anyone provide some guidance? Thanks!
<script type="text/javascript">
var myItems = null;
var siteUrl = 'https://chartiscorp.sp.ex3.secureserver.net/'
function SuperDuper()
{
var queryString = '<View><Query><Where><Gt><FieldRef name="End State" /><Value Type="String">Decommission</Value></Gt></Where></Query></View>';
var myContext = new SP.ClientContext(siteUrl);
var myWeb = myContext.get_web();
var myList = myWeb.get_lists().getByTitle('System_Information');
var myQuery = new SP.CamlQuery();
myQuery.set_viewXml(queryString);
myItems = myList.getItems(myQuery);
myContext.load(myItems,'Includes(End State)');
myContext.executeQueryAsynch(Function.createDelegate(this,SuperDuperSuccess),Function.createDelegate(this,SuperDuperFail));
}
function SuperDuperFail(sender, args)
{
alert('Failed ' + args.get_message());
}
function SuperDuperSuccess(sender, args)
{
var endStateEnumerator = myItems.getEnumerator();
var decommCount = 0;
while(endStateEnumerator.moveNext())
{
//var currentEndState = endStateEnumerator.get_current();
decommCount = decommCount + 1;
}
alert(decommCount);
}
window.onload = SuperDuper;
</script>
What is the error?
Have you tried to see the script error it is throwing?
In function SuperDuperSuccess() you can simply put
var count=0;
count=this.myItems.get_count();
No need to write while loop .
Pls try to put alert and after some line and see what is coming.
I am working with the Sharepoint Client Object Model using javascript and looking to make as much of my code as reusable as possible.
Examples of using the COM usually looks like this with a call and then a success delegate function to output the results.
function loadProfile()
{
var context = SP.ClientContext.get_current();
var web = context.get_web();
var userInfoList = web.get_siteUserInfoList();
camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml('');
this.listItems = userInfoList.getItems(camlQuery);
context.load(listItems);
context.executeQueryAsync(Function.createDelegate(this, this.onProfileSuccessMethod), Function.createDelegate(this, this.onFail));
}
function onProfileSuccessMethod(sender, args)
{
var item = listItems.itemAt(0);
var first_name = item.get_item('FirstName');
var last_name = item.get_item('LastName');
alert(first_name + " " + last_name);
}
function onFail(sender, args)
{
alert('Error: ' + args.get_message() + '\n' + args.get_stackTrace());
}
What I am trying to achieve is being able return the values after instantiating an object but given that it is asynchronous I am not sure how this is possible, would I need to "listen" for the call to complete before values are returned.
Would it be something like this? Or can you not have a delegate function internal to the function it creates it from. Apologies for my limited understanding!
var profile = new loadProfile("testid");
alert(profile.onProfileSuccessMethod());
function loadProfile (id)
{
this.user_id = id;
var context = SP.ClientContext.get_current();
var web = context.get_web();
var userInfoList = web.get_siteUserInfoList();
camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml('');
this.listItems = userInfoList.getItems(camlQuery);
context.load(listItems);
context.executeQueryAsync(Function.createDelegate(this, this.onProfileSuccessMethod), Function.createDelegate(this, this.onFail));
this.onProfileSuccessMethod = function()
{
var item = listItems.itemAt(0);
this.first_name = item.get_item('FirstName');
this.last_name = item.get_item('LastName');
return this.first_name
};
}
If it is asynchronous, it is impossible to return values from it. You need to use a callback pattern.
function secondStep(data){
console.log(data)
}
var profile = new loadProfile("testid", secondStep);
and
function loadProfile (id, callback)
...
this.onProfileSuccessMethod = function(){
callback({});
}