SharePoint working with lookup dropdowns and getting values - javascript

I seem to have a little trouble getting a value to be returned from a dropdown lookup field. I've got the following code that gets me the values from the list I'm doing the lookup upon:
var siteUrl = _spPageContextInfo.webServerRelativeUrl;
function getDropdownValues(tempNumTitle) {
var clientContext = new SP.ClientContext(siteUrl);
var tempDropdownValueList = clientContext.get_web().get_lists().getByTitle('Temps');
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml('<View>' +
'<RowLimit>' +
'100' +
'</RowLimit>' +
'</View>');
this.tempQuery = tempDropdownValueList.getItems(camlQuery);
clientContext.load(tempQuery);
clientContext.executeQueryAsync(
// on success of getting Temp Values from dropdown
// match it with the tempNum entry
function (sender, args) {
var tempDropDownValues = {};
var tempEnumerator = tempQuery.getEnumerator();
while(tempEnumerator.moveNext()) {
var tempItem = tempEnumerator.get_current();
var tempTitle = tempItem.get_item('Title');
var tempId = tempItem.get_item('ID');
tempDropDownValues[tempTitle] = tempId;
}
selectTemp(tempNumTitle, tempDropdownValues)
},
// on failure
function (sender, args) {
console.info('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}
);
}
It performs this fine, giving me the dropdown values. It then calls the function selectTemp with the parameters of the tempNumTitle we are looking for, and the list of dropdown values retrieved. Here is the next function:
function selectTemp(tempNumTitle, tempValues) {
var clientContext = new SP.ClientContext(siteUrl);
var tempMatchValueList = clientContext.get_web().get_lists().getByTitle('Numbers-Temp');
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml('<View>' +
'<Query>' +
'<Where>' +
'<Eq>' +
'<FieldRef Name="Title" />' +
'<Value Type="Text">' + tempNumTitle + '</Value>' +
'</Eq>' +
'</Where>' +
'</Query>' +
'</View>');
this.tempMatchValueQuery = tempMatchValueList.getItems(camlQuery);
clientContext.load(tempMatchValueQuery);
clientContext.executeQueryAsync(
// on success
function (sender, args) {
var temp = '';
tempEnumerator = tempMatchValueQuery.getEnumerator();
while(tempEnumerator.moveNext()) {
var tempItem = tempEnumerator.get_current();
temp = tempItem.get_item('Temp0');
}
},
// on failure
function (sender, args) {
console.info('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}
);
}
It almost gets me what I'm looking for, but I get something like this:
temp: {$1E_1: 3, $2e_1: "Temp 3"}
Where I want the value of the $2e_1, or "Temp 3". How can I get that value, without just going temp["$2e_1"]?

When accessing a lookup column or a people picker column, the column value is a complex type rather than a simple string.
You can invoke .get_lookupValue() on the returned object to get a text representation of the lookup column's value, or .get_lookupId() to get the ID number of the corresponding item in the lookup list (or in the site collection's user information list in the case of a people picker column).
So in your case, assuming "Temp0" is the internal name of a lookup column, you should be able to do this:
temp = tempItem.get_item('Temp0').get_lookupValue();

Related

Issues attempting to display data from JSON file

Premise:
I'm playing around with javascript and have been trying to display a populated JSON file with an array of people on the browser. I've managed to display it through ajax, but now I'm trying to perform the same task with jQuery.
Problem:
The problem is that it keeps saying customerdata[i] is undefined and can't seem to figure out why.
$(function() {
console.log('Ready');
let tbody = $("#customertable tbody");
var customerdata = [];
$.getJSON("MOCK_DATA.json", function(data) {
customerdata.push(data);
});
for (var i = 0; i < 200; i++) {
//Cell for name
let nameTD = $('<td>').text(customerdata[i].first_name + ", " + customerdata[i].last_name);
//Cell for birthdate
let mDate = moment(customerdata[i].birthdate);
let formattedmDate = mDate.format('YYYY-MM-DD');
let birthdateTD = $('<td>').text(formattedmDate);
//Cell for Address
let addressTD = $('<td>').html("City: " + customerdata[i].city + '<br>' + "Email: " + customerdata[i].email + '<br>' + '<a href=' + customerdata[i].website + '>Website</a>');
//Cell for Credits
let creditTD = $('<td>').text(customerdata[i].credits);
let row = $('<tr>').append(nameTD).append(birthdateTD).append(addressTD).append(creditTD);
tbody.append(row);
}
})
SAMPLE CONTENT OF MOCK_DATA.json
[
{"id":1,"first_name":"Tracey","last_name":"Jansson","email":"tjansson0#discuz.net","gender":"Female","ip_address":"167.88.183.95","birthdate":"1999-08-25T17:24:23Z","website":"http://hello.com","city":"Medellín","credits":7471},
{"id":2,"first_name":"Elsa","last_name":"Tubbs","email":"etubbs1#uol.com.br","gender":"Female","ip_address":"61.26.221.132","birthdate":"1999-06-28T17:22:47Z","website":"http://hi.com","city":"At Taḩālif","credits":6514}
]
Firstly, you're pushing an array into an array, meaning you're a level deeper than you want to be when iterating over the data.
Secondly, $.getJSON is an asynchronous task. It's not complete, meaning customerdata isn't populated by the time your jQuery is trying to append the data.
You should wait for getJSON to resolve before you append, by chaining a then to your AJAX call.
$.getJSON("MOCK_DATA.json")
.then(function(customerdata){
for(var i = 0; i < 200; i++){
//Cell for name
let nameTD = $('<td>').text(customerdata[i].first_name + ", " + customerdata[i].last_name);
//Cell for birthdate
let mDate = moment(customerdata[i].birthdate);
let formattedmDate = mDate.format('YYYY-MM-DD');
let birthdateTD = $('<td>').text(formattedmDate);
//Cell for Address
let addressTD = $('<td>').html("City: " +
customerdata[i].city + '<br>' + "Email: " +
customerdata[i].email + '<br>' + '<a
href='+customerdata[i].website+'>Website</a>');
//Cell for Credits
let creditTD = $('<td>').text(customerdata[i].credits);
let row = $('<tr>').append(nameTD).append(birthdateTD).append(addressTD).append(creditTD);
tbody.append(row);
}
})
You also won't need to define customerdata as an empty array at all with this approach.
The problem is that data is already an array.
so you should use:
customerdata = data;
otherwhise you are creating an array in the pos 0 with all the data

SharePoint 2013 - JavaScript: Why isn't my CAML query filtering my list data?

I'm trying to display data from a list on my SharePoint 2013 site using JavaScript. I'm able to display the data from the list, but I'm also trying to filter that data using a CAML query. My code is working with no errors displayed, but it's displaying all of the items from the list instead of the filtered list of results that I'm expecting. Please see my code below and let me know if I'm doing anything wrong:
function GetListItemsFromSPList(listId) {
var context = new SP.ClientContext.get_current();
var web = context.get_web();
var list = web.get_lists().getById(listId);
var query = new SP.CamlQuery();
query.set_viewXml('<Query><Where><Eq><FieldRef Name=\'Title\' /><Value Type=\'Single line of text\'>CR1</Value></Eq></Where></Query>');
var queryResults = list.getItems(query);
context.load(queryResults);
context.executeQueryAsync(Function.createDelegate(this, function () { onQuerySuccess(queryResults); }),
Function.createDelegate(this, this.onQueryFailed));
}
function onQuerySuccess(allItems) {
var listItemInfo = '';
var ListEnumerator = allItems.getEnumerator();
while (ListEnumerator.moveNext())
{
var currentItem = ListEnumerator.get_current();
listItemInfo += '\nID: ' + currentItem.get_id() + ", Title: " + currentItem.get_item('Title') + ", ContractNo: " + currentItem.get_item('ContractNo');
}
alert(listItemInfo.toString());
}
function onQueryFailed(sender, args) {
alert('Error: ' + args.get_message() + '\n' + args.get_stackTrace());
}
The type of the column in your CAML query should be "Text" instead of "Single line of text". Try changing that line to:
query.set_viewXml('<View><Query><Where><Eq><FieldRef Name=\'Title\' /><Value Type=\'Text\'>CR1</Value></Eq></Where></Query></View>');

Making web form for updating data in Firebase

I am making an interface to manipulate data in Firebase. I managed to make a form that inserts new data, I have a list of retrieved data, the only thing that is missing is editing/updating existing data.
I am using Foundation 6 to speed up coding HTML and CSS and I created a modal that pops up when you click on a name. Also, I made that every name has a class that is their child key in Firebase so I can open data for the right item. I've stuck here and I don't know how to make that form in modal to fill data from clicked name. Can somebody help me a bit?
Here is my code:
var ref = new Firebase("https://myname.firebaseio.com/data/users");
ref.on("child_added", function(snapshot) {
var key = snapshot.key();
var data = snapshot.val();
var name = data.name;
var city = data.city;
$("#results").append($("<li class=\"" + key + "\">" + "<a data-open=\"modal\">" + name + ", " + city + "</a></li>"));
// this is for filling up the form with loaded data
$(".name").val(name);
$(".name").focus(function(){
$(this).val(name);
});
});
Try this:
var ref = new Firebase("https://myname.firebaseio.com/data/users");
var data;
ref.on('value', function(snapshot) {
data = snapshot.val();
$("#results").empty();
Object.keys(data).forEach(function(key) {
var value = data[key];
var name = value.name;
var city = value.city;
var li = $("<li class=\"" + key + "\">" + "<a data-open=\"modal\">" + name + ", " + city + "</a></li>");
$("#results").append(li);
li.click(function() {
$('#name').val(name);
$('#city').val(city);
$('#key').val(key);
});
});
});
$('form').submit(function() {
var key = $('#key').val();
var name = $('#name').val();
var city = $('#city').val();
data[key].name = name;
data[key].city = city;
ref.set(data);
return false;
});
JSFIDDLE

how to run javascript object from string without using eval()

i have a json object that has item type and id, i need to create new object
var data = {
"items":[
{"type":"generator","id":"item_1","x":200,"y":200},
{"type":"battery","id":"item_2","x":50,"y":300},
{"type":"generator","id":"item_3","x":200,"y":280},
{"type":"battery","id":"item_4","x":100,"y":400}
]
};
and i need to run for each item in items
jQuery.each(data.items, function(index,value) {
eval("var " + value.id + " = new " + value.type + "(" + (index + 1) + ");");
eval(value.id + ".id = '" + value.id + "';");
eval(value.id + ".draw(" + value.x + "," + value.y + ");")
});
this is not a good practice, but what else can i do?
i need then to have the control on the items
something like
item_1.moveto(300,700);
but i always get item_1 is undefind
You can create a factory method which allows to generate concrete types out of an abstract data structure:
var createItem = (function () {
var types = {};
function createItem(index, data) {
data = data || {};
var ctor = types[data.type], item;
if (!ctor) throw new Error("'" + data.type + "' is not a registered item type.");
item = new ctor(index);
item.id = data.id;
return item;
}
createItem.registerType = function (type, ctor) {
types[type] = ctor;
};
return createItem;
})();
Then register item types to the factory:
function Generator(index) {/*...*/}
createItem.registerType('generator', Generator);
And finally create an object map to lookup your items by id (you could use a specialized object like ItemsMap instead of a plain object), loop through your items and add them to the map.
var itemsMap = {};
data.items.forEach(function (itemData, i) {
var item = itemsMap[itemData.id] = createItem(i + 1, itemData);
//you can also draw them at this point
item.draw(itemData.x, itemData.y);
});
You can now lookup objects by id like:
var item1 = itemsMap['item_1'];
var objects = {};
objects[value.id] = new window[value.type](index + 1);

Changing the objectId thats returned in a query to that of the actual user

Using parse.com and JavaScript SDK.
This is what I'm attempting to achieve.
A list of users (friends) is returned on the page to the user, They can then click on one of these users and the page is updated to list all of that users items (which are basically images).
This query works correctly and returns a list of users.
var currentUser = Parse.User.current();
var FriendRequest = Parse.Object.extend("FriendRequest");
var query = new Parse.Query(FriendRequest);
query.include('toUser');
query.include('SentTo');
query.include("myBadge");
query.equalTo("fromUser", currentUser);
query.equalTo("status", "Request sent");
query.find({
success: function (results) {
var friends = [];
for (var i = 0; i < results.length; i++) {
friends.push({
imageURL: results[i].get('toUser').get('pic'),
friendRequestId: results[i].id,
username: results[i].get('toUser').get('username')
});
}
// TW: replaced dynamic HTML generation with wrapper DIV that contains IMG and name DIV
_.each(friends, function (item) {
// using a wrapper so the user can click the pic or the name
var wrapper = $('<div class="wrapper" data-friend-request-id="' + item.friendRequestId + '"></div>');
wrapper.append('<img class="images" src="' + item.imageURL + '" />');
wrapper.append('<div>' + item.username + '</div>');
$('#container').append(wrapper);
});
},
error: function (error) {
alert("Error: " + error.code + " " + error.message);
}
});
****This below query should contain the user who has selected above and stored in window.selectedFriendRequestId (which is saved in the variable friendRequest ****
This query looks at the myBadges class and the user reference "SentTo" the ref used is for example a3aePaphBF which is the actual _User objectID.
function FriendProfile() {
var friendRequest = "window.selectedFriendRequestId";
console.log(window.selectedFriendRequestId);
var myBadges = Parse.Object.extend("myBadges");
var query = new Parse.Query(myBadges);
query.equalTo("SentTo", friendRequest);
query.find({
success: function (results) {
// If the query is successful, store each image URL in an array of image URL's
imageURLs = [];
for (var i = 0; i < results.length; i++) {
var object = results[i];
imageURLs.push(object.get('BadgeName'));
}
// If the imageURLs array has items in it, set the src of an IMG element to the first URL in the array
for (var j = 0; j < imageURLs.length; j++) {
$('#imgs').append("<img src='" + imageURLs[j] + "'/>");
}
},
error: function (error) {
// If the query is unsuccessful, report any errors
alert("Error: " + error.code + " " + error.message);
}
});
}
The issue is that the first query is not returning an objectId that I can use in the second query as a reference. For example a3aePaphBF is not returned but cr3LG70vrF is.
How to I return the actual _User objectid in the first query so I can make these match?
To get the ID of a user:
results[i].get('toUser').id
So if you update your section of code that is doing friends.push(...):
friends.push({
imageURL: results[i].get('toUser').get('pic'),
friendRequestId: results[i].id,
username: results[i].get('toUser').get('username'),
userId: results[i].get('toUser').id
});
Then in your bit where you create the wrapper:
_.each(friends, function (item) {
// using a wrapper so the user can click the pic or the name
var wrapper = $('<div class="wrapper"'
+ ' data-friend-request-id="' + item.friendRequestId + '"'
+ ' data-to-user-id="' + item.userId + '"></div>');
wrapper.append('<img class="images" src="' + item.imageURL + '" />');
wrapper.append('<div>' + item.username + '</div>');
$('#container').append(wrapper);
});
Notice that I've added another data-property to hold the ID of the toUser.
Now if you followed the tips from your other question, you can tweak the code that attaches the on-click handler to pass toUserId also:
$('#container').on('click', '.wrapper', function () {
var wrapper = $(this);
var friendRequestId = wrapper.data('friendRequestId');
var toUserId = wrapper.data('toUserId');
FriendProfile(friendRequestId, toUserId);
// other code ...
});
Lastly your FriendProfile() function can now use either of those parameters as needed:
function FriendProfile(friendRequestId, toUserId) {
var toUser = new Parse.User();
toUser.id = toUserId;
var myBadges = Parse.Object.extend("myBadges");
var query = new Parse.Query(myBadges);
query.equalTo("SentTo", toUser);
// ... etc ...
}
NOTE: The User class should be locked down for privacy reasons, you shouldn't be able to read any properties of other users except in Cloud Code when you have the following line in your Cloud Function:
Parse.Cloud.useMasterKey();

Categories

Resources