switching from ajax function to fetch - ajax

I have a little ajax function that return a url in a modal window. I have been told that the fetch API is better. I cant find a way to do the equivalent to what I already have. Can anyone give me an example of some thing similar to
function loadDoc(url) {
var xhttp = new XMLHttpRequest()
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
document.getElementById('results').innerHTML = this.responseText
} else
document.getElementById('results').innerHTML =
'<div class="loader" style="display: flex; align-items: center; justify-content: center;padding: 150px 0;">' +
'<img src="/eigg/img/ajax-loader.gif" alt="Smiley face" style="width: 50px;height: auto;background-repeat: no-repeat;"></div>'
}
xhttp.open('POST', url, true)
xhttp.send()
}
Much appreciated, I find the docs quite hard to understand. Also would be nice to know why fetch is "better" than ajax

Related

How to make an id= from an XML call give a link to what its calling?

One of my API calls gives a youtube link and I want the link to be clickable and open on another tab, but nothing is working
this is mode code HTML:
//the id produces a youtube link that that can be clicked, but if I add the id to the href, then it wont work.
<a href="" target="_blank">
<p id="strYoutube2"></p>
</a>
my js code:
//this is my XML call, if theres another .link function other than .innerXML for the youtube link, maybe that can be the issue, but I cant find anything online.
function getPosts() {
let xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.themealdb.com/api/json/v1/1/random.php', true);
console.log(xhr.readyState);
xhr.send();
xhr.onreadystatechange = () => {
if (xhr.readyState == 4 && xhr.status == 200) {
let response = JSON.parse(xhr.responseText);
console.log('response below:')
console.log(response);
console.log(response.meals[0].strMealThumb);
document.getElementById('strMeal').innerText = response.meals[0].strMeal
document.getElementById('strCategory').innerText = response.meals[0].strCategory
document.getElementById('strArea').innerText = response.meals[0].strArea
document.getElementById('strTags').innerText = response.meals[0].strTags
document.getElementById('strYoutube').innerHTML = response.meals[0].strYoutube
document.getElementById('strMealThumb').src = response.meals[0].strMealThumb
}
}
}
The HTML element with id strYoutube does NOT exist in you provided code:
document.getElementById('strYoutube').innerHTML = response.meals[0].strYoutube
For achieve what you're triyng to do, you can change your code as follows:
Check that I set an img HTML element with a predefined width and height.
Check the working jsfiddle here too:
// This is your function for get the posts of the given API URL.
function getPosts() {
let xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.themealdb.com/api/json/v1/1/random.php', true);
console.log(xhr.readyState);
xhr.send();
xhr.onreadystatechange = () => {
if (xhr.readyState == 4 && xhr.status == 200) {
let response = JSON.parse(xhr.responseText);
console.log('response below:')
console.log(response);
console.log(response.meals[0].strMealThumb);
// Comented due these HTML elements aren't here.
//document.getElementById('strMeal').innerText = response.meals[0].strMeal
//document.getElementById('strCategory').innerText = response.meals[0].strCategory
//document.getElementById('strArea').innerText = response.meals[0].strArea
//document.getElementById('strTags').innerText = response.meals[0].strTags
//document.getElementById('strYoutube').innerHTML = response.meals[0].strYoutube
//document.getElementById('strMealThumb').src = response.meals[0].strMealThumb
// Here I set the values to your HTML elements:
// "strYoutube" is the HTML anchor element "<a href>".
document.getElementById('strYoutube').href = response.meals[0].strYoutube;
// "myImg" is the HTML image element "<img src>".
document.getElementById('myImg').src = "https://www.themealdb.com/images/media/meals/ysqupp1511640538.jpg";
document.getElementById('myImg').alt = response.meals[0].strMeal;
document.getElementById('myImg').title = response.meals[0].strMeal;
}
}
}
// Call your function and set the values ion the HTML elements:
getPosts();
<a href="" target="_blank" id="strYoutube">
<p id="strYoutube2">
<img src="#" id="myImg" alt="image" title="" style="width: 150px; height: 150px;" />
</p>
</a>

An Ajax call in Liferay 6.2 portlet

