Get multiple list items by ID in SharePoint List - sharepoint-2013

I am trying to retrieve a list items from a SharePoint list but my issue is that I would like to retrieve the last four items by ID and I don't know how to proceed using JSOM.
Can someone help me whit some CAML code on how to do that?
var ctx = new SP.ClientContext.get_current();
var web = ctx.get_web();
//Geting reference to the list
var olist = web.get_lists().getByTitle('Configs');
var oitem = olist.getItemById(1);
//get Title,id,ConfigItem fields
ctx.load(oitem, "Title", "Id", "ConfigItem");
ctx.executeQueryAsync(function () {
alert(oitem.get_item("Title"));
alert(oitem.get_item("ConfigItem"));
}, function (a, b) {
alert(b.get_message());
});

You could use rest api with order by and $top option for this requirement.
/_api/web/lists/getbytitle('chart')/items?$select=ID,Title&$orderby= ID desc&$top=4
Rest api get list items.
$.ajax({
url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbytitle('chart')/items?$select=ID,Title&$orderby= ID desc&$top=4",
type: "GET",
headers:
{
"Accept": "application/json;odata=verbose",
"Content-Type": "application/json;odata=verbose"
},
success: function (data) {
for (var i = 0; i < data.d.results.length; i++) {
var item = data.d.results[i];
//to do
}
},
error: function (data) {
console.log(data.responseJSON.error);
}
});

Here is JSOM solution with use of CamlQuery.
var ctx = new SP.ClientContext.get_current();
var web = ctx.get_web();
var query = new SP.CamlQuery()
query.set_viewXml("<View><Query><OrderBy><FieldRef Name='ID' Ascending='FALSE' /></OrderBy></Query><RowLimit>4</RowLimit></View>")
var list = web.get_lists().getByTitle('Configs');
var items = list.getItems(query, "ID", "Title", "FirstName", "LastName", "Level", "Grade", "Date");
var dictionary = [];
ctx.load(items);
ctx.executeQueryAsync(function () {
var enumerator = items.getEnumerator();
while (enumerator.moveNext()) {
var item = enumerator.get_current();
dictionary.push({
title: item.get_item("Title"),
firstName: item.get_item("FirstName"),
lastName: item.get_item("LastName"),
level: item.get_item("Level"),
grade: item.get_item("Grade"),
date: item.get_item("Date"),
});
}
}, function (a, b) {
alert(b.get_message());
});

Related

How to apply filters to Embedded Power BI Visual?

