I am new to JQUERY and AJAX.
I need to make a get request to the git search api based on the topic the user chooses, i.e. if the user chooses clicks the button named ruby, I want to make a request to git for the top 10 python apis, similarly if he clicks a button named php i want to display repos of php.
To achieve this i created 2 ajax functions and called the respective ajax function at the button click.
<button id="ruby" onclick="startAjax();" class="btn btn-outline-dark">Java</button>
<button id="php" onclick="startAjax1();" class="btn btn-outline-dark">ios</button>
then,
function startAjax(){
$.ajax({
headers:{ "Content-Type":"application/json","Accept": "application/json"},
type:'GET',
url:'https://api.github.com/search/repositories?q=repos+topic:ruby&sort=stars&order=desc&per_page=10', });
function startAjax1(){
$.ajax({
headers:{ "Content-Type":"application/json","Accept": "application/json"},
type:'GET',
url:'https://api.github.com/search/repositories?q=repos+topic:ios&sort=stars&order=desc&per_page=10',});
This requires me to write as many ajax calls as buttons are there, is there a better way to do this? Can i use the id of the button and change the get url accordingly?
Thank you:)
What you always have to do is to look what are the differences in a function, what is variable. Everything variable should be - you guessed it - a variable. :-)
So in your case, it would be simple to use the id (or a data-attribute). To do this, try something like
$('button').on('click', function() {
$.ajax({
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
type: 'GET',
url: 'https://api.github.com/search/repositories?q=repos+topic:' + $(this).attr(“id”) + '&sort=stars&order=desc&per_page=10',
}).then(s => console.log(s));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="ruby" class="btn btn-outline-dark">Java</button>
<button id="php" class="btn btn-outline-dark">ios</button>
Also, don't use inline javascript. Better assign a proper event listener and handler like demonstrated above.
Use data attributes
<button class="btn btn-outline-dark ajax-button" data-url="https://api.github.com/search/repositories?q=repos+topic:ruby&sort=stars&order=desc&per_page=10">Ruby</button>
<button class="btn btn-outline-dark ajax-button" data-url="https://api.github.com/search/repositories?q=repos+topic:ios&sort=stars&order=desc&per_page=10">ios</button>
Then send the data attribute to a single function.
function startAjax(url){
$.ajax({
headers: {
"Content-Type":"application/json",
"Accept": "application/json"
},
type: 'GET',
url: url
});
$(document)ready(function(){
$(".ajax-button").click(function(event){
var url = $(event.target).data("url");
startAjax(url);
});
});
I usually use this ajax delegation logic to implement jquery/ajax unless I need more control over the request queue, in which case I'll use the $.when.apply() method posted below.
As far as your question about different URL's for different buttons, you can use the data attribute on the button element to store the URL's and access via the jquery .data() function.
Ajax Delegation
(function($){
$(function(){
//Usage Example
var inputString = $("#myInput").val();
var inputNumber = $("#myInteger").val();
var data = {inputString: inputString, inputNumber : inputNumber};
$('parent').on('click', 'button', delegateAjax('js/myAjax.php', data, 'POST');
});
function delegateAjax(url, data, responseType, dataType, callback) {
function successHandler() {
console.log("Ajax Success");
};
function failureHandler(xhr, status, error) {
console.log("Ajax Error");
console.log(status);
console.log(error);
console.dir(xhr);
};
function handler404(xhr, status, error) {
console.log("404 Error");
console.log(status);
console.log(error);
console.dir(xhr);
};
function handler500(xhr, status, error) {
console.log("500 Error");
console.log(status);
console.log(error);
console.dir(xhr);
};
url = typeof url !== 'undefined' ? url : 'js/ajaxDefault.php';
data = typeof data !== 'undefined' ? data : new Object();
responseType = typeof responseType !== 'undefined' ? responseType : 'GET';
dataType = typeof dataType !== 'undefined' ? dataType : 'json';
callback = typeof callback !== 'undefined' ? callback : 'callback';
var jqxhr = $.ajax({url: url, type: responseType, cache: true, data: data, dataType: dataType, jsonp: callback,
statusCode: { 404: handler404, 500: handler500 }});
jqxhr.done(successHandler);
jqxhr.fail(failureHandler);
};
})(jQuery);
Ajax Request Queue
//Set this var to max requests in queue.
var ajaxMax = 5;
var ajaxActive = 0;
$( document ).ajaxStart(function() {
ajaxActive++;
document.ajaxRunning = ajaxActive > 0;
document.ajaxQueueFull = ajaxActive > ajaxMax;
});
$(document).ajaxStop(function() {
ajaxActive--;
document.ajaxRunning = ajaxActive > 0;
document.ajaxQueueFull = ajaxActive > ajaxMax;
}
var request = $.ajax({
type: 'POST',
url: 'someurl',
success: function(result){}
});
while(request === null && (request.readyState < 1 || request.readyState > 4)) {
if (document.ajaxQueueFull) {
//abort existing requests
$.each(request as v) {
v.abort();
}
}
pendingAjax.push(request);
}
$.when.apply($, pendingAjax).done( successCallback ).fail( failCallback)
Related
I am using a button to trigger an AJAX call to retrieve data from an SQL database. The problem I'm having is when the button click also triggers a call to the server, the AJAX call fails.
Code:
$('.ptimage').click(function () {
document.getElementById('loading').style.display = "block";
if (dataStore.getItem('mlist') == null || dataStore.getItem('flist') == null) {
alert('isnull');
var nulldata = {};
nulldata.nullvar = "thing";
var jsonData = JSON.stringify({
nulldata: nulldata
});
$.ajax({
type: "POST",
url: "WebService.asmx/Getmf",
data: jsonData,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess,
error: OnErrorCall
});
function OnSuccess(response) {
var arraystring = response.d;
alert(arraystring);
mlist = arraystring.split(',');
mlist.splice(0, 1);
mlist.splice(-1, 1);
dataStore.setItem('mlist', JSON.stringify(mlist));
flist = arraystring.split(';');
flist.splice(0, 1);
flist.splice(-1, 1);
dataStore.setItem('flist', JSON.stringify(flist));
}
function OnErrorCall(response) {
alert("fail");
}
}
ptsession = dataStore.getItem('ptsessionval');
if (ptsession !== focusedcell) {
btn57.click();
}
})
So if ptsession != focusedcell, essentially if the clicked record is different from the current one, it will trigger a server call to the c# codebehind to get the new record.
If the record is different, the AJAX call fails and the call to the server from button57 (postback) succeeds. If the record is the same (so no call to the server from button57) the AJAX call succeeds. I can't figure out why this is happening.
(function($) {
$('.myclass').each(function(){
$(function() {
$.ajax({
url: "myPHP.php?app",
method: 'GET',
complete: function(jqXHR, textStatus) {
var response = JSON.parse(jqXHR.responseText);
$('.myclass').html(response.app);
}
});
});
});
})(jQuery);
i have multiple instances of myclass and I want each instance to be replaced with response.app but it doesnt happen.
What am i missing?
With your code, on every response from the server, all of your .myclass will be modified. You could try something like this:
$('.myclass').each(function() {
var $elem = $(this); // <-------------- Save the element for the ajax callback
$.ajax({
url: "myPHP.php?app",
method: 'GET',
complete: function(jqXHR, textStatus) {
var response = JSON.parse(jqXHR.responseText);
$elem.html(response.app); // <-------------- Use it
}
});
});
By the way, the requested URL seems to be the same for each call, with no specific parameter. If that's the case in your real code, then you only need to make one request (no .each()), and apply the result to all of your elements:
$.ajax({
url: "myPHP.php?app",
method: 'GET',
complete: function(jqXHR, textStatus) {
var response = JSON.parse(jqXHR.responseText);
$('.myclass').html(response.app);
}
});
jquery´s html function handles the replacement off all occurrence of myclass
so you just have to make the ajax call and pass the response
$.ajax({
url: "myPHP.php?app",
method: 'GET'
}).done(function(response){
$('.myclass').html(response.app)
});
This question is a followup of this one. I have created a simple example to check how code is executed within the handler. For the form
<form id="calendar_id" method="post">
Insert date: <input id="date_id" type="text" name="l_date" required>
</form>
I'm trying to retrieve the fields using the following javascript:
function get_form_data_uid($form) {
var unindexed_array = $form.serializeArray();
var indexed_array = {};
$.map(unindexed_array, function (n, i) {
indexed_array[n['name']] = n['value'];
});
indexed_array['uid'] = 'badbfadbbfi';
return indexed_array;
}
$("#calendar_id").submit(function (e) {
var uri, method, formId, $form, form_data;
// Prevent default submit
e.preventDefault();
e.stopImmediatePropagation();
uri = "/";
method = "POST";
formId = "#calendar_id";
$form = $(formId);
form_data = get_form_data_uid($form);
alert("form_data " + form_data);
// Set-up ajax call
var request = {
url: uri,
type: method,
contentType: "application/json",
accepts: "application/json",
cache: false,
// Setting async to false to give enough time to initialize the local storage with the "token" key
async: false,
dataType: "json",
data: form_data
};
// Make the request
$.ajax(request).done(function (data) { // Handle the response
// Attributes are retrieved as object.attribute_name
console.log("Data from change password from server: " + data);
alert(data.message);
}).fail(function (jqXHR, textStatus, errorThrown) { // Handle failure
console.log(JSON.stringify(jqXHR));
console.log("AJAX error on changing password: " + textStatus + ' : ' + errorThrown);
});
});
However, the code within the handler is not executed (the alert is not shown). Why?
Edit:
The code works jsfiddle but not in firefox.
At least, you are calling a function get_form_data_with_token() which is not defined anywhere in your posted code. Perhaps you meant to call your get_form_data_uid().
Would have just made this a comment, but apparently cannot.
I am loading map data from a GeoJSON file and attaching a click event for every polygone. on click, the script should fetch data from the server AND modify one of the clicked polygon's properties. i.e:
function onClick(e) {
var status = e.target.feature.properties.ACCESS;
$.ajax({
url: "http://127.0.0.1:8080/?&u=x&p="+e.target.feature.properties.ID_PARCELL,
dataType: 'jsonp',
type: 'GET',
success: function(data) {
status = data.status;
e.target.feature.properties.ACCESS = data.status;
e.target.bindPopup("Owner: <b>"+ data.status +"</b>").openPopup();
},
error: function(data){console.log(data)}
});
e.target.feature.properties.ACCESS = status;
map.fitBounds(e.target.getBounds());
}
But since the success function is an callback (synchronous or not, it doesn't really matter), I am not able to get back to the original event source (namely e) so I could modify one of its properties.
My question is: How can I get back to the event source after loading this data? Is there any generic Javascript way? If not, is there any way I can query the GeoJSON layer by feature ID ? (=> I can therefore send the feature ID in the ajax call, and simply get it back with the response)
The solution is to send the desired variable e to the anonymous function by using the context entry:
function onClick(e) {
var status = e.target.feature.properties.ACCESS;
$.ajax({
url: "http://127.0.0.1:8080/?&u=x&p="+e.target.feature.properties.ID_PARCELL,
dataType: 'jsonp',
context: e,
type: 'GET',
success: function(data) {
status = data.status;
e.target.feature.properties.ACCESS = data.status;
e.target.bindPopup("Owner: <b>"+ data.status +"</b>").openPopup();
},
error: function(data){console.log(data)}
});
e.target.feature.properties.ACCESS = status;
map.fitBounds(e.target.getBounds());
}
You'r using the same event name 'e' on both Click and success functions. Try to change one of them. ie
function onClick(e) {
var status = e.target.feature.properties.ACCESS;
$.ajax({
url: "http://127.0.0.1:8080/?&u=x&p="+e.target.feature.properties.ID_PARCELL,
dataType: 'jsonp',
type: 'GET',
success: function(data, evt) {
status = data.status;
e.target.feature.properties.ACCESS = data.status;
e.target.bindPopup("Owner: <b>"+ data.status +"</b>").openPopup();
},
error: function(data){console.log(data)}
});
e.target.feature.properties.ACCESS = status;
map.fitBounds(e.target.getBounds());
}
now you can change the initial event 'e' properties when the result is returned.
Hope this helps.
I need to copy file between document libraries. Library A is located in one site and Library B is located in subsite. I know how to copy file between libraries on the same level but the problem is with copying between different level.
The code I use to copy file between libraries on the same level.
$.ajax({
url : "http://xxx/PWA/_api/web/folders/GetByUrl('/PWA/CopyFromLibrary')/Files/getbyurl('Import.csv')/copyTo(strNewUrl = '/PWA/TargetLibrary/Import.csv',bOverWrite = true)",
method: 'POST',
headers: {
"Accept": "application/json; odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val()
},
success: function () {
alert("Success! Your file was copied properly");
},
error: function () {
alert("Problem with copying");
}
});
For different level I use just another target URL:
url : "http://xxx/PWA/_api/web/folders/GetByUrl('/PWA/CopyFromLibrary')/Files/getbyurl('Import.csv')/copyTo(strNewUrl = '/PWA/Subsite/TargetLibrary/Import.csv',bOverWrite = true)",
And it doesn't work.
How to work around this problem?
Just figured this one out today for the cross site solution. The trick is-- don't use $.ajax for the download of the document. Use good old XMLHttpRequest. The reason is that JQuery simply doesn't let you get a raw binary data array from SharePoint. But, the XMLHttpRequest does because it allows you to get an arraybuffer as part of its implementation, which SharePoint accepts!
The following is the code with the parts identified for building the full source and target REST urls. Note that you can use $.ajax to upload the file.
sourceSite is a sharepoint site suitable for appending the '_api' rest endpoint
sourceFolderPath is the relative folder path your document is located within
sourceFileName is the filename of the document
targetSite, targetFolderPath and targetFileName are the mirror images or source, only for the destination.
requestDigest is that special value you need for SharePoint to accept updates.
function copyDocument(sourceSite, sourceFolderPath, sourceFileName, targetSite, targetFolderPath, targetFileName, requestDigest) {
var sourceSiteUrl = sourceSite + "_api/web/GetFolderByServerRelativeUrl('" + sourceFolderPath + "')/Files('" + sourceFileName + "')/$value";
var targetSiteUrl = targetSite + "_api/web/GetFolderByServerRelativeUrl('" + targetFolderPath + "')/Files/Add(url='" + targetFileName + "',overwrite=true)";
var xhr = new XMLHttpRequest();
xhr.open('GET', sourceSiteUrl, true);
xhr.setRequestHeader('binaryStringResponseBody', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function (e) {
if (this.status == 200) {
var arrayBuffer = this.response;
$.ajax({
url: targetSiteUrl,
method: 'POST',
data: arrayBuffer,
processData: false,
headers: { 'binaryStringRequestBody': 'true', 'Accept': 'application/json;odata=verbose;charset=utf-8', 'X-RequestDigest': requestDigest }
})
.done(function (postData) {
console.log('we did it!');
})
.fail(function (jqXHR, errorText) {
console.log('dadgummit');
});
}
}
xhr.send();
}
What kind of error are you getting?
One probable cause of your problem is that your RequestDigest does not match the location where you want to POST your file since it is fetched from the page where your code is running. Fetch a matching RequestDigest by calling '_api/contextinfo' on your target location.
See:
http://blogs.breeze.net/mickb/2012/11/20/SP2013GettingAFormDigestForUpdateRESTCalls.aspx
and
http://msdn.microsoft.com/en-us/magazine/dn198245.aspx (writing to Sharepoint section)
Note
File Move operations only work within the scope of a given document library. You cannot copy between document libraries.
http://msdn.microsoft.com/en-us/library/office/dn605900(v=office.15).aspx#Folder6
For POST - operation we need request digest value, which is used by SharePoint to authenticate mainly for Post, Delete, Update not needed for GET operation,
Sample jquery ajax code for post operation-
$.ajax({
url: url + "/_api/web/lists/getbytitle('" + listname + "')/items",
type: "POST",
contentType: "application/json;odata=verbose",
data: JSON.stringify(item),
headers: {
"Accept": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val()
},
success: function (data) {
success(data); // Returns the newly created list item information
},
error: function (data) {
failure(data);
}
});
You can try the following code for copying file from one location to another within SharePoint.
The following example will be helpful in copying files within SharePoint sandbox.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="myapp" ng-controller="mycont">
<input type="button" ng-click = "myclick()" value="Angular File Copy" />
</div>
<input type=button onclick="x()" value="jQueryFile copy" />
<script>
var dt =new Date();
var val_ue = dt.getDate()+""+dt.getHours()+""+dt.getMinutes()+""+dt.getSeconds() +"1" ;
var url1 = "/_api/web/getfilebyserverrelativeurl('/Lists/Document_Mapping/Attachments/1/9.jpg')";
var url2 = "/Lists/AddressVersioning/Attachments/84/" ;
var combined = "";
var app = angular.module('myapp',[]);
var _headers = {
'X-RequestDigest': document.getElementById("__REQUESTDIGEST").value,
'accept':'application/json;odata=verbose'
};
app.controller('mycont',function($scope,$http){
$scope.myclick = function(){
combined = url1 + "/copyTo('" + url2 + val_ue + ".jpg')";
$http({method:'POST',url:combined,headers:_headers}).then(
function(response){
console.log("hi");
val_ue += 1;
},
function(error){
console.log("Error:");
console.log(error);
},
function(process){
console.log("process:");
console.log(process);
}
);
}
});
var x = function(){
combined = url1 + "/copyTo('" + url2 + val_ue + ".jpg')";
$.ajax({
url : combined,
method: 'POST',
headers: {
"Accept": "application/json; odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val()
},
success: function () {
alert("Success! Your file was copied properly");
val_ue +=1;
},
error: function () {
alert("Problem with copying");
}
});
}
</script>
Note: the above function will not work if the list item is newly created. But for all other situations it will work (even form one doc library to another doc library or cross site / site collection)