I'm beginner with Liferay, and I would Like to make an ajax call. What i am doing is: - I have a button In the jsp page to make the ajax call
a variable is initialized in the javascript code, and incremented every time the user clicks on the button. this variable is transmeted to the server to be used as a parameter of a function.
Code Snippet
aui_ajax.jsp:
<input type="button" value = "Ajouter un projet" onClick="<portlet:namespace/>Test();return false;">
<div id="usersTable">
<input type="button" value = "Ajouter un projet" onClick=" <portlet:namespace/>Test();return false;">
</div>
<div id="wait" style="display:none; width: 69px; height: 89px; border: 1px solid black; position: absolute; top: 50%; left: 50%; padding: 2px;">
<img src='http://www.w3schools.com/jquery/demo_wait.gif' width="64" height="64" /> <br>Loading..
</div>
<script>
var i=1
function <portlet:namespace/>Test() {
var i=1;
AUI().use('aui-base','aui-io-request', function(A){
i++;
A.one('#wait').setStyle('display', 'block');
var allRows=A.one('#usersTable').getHTML();
var querystring = 'message:' + '1';
//aui ajax call to get updated content
A.io.request('<%=updaContentURL%>',{
dataType: 'json',
method: 'GET',
data: querystring,
on: {
success: function() {
var data=this.get('responseData');
A.Array.each(data, function(obj, idx){
var tableRow=obj.firstName;
//allRows=allRows.trim()+tableRow.trim();
//A.one('#usersTable').empty();
//A.one('#usersTable').setHTML(tableRow.trim());
A.one('#usersTable').append(tableRow.trim());
A.one('#wait').setStyle('display','none');
});
}
}
});
});
}
</script>
ContentAutoUpdateAction.java
public class ContentAutoUpdateAction extends MVCPortlet {
public void serveResource(ResourceRequest resourceRequest,
ResourceResponse resourceResponse)
throws IOException, PortletException {
try {
System.out.println("====serveResource========");
JSONObject jsonUser=null;
JSONArray usersJsonArray=JSONFactoryUtil.createJSONArray();
resourceRequest.getParameter("message");
int i=Integer.parseInt(message);
i++;
System.out.println(i);
//}
PrintWriter out=resourceResponse.getWriter();
System.out.println(usersJsonArray.toString());
out.print(usersJsonArray.toString());
}
catch (Exception e) {
e.printStackTrace();
}
}
the problem is that I can't get the parameter "message" in the ContentAutoUpdateAction.java
Although an old question but wanted to answer.
You have to enable ajax for the portlet.
<ajaxable>true</ajaxable>
within liferay-portlet.xml
Secondly, you can pass the parameter in ajax by using
data: {
paramName1: paramValue,
paramName2: paramValue2
}
If you want to concatenate it as a querystring then you can use
var ajaxURL = "<portlet:resourceURL/>";
ajaxURL = ajaxURL + "&message=1";
and then use the ajaxURL for the url of the ajax request.
The information I have heard is that it's a known bug.
I know a workaround:
HttpServletRequest httpReq = PortalUtil.getHttpServletRequest(resourceRequest);
param = PortalUtil.getOriginalServletRequest(httpReq).getParameter("name");
Hope it helps.
Not sure about this:
var querystring = 'message:' + '1';
You are constructing a GET request string, so I would change it to:
var querystring = '&message=' + '1';
Also, that's not the only way to pass parameters to ajax request, you can also try this way:
A.io.request('<%=updaContentURL%>',{
dataType: 'json',
method: 'POST',
data: {message: '1'}

how to implement onpopstate? confused after reading so many things

I am loading content using AJAX, and changing URL by using pushastate, below is my code, can anybody tell me how to implement onpopstate to enable back button in my case.
HTML
<div id="tabs" style="margin:1px 0px 0px 15px;">
<ul class="tabs-ul">
<li id="boardLi" class="current-tab"><a class="current-tab" href="board.jsp">Board</a></li>
<li id="aboutLi">Info</li>
<li id="photoLi">Photo Albums</li>
</ul>
</div>
JS
$(document).ready(function() {
function loadContent(path,c,pageName){
$.ajax({ url: path, success: function(html) {
$('#ajax-content').empty().append(html);
window.history.pushState({path:''},'',pageName+'?tab='+c);
}
});
}
function checkC(target){
var c='';
if(target=='aboutme.jsp')
{c='info';}
else if(target=='board.jsp')
{c='board';}
else if(target=='photo.jsp')
{c='photo';}
else if(target=='tab.jsp')
{c='ht';}
return c;
}
$(".tabs-ul li a").on('click', function(e) {
e.preventDefault();
$('#ajax-content').empty().append("<div id='loading'><img src='images/preloader.gif' alt='Loading' /></div>");
$('.tabs-ul li a').removeClass('current-tab');
$('.tabs-ul li').removeClass('current-tab');
$(this).addClass('current-tab');
$(this).parent().addClass('current-tab');
var url = window.location.pathname;
var pageName = url.substring(url.lastIndexOf('/') + 1);
var target=$(this).attr('href');
var c=checkC(target);
loadContent(target,c,pageName);
return false;
});
var loaded = false;
window.onpopstate = function(e) {
if (!loaded) {
loaded = true;
return;
} else {
alert(window.loacation.back().pathname);
loadContent();
}
};
});
When user clicks on link, first of all I am adding removing class for loading then I am getting URL and getting the page name from that URL(saved in 'pageName'), 'target' is href attr of clicked link and 'c' is the value I will be showing in url(for example, example.com/profile.jsp?tab=info, here if the href is info.jsp then 'c' would be info), finally I am calling 'loadContent' function which loads ajax content and changes URL using pushState.

AJAX loading indicator

I use this AJAX code:
<script language="javascript" type="text/javascript">
<!--
//Browser Support Code
function ajaxFunction(){
var ajaxRequest; // The variable that makes Ajax possible!
try{
// Opera 8.0+, Firefox, Safari
ajaxRequest = new XMLHttpRequest();
} catch (e){
// Internet Explorer Browsers
try{
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try{
ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e){
// Something went wrong
alert("Your browser broke!");
return false;
}
}
}
// Create a function that will receive data sent from the server
ajaxRequest.onreadystatechange = function(){
if(ajaxRequest.readyState == 4){
var ajaxDisplay = document.getElementById('ajaxDiv');
ajaxDisplay.innerHTML = ajaxRequest.responseText;
}
}
var age = document.getElementById('age').value;
var wpm = document.getElementById('wpm').value;
var sex = document.getElementById('sex').value;
var queryString = "?age=" + age + "&wpm=" + wpm + "&sex=" + sex;
ajaxRequest.open("GET", "file.php" + queryString, true);
ajaxRequest.send(null);
}
//-->
</script>
How to indicate AJAX loading?
Common scenario is to show animated gif image or change mouse cursor on start of ajax request and at end.
Gif is much simpler. Something like (I am using JQuery Syntax):
For start:
$("#progressIndicator").show();
In your onreadystatechange handler
$("#progressIndicator").hide();
If your using JQuery you can do something like this:
$("#progressIndicator").show();
var age = $('#age')[0].value;
var wpm = $('#wpm')[0].value;
var sex = $('#sex')[0].value;
var queryString = "?age=" + age + "&wpm=" + wpm + "&sex=" + sex;
$.get("file.php" + queryString, function (data) {
$("ajaxDiv").html(data);
$("#progressIndicator").hide();
})
you can see more about the JQuery get method
here
You can bind the showing/hiding globally in your app (or just in some part of it) with the following events:
$(document).on({
ajaxStart: function () { $body.addClass("loading"); },
ajaxStop: function () { $body.removeClass("loading"); }
});
And then you define the class loading:
/* Start by setting display:none to make this hidden.
Then we position it in relation to the viewport window
with position:fixed. Width, height, top and left speak
for themselves. Background we set to 80% white with
our animation centered, and no-repeating */
.modal {
display: none;
position: fixed;
z-index: 1000;
top: 0;
left: 0;
height: 100%;
width: 100%;
background: rgba( 255, 255, 255, .8 ) url('../Images/Loader.gif') 50% 50% no-repeat;
}
/* When the body has the loading class, we turn the scrollbar off with overflow:hidden */
body.loading {
overflow: hidden;
}
/* Anytime the body has the loading class, our modal element will be visible */
body.loading .modal {
display: block;
}
In this way you don't need to manage the loading effect for every ajax call and you can maintain a consistent style through the entire application.

How to load vtip tooltip on a dynamically generated element?

I'm new to jQuery and trying to combine the use of a tooltip plugin and a lightbox plugin. More specifically, I am using Colorbox and vtip.
Colorbox generates a div which displays an image like this:
<div id="cboxLoadedContent" style="display: block; width: 400px; overflow: auto; height: 498px;">
<br>
<img src="image.jpg" id="cboxPhoto" style="margin: 49px auto auto; border: medium none; display: block; float: none; cursor: pointer;">
<br>
</div>
</code>
I next add class="vtip" title="This is a tip." in order to use the vtip style, but for some reason it does not work when it's a title tag on an element dynamically generated by Colorbox, but works on anything already loaded on the page.
Can anyone explain to me why this is and possibly offer some solutions to fix this problem?
If you don't want to have to re-call the function every time a new element is written to the page, I wrote an update to vtip. I rewrote the vtip function as a jQuery plugin, to be chainable, to allow custom settings, and to work with live elements. Its using a mapping of events, so it will work with jQuery 1.4.3 and up.
(function ($) {
$.fn.vtip = function (options) {
var settings = {
xOffset: -10,
yOffset: 6,
arrow: '/images/vtip_arrow.png'
};
if (options) $.extend(settings, options);
return this.live({
mouseenter: function (a) {
this.t = this.title;
this.title = "";
this.top = (a.pageY + settings.yOffset);
this.left = (a.pageX + settings.xOffset);
$("body").append('<p id="vtip"><img id="vtipArrow" />' + this.t + "</p>");
$("p#vtip #vtipArrow").attr("src", settings.arrow);
$("p#vtip").css("top", this.top + "px").css("left", this.left + "px").fadeIn("fast");
},
mouseleave: function (a) {
this.title = this.t;
$("p#vtip").fadeOut("fast").remove();
},
mousemove: function (a) {
this.top = (a.pageY + settings.yOffset);
this.left = (a.pageX + settings.xOffset);
$("p#vtip").css("top", this.top + "px").css("left", this.left + "px");
}
});
};
})(jQuery);
// You can use it with any class, I'm using the class 'vtip' below.
$(document).ready(function(){
$('.vtip').vtip();
});
// If necessary, add custom settings like so:
$('.vtip').vtip({xOffset:-10,yOffset:10,arrow:'/images/customArrow.png'});
I tried the code/re-written plugin on this page and ran into some complications... perhaps this will work better for someone and save you some time:
(function ($) {
$.fn.vtip = function (options) {
var settings = {
xOffset: -10,
yOffset: 20,
arrow: 'http://simages0.showtimesfast.com/icons2/vtip_arrow.png'
};
if (options) $.extend(settings, options);
return this.live('mouseover mouseout mousemove', function(a){
if(a.type == 'mouseover'){
this.top = (a.pageY + settings.yOffset);
this.left = (a.pageX + settings.xOffset);
$("body").append('<p id="vtip"><img id="vtipArrow" />' + this.title + "</p>");
$("p#vtip #vtipArrow").attr("src", settings.arrow);
$("p#vtip").css("top", this.top + "px").css("left", this.left + "px").fadeIn("fast");
}else if (a.type == 'mouseout'){
$("p#vtip").fadeOut("fast").remove();
}else if (a.type == 'mousemove'){
this.top = (a.pageY + settings.yOffset);
this.left = (a.pageX + settings.xOffset);
$("p#vtip").css("top", this.top + "px").css("left", this.left + "px");
}
});
};
})(jQuery);
Currently in use on http://www.showtimes.ca/ for you to see it working in action. Thanks to Steve above as you led me in the right direction for working with live events.
The clue is at the bottom of the vtip file:
jQuery(document).ready(function($){vtip();})
vtip is being called in document ready. It doesnt know about the elements you havent yet added. You need to recall the vtip function after you've added your elements.
vtip();
PS vtip hasnt been written as a plugin, otherwise you could chain it together with your other code eg
$('div').append('<a>example</a>').vtip(); //currently this wont work
You might want to contact the author and suggest the change, or find another tooltip - there are plenty around.

Resources