I am working on a project where we need to embed a Power BI Report but not with the EmbedType of a Report - it should be visual. What I did is to embed each visual of the report into a separate DIV and what I have to do now is to apply the filters on each.
Sample Code (cshtml):
var embedContainer = '';
var pageName = '';
var visualName = '';
var type = '';
var DisplayObject = [
{
embedContainer: $('#report-container_hSlicer')[0],
pageName: 'ReportSection',
visualName: '0e2d3a2ad25c8c8c224b',
type: 'visual',
},
{
embedContainer: $('#report-container_lSlicer')[0],
pageName: 'ReportSection',
visualName: "1f1841a2b8b3414a4318",
type: 'visual',
},
{
embedContainer: $('#report-container_fSlicer')[0],
pageName: 'ReportSection',
visualName: "3acac86be0dd995b34b1",
type: 'visual',
},
{
embedContainer: $('#report-container_index')[0],
pageName: 'ReportSection',
visualName: '802df8d5bc156f326b5a',
type: 'visual',
},
{
embedContainer: $('#report-container_cbCity')[0],
pageName: 'ReportSection',
visualName: "3cd8ddf8eb40dcc35d4d",
type: 'visual',
},
{
embedContainer: $('#report-container_All')[0],
type: 'report',
},
]
On the JS for embedding:
var resultModel = {};
var report = null;
var pages = [];
var config = {};
var reports = [];
function getParameters() {
var model = {
"workspace": "8b4f5f85-02a4-4afe-9104-3d4929d025c4",
"report": "038b5e5b-4b51-40ae-91f6-580c745b32c3"
}
$.ajax({
type: "POST",
url: "/embedinfo/getembedinfo",
contentType: 'application/json',
data: JSON.stringify(model),
success: function (data) {
resultModel = {
token: data.embedToken.token,
embedUrl: data.embedReport[0].embedUrl,
reportID: data.embedReport[0].reportId,
type: data.type
}
//Display each visual
DisplayObject.forEach(e => {
embedContainer = e.embedContainer;
pageName = e.pageName;
visualName = e.visualName;
type = e.type;
embedPowerBIReport(resultModel.token, resultModel.embedUrl, resultModel.reportID, resultModel.type);
});
console.log(resultModel);
console.log('Got tokens');
},
error: function (err) {
alert(err);
}
});
};
let loadedResolve, reportLoaded = new Promise((res, rej) => { loadedResolve = res; });
let renderedResolve, reportRendered = new Promise((res, rej) => { renderedResolve = res; });
models = window["powerbi-client"].models;
function embedPowerBIReport(accessToken_, embedURL, embedReportID, TokenType) {
// Read embed application token
let accessToken = accessToken_;
// Read embed URL
let embedUrl = embedURL;
// Read report Id
let embedReportId = embedReportID;
// Read embed type from radio
let tokenType = TokenType;
// We give All permissions to demonstrate switching between View and Edit mode and saving report.
let permissions = models.Permissions.All;
// Create the embed configuration object for the report
// For more information see https://go.microsoft.com/fwlink/?linkid=2153590
if (type == 'report') {
config = {
type: type,
tokenType: tokenType == '0' ? models.TokenType.Aad : models.TokenType.Embed,
accessToken: accessToken,
embedUrl: embedUrl,
id: embedReportId,
settings: {
panes: {
filters: {
visible: false
},
}
}
};
}
else {
config = {
type: 'visual',
tokenType: tokenType == '0' ? models.TokenType.Aad : models.TokenType.Embed,
accessToken: accessToken,
embedUrl: embedUrl,
id: embedReportId,
permissions: permissions,
pageName: pageName,
visualName: visualName,
navContentPaneEnabled: false,
settings: {
panes: {
filters: {
visible: false
},
}
}
};
}
// Get a reference to the embedded report HTML element
//let embedContainer = $('#report-container')[0];
// Embed the report and display it within the div container.
report = powerbi.embed(embedContainer, config);
// report.off removes all event handlers for a specific event
report.off("loaded");
// report.on will add an event handler
report.on("loaded", function () {
loadedResolve();
report.off("loaded");
});
// report.off removes all event handlers for a specific event
report.off("error");
report.on("error", function (event) {
console.log(event.detail);
});
// report.off removes all event handlers for a specific event
report.off("rendered");
// report.on will add an event handler
report.on("rendered", function () {
renderedResolve();
report.off("rendered");
});
reports.push(report);
}
async function main() {
await getParameters();
await reportLoaded;
console.log('Report Loaded');
// Insert here the code you want to run after the report is loaded
await reportRendered;
console.log('Report Rendered');
//console.log('got all page');
//var reportAll = reports.filter(function (report) {
// return report.embedtype == 'report';
//})[0];
console.log('got all page');
// Insert here the code you want to run after the report is rendered
const filter = {
$schema: "http://powerbi.com/product/schema#basic",
target: {
table: "tblLifeStage",
column: "Life Stage"
},
operator: "In",
values: ["F2 - Upscale Earners"],
filterType: models.FilterType.BasicFilter,
requireSingleSelection: true
};
//// Retrieve the page collection and get the visuals for the active page.
//pages = await reportAll.getPages();
//// Retrieve the active page.
//let page = pages.filter(function (page) {
// return page.isActive;
//})[0];
//const visuals = await page.getVisuals();
//console.log(visuals);
//// Retrieve the target visual.
//let slicer = visuals.filter(function (visual) {
// return visual.type === "slicer" && visual.name === "1f1841a2b8b3414a4318";
//})[0];
//console.log(slicer);
// Set the slicer state which contains the slicer filters.
for (const report of reports) {
console.log(report);
await report.setSlicerState({ filters: [filter] });
console.log("slicer was set.");
};
};
//Calling Async function
main();
We can Apply Visual level filters to every Visual. You can use updateFilters to set new filter to the Visual our Update the filters.
Simply add this piece of code On the js for embedding in the display each Visual section or you use the variable visualName and apply filters later to the visual.
await visualName.updateFilters(models.FiltersOperations.Replace, filtersArray);
Reference:
https://learn.microsoft.com/javascript/api/overview/powerbi/control-report-filters#visual-level-filters

