I need Data inside a jQuery autocomplete from a XMLHttpRequest
This is my code for XMLHttpRequest:
var jsonRequest = new XMLHttpRequest();
jsonRequest.open('GET', path);
jsonRequest.onload = function(){
var a = jsonRequest.removeEventListener;
}; jsonRequest.send();
This Code also works but how can I use the var a inside my jQuery autocomplete?
This is the jQuery:
$('#tags').autocomplete({
source: function(request, response) {
var data = a;
var datamap = data.map(function(i) {
return {
label: i.serial + ' - ' + i.mac,
value: i.serial + ' - ' + i.mac,
desc: i.cpe_ip
}
});
var key = request.term;
datamap = datamap.filter(function(i) {
return i.label.toLowerCase().indexOf(key.toLowerCase()) >= 0;
});
response(datamap.slice(0, 15));
},
minLength: 1,
delay: 100
});
If I use this with JSON-Data for the var data it works fine. But like this it won't work.
Now I have this:
$('#snmcAuto').autocomplete({
source: function(request, response) {
var jsonRequest = new XMLHttpRequest();
jsonRequest.open('GET', path);
jsonRequest.onload = function(data){
response(JSON.parse(data));
};
var datamap = data.map(function(i) {
return {
label: i.serial + ' - ' + i.mac,
value: i.serial + ' - ' + i.mac,
desc: i.cpe_ip
}
});
var key = request.term;
datamap = datamap.filter(function(i) {
return i.label.toLowerCase().indexOf(key.toLowerCase()) >= 0;
});
response(datamap.slice(0, 15));
jsonRequest.send();
},
minLength: 1,
delay: 100
});
This is the code which works for me and yeah its not the best performance but it's still fast.
$('#snmcAuto').autocomplete({
source: function(request, response) {
var jqxhr = $.getJSON( path, function() {
var data = jqxhr.responseJSON;
var datamap = data.map(function(i) {
return {
label: i.serial + ' - ' + i.mac,
value: i.serial + ' - ' + i.mac,
desc: i.cpe_ip
}
});
var key = request.term;
datamap = datamap.filter(function(i) {
return i.label.toLowerCase().indexOf(key.toLowerCase()) >= 0;
});
response(datamap.slice(0, 15));
})
},
});;
To use the remote datasource (accessed by AJAX) as the source of the autocomplete data you can do something like this. The key thing is that you must return the response to the autocomplete inside the "onload" callback of the AJAX request, so that it has access to the downloaded data. You also have to pass the search term entered by the user to the server via the querystring.
$('#tags').autocomplete({
source: function(request, response) {
var jsonRequest = new XMLHttpRequest();
jsonRequest.open('GET', path + "?term=" + request.term);
jsonRequest.onload = function(data){
response(JSON.parse(data.responseText));
};
jsonRequest.send();
},
minLength: 1,
delay: 100
});
Related
I am trying to understand how the batch rest calls work.
I could not find any simple example on the internet. I have found the examples from https://github.com/andrewconnell/sp-o365-rest but can't run these examples or I have no idea how yet. I am guessing you have to deploy the app to a sharepoint site.
Given that, I am just looking for the simplest example of a add list item and update list item in bulk/batch. Also if anyone knows how I can make the app from that git to run will be really appreciated.
Thanks.
The github project is a add-in project so you need deploy the add-in project, then you can use it.
You could check below script from here.
My test result in this thread
(function () {
jQuery(document).ready(function () {
jQuery("#btnFetchEmployees").click(function () {
addEmployees();
});
});
})();
function addEmployees() {
var employeesAsJson = undefined;
employeesAsJson = [
{
__metadata: {
type: 'SP.Data.EmployeeInfoListItem'
},
Title: 'Geetanjali',
LastName: 'Arora',
Technology: 'SharePoint'
},
{
__metadata: {
type: 'SP.Data.EmployeeInfoListItem'
},
Title: 'Geetika',
LastName: 'Arora',
Technology: 'Graphics'
},
{
__metadata: {
type: 'SP.Data.EmployeeInfoListItem'
},
Title: 'Ashish',
LastName: 'Brajesh',
Technology: 'Oracle'
}
];
addEmployeeInfoBatchRequest(employeesAsJson);
}
function generateUUID() {
var d = new Date().getTime();
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c == 'x' ? r : (r & 0x7 | 0x8)).toString(16);
});
return uuid;
};
function addEmployeeInfoBatchRequest(employeesAsJson) {
// generate a batch boundary
var batchGuid = generateUUID();
// creating the body
var batchContents = new Array();
var changeSetId = generateUUID();
// get current host
var temp = document.createElement('a');
temp.href = _spPageContextInfo.webAbsoluteUrl;
var host = temp.hostname;
// iterate through each employee
for (var employeeIndex = 0; employeeIndex < employeesAsJson.length; employeeIndex++) {
var employee = employeesAsJson[employeeIndex];
// create the request endpoint
var endpoint = _spPageContextInfo.webAbsoluteUrl
+ '/_api/web/lists/getbytitle(\'EmployeeInfo\')'
+ '/items';
// create the changeset
batchContents.push('--changeset_' + changeSetId);
batchContents.push('Content-Type: application/http');
batchContents.push('Content-Transfer-Encoding: binary');
batchContents.push('');
batchContents.push('POST ' + endpoint + ' HTTP/1.1');
batchContents.push('Content-Type: application/json;odata=verbose');
batchContents.push('');
batchContents.push(JSON.stringify(employee));
batchContents.push('');
}
// END changeset to create data
batchContents.push('--changeset_' + changeSetId + '--');
// batch body
var batchBody = batchContents.join('\r\n');
batchContents = new Array();
// create batch for creating items
batchContents.push('--batch_' + batchGuid);
batchContents.push('Content-Type: multipart/mixed; boundary="changeset_' + changeSetId + '"');
batchContents.push('Content-Length: ' + batchBody.length);
batchContents.push('Content-Transfer-Encoding: binary');
batchContents.push('');
batchContents.push(batchBody);
batchContents.push('');
// create request in batch to get all items after all are created
endpoint = _spPageContextInfo.webAbsoluteUrl
+ '/_api/web/lists/getbytitle(\'EmployeeInfo\')'
+ '/items?$orderby=Title';
batchContents.push('--batch_' + batchGuid);
batchContents.push('Content-Type: application/http');
batchContents.push('Content-Transfer-Encoding: binary');
batchContents.push('');
batchContents.push('GET ' + endpoint + ' HTTP/1.1');
batchContents.push('Accept: application/json;odata=verbose');
batchContents.push('');
batchContents.push('--batch_' + batchGuid + '--');
batchBody = batchContents.join('\r\n');
// create the request endpoint
var endpoint = _spPageContextInfo.webAbsoluteUrl + '/_api/$batch';
var batchRequestHeader = {
'X-RequestDigest': jQuery("#__REQUESTDIGEST").val(),
'Content-Type': 'multipart/mixed; boundary="batch_' + batchGuid + '"'
};
// create request
jQuery.ajax({
url: endpoint,
type: 'POST',
headers: batchRequestHeader,
data: batchBody,
success: function (response) {
var responseInLines = response.split('\n');
$("#tHead").append("<tr><th>First Name</th><th>Last Name</th><th>Technology</th></tr>");
for (var currentLine = 0; currentLine < responseInLines.length; currentLine++) {
try {
var tryParseJson = JSON.parse(responseInLines[currentLine]);
$.each(tryParseJson.d.results, function (index, item) {
$("#tBody").append("<tr><td>" + item.Title + "</td><td>" + item.LastName + "</td><td>" + item.Technology + "</td></tr>");
});
} catch (e) {
}
}
},
fail: function (error) {
}
});
}
I have 2 lists in my Sharepoint : speeches and schools.
In my speeches form, I have a school field. I want to autocomplete this field with values (name, adress, city) from schools list.
Here's my code :
$(School_fieldID).autocomplete({
minLength: 2,
source: function (request, response) {
var term = request.term.replace(/ /g, "*\",\"*");
var searchUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/search/query?querytext='and(\"*" + term + "*\",path:\"" + _spPageContextInfo.webAbsoluteUrl + "/Lists/Schools\")'&enablefql=true";
var executor = new SP.RequestExecutor(_spPageContextInfo.webAbsoluteUrl);
executor.executeAsync({
url: searchUrl,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
var jsonObject = JSON.parse(data.body);
var results = jsonObject.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results;
var clientContext = new SP.ClientContext();
var schoolList = clientContext.get_web().get_lists().getByTitle('Schools');
response($.map(results, function (result) {
school = schoolList.getItemById(result.Cells.results[6].Value.split('=').pop());
clientContext.load(school, 'Title', 'Adress', 'City');
clientContext.executeQueryAsync(Function.createDelegate(this, function (schoolName, schoolAdress, schoolCity) {
schoolName = school.get_item('Title');
schoolAdress = school.get_item('Adress');
schoolCity = school.get_item('City');
}), Function.createDelegate(this, function (sender, args) {
alert('Error occured: ' + args.get_message());
}));
return {
label: schoolName + " (" + schoolAdress + " " + /*schoolCity + */ ")",
value: schoolName
};
}));
}
});
}
});
When I test this code, schoolName, schoolAdress et schoolCity are undefined because of asynchronous function executeQueryAsync.
So I think solution is in Promise or Callback, but I tried different solutions for a week, without success :-(
Please note I read carefully this post How do I return the response from an asynchronous call?, but can't find a good solution anyway...
Can anyone help me ?
Thanks in advance,
Florent
Considering you have to pass an array of objects to the response callback function and each one of the result is calling the async function clientContext.executeQueryAsync we can turn each one of them into a promise and pass them to Promise.all() which will wait for all of them to be resolved and returned them.
When they are all resolved, the objects will be inside the schoolObjectArray which then you can pass to the response function.
Is should work.
$(School_fieldID).autocomplete({
minLength: 2,
source: function (request, response) {
var term = request.term.replace(/ /g, "*\",\"*");
var searchUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/search/query?querytext='and(\"*" + term + "*\",path:\"" + _spPageContextInfo.webAbsoluteUrl + "/Lists/Schools\")'&enablefql=true";
var executor = new SP.RequestExecutor(_spPageContextInfo.webAbsoluteUrl);
executor.executeAsync({
url: searchUrl,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
var jsonObject = JSON.parse(data.body);
var results = jsonObject.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results;
var clientContext = new SP.ClientContext();
var schoolList = clientContext.get_web().get_lists().getByTitle('Schools');
Promise.all($.map(results, function (result) {
school = schoolList.getItemById(result.Cells.results[6].Value.split('=').pop());
clientContext.load(school, 'Title', 'Adress', 'City');
return new Promise(function(resolve,reject) {
clientContext.executeQueryAsync(Function.createDelegate(this, function (schoolName, schoolAdress, schoolCity) {
schoolName = school.get_item('Title');
schoolAdress = school.get_item('Adress');
schoolCity = school.get_item('City');
resolve({
label: schoolName + " (" + schoolAdress + " " + /*schoolCity + */ ")",
value: schoolName
});
}), Function.createDelegate(this, function (sender, args) {
reject('Error occured: ' + args.get_message());
}));
})
}))
.then(function(schoolObjectArray){
response(schoolObjectArray)
})
.catch(console.error);
}
});
}
});
I have the following function which populates elements options.
player.onTracksChanged_ = function(event) {
// Update the track lists.
var lists = {
video: document.getElementById('videoTracks'),
audio: document.getElementById('audiotrackButton'),
text: document.getElementById('captionButton')
};
var formatters = {
video: function(track) {
return track.width + 'x' + track.height + ', ' +
track.bandwidth + ' bits/s';
},
audio: function(track) {
return 'language: ' + track.language + ', ' +
track.bandwidth + ' bits/s';
},
text: function(track) {
return 'language: ' + track.language + ' ' +
'(' + track.kind + ')';
}
};
// Clear the old track lists.
Object.keys(lists).forEach(function(type) {
var list = lists[type];
while (list.firstChild) {
list.removeChild(list.firstChild);
}
});
// Populate with the new tracks.
var tracks = player.getTracks();
tracks.sort(function(t1, t2) {
// Sort by language, then by bandwidth.
if (t1.language) {
var ret = t1.language.localeCompare(t2.language);
if (ret) return ret;
}
return t1.bandwidth - t2.bandwidth;
});
tracks.forEach(function(track) {
var list = lists[track.type];
var option = document.createElement('option');
option.textContent = formatters[track.type](track);
option.track = track;
option.value = track.id;
option.selected = track.active;
list.appendChild(option);
});
};
What I am trying to achieve is an if statement based on this which determines if the number of each 'type' of 'track' is greater than or equal to 2, this is what I've got:-
var mediaTracks = player.getTracks();
if (mediaTracks.length >= 2) {
console.log('there are more than 2 tracks');
} else {
console.log('there are less than 2 tracks');
};
When in fact I need to do something more like this:-
var mediaTracksVideo = player.getTracks(video)
var mediaTracksAudio = player.getTracks(audio)
Then do something like:-
if (mediaTracksAudio >= 2) {...
But when I try player.getTracks(audio); the console logs 'audio is not defined'.
Any idea why?
With player.getTracks(audio) you're using the variable audio, which is undefined. You probably want to use player.getTracks('audio'), where 'audio' is a string.
I am not sure if this is due to the fact that getJSON is asynchronous or not. I think that would be the most obvious reason, but I don't have a clear understanding of how that works. In my js file, I call the healthCheck method on the body element. Nothing happens. Is my getJSON callback function even getting called? I don't know.
I have uploaded the script on JSFiddle.
The code is also below:
var baseURL = "http://someURL";
var id = "00000001";
var key = "0000aaaa-aa00-00a0-a00a-0000000a0000";
var healthcheck = "/version/healthcheck?";
( function($) {
$.fn.healthCheck = function() {
var timestamp = new Date().toJSON().toString();
var request = healthcheck + "timestamp=" + timestamp + "&devid=" + id;
var signature = CryptoJS.HmacSHA1(request, key);
request = baseURL + request + "&signature=" + signature;
$.getJSON(request, function(data) {
var result = new Object();
$.each(data, function(key, val) {
result.key = val;
if (val == false) {
this.innerHTML = "PTV API is currently not working. Error type: " + key + ".";
} else {
this.append(key + " working. <br />");
}
});
});
return this;
};
}(jQuery));
Many thanks in advance. I hope my query is well placed. If anyone knows some good resources to get a better understanding of asynchronous methods in jQuery that would be greatly appreciated, also. I haven't found many that have been easy to follow yet.
Try 1) setting context of jQuery.ajax( url [, settings ] ) to this of $.fn.healthCheck ; 2) create reference to this object at $.each()
var baseURL = "http://someURL";
var id = "00000001";
var key = "0000aaaa-aa00-00a0-a00a-0000000a0000";
var healthcheck = "/version/healthcheck?";
(function($) {
$.fn.healthCheck = function() {
// set `this` object within `$.getJSON`
var timestamp = new Date().toJSON().toString();
var request = healthcheck + "timestamp=" + timestamp + "&devid=" + id;
var signature = CryptoJS.HmacSHA1(request, key);
request = baseURL + request + "&signature=" + signature;
$.ajax({
url:request
, type:"GET"
, contentType: false
, context: this
, processData:false
}).then(function(data) {
// reference to `this` within `$.each()`
var that = this;
var result = new Object();
$.each(JSON.parse(data), function(key, val) {
result.key = val;
if (val == false) {
// `that` : `this`
that.innerHTML = "PTV API is currently not working. Error type: " + key + ".";
} else {
that.append(key + " working. <br />");
console.log("complete"); // notification
}
});
}, function(jqxhr, textStatus, errorThrown) {
console.log(textStatus, errorThrown); // log errors
});
return this;
};
}(jQuery));
$("body").healthCheck();
See also How do I return the response from an asynchronous call?
var baseURL = "https://gist.githubusercontent.com/guest271314/23e61e522a14d45a35e1/raw/62775b7420f8df6b3d83244270d26495e40a1e9d/a.json";
var id = "00000001";
var key = "0000aaaa-aa00-00a0-a00a-0000000a0000";
var healthcheck = "/version/healthcheck?";
(function($) {
$.fn.healthCheck = function() {
var timestamp = new Date().toJSON().toString();
var request = healthcheck + "timestamp=" + timestamp + "&devid=" + id;
var signature = 123;// CryptoJS.HmacSHA1(request, key);
request = baseURL + request + "&signature=" + signature;
$.ajax({
url:request
, type:"GET"
, contentType: false
, context: this
, processData:false
}).then(function(data) {
var that = this;
var result = new Object();
$.each(JSON.parse(data), function(key, val) {
result.key = val;
if (val == false) {
that.innerHTML = "PTV API is currently not working. Error type: " + key + ".";
} else {
that.append(key + " working. <br />");
console.log("complete"); // notification
}
});
}, function(jqxhr, textStatus, errorThrown) {
console.log(textStatus, errorThrown); // log errors
});
return this;
};
}(jQuery));
$("body").healthCheck()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
This is very early in my Node and JavaScript learning. Ideally, what I am attempting to do is create a small module querying a specific type of rest endpoint and returning a specific feature based on an attribute query. The module is correctly logging out the result, but I am struggling to get the .findById function to return this result. Although aware it has something to do with how the callbacks are working, I am not experienced enough to be able to sort it out yet. Any help, advice and direction towards explaning the solution is greatly appreciated.
// import modules
var restler = require('restler');
// utility for padding zeros so the queries work
function padZeros(number, size) {
var string = number + "";
while (string.length < size) string = "0" + string;
return string;
}
// create feature service object
var FeatureService = function (url, fields) {
// save the parameters
this.restEndpoint = url;
this.fields = fields;
var self = this;
this.findById = function (idField, value, padZeroLength) {
var options = {
query: {
where: idField + '=\'' + padZeros(value, padZeroLength) + '\'',
outFields: this.fields,
f: "pjson"
},
parsers: 'parsers.json'
};
var url = this.restEndpoint + '/query';
restler.get(url, options).on('complete', function(result){
if (result instanceof Error){
console.log('Error:', result.message);
} else {
console.log(result); // this log result works
self.feature = JSON.parse(result);
}
});
return self.feature;
};
};
var restEndpoint = 'http://services.arcgis.com/SgB3dZDkkUxpEHxu/ArcGIS/rest/services/aw_accesses_20140712b/FeatureServer/1';
var fields = 'nameRiver,nameSection,nameSectionCommon,difficulty,diffMax';
var putins = new FeatureService(restEndpoint, fields);
var feature = putins.findById('awid_string', 1143, 8);
console.log(feature); // this log result does not
//console.log('River: ' + feature.attributes.nameRiver);
//console.log('Section: ' + feature.attributes.nameSection + ' (' + feature.attributes.nameSectionCommon + ')');
//console.log('Difficulty: ' + feature.attributes.difficulty);
So, I sorted out how to insert a callback from a previous thread. It appears it is just passed in as a variable and called with expected parameters. However, I now wonder if there is a better way to accept parameters, possibly in the form of options. Any advice in this regard?
// import modules
var restler = require('restler');
// utility for padding zeros so the queries work
function padZeros(number, size) {
var string = number + "";
while (string.length < size) string = "0" + string;
return string;
}
// create feature service object
var FeatureService = function (url, fields) {
// save the parameters
this.restEndpoint = url;
this.fields = fields;
var self = this;
// find and return single feature by a unique value
this.findById = function (idField, value, padZeroLength, callback) {
// query options for
var options = {
query: {
where: idField + '=\'' + padZeros(value, padZeroLength) + '\'',
outFields: this.fields,
f: "pjson"
},
parsers: 'parsers.json'
};
var url = this.restEndpoint + '/query';
restler.get(url, options)
.on('success', function(data, response){
var dataObj = JSON.parse(data).features[0];
console.log(dataObj);
callback(dataObj);
})
.on('fail', function(data, response){
console.log('Error:', data.message);
});
return self.feature;
};
};
var restEndpoint = 'http://services.arcgis.com/SgB3dZDkkUxpEHxu/ArcGIS/rest/services/aw_accesses_20140712b/FeatureServer/1';
var fields = 'nameRiver,nameSection,nameSectionCommon,difficulty,diffMax';
var putins = new FeatureService(restEndpoint, fields);
putins.findById('awid_string', 1143, 8, function(dataObject){
console.log('River: ' + dataObject.attributes.nameRiver);
console.log('Section: ' + dataObject.attributes.nameSection + ' (' + dataObject.attributes.nameSectionCommon + ')');
console.log('Difficulty: ' + dataObject.attributes.difficulty);
});