Get User/Group Permissions for List using javascript(ecmascript) - javascript

I am trying to use the javascript object model to retrieve a list of users/groups for a list and their permissions at the list level. So far I have this which returns a member object but I cant get any information about the member. When I try to use rAssignment.get_member().get_id(), or rAssignment.get_member().get_title() I get an error.
//Get List Permissions
function getListPerms() {
var clientContext = new SP.ClientContext();
var siteColl = clientContext.get_site();
var site = clientContext.get_web();
listSecurableObject = site.get_lists().getByTitle($("[name='ListSlct']").val());
listRoleAssignments = listSecurableObject.get_roleAssignments();
clientContext.load(listRoleAssignments);
clientContext.executeQueryAsync(Function.createDelegate(this, this.getListPerms_onQuerySucceeded),Function.createDelegate(this, this.getListPerms_onQueryFailed));
}
function getListPerms_onQuerySucceeded() {
var listPerms="";
listPerms += '<table border="1">';
listPerms += '<tr>';
listPerms += '<td align="center">ID</td>';
listPerms += '</tr>';
var listPermsEnumerator = this.listRoleAssignments.getEnumerator();
while (listPermsEnumerator.moveNext()) {
var rAssignment = listPermsEnumerator.get_current();
listPerms += '<tr>';
listPerms += '<td align="center">' + rAssignment.get_member() + '</td>';
listPerms += '</tr>';
}
listPerms += '</table>';
document.getElementById('listPermsTable').innerHTML = listPerms;
}
function getListPerms_onQueryFailed(sender, args) {
alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}

Try changing your clientContext.load() function call as follows:
clientContext.load(listSecurableObject, 'Include(RoleAssignments, RoleAssignments.Include(Member))');
Now in the getListPerms_onSucceeded() method you ought to be able to enumerate through listSecurableObject.get_roleAssignments() and get the members similar to how you're already doing it (although you'll probably want to use rAssignment.get_member().get_loginName() ).

Related

$.getJSON and for loop with an array and how to get them to work together - for loop completes before JSON is returned

I am trying to cycle through an array and with each value in the array, use $.getJSON to return some JSON and populate an HTML table with the return values.
I have been following this post, but seem not get this to work:
$.getJSON calls misbehaving inside a for loop
Here is my function:
$("#selectProviderTop").click(function() {
var restURL = window.location.protocol + "//" + window.location.hostname + (window.location.port == "" ? "" : (":" + window.location.port)) + "/restGetProvider/";
var selected = [];
var providerKey;
var providerID;
var providerLegacyID;
var providerName;
var finalURL;
var tr;
// First, create an array from the User Provider Keys...
var userProviderKeys = $("#hiddenUserProviderKeys").val();
selected = userProviderKeys.split(",");
console.log("selected: " + selected);
var tableHTML = "";
var focus = $("<div></div>"); // either match an existing element or create one: '<div />'
var arrayLength = selected.length;
for (var i = 0; i < arrayLength; i++) {
(function(i) {
console.log("i: " + i);
providerKey = selected[i];
console.log("providerKey: " + providerKey);
// Get that provider and populate the table...
finalURL = restURL + providerKey;
console.log("finalURL: " + finalURL);
focus.queue('apicalls', function(next) {
$.getJSON(finalURL, function(jsonObject) {
tableHTML += "<tr>";
tableHTML += "<td><a href=\"#\" onclick='selectProvider(\"" + providerKey + "\")'>" + jsonObject["providerName"] + "</a></td>";
tableHTML += "<td>" + jsonObject["providerID"] + "</td>";
tableHTML += "<td>" + jsonObject["providerLegacyID"] + "</td>";
tableHTML += "</tr>";
console.log("tableHTML: " + tableHTML);
next();
});
});
})(i);
}
// Replace table’s tbody html with tableHTML...
console.log("final tableHTML: " + tableHTML);
$("#tableProviderSelect tbody").html(tableHTML);
$('#modalSelectProviderForPTP').modal('show');
});
The userProviderKeys value is 0be32d8057924e718a8b6b4186254756,2dc5f826601e4cc5a9a3424caea4115f
The code never makes the $.getJSON call it just completes the for loop.
How do I update this code to get the first value in the array, grab the JSON, create the HTML, and then cycle through the loop?
I have tried setTimeout but that didn't help me out.
If you have some ideas, could you update my existing code - I understand better when I see the code itself. Thanks.
I don't know why you're doing this using queues. But you are, so I'm not going to rewrite your code to do it some other way.
The last few lines need to be called after all the queued functions have run, which means they should be called asynchronously. (Yes, you could make the whole thing synchronous as Marcus Höglund suggested, but that's no way to write scalable applications in javascript.) You could do this by adding another function to the queue containing these lines. Like this:
$("#selectProviderTop").click(function() {
var restURL = window.location.protocol + "//" + window.location.hostname + (window.location.port == "" ? "" : (":" + window.location.port)) + "/restGetProvider/";
var selected = [];
var providerKey;
var providerID;
var providerLegacyID;
var providerName;
var finalURL;
var tr;
// First, create an array from the User Provider Keys...
var userProviderKeys = $("#hiddenUserProviderKeys").val();
selected = userProviderKeys.split(",");
console.log("selected: " + selected);
var tableHTML = "";
var focus = $("<div></div>"); // either match an existing element or create one: '<div />'
var arrayLength = selected.length;
for (var i = 0; i < arrayLength; i++) {
(function(i) {
console.log("i: " + i);
providerKey = selected[i];
console.log("providerKey: " + providerKey);
// Get that provider and populate the table...
finalURL = restURL + providerKey;
console.log("finalURL: " + finalURL);
focus.queue('apicalls', function(next) {
$.getJSON(finalURL, function(jsonObject) {
tableHTML += "<tr>";
tableHTML += "<td><a href=\"#\" onclick='selectProvider(\"" + providerKey + "\")'>" + jsonObject["providerName"] + "</a></td>";
tableHTML += "<td>" + jsonObject["providerID"] + "</td>";
tableHTML += "<td>" + jsonObject["providerLegacyID"] + "</td>";
tableHTML += "</tr>";
console.log("tableHTML: " + tableHTML);
next();
});
});
})(i);
}
focus.queue('apicalls', function(next) {
// Replace table’s tbody html with tableHTML...
console.log("final tableHTML: " + tableHTML);
$("#tableProviderSelect tbody").html(tableHTML);
$('#modalSelectProviderForPTP').modal('show');
next();
});
});
Edit: Sunshine has pointed out that the linked stackoverflow post has mysterious references to the .dequeue method. In the accepted answer, this method is called explicitly after the tasks have been queued. I don't know whether this was necessary or not. I had thought that the problem was that the $.json bit wasn't happening until after the $("#tableProviderSelect tbody").html(tableHTML); part. But now I realise you wrote: "The code never makes the $.getJSON call it just completes the for loop." In that caseSunshine may have been right, and you need to add focus.dequeue('apicalls'); just after the last focus.queue(...);.

Display JSON data in tablular format of predefined format

I am working on a small project's interface. Basically, an API sends the following JSON data:
{
"wallet_transactions": [
{
"total_cost": "80.000",
"expense_type__name": "Gas",
"total_quantity": "5.000",
"trans_type": "Purchased"
},
{
"total_cost": "250.000",
"expense_type__name": "Gas",
"total_quantity": "35.000",
"trans_type": "Rent"
}
]}
The data basically shows how much of GAS was given, its cost and its means (on credit or it was bought).
I tried to build a table out of it directly, but it was dimmed unfriendly since GAS was written twice.
What I tried was:
$.each(response.wallet_transactions, function(index) {
var exp_name=response.wallet_transactions[index].expense_type__name;
var quantity=response.wallet_transactions[index].total_quantity;
var price=response.wallet_transactions[index].total_cost;
var trans_type=response.wallet_transactions[index].trans_type;
rows=rows+'<tr><td>' + exp_name + '</td>';
rows=rows + '<td>' + price + '</td>';
rows=rows + '<td>' + quantity + '</td>';
rows=rows + '</tr>';
});
The output that is needed now looks like the image below:
Group the data for each name together in another object, then build the table from that.
var table_data = {};
$.each(response.wallet_transactions, function(i, trans) {
var exp_name = trans.expense_type__name;
var quantity = trans.total_quantity;
var price = trans.total_cost;
var trans_type = trans.trans_type;
if (!table_data[exp_name]) {
table_data[exp_name] = {}
}
table_data[exp_name][trans_type] = {
quantity: quantity,
cost: price
};
}
$.each(table_data, function(name, data) {
rows += "<tr><td>" + name + "</td>";
rows += "<td>" + data.Rent.cost + "</td>";
rows += "<td>" + data.Rent.quantity + "</td>";
rows += "<td>" + data.Purchased.cost + "</td>";
rows += "<td>" + data.Purchased.quantity + "</td>";
rows += "</tr>";
}
Notice that $.each passes the array element as the second argument to the callback function, so you don't have to repeat response.wallet_transactions[index] on every line.

Getting JSON data in HTML table format

This is my code and I am trying to pull in JSON data from an API.
The data is being successfully pulled but it is not coming in table format. It is coming as a continuous horizontal string.
if (this.readyState == 4 && this.status == 200) {
// Typical action to be performed when the document is ready:
var respoTxt = xhttp.responseText;
var myObj = JSON.parse(respoTxt);
document.getElementById("demo").innerHTML = '<table><tr><thead>' +
myObj["dataset"]["column_names"][5] + '</thead><thead>' + myObj["dataset"]
["column_names"][6] + '</thead></tr>';
myObj["dataset"]["data"].forEach(function(p, i) {
//Below is 1st code version:
// var tr = document.createElement("tr");
// document.getElementById("demo").appendChild(tr);
// var td1 = document.createElement("td");
// tr.appendChild(td1);
// var td2 = document.createElement("td");
// tr.appendChild(td2);
// td1.innerHTML = myObj["dataset"]["data"][i][5];
// td2.innerHTML = myObj["dataset"]["data"][i][6];
document.getElementById("demo").innerHTML += '<tr>';
document.getElementById("demo").innerHTML += '<td>' + myObj["dataset"]
["data"][i][5] + '</td>';
document.getElementById("demo").innerHTML += '<td>' + myObj["dataset"]
["data"][i][6] + '</td>';
document.getElementById("demo").innerHTML += '</tr>';
//Here's the 3rd code version:
// document.getElementById("demo").innerHTML += '<tr><td>' +
myObj["dataset"]["data"][i][5] + '</td><td>' + myObj["dataset"]["data"][i]
[6] + '</td></tr>';
});
document.getElementById("demo").innerHTML += '</table>';
}
I have used 3 different types of code inside (2 of them marked in comments above and below the active one).
None of them are showing the data in table format.
Here's the Codepen.
The problem is that when you set the innerHTML of an element, the browser automatically closes any unopened tags, because it has to parse whatever you've assigned as complete HTML. So you can't concatenate the opening tag, contents, and closing tags in separate assignments.
The solution is to assign all the HTML to a string variable as you're building it up, then assign that to .innerHTML at the very end. This is also more efficient, since it doesn't have to keep parsing HTML.
if (this.readyState == 4 && this.status == 200) {
// Typical action to be performed when the document is ready:
var respoTxt = xhttp.responseText;
var myObj = JSON.parse(respoTxt);
var html = '<table><tr><thead>' +
myObj["dataset"]["column_names"][5] + '</thead><thead>' + myObj["dataset"]
["column_names"][6] + '</thead></tr>';
myObj["dataset"]["data"].forEach(function(p, i) {
html += '<tr>';
html += '<td>' + myObj["dataset"]
["data"][i][5] + '</td>';
html += '<td>' + myObj["dataset"]
["data"][i][6] + '</td>';
html += '</tr>';
});
html += '</table>';
document.getElementById('demo').innerHTML = html;
}
Little bit modification to your code.
Please use it in the below manner
document.getElementById("demo").innerHTML = '<table><thead><tr><th>' +
myObj["dataset"]["column_names"][5] + '</th><th>' + myObj["dataset"]
["column_names"][6] + '</th></tr></thead>';

Embed Post not showing with FB.api Call Facebook Javascript Api

I'm using Facebook Javascript SDK and FB.api. I read public pages' posts and wanted to show it on my website. So I made the call with FB.api and got the response. But while I try to show them by Facebook Embed System it just didn't show up.
Here is my code
FB.api("/" + PageId + "/posts",
{
access_token: getCookie("access_token"),
since: From,
until: To,
fields: "id,likes.summary(true).limit(0),comments.summary(true).limit(0),shares,link",
limit: LoadLimit,
date_format: "U",
},
function (res) {
$("#load_post").attr("disabled", false).attr("value", "Load Posts");
if (typeof res.error === 'undefined') {
if (res.data.length > 0) {
for (var i = 1; i <= res.data.length; i++) {
var NewData = res.data[i - 1];
var Id = NewData.id.split("_")[1];
var CreatedTime = NewData.created_time;
var Likes = NewData.likes.summary.total_count;
var Comment = NewData.comments.summary.total_count;
var Share = 0;
var Link = NewData.link;
if (typeof NewData.shares !== 'undefined') {
Share = NewData.shares.count;
}
var Data = "";
Data += "<tr>";
Data += "<td>" + i + "</td>";
Data += "<td><div id='" + Id + "' class='fb-post' data-href='" + Link + "' data-width='350'></div></td>";
Data += "<td>" + CreatedTime + "</td>";
Data += "<td>" + Likes + "</td>";
Data += "<td>" + Comment + "</td>";
Data += "<td>" + Share + "</td>";
Data += "<td></td>";
Data += "<td></td>";
Data += "<td></td>";
Data += "</tr>";
$("#data_area").append(Data);
FB.XFBML.parse(document.getElementById(Id));
}
} else {
alert("No data found.");
}
} else {
alert("Error occured.\n" + res.error.message);
}
});
Even I tried "FB.XFBML.parse" but lately checking the documentation I found that it has no effect on Embed Post.
I checked the console and found no error or something.
Please help me out.

how to add multiple values in javascript?

i have this situation:
...
for (var i = 0; i < json.length; i++)
{
output += '<tr>';
for ( var objects in json[i])
{
if (objects == 'amt_1')
{
output += '<td id="amt">' + json[i][objects] + '</td>';
}
}
output += '</tr>';
}
output += '<tr">';
var amt = 0;
$('#amt').each(function() {
amt += $(this).text();
});
output += '<td>' + amt + '</td>';
output += '</tr>';
$('#details').append(output);
}
this is a part of a table that give's me something like this:
<td id="amt">4.58</td>
<td id="amt">55.74</td>
<td id="amt">193.5</td>
<td></td>
and in the last td i would like the sum of the rest of them with the id = amt
what i have seems not to work
any ideas?
Thnaks
The problem is that you are using id's instead of classes, id's are supposed to be unique, so javascript only returns 1 td. Multiple elements however, can share the same class.
Also, the jQuery won't work because the elements haven't been added to the document yet.
for (var i = 0; i < json.length; i++)
{
output += '<tr>';
for ( var objects in json[i])
{
if (objects == 'amt_1')
{
output += '<td class="amt">' + json[i][objects] + '</td>';
}
}
output += '</tr>';
}
output += '<tr">';
$('#details').append(output); //Copied here, this will add the above elements
//to the document subtree, which allows jquery
//to search for them
output = ""; //Reset output
var amt = 0;
$('.amt').each(function() { //Changed to class selector
amt += parseInt($(this).text());
});
output += '<td>' + amt + '</td>';
output += '</tr>';
$('#details').append(output); //Append result
Like they said you should use a class instead of id
output += '<td class="amt">' + json[i][objects] + '</td>';
Then you must add the output to the DOM before your jQuery selector, $('.amt'), can find the elements
$('#details').append(output); //<--append BEFORE you select the .amt elements
var amt = 0;
$('.amt').each(function() {
amt += parseFloat($(this).html()); //parseFloat on the html
});
output = '<tr">'; //<-- reset output here
output += '<td>' + amt + '</td>';
output += '</tr>';
$('#details').append(output);
Still it would be better to just sum the amount in your for loop
var total = 0;
...
if (objects == 'amt_1')
{
var curAmt = json[i][objects];
output += '<td class="amt">' + curAmt + '</td>';
total += parseFloat(curAmt);
}
...
output += '<td>' + total + '</td>';
You can't have more than one element with the same id on a page. $("#someId") will always select at most 1 element. So, your first problem is you don't even have a list of elements. You can solve that by using class instead.
Once you resolve the id issue, the trouble you'll have is you are trying to add text as though it were a number. First, you convert text to a number in one loop, then you loop through your entire collection again and try to add the textual numbers. Just get the total during the first loop. You'll be adding numbers instead of text, and you'll only have to iterate your collection once.
Also, you don't need to iterate the keys of an object just get a property. You can just reference the property directly: json[i].amt_1
While we're at it, let's not build up the html string, but instead just create the DOM elements directly. And take advantage of $.each() to do our looping.
var total = 0;
$.each(json, function (i, item) {
var row = $('<tr>').appendTo("#details");
$("<td>").appendTo(row).addClass("amt").text(item.amt_1);
total += item.amt_1;
});
var row = $("<tr>").appendTo("#details");
$("<td>").appendTo(row).text(total);

Categories