Update SharePoint List Item using Rest API and HTML Input Element

I am having a difficult time trying to get my below script to work for updating items on my SharePoint list “ProjectTracker”. I researched and tried several similar methods, but I can’t seem to get the any script version to update the list item(s). I continually receive the SharePoint error message “value”: This type SP.ListItemEntityCollection does not support HTTP PATCH method.” Statue”:400,”statusText”:”Bad Request”}. I included a screen grab of the error and below is the script I am using.
Any help or advice will be greatly appreciated. Thank you in advance.
jQuery(document).on("click", '#UpdateListItem', function(){
UpdateListItem();
});//Button close
function UpdateListItem() {
var myID = $("#itemID").val();
var listName = "ProjectTracker";
var office = $("#uOffice").val();
var title = $("#uProjectTitle").val();
var priority = $("#uPriority").val();
var startDate = $("#uStartDate").val();
var assignedTo = $("#uAssignedTo").val();
var status = $("#uStatus").val();
var requestor = $("#uRequestor").val();
var item = {
"__metadata": { "type": "SP.Data.ProjectTrackerListItem" },
"Office": office,
"ProjectTitle": title,
"Priority": priority,
"StartDate": startDate,
"AssignedTo": assignedTo,
"Status": status,
"Requestor": requestor
};
$.ajax({
url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbytitle('" + listName + "')/items(" + myID + ")",
type: "POST",
data: JSON.stringify(item),
headers: {
contentType: "application/json;odata=verbose",
"Accept": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val(),
"IF-MATCH": "*",
"X-HTTP-Method":"MERGE",
},
success: onSuccess,
error: onError
});
function onSuccess(data) {
alert('List Item Updated');
}
function onError(error) {
alert(JSON.stringify(error));
}
}//Function close
Please check list internalname and column internal name
For more details with AJAX call refer below age for full ajax call l.
https://sharepointmasterhub.blogspot.com/2020/12/sharepoint-crud-operations-with-rest-api.html?m=1#Update

How to get the total number of Items in a specific view in a list using rest api

I have requirement to get the total number of items in a specific view
in a SharePoint list.
I am trying below end point but it is returning count of all item in a
list.
/_api/Web/Lists/GetByTitle('<list_name>')/Items
let say view name is XYZ and list name is ABC how to build a rest api
to get total count of items in XYZ view from ABC list?
To get the item count in a specific list view, firstly get the list view CAML Query, then use this CAML Query with Post Request in Rest API to return items, here is a code snippet for your reference:
<script type="text/javascript">
getListItemsForView(_spPageContextInfo.webAbsoluteUrl,'ABC','XYZ')
.done(function(data)
{
var itemsCount = data.d.results.length;
alert(itemsCount);
})
.fail(
function(error){
console.log(JSON.stringify(error));
});
function getListItemsForView(webUrl,listTitle,viewTitle)
{
var viewQueryUrl = webUrl + "/_api/web/lists/getByTitle('" + listTitle + "')/Views/getbytitle('" + viewTitle + "')/ViewQuery";
return getJson(viewQueryUrl).then(
function(data){
var viewQuery = data.d.ViewQuery;
return getListItems(webUrl,listTitle,viewQuery);
});
}
function getJson(url)
{
return $.ajax({
url: url,
type: "GET",
contentType: "application/json;odata=verbose",
headers: {
"Accept": "application/json;odata=verbose"
}
});
}
function getListItems(webUrl,listTitle, queryText)
{
var viewXml = '<View><Query>' + queryText + '</Query></View>';
var url = webUrl + "/_api/web/lists/getbytitle('" + listTitle + "')/getitems";
var queryPayload = {
'query' : {
'__metadata': { 'type': 'SP.CamlQuery' },
'ViewXml' : viewXml
}
};
return $.ajax({
url: url,
method: "POST",
data: JSON.stringify(queryPayload),
headers: {
"X-RequestDigest": $("#__REQUESTDIGEST").val(),
"Accept": "application/json; odata=verbose",
"content-type": "application/json; odata=verbose"
}
});
}
</script>
Reference:
Using REST to fetch SharePoint View Items
You can do it either way, using CAML Query and using same filters as list view or using filters in your Rest API URL.
For details please check https://sharepoint.stackexchange.com/a/266795/68021

google maps marker load via ajax and infocontent

In my app I have a google map and I want to add many marker on it and so I load the data via ajax (I'm in Django). I have the probem with infocontent and the 'click' event on the marker load via ajax: When I do 'click' on the marker nothing happened. This is my code:
function initialize() {
var latlng = new google.maps.LatLng({{lat}}, {{long}});
var myOptions = {
zoom: 16,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("mapCanvas"), myOptions);
var contentString = '<div id="content">{{name}}<br><span style="font-size:10px;">{{road}}</span><br><span style="font-size:10px;">{{city}} ({{prov}})</span></div>';
var infowindow_strutt = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: latlng,
map: map,
title: '{{name}}'
});
google.maps.event.addListener(marker, 'click', function() {
infowindow_strutt.open(map,marker);
});
var markers = [];
var markers_strutt = [];
var markers_concor = [];
var icon_strutt = {
url: 'http://icons.iconarchive.com/icons/graphicloads/colorful-long-shadow/24/Home-icon.png'
};
var icon_concor = {
url: 'http://icons.iconarchive.com/icons/graphicloads/100-flat/24/home-icon.png'
};
var marker_concor
var marker_strutt
map.addListener('bounds_changed', function() {
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
var bounds = map.getBounds();
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
$.ajax({
url: '/api/get_marker/',
cache: false,
data: {
'fromlat': southWest.lat(),
'tolat': northEast.lat(),
'fromlng': southWest.lng(),
'tolng': northEast.lng()
},
dataType: 'json',
type: 'GET',
async: false,
success: function (data) {
if (data) {
$.each(data, function (i, item) {
if (item.type = 1) {
var marker_concor = new google.maps.Marker({
position: new google.maps.LatLng(item.lat, item.lng),
icon: icon_concor,
map: map,
draggable: false
});
} else if (item.type = 2) {
var marker_strutt = new google.maps.Marker({
position: new google.maps.LatLng(item.lat, item.lng),
icon: icon_strutt,
map: map,
draggable: false
});
//Create an infoWindow
var infowindow_strutt = new google.maps.InfoWindow();
//set the content of infoWindow (the name)
infowindow_strutt.setContent(item.name);
//add click listner to marker which will open infoWindow
map.addListener(marker_strutt, 'click', function() {
infowindow_strutt.open(marker_strutt); // click on marker opens info window
});
}
markers_concor.push(marker_concor);
markers_strutt.push(marker_strutt);
if (marker_strutt) {
marker_strutt.setMap(map);
}
if (marker_concor) {
marker_concor.setMap(map);
}
});
}
}
});
});
}
jQuery(document).ready(function(e) {
initialize();
});
Where is the issue? Thanks a lot
EDIT: View code
def view_get_marker(request):
id = 24
list_id = []
list_marker = []
list_id.append(id)
# type 1 data
A_list = tab_A.objects.filter(id_struttura=id).filter(lat__gt=request.GET.get('fromlat'), lat__lt=request.GET.get('tolat')).filter(lng__gt=request.GET.get('fromlng'), lng__lt=request.GET.get('tolng'))
for a in A_list:
list_marker.append([a.lat, a.lng, a.name, a.road, a.city, a.id, 1])
list_id.append(a.id)
# type 2 data
B_list = list(tab_B.objects.all().values_list('lat','lng','name','road','city','id').exclude(lng__isnull=True).exclude(id__in=lista_id).filter(lat__gt=request.GET.get('fromlat'), lat__lt=request.GET.get('tolat')).filter(lng__gt=request.GET.get('fromlng'), lng__lt=request.GET.get('tolng')))
for lat, lng, name, road, city, id in B_list:
list_marker.append([lat, lng, name, road, city, id, 2])
if request.is_ajax():
results = []
for row in list_marker:
h_json = {}
h_json['lat'] = row[0]
h_json['lng'] = row[1]
h_json['name'] = unicode(row[2])
h_json['road'] = unicode(row[3])
h_json['city'] = unicode(row[4])
h_json['id'] = row[5]
h_json['type'] = row[6]
results.append(h_json)
data = json.dumps(results)
else:
data = 'fail'
mimetype = 'application/json'
return HttpResponse(data, mimetype)
EDIT 2:
I found the solution. The problem was in the event 'click' declaration. The right way is this:
google.maps.event.addListener(marker_strutt, 'click', (function(marker_strutt, i) {
return function() {
infowindow.setContent('my content');
infowindow.open(map, marker_strutt);
}
})(marker_strutt, i));
In this way I have the popoup!

How do I write a findMany that will get in chunks?

Ember 1.5.1
Ember-Data 1.0 beta 7
I've tried to modify the DS.ActiveModelAdapter's findMany so it'll get in chunks of 40... this is because I can't use the links feature and it seems to be generating 400 errors because it has too many ids in the URL its creating.
I tried using this adapter, but I keep getting error messages that look like this:
Error: Assertion Failed: Error: no model was found for 'super'
Here's my Adapter:
App.ApplicationAdapter = DS.ActiveModelAdapter.extend({
findMany: function(store, type, ids) {
self = this;
return new Ember.RSVP.Promise(function(resolve, reject) {
var idsPerRequest = 40;
var totalIdsLength = ids.length;
var numberOfBins = Math.ceil( totalIdsLength / idsPerRequest ); // number per bin
var bins = [];
ids.forEach( function(someId, index) {
var thisBinIndex = index % numberOfBins;
var thisBin = Ember.A( bins[thisBinIndex] );
thisBin.pushObject(someId);
bins[thisBinIndex] = thisBin;
});
var requestPromises = bins.map(function(binOfIds) {
return self.ajax(self.buildURL(type.typeKey), 'GET', { data: { ids: binOfIds } });
});
Ember.RSVP.all(requestPromises).then(function(resolvedBinRequests) {
var resolvedObjects = Em.A([]);
resolvedBinRequests.forEach(function(resolvedBin) {
resolvedObjects.addObjects(resolvedBin);
});
resolve(resolvedObjects);
}, function(error) {
reject(error);
});
});
}
});
Can anyone help me out with this? It'd be really appreciated. Am I just missing something obvious or have I perhaps done something silly?
Thanks in advance!
[edit] Okay so further to this I've figured out why it's not working, and that's because the response that's coming back is a promise for the JSON payload, but what I'm doing is joining multiples of these into an array and returning that... which obviously won't be right... but what I need to do is merge the arrays inside the objects returned into one, I think (in concept)... I'm not really sure how to do this in actuality, though... I've tried various things, but none of them seem to work well... :(
I'm not sure how much control you have over the back-end, but this seems like a perfect use case for using links instead of returning all of the ids.
App.Foo = DS.Model.extend({
bars: DS.hasMany('bar', {async:true})
});
App.Bar = DS.Model.extend({
name: DS.attr()
});
Then when you query for foo your json returns a link instead of a list of ids
{
foo: {
id:1,
links: {
bars: '/foo/1/bars' // or anything, you could put /bars?start=1&end=9000
}
}
}
Here's an example with 1000 relationship records hitting a simple endpoint:
http://emberjs.jsbin.com/OxIDiVU/579/edit
Okay so I finally worked out how to make this work.
I'll share my answer here for future posterity ;-)
Of interest is that the required response had to be a promise and it had to contain a straight up JS object, so I "munged" all the responses into one JS object and manually built the pluralized camelized type key... I wasn't sure how else to do this. So... sorry it's so hacky, but this actually works and lets me fix my app for now until the "links" feature is working again.
App.ApplicationAdapter = DS.ActiveModelAdapter.extend({
findMany: function(store, type, ids) {
self = this;
return new Ember.RSVP.Promise(function(resolve, reject) {
var idsPerRequest = 40;
var totalIdsLength = ids.length;
var numberOfBins = Math.ceil( totalIdsLength / idsPerRequest ); // number per bin
var bins = [];
ids.forEach( function(someId, index) {
var thisBinIndex = index % numberOfBins;
var thisBin = Ember.A( bins[thisBinIndex] );
thisBin.pushObject(someId);
bins[thisBinIndex] = thisBin;
});
// build an array of promises, then resolve using Ember.RSVP.all
var requestPromises = bins.map(function(binOfIds) {
return self.ajax(self.buildURL(type.typeKey), 'GET', { data: { ids: binOfIds } });
});
// build the required return object, which is a promise containing a plain JS object
// note this can't be an Ember object
Ember.RSVP.all(requestPromises).then(function(resolvedBinRequests) {
var pluralizedDecamelizedTypeKey = type.typeKey.decamelize().pluralize();
var resolvedObjects = Em.A([]);
var returnObject = {};
returnObject[pluralizedDecamelizedTypeKey] = resolvedObjects;
resolvedBinRequests.forEach(function(resolvedBin) {
var theArray = resolvedBin[pluralizedDecamelizedTypeKey];
resolvedObjects.addObjects(theArray);
});
var responsePromise = Ember.RSVP.Promise.cast(returnObject);
resolve(responsePromise);
}, function(error) {
reject(error);
});
});
}
});
After some feedback I updated this response to attempt to extract the response payloads in the serializer instead of attempting to mimic the store's logic in the adapter.
http://emberjs.jsbin.com/wegiy/60/edit
App.ApplicationAdapter = DS.ActiveModelAdapter.extend({
findMany: function(store, type, ids) {
// build an array of promises, then resolve using Ember.RSVP.all
var idsPerRequest = 40;
var totalIdsLength = ids.length;
var numberOfBins = Math.ceil( totalIdsLength / idsPerRequest ); // number per bin
var bins = [];
ids.forEach( function(someId, index) {
var thisBinIndex = index % numberOfBins;
var thisBin = Ember.A( bins[thisBinIndex] );
thisBin.pushObject(someId);
bins[thisBinIndex] = thisBin;
});
var requestPromises = bins.map(function(binOfIds) {
return self.ajax(self.buildURL(type.typeKey), 'GET', { data: { ids: binOfIds } });
});
return Ember.RSVP.all(requestPromises);
}
});
App.ApplicationSerializer = DS.ActiveModelSerializer.extend({
extractFindMany: function(store, type, responsePayloads) {
// responsePayloads is the resolved value from the Ember.RSVP.all(requestPromises) promise
var serializer = this;
var extractedResponses = responsePayloads.map(function(payload) {
return serializer.extractArray(store, type, payload);
});
// extractedResponses is an array of arrays. We need to flatten it into 1 array.
return [].concat.apply([], extractedResponses);
}
});