I have requirement in ServiceNow application that user has manager and that manager has another manager so i'am getting New Manager ( field in table) managers and storing in array.
I am trying to match that If login user ( user logged in ServiceNow) is one of the New Manager managers
Script:
var NewReportsTo ='';
NewReportsTo = current.variables.new_manager;
var item = [];
for ( var i =1 ; i<=6;i++){
NewReportsTo = NewReportsTo.manager;
var Newmanager = NewReportsTo.toString();
item.push(Newmanager);
//var list = item.split(',');
gs.log('Check ACL:'+Newmanager, 'TEST ACL TCR');
if(item.indexOf(gs.getUserID())){
gs.log('Check ACL:'+current.sys_id, 'TEST ACL INSIDE TCR');
answer = true;
}
}
getUserID() is the login user and item array has all the manager for New manager field
Array.indexOf() returns the first index at which the given item can be found in the array, or -1 if it's not found.
You should change your code to:
if(item.indexOf(gs.getUserID() != -1)){
...
}
Related
I have two lists: Products and Suppliers.
In Products, i have 3 columns :
-Name of Product (single line of text)
-Supplier (lookup of Suppliers : Name of Supplier)
-Price (choice list)
In Suppliers, i have 3 columns too :
-Name of Supplier (single line of text)
-Product (lookup of Products : Name of Product)
-Category (choice list)
Actually, in the .js linked to Product (list), i'm using this code to get the informations of the list Suppliers
var oList = clientContext.get_web().get_lists().getByTitle('Suppliers');
But it's hardcoded and i have to dynamise the code so i will be able to apply this code to other lists.
For example:
var NameOfList = "code to get the name of the list which is linked by the lookup (in my case it's the list Suppliers)";
var ColumnsOfList = "NameOfList.getAllColumns (in my case it's Name of Supplier, Product, Category)";
var oList = clientContext.get_web().get_lists().getByTitle(NameOfList);
var txt = [];
txt.push('The list ' + NameOfList + ' has those columns : ');
for(i=0 ; i<ColumnsOfList.length ; i++){
txt.push(ColumnsOfList[i]);
}
alert(txt);
It will display The list Suppliers has those columns : Name of Supplier, Product, Category.
So, i would like to know which code or function to use for retrieve the listname and columns of the list which is linked by lookup. In my case, i would like to get "Suppliers" as listname and "Name of Supplier, Product, Category" as columns name.
Can someone help me please ?
EDIT :
enter image description here
You can get the details of the lookup column by retrieving it from the field collection using SPList.get_fields().getByInternalNameOrTitle(), invoking executeQueryAsync(), and then examining the lookup column's schema XML (via the SPField.get_schemaXml() method).
From the column's schema XML you can grab the lookup column's source list and run another executeQueryAsync() to load up its field collection so you can get the names of all its fields.
Here's an example of how your code might appear.
var listName = "Products";
var lookupColumn = "Supplier";
var clientContext = new SP.ClientContext();
var list = clientContext.get_web().get_lists().getByTitle(listName);
// get a reference to the lookup field on the current list
var lookupField = list.get_fields().getByInternalNameOrTitle(lookupColumn);
// queue up the lookup field for retrieval
clientContext.load(lookupField);
clientContext.executeQueryAsync(
function(){
// get the lookup list GUID from the lookup column's schema XML:
var lookupListId = lookupField.get_schemaXml().match(/List=(.*?)(?!\S)/g)[0].match(/[^List="][^"]*/)[0];
// get references to the lookup list and its field collection
var lookupList = clientContext.get_web().get_lists().getById(lookupListId);
var lookupListFields = lookupList.get_fields();
// queue up the lookup list and field collection for retrieval
clientContext.load(lookupList);
clientContext.load(lookupListFields);
clientContext.executeQueryAsync(
function(){
var lookupListName = lookupList.get_title();
var fieldNames = [];
// enumerate through the field collection to get the field names
var fieldEnum = lookupListFields.getEnumerator();
while(fieldEnum.moveNext()){
var field = fieldEnum.get_current();
fieldNames.push(field.get_title());
}
doSomethingWithListAndFieldNames(lookupListName,fieldNames);
},
function(sender,args){alert(args.get_message());}
);
},
function(sender,args){ // onError
alert(args.get_message());
}
);
Replace doSomethingWithListAndFieldNames() with your own function.
Getting only the fields from the default view:
If you only want the fields that display in the default view of the lookup list, you need to do a little extra work to query the views of the lookup list and look for the default view, then get the view fields from that view.
var listName = "Products"; // original list title
var lookupColumn = "Supplier"; // lookup column name
var clientContext = new SP.ClientContext();
var list = clientContext.get_web().get_lists().getByTitle(listName);
// get a reference to the lookup field on the current list
var lookupField = list.get_fields().getByInternalNameOrTitle(lookupColumn);
// queue up the lookup field for retrieval
clientContext.load(lookupField);
clientContext.executeQueryAsync(
function(){
// get the lookup list GUID from the lookup column's schema XML:
var lookupListId = lookupField.get_schemaXml().match(/List=(.*?)(?!\S)/g)[0].match(/[^List="][^"]*/)[0];
// get reference to the lookup list
var lookupList = clientContext.get_web().get_lists().getById(lookupListId);
// queue up the lookup list for retrieval
clientContext.load(lookupList);
clientContext.executeQueryAsync(
function(){
var lookupListName = lookupList.get_title();
// get the views on the list
var views = lookupList.get_views();
// queue up the viewsfor retrieval
clientContext.load(views);
clientContext.executeQueryAsync(
function(){
// loop through the views until you find the default view
var viewEnum = views.getEnumerator();
while(viewEnum.moveNext()){
var view = viewEnum.get_current();
if(view.get_defaultView()){
// retrieve the fields from the view
var lookupListFields = view.get_viewFields();
clientContext.load(lookupListFields);
clientContext.executeQueryAsync(
function(){
var fieldNames = [];
// enumerate through the field collection to get the field names
var fieldEnum = lookupListFields.getEnumerator();
while(fieldEnum.moveNext()){
fieldNames.push(fieldEnum.get_current());
}
doSomethingWithListAndFieldNames(lookupListName,fieldNames);
},
function(sender,args){alert(args.get_message());}
);
break;
}
}
},
function(sender,args){alert(args.get_message());});
},
function(sender,args){alert(args.get_message());}
);
},
function(sender,args){ // onError
alert(args.get_message());
}
);
I am using parse.com as my back end.
I am using containedIn query to retrieve multiple user rows from parse "User" table.
My problem is that I am not able to get user's object Id in the success block
following is my code:
r_userIdList= ['PzpdRdKTVZ','PoJdRdKTVU','fvdRdKTVX'];
var query = new Parse.Query("_User");
query.containedIn("objectId", r_userIdList); // returns multiple rows
query.find({
success: function(r_uobject) {
var userObjId ,fName,lName,full_Name="Unknown User";
for(var i =0; i<r_uobject.length;i++){
var r_obj = r_uobject[i];
uID = r_obj.get('objectId');//not working
var u = uID.id;//not working
fName = r_obj.get('firstName');
lName = r_obj.get('lastName');
full_Name = firstName+' '+lastName;
r_userIdList[u].fullName = full_Name; //not working
}
}
});
Once I enter in the success block, I am unable to identify that which user's data has been retrieved.
Actually I need user's ObjectId because I have array called r_userIdList in which I need to store the firstName and LastName of user as Object.
IDs can usually be accessed with .id - in your case r_obj.id. Your uID.id won't work as uID is itself going to be undefined.
You also need to check that you are getting any results back at all: does r_userIdList have a length?
On CRM 2013 I'm trying to insert multiple participants into the email "to" field when users click on "Reply All". However I need to remove certain email addresses from the To line. So I created an array to loop and get all the email addresses except the one that needs to be removed.
However the problem here is that it only works if there is only one participant left after removing the unwanted participants. If there are two or more participants the script will not populate any participants at all.
Is there a way to populate multiple email participants? Or is there a better approach than what I'm trying to do here?
Here's my code:
var toParty = Xrm.Page.getAttribute("to").getValue();
var partyListArray = new Array();
for (var indxAttendees = 0; indxAttendees < toParty.length; indxAttendees++) {
// using oData to get participant email address
var email = getParticipantEmail(
toParty[indxAttendees].entityType,
toParty[indxAttendees].id
);
if (email != "test#test.com") {
partyListArray[indxAttendees] = new Object();
partyListArray[indxAttendees].id = toParty[indxAttendees].id;
partyListArray[indxAttendees].name = toParty[indxAttendees].name;
partyListArray[indxAttendees].entityType = toParty[indxAttendees].entityType;
}
}
Xrm.Page.getAttribute("to").setValue(null);
Xrm.Page.getAttribute("to").setValue(partyListArray);
Instead of creating a whole new array, you can delete what you want from the array itself. Try this:
var emails = [{email: "add1#domain.com"}, {email: "add2#domain.com"}, {email: "address#toBe.Removed"}, {email: "add3#domain.com"}, {email: "add4#domain.com"}];
var removeIndex = emails.map(function(item) { return item.email; }).indexOf("address#toBe.Removed");
removeIndex > -1 && emails.splice(removeIndex, 1);
I've been trying to 'correlate' between user picked answers and an object property name so that if the two matches then it will display what is inside.
My program is a recipe finder that gives back a recipe that consists of the ingredients the user picked.
my code currently looks like:
//property are the ingredients and the value are the recipes that contain those ingredients. The map is automatically generated
``var map = {
"pork" : [recipe1, recipe2, ...],
"beef" : [],
"chicken" :[],
}
//this gets the user pick from the dom
var cucumber = specificVegetable[7];
var lemon = specificFruits[0];
//Then this code finds the intersection of the recipe(recipes that use more than one ingredients)
function intersect(array1, array2)
{
return array1.filter(function(n) {
return array2.indexOf(n) != -1
});
}
var recipiesWithLemon = map["lemon"]; **// makes the lemon object is map**
var recipiesWithCucumber = map["cucumber"]; **// makes the cucumber object in map**
//Here is where I am stuck
function check(){
var both = intersect(recipiesWithLemon, recipiesWithCucumber);
if ( cucumber.checked && lemon.checked){
for (var stuff in map){
if(stuff="cucumber" && stuff="lemon"){
return both;
}
}
}
}
check();
so basically what I tried to do was I made my intersect and then if user pick is lemon and cucumber then look at the properties in the map object. if the name of the property equals to the exact string then return both. That was the plan but the code does not work and I'm not sure how to fix it.
My plan is to write code for every possible outcome the user may makes so I need to find the correlation between the user pick and the map which stores the recipe. I realize this is not the most effective way but I'm stumped on how to do it another way.
Thanks for the help.
Im using the open source project jinqJs to simplify the process.
I also changed your map to an array of JSON objects. If you must have the map object not as an array, let me know. I will change the sample code.
var map = [
{"pork" : ['recipe1', 'recipe2']},
{"beef" : ['recipe3', 'recipe4']},
{"peach" :['recipe5', 'recipe6']},
{"carrot" :['recipe7', 'recipe8']}
];
var selectedFruit = 'peach';
var selectedVeggie = 'carrot';
var selections = [selectedFruit, selectedVeggie];
var result = jinqJs().from(map).where(function(row){
for(var f in row) {
if (selections.indexOf(f) > -1)
return true;
}
return false;
}).select();
document.body.innerHTML += '<pre>' + JSON.stringify(result, null, 2) + '</pre><br><br>';
<script src="https://rawgit.com/fordth/jinqJs/master/jinqjs.js"></script>
In my web app , i am using jquery ui autocomplete which data are stored in the database (Mysql).
In this application, i have the administration official data And i enable the users to enter their own data. Data will be displayed in the autocomplete drop down list .
The administration data are limited and never change thus are preloaded and cached in memory, however the user data aren't (since user data grows exponentially and there is no point of using a database if all is to be cached in memory).
So i am doing multi levels caching in my web app, of which, i am caching autocomplete's user data on the client side (instead of getting them from db on each search).
The scenario is as follow:
When the app loads, the admin data (that are preloaded in memory) are loaded and cached in a JS object to be used in the autocomplete mechanism.
Thus when a user searches for a word, it will check the admin data JS object and if it can't find it, it will go to db and find it in user data.
So for the case of searching user's data in db, What i am doing right now is the following:
$( "#search" ).autocomplete({
source:function(request, response) {
var results = $.ui.autocomplete.filter(data, request.term);
if (request.term.toUpperCase() in autocomplete_cache) {
response($.map(autocomplete_cache[request.term.toUpperCase()], function(item) {
return {value: item.members.name, md5: item.members.ID}
}))
return;
}
where autocomplete_cache is a javascript object:
var autocomplete_cache = {};
// ...it gets filled everytime a new $.post gets new data
...autocomplete_cache[request.term.toUpperCase()] = data;
For the moment, it is caching the exact term searched by a user.
For example, if a user writes "ABCD" and which is not already cached :
--> go to the database (MySQL) do :"WHERE term Like %ABCD%"
--> autocomplete_cache["ABCD"] = "data parsed from mysql"
So if the same USER now retypes "ABCD" it will get it from the autocomplete_cache Object. However if the USER type "ABC" it won't get it from the cache object because of the line:
if (request.term.toUpperCase() in autocomplete_cache)
So what i would like to do is to match what the User types in the cache, so in this scenario if the User types "ABC" (which is contained in cache's "ABCD" String) , the autocomplete will build a drop down list containing "ABCD".
Is there a way of doing that? the reason for this requirement instead of finding the exact String index in the cache object , it will find a wider range and thus limit probabilities of needing to go to db to find the new matches.
Instead of looking for a specific key, test each key whether the term is a substring:
var term = request.term.toUpperCase();
for (var key in autocomplete_cache) {
if (key.indexOf(term) > -1) {
// term is contained in key
}
}
And instead of calling response on the first match, collect all matches’ items in an additional array and call response at the end:
var term = request.term.toUpperCase(),
items = [];
for (var key in autocomplete_cache) {
if (key.indexOf(term) > -1) {
items.merge($.map(autocomplete_cache[key], function(item) {
return {value: item.members.name, md5: item.members.ID}
});
}
}
if (items.length > 0) response(items);
You might also want to remove any duplicates in items and sort the resulting items before calling response:
var term = request.term.toUpperCase(),
items = [],
index = {};
for (var key in autocomplete_cache) {
if (key.indexOf(term) > -1) {
$.each(autocomplete_cache[key], function(item) {
var id = item.members.ID;
if (!index[id]) {
items.push({value: item.members.name, md5: item.members.ID});
index[id] = true;
}
});
}
}
items.sort(function(a, b) { return a.name.localeCompare(b.name); });
if (items.length > 0) response(items);