Good afternoon, I am new to programing and have been having problems making a javascript/jquery API call load to a Twitter Tweet. The goal is to be able to hit the Tweet button and send the current quote featured on the page in a Tweet. This is my current attempt on CodePen with the Javascript below;
var counter = 0;
var $body = $('body'),
redVal = 55,
greenVal = 50,
blueVal = 25,
quote;
var sendText = "something current..."; //this is the variable that should be replaced by the API calls and sent to Twitter
//this is Twitter's function to format the page
window.twttr = (function(d, s, id) {
var t, js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s);
js.id = id;
js.src = "https://platform.twitter.com/widgets.js";
fjs.parentNode.insertBefore(js, fjs);
return window.twttr || (t = {
_e: [],
ready: function(f) {
t._e.push(f)
}
});
}(document, "script", "twitter-wjs"));
//the actions to call the quote API
function start() {
redVal = (redVal + 45) % 255;
greenVal = (greenVal + 40) % 255;
blueVal = (blueVal + 20) % 255;
var colorVal = "rgba(" + redVal + "," + greenVal + "," + blueVal + ", 0.4)";
$body.css({"background-color": colorVal });
if (counter % 2 == 0) {
$.ajax({
url: "http://quotes.stormconsultancy.co.uk/quotes/random.json?",
jsonp: "callback",
dataType: "jsonp",
data: {
q: "id, author, quote",
format: "json"
},
success: function( response ) {
var quote = response.quote;
var author = response.author;
document.getElementById("textDisplay").innerHTML = quote;
document.getElementById("author").innerHTML = author;
passText(quote);
}
});
counter += 1;
} else { $.ajax({
url: "http://api.icndb.com/jokes/random?",
jsonp: "callback",
dataType: "jsonp",
success: function( response ) {
var quote = response.value.joke;
var author = " ";
document.getElementById("textDisplay").innerHTML = quote;
document.getElementById("author").innerHTML = author;
passText(quote);
}
});
counter += 1;
}
}
//my attempted helper function to pass the quote values
function passText(superT) {
console.log(superT);
sendText = superT;
return sendText;
}
//the API call to Twitter to send the Tweet
twttr.ready(function (twttr) {
twttr.events.bind('tweet',
twttr.widgets.createShareButton(
'https://dev.twitter.com/',
document.getElementById('container'),
{
text: sendText }
));
})
I think the issue is that the API calls as conducted in the jQuery AJAX script are not being recognized as a reassignment to the quote variable in a way that is accessible outside of the jQuery AJAX call. I read other suggestions ( example ) to try and assign the quote variable from global scope or pass the value through a helper function ( example, as I attempted above…), but both just send the value initially assigned to the quote variable to the Twitter API without the JQuery values.
I hope there is something simple that I don’t know that will get this working. If it is not an issue with the scope of the variable, or if there is a better way to approach this than the JQuery AJAX function I would appreciate any suggestions. Thank you for your time and any help.
Related
I am trying to share canvas image to Facebook using Graph API.I have to converted it into Base 64 image and upload into Facebook blob storage. All things working fine only when I have to add debugger in code and debug it step by step, but if I have directly click Facebook share button then this not shared on Facebook. Please check following code.
window.fbAsyncInit = function () {
FB.init({
appId: '338935439835732',
xfbml: true,
version: 'v2.8'
});
};
(function (d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) { return; }
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
$("#btnfacebook").on('click', function () {
debugger;
var data = getCanvas.toDataURL("image/png").replace(/^data:image\/png/, "data:application/octet-stream");
var blob;
try {
var byteString = atob(data.split(',')[1]);
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
blob = new Blob([ab], { type: 'image/png' });
} catch (e) {
console.log(e);
}
var fd = new FormData();
fd.append("source", blob);
fd.append("message", "Photo Text");
FB.login(function () {
var auth = FB.getAuthResponse();
alert(auth.accessToken);
$.ajax({
url: "https://graph.facebook.com/" + auth.userID + "/photos?access_token=" + auth.accessToken,
type: "POST",
data: fd,
processData: false,
contentType: false,
cache: false,
success: function (data) {
console.log("success " + data);
},
error: function (shr, status, data) {
console.log("error " + data + " Status " + shr.status);
},
complete: function () {
console.log("Ajax Complete");
}
});
}, { scope: 'publish_actions' });
});
Please help me to find fix
This question already has answers here:
jQuery Deferred - waiting for multiple AJAX requests to finish [duplicate]
(3 answers)
Closed 6 years ago.
I'm trying to execute a callback after multiple jQuery Ajax have completed.
In my code both Ajax requests call another function and when I try to use these functions I get undefined.
I think the problem has to do with using deferred/promise, but I don't know how to use them.
Here is my code:
<link rel="stylesheet" type="text/css" href="https://tag/sites/ocean1/maker/captions/shared%20documents/Web_ComplianceCSS.txt">
<div id = "cabbage" style="font-size:10px">
<p>Web Compliance Stats</p>
</div>
<script type = "text/javascript">
var WebComplianceReportApp = {} || WebComplianceReportApp;
WebComplianceReportApp.GetStatuses = (function() {
var pub = {},
_userId,
_ultimateObjectHolderArr = [],
_items = [],
_options = {
listName: "M_Web_Compliance",
container: "#cabbage",
};
pub.init = function() {
var clientContext = new SP.ClientContext.get_current();
_userId = clientContext.get_web().get_currentUser();
clientContext.load(_userId);
clientContext.executeQueryAsync(getUserInfo, _onQueryFailed);
};
function getUserInfo() {
_userId = _userId.get_id();
getSpecifiedList(_options.listName, _userId);
}
function buildObject(results, listName) {
_items = results.d.results;
$.each(_items, function(index, item) {
_ultimateObjectHolderArr.push({
"Division": item.ParentOrg,
"ORG": item.ORG,
"URL": item.URL,
"Status": item.Site_Status
});
});
//createStatusView2(_ultimateObjectHolderArr);
}
function getSpecifiedList(listName, userId) {
var counter = 0;
var baseUrl = SP.PageContextInfo.get_webServerRelativeUrl() + "/_vti_bin/listdata.svc/" + listName;
var url1 = baseUrl + "?$select=ParentOrg,ORG,URL,Site_Status&$inlinecount=allpages";
var call1 = $.ajax({
url: url1,
type: "GET",
headers: {
"accept": "application/json;odata=verbose",
}
}).done(function(results) {
buildObject(results, listName);
}).fail(function(error) {
console.log("Error in getting List: " + listName);
$(_options.container).html("Error retrieving your " + listName + ". " + SP.PageContextInfo.get_webServerRelativeUrl());
});
var url2 = baseUrl + "?$select=ParentOrg,ORG,URL,Site_Status&$inlinecount=allpages&$skiptoken=1000";
var call2 = $.ajax({
url: url2,
type: "GET",
headers: {
"accept": "application/json;odata=verbose",
}
}).done(function(results) {
buildObject(results, listName);
}).fail(function(error) {
console.log("Error in getting List: " + listName);
$(_options.container).html("Error retrieving your " + listName + ". " + SP.PageContextInfo.get_webServerRelativeUrl());
});
}
function createStatusView2(Arr) {
var divisionArr = [];
var oRGArr = [];
var divisionCount = 0;
var oRGCount = 0;
for (var i = 0; i < Arr.length; i++) {
if ($.inArray(Arr[i].Division, divisionArr) === -1) {
divisionArr.push(Arr[i].Division);
var divisionHolderElement = $("<div id='p_" + Arr[i].Division + "' class='division_row_holder'></div>");
var divisionElement = $("<div id='" + Arr[i].Division + "' class='division_div ORG'></div>").text(Arr[i].Division);
$("#cabbage").append(divisionHolderElement);
$(divisionHolderElement).append(divisionElement);
}
if ($.inArray(Arr[i].ORG, oRGArr) === -1) {
oRGArr.push(Arr[i].ORG);
var orgElement = $("<div class='org_div ORG' id='" + Arr[i].ORG + "' style='font-size:10px;'></div>").text(Arr[i].ORG);
$("#p_" + Arr[i].Division).append(orgElement);
}
}
}
//automatically fired by init
function _onQueryFailed(sender, args) {
alert('Request failed.\nError: ' + args.get_message() + '\nStackTrace: ' + args.get_stackTrace());
}
return pub
}());
$(document).ready(function() {
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function() {
//After the SP scripts are run, we access the WebComplianceReportApp.GetStatuses
WebComplianceReportApp.GetStatuses.init();
});
});
</script>
I dont know if this will make your code dirty, but I would use a flag in this case
ex:
var ajaxCalls = 0;
function checkAjaxCalls()
{
if (ajaxCalls == 2)
{
//do your thing...
//and maybe you want to reset ajaxCalls value to zero if needed...
}
}
And from each Ajax response completes, increment ajaxCalls variable by one, and call the checkAjaxCalls function from both your Ajax responses.
Method One:
This time we'll have waited for the request to complete instead of waiting for the request to succeed
$(".ajax-form-button-thingy").on("click", function() {
$.ajax({
url: $(this).attr("href"),
type: 'GET',
error: function() {
throw new Error("Oh no, something went wrong :(");
},
complete: function(response) {
$(".ajax-form-response-place").html(response);
}
});
});
Method Two:
If you want to wait for ALL Ajax requests to complete without changing the async option to false then you might be looking for jQuery.ajaxComplete();
In jQuery every time an Ajax request completes the jQuery.ajaxComplete(); event is triggered.
Here is a simple example but there is more info on jQuery.ajaxComplete(); over here.
$(document).ajaxComplete(function(event, request, settings) {
$(".message").html("<div class='alert alert-info'>Request Complete.</div>");
});
Also you can take a look at the Ajax response by using request.responseText this might be useful in case you want to double check the response.
For more information about jQuery.ajax you can read the docs here
You could call createStatusView(); and then call createStatusView2(); after all of your Ajax requests are done
$(document).ready(function(){
createStatusView();
$(this).ajaxStop(function() {
// NOTE: I did not see you use createStatusView(); in your code
createStatusView2();
});
});
How do I extract highlighted(in green) data from Wikipedia API and display on front-end. I want to separate those value and display it separately in front-end.
function getJSONP(url, success) {
var ud = '_' + +new Date,
script = document.createElement('script'),
head = document.getElementsByTagName('head')[0] || document.documentElement;
window[ud] = function(data) {
head.removeChild(script);
success && success(data);
};
script.src = url.replace('callback=?', 'callback=' + ud);
head.appendChild(script);
}
getJSONP('http://en.wikipedia.org/w/api.php?format=json&action=query&titles=List_of_metropolitan_areas_by_population&prop=revisions&rvprop=content&callback=?', function(data){
console.log(data);
document.getElementById("title").innerHTML = data.query.pages[125279].title;
var inContent = data.query.pages[125279].revisions[0];
document.getElementById("con").innerHTML = inContent;
});
<div id="title"></div>
<div id="con"></div>
I have three separate javascript/jquery functions, all of which fire off after the user clicks a button. One function posts to a form handler. Another function creates a new tab. And the third function grabs the id of the new tab and posts sends new information into the tab via an ajax call. They all work together and depend on one another.
I have tried many different configurations, and I cannot figure out how to properly get a confirmation dialog (e.g., "Do you want to perform this action?) to work with all three of these simultaneously. If the user clicks "yes," the process should fire. If the user clicks "no," the process should die. Any help is greatly appreciated.
Edit: I've posted my code below. I'm sure it's really noobish, which is why I didn't post it the begin with. Trying to learn though. Thanks!
jQuery(".update_form").click(function(e) { // changed
e.preventDefault();
jQuery.ajax({
type: "POST",
url: "/eemcontrolpanel/process.cshtml",
data: jQuery(this).parent().serialize() // changed
});
return false; // avoid to execute the actual submit of the form.
});
jQuery(".update_form").click(function () {
var form = jQuery(this).parents('form:first');
title = jQuery("input[name='process']", form).val();
$('#tt').tabs('add',{
title:title,
content:'Script starting',
closable:true
});
$('div.panel-body:last').attr("id","tab" + panelIds[panelIds.length - 1] + 1);
panelIds.push(panelIds[panelIds.length - 1] + 1);
});
jQuery(".update_form").click(function (e) {
e.preventDefault();
//var j = jQuery.noConflict();
var form = jQuery(this).parents('form:first');
var fileName = jQuery("input[name='process']", form).val();
jQuery(document).ready(function () {
var XHR;
var stopMe = 1;
var isSame = 0;
var oldhtml;
var tabID = "tab" + panelIds[panelIds.length - 1];
jQuery("#"+ tabID).everyTime(1000, function (i) {
if (stopMe != 2){
XHR = jQuery.ajax({
url: "/eemcontrolpanel/jobs/" + fileName + ".txt",
cache: false,
success: function (html){
if (html === oldhtml){
isSame++;
if (isSame === 10){
stopMe = 2;
}
}
jQuery("#"+ tabID).html("<pre>" + html + "</pre>").scrollHeight;
oldhtml = html;
}
});
} else {
jQuery("#"+ tabID).stopTime();
}
jQuery("#"+ tabID).css({ color: "white" });
});
});
});
This is what I ended up doing. I basically combined all the functions into one big function.
var panelIds = new Array();
panelIds.push('0');
jQuery(".update_form").click(function (e) {
if (confirm('Are you sure?')) {
e.preventDefault();
jQuery.ajax({
type: "POST",
url: "/eemcontrolpanel/process.cshtml",
data: jQuery(this).parent().serialize() // changed
});
var form = jQuery(this).parents('form:first');
var title = jQuery("input[name='process']", form).val();
$('#tt').tabs('add',{
title:title,
content:'Script starting',
closable:true
});
$('div.panel-body:last').attr("id","tab" + panelIds[panelIds.length - 1] + 1);
panelIds.push(panelIds[panelIds.length - 1] + 1);
//var j = jQuery.noConflict();
var fileName = jQuery("input[name='process']", form).val();
var XHR;
var stopMe = 1;
var isSame = 0;
var oldhtml;
var tabID = "tab" + panelIds[panelIds.length - 1];
//alert(tabID);
jQuery("#"+ tabID).everyTime(1000, function (i) {
//alert(stopMe);
//add also if stopme=false else quit/end/whatever
if (stopMe != 2){
//alert(stopMe);
XHR = jQuery.ajax({
url: "/eemcontrolpanel/jobs/" + fileName + ".txt",
cache: false,
success: function (html){
//alert(html);
if (html === oldhtml){
isSame++;
//alert(isSame);
if (isSame === 10){
stopMe = 2;
//alert(stopMe);
}
}
jQuery("#"+ tabID).html("<pre>" + html + "</pre>").scrollHeight;
oldhtml = html;
//alert(oldhtml);
}
});
} else {
jQuery("#"+ tabID).stopTime();
}
jQuery("#"+ tabID).css({ color: "white" });
});
} else {
return false;
}
});
Have you tried this:
Function onButtonPush(){
if(confirm('confirm message')){
function1();
function2();
function3();
}
}
I am developing a html application for Android and I am trying to load images in a list view. Data specific to list items is being served by multiple xml files. I am using ajax to load xml files and populate the list items. Problem I am facing here is that there are 164 list items. Hence, 164 images and 10 xml files to load. my loader function exhausts after two iterations. It does read the xml files but it's unable to dynamically create list items and populate them with images after two iterations. I believe it's due to stack limitations. I can't think of alternate solution. If somebody could suggest an alternate solution that will be highly appreciated. Below is my loader function. It's a recursive function:
function loadChannels() {
$.ajax({
type: "GET",
url: curURL,
dataType: "xml",
error: function(){ console.log('Error Loading Channel XML'); },
success: function(nXml) {
var noOfItems = parseInt($($(nXml).find('total_items')[0]).text(), 10);
var startIdx = parseInt($($(nXml).find('item_startidx')[0]).text(), 10);
var allItems = $(nXml).find('item');
$(allItems).each(function() {
var obj = $("<li><span id='cont-thumb'></span><span id='cont-name'></span></li>");
$("#content-scroller ul").append($(obj));
var imgURL = $($(this).find('item_image')[0]).text();
var contThumb = $(obj).children()[0];
$(contThumb).css("background-image", 'url('+imgURL+')');
var name = $($(this).find('name')[0]).text();
var contName = $(obj).children()[1];
$(contName).text(name).css('text-align', 'center');
var url = $($(this).find('link')[0]).text();
$(obj).data('item_link', url);
$(obj).bind('click', onJPContSelected);
});
if(startIdx+allItems.length < noOfItems){
var newIdx = new Number(startIdx+allItems.length);
var tokens = curURL.split("/");
tokens[tokens.length-2] = newIdx.toString(10);
curURL = "http:/";
for(var i=2; i<tokens.length; i++)
curURL = curURL + "/" + tokens[i];
loadChannels();
}
}
});
}
try to remove the recursion with an outer loop - something like that:
function loadChannels(){
var stopFlag = false;
// request the pages one after another till done
while(!stopFlag)
{
$.ajax({
type: "GET",
url: curURL,
dataType: "xml",
error: function(){
console.log('Error Loading Channel XML');
errorFlaf = true;
},
success: function(nXml) {
var noOfItems = parseInt($($(nXml).find('total_items')[0]).text(), 10);
var startIdx = parseInt($($(nXml).find('item_startidx')[0]).text(), 10);
var allItems = $(nXml).find('item');
$(allItems).each(function() {
var obj = $("<li><span id='cont-thumb'></span><span id='cont-name'></span></li>");
$("#content-scroller ul").append($(obj));
var imgURL = $($(this).find('item_image')[0]).text();
var contThumb = $(obj).children()[0];
$(contThumb).css("background-image", 'url('+imgURL+')');
var name = $($(this).find('name')[0]).text();
var contName = $(obj).children()[1];
$(contName).text(name).css('text-align', 'center');
var url = $($(this).find('link')[0]).text();
$(obj).data('item_link', url);
$(obj).bind('click', onJPContSelected);
});
if(startIdx+allItems.length < noOfItems){
var newIdx = new Number(startIdx+allItems.length);
var tokens = curURL.split("/");
tokens[tokens.length-2] = newIdx.toString(10);
curURL = "http:/";
for(var i=2; i<tokens.length; i++)
curURL = curURL + "/" + tokens[i];
// lets disable the recursion
// loadChannels();
}
else {
stopFlag = true;
}
}
});
}
}