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

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>

Related

My Ajax code isn't working.

"text.txt" is located in the same folder as the html file so that shouldn't be the problem. I want to change the h4 header to the text within the text file
function load_doc(){
var xhttp = new XMLHttpRequest();
xttp.onreadystatechange = function(){
if (this.readyState == 4 && this.status == 200){
document.getElementById("ajax_example").innerHTML = this.responseText;
}
};
xhttp.open("GET","text.txt",true);
xhttp.send();
}
<div id="ajax_example">
<h4>Request Object</h4>
<button type="button" onclick="load_doc()">Change Text</button>
</div>
have you tried with full path specification?
something like
xhttp.open('GET', 'file:///home/user/text.txt', true);

How to complete XMLHttpRequest

I'm making a type of dictionary webpage and I cannot figure out how to get the XMLHttpRequest working. I need to transfer XML information to a specific place in the html, id="data". I'm trying to do it this way so that the page won't have to refresh. The code is very messy I apologize.
<p> <!-- This is the button that will trigger the data appearing -->
<div id="div1" id="buttons" >
<ul class="actions">
<li><input type="button" id="ajaxButton" value="Traditional" class="special"/></li>
</ul>
</div>
<script type="text/javascript">
(function () {
var httpRequest;
document.getElementById("ajaxButton").onclick = function() {
var title = document.getElementById("data").value;
makeRequest('data.xml', word)
}
};
function makeRequest(url, word) {
httpRequest = new XMLRequst();
if (!httpRequest) {
alert('Giving up. Cannot create an XMLHTTP instance');
return false;
}
xmlhttp.onreadystatechange = contents;
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
//contents(xmlhttp);
httpRequst.open("GET", url);
httpRequest.send();
}
function contents() {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
if(xmlhttp.status == 200) {
//This is where the XML should be sent to the HTML
}
</script>
<div id="data">
<!-- XML DATA WILL GO HERE POTENTIALLY -->
</div>
And here is the XML file 'data.xml'
<dictionary>
<word>
<title>Ubiquitous</title>
<trad>This is the traditional defintion ubiquitous</trad>
<simp>This is the simplified defintion hopefully ubiquitous</simp>
</word>
<word>
<title>Lithe</title>
<trad>This is the traditional defintion of lithe</trad>
<simp>This is the simplified defintion of lithe hopefully</simp>
</word>
</dictionary>
May be of your interest to include an asynchronous function between httpRequest.open(...) and httpRequest.send() like this:
//f is your xml file
var fileURL = URL.createObjectURL(f);
httpRequest.open("GET", fileURL);
httpRequest.onload = function(){
URL.revokeObjectURL(fileURL);
populateHTML(this.responseXML);
};
httpRequest.send();
Then create outside a method populateHTML to manipulate what is obtained:
function populateHTML(xmlDoc){
var accessAtr = xmlDoc.getElementsByTagName("trad")[0].childNodes[0].nodeValue;//gets the content of first trad tag.
//use accessAtr to continue writing your "data" id HTML content from here.
}

PhoneGap upload Image to server on form submit

I am facing problem here as in phonegap image is uploaded to the server once u select a picture.I don't want to upload image before submitting form. Image is uploaded automatically to server which is something i don't want.I want to upload image with the form, where form contains many more fields which is required to send along with image. What are the possible ways to submit with form?
<!DOCTYPE HTML >
<html>
<head>
<title>Registration Form</title>
<script type="text/javascript" charset="utf-8" src="phonegap-1.2.0.js"></script>
<script type="text/javascript" charset="utf-8">
// Wait for PhoneGap to load
document.addEventListener("deviceready", onDeviceReady, false);
// PhoneGap is ready
function onDeviceReady() {
// Do cool things here...
}
function getImage() {
// Retrieve image file location from specified source
navigator.camera.getPicture(uploadPhoto, function(message) {
alert('get picture failed');
},{
quality: 50,
destinationType: navigator.camera.DestinationType.FILE_URI,
sourceType: navigator.camera.PictureSourceType.PHOTOLIBRARY
});}
function uploadPhoto(imageURI) {
var options = new FileUploadOptions();
options.fileKey="file";
options.fileName=imageURI.substr(imageURI.lastIndexOf('/')+1);
options.mimeType="image/jpeg";
var params = new Object();
params.value1 = "test";
params.value2 = "param";
options.params = params;
options.chunkedMode = false;
var ft = new FileTransfer();
ft.upload(imageURI, "http://yourdomain.com/upload.php", win, fail, options);
}
function win(r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
alert(r.response);
}
function fail(error) {
alert("An error has occurred: Code = " = error.code);
}
</script>
</head>
<body>
<form id="regform">
<button onclick="getImage();">select Avatar<button>
<input type="text" id="firstname" name="firstname" />
<input type="text" id="lastname" name="lastname" />
<input type="text" id="workPlace" name="workPlace" class="" />
<input type="submit" id="btnSubmit" value="Submit" />
</form>
</body>
</html>
Create two functions you can call separately. One function for just getting the image, and another function to upload the image.
You can do something like below.
<!DOCTYPE html>
<html>
<head>
<title>Submit form</title>
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<script type="text/javascript" charset="utf-8">
var pictureSource; // picture source
var destinationType; // sets the format of returned value
// Wait for device API libraries to load
//
document.addEventListener("deviceready",onDeviceReady,false);
// device APIs are available
//
function onDeviceReady() {
pictureSource = navigator.camera.PictureSourceType;
destinationType = navigator.camera.DestinationType;
}
// Called when a photo is successfully retrieved
//
function onPhotoURISuccess(imageURI) {
// Show the selected image
var smallImage = document.getElementById('smallImage');
smallImage.style.display = 'block';
smallImage.src = imageURI;
}
// A button will call this function
//
function getPhoto(source) {
// Retrieve image file location from specified source
navigator.camera.getPicture(onPhotoURISuccess, onFail, { quality: 50,
destinationType: destinationType.FILE_URI,
sourceType: source });
}
function uploadPhoto() {
//selected photo URI is in the src attribute (we set this on getPhoto)
var imageURI = document.getElementById('smallImage').getAttribute("src");
if (!imageURI) {
alert('Please select an image first.');
return;
}
//set upload options
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = imageURI.substr(imageURI.lastIndexOf('/')+1);
options.mimeType = "image/jpeg";
options.params = {
firstname: document.getElementById("firstname").value,
lastname: document.getElementById("lastname").value,
workplace: document.getElementById("workplace").value
}
var ft = new FileTransfer();
ft.upload(imageURI, encodeURI("http://some.server.com/upload.php"), win, fail, options);
}
// Called if something bad happens.
//
function onFail(message) {
console.log('Failed because: ' + message);
}
function win(r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
//alert("Response =" + r.response);
console.log("Sent = " + r.bytesSent);
}
function fail(error) {
alert("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
}
</script>
</head>
<body>
<form id="regform">
<button onclick="getPhoto(pictureSource.PHOTOLIBRARY);">Select Photo:</button><br>
<img style="display:none;width:60px;height:60px;" id="smallImage" src="" />
First Name: <input type="text" id="firstname" name="firstname"><br>
Last Name: <input type="text" id="lastname" name="lastname"><br>
Work Place: <input type="text" id="workplace" name="workPlace"><br>
<input type="button" id="btnSubmit" value="Submit" onclick="uploadPhoto();">
</form>
</body>
</html>
You're already sending custom fields in your example.
var params = new Object();
params.value1 = "test";
params.value2 = "param";
options.params = params;
Just populate params with your form fields.
I also faced same problem, but I have done using two server side calls on one click. In this, in first call submit data and get its id in callback using JSON then upload image using this id. On server side updated data and image using this id.
$('#btn_Submit').on('click',function(event) {
event.preventDefault();
if(event.handled !== true)
{
var ajax_call = serviceURL;
var str = $('#frm_id').serialize();
$.ajax({
type: "POST",
url: ajax_call,
data: str,
dataType: "json",
success: function(response){
//console.log(JSON.stringify(response))
$.each(response, function(key, value) {
if(value.Id){
if($('#vImage').attr('src')){
var imagefile = imageURI;
$('#vImage').attr('src', imagefile);
/* Image Upload Start */
var ft = new FileTransfer();
var options = new FileUploadOptions();
options.fileKey="vImage";
options.fileName=imagefile.substr(imagefile.lastIndexOf('/')+1);
options.mimeType="image/jpeg";
var params = new Object();
params.value1 = "test";
params.value2 = "param";
options.params = params;
options.chunkedMode = false;
ft.upload(imagefile, your_service_url+'&Id='+Id+'&mode=upload', win, fail, options);
/* Image Upload End */
}
}
});
}
}).done(function() {
$.mobile.hidePageLoadingMsg();
})
event.handled = true;
}
return false;
});
On server side using PHP
if($_GET['type'] != "upload"){
// Add insert logic code
}else if($_GET['type'] == "upload"){
// Add logic for image
if(!empty($_FILES['vImage']) ){
// Copy image code and update data
}
}
I could not get these plugins to upload a file with the other answers.
The problem seemed to stem from the FileTransfer plugin, which states:
fileURL: Filesystem URL representing the file on the device or a data URI.
But that did not appear to work properly for me. Instead I needed to use the File plugin to create a temporary file using the data uri to get me a blob object: in their example, writeFile is a function which takes a fileEntry (returned by createFile) and dataObj (blob). Once the file is written, its path can be retrieved and passed to the FileTransfer instance. Seems like an awful lot of work, but at least it's now uploading.

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.

jQuery pagination kills my toggle switches

My page shows posts stored in my Database through a loop. Each post is paired with a like and dislike button. The page has two master controls switches that show/hide all liked posts and show/hide all dislike posts.
This all works perfectly. I am now trying to paginate said posts while still keeping the above functions intact. This is proving difficult. In short, if I click on a div with class "like" var value is set to "1" and ajax fires, storing that value in my database and returns a success message. The same happens for dislike with the difference being that var value is set to "0".
If the user chooses to hide all liked posts, they do indeed hide but no other posts pop up in their places. I'd like it for the pagination to ALWAYS display X results per page even after some posts get toggled. As it is, If I hide 3 of 5 posts, only 2 posts remain instead of having 3 next posts come in.
imtech_pager.js looks for a div called "contained" and looks inside it for all divs with class "z". These divs then get paginated. This does work. It's just that it causes the above problem.
likedislike.js (toggling x number of posts doesn't result in pulling in the next x number of posts):
$(document).ready(function() {
likestatus = 1;
dislikestatus = 1;
$(document).on("click", ".like", function(){
postID = $(this).attr('id').replace('like_', '');
// Declare variables
value = '1';
myajax();
return false;
});
$(document).on("click", ".dislike", function(){
postID = $(this).attr('id').replace('dislike_', '');
// Declare variables
value = '0';
myajax();
return false;
});
function myajax(){
// Send values to database
$.ajax({
url: 'check.php',
//check.php receives the values sent to it and stores them in the database
type: 'POST',
data: 'postID=' + postID + '&value=' + value,
success: function(result) {
$('#Message_' + postID).html('').html(result).prependTo('#post_' + postID);
if (result.indexOf("No") < 0){ //If return doesn't contain string "No", do this
if (value == 1){ //If post is liked, do this
$('#post_' + postID).removeClass('dislike').addClass('like');
$('#dislikebtn_' + postID).removeClass('dislikeimgon').addClass('dislikeimgoff');
$('#likebtn_' + postID).removeClass('likeimgoff').addClass('likeimgon');
// If Hide Liked checkbox is on, toggle the post
if (likestatus % 2 == 0) {
$('#post_' + postID).toggle();
}
} else if (value == 0){ //If post is disliked, do this
$('#post_' + postID).removeClass('like').addClass('dislike');
$('#likebtn_' + postID).removeClass('likeimgon').addClass('likeimgoff');
$('#dislikebtn_' + postID).removeClass('dislikeimgoff').addClass('dislikeimgon');
// If Hide Disliked checkbox is on, toggle the post
if (dislikestatus % 2 == 0) {
$('#post_' + postID).toggle();
}
}
}
}
});
}
//When Hide Liked checkbox clicked, toggle all Liked posts.
$('#show_likes').on('click', function() {
countlikes = $('[id^=post_].like').length;
if (countlikes >0) {
likestatus++;
$('[id^=post_].like').toggle();
if (likestatus % 2 == 0) {
$('#hidelikedbtn').removeClass('hidelikedimgoff').addClass('hidelikedimgon');
} else {
$('#hidelikedbtn').removeClass('hidelikedimgon').addClass('hidelikedimgoff');
}
}
return false;
});
//When Hide Disliked checkbox clicked, toggle all Disliked posts.
$('#show_dislikes').on('click', function() {
countdislikes = $('[id^=post_].dislike').length;
if (countdislikes >0) {
dislikestatus++;
$('[id^=post_].dislike').toggle();
if (dislikestatus % 2 == 0) {
$('#hidedislikedbtn').removeClass('hidedislikedimgoff').addClass('hidedislikedimgon');
} else {
$('#hidedislikedbtn').removeClass('hidedislikedimgon').addClass('hidedislikedimgoff');
}
}
return false;
});
});
imtech_pager.js (this paginates all divs with class "z" - works fine)
var Imtech = {};
Imtech.Pager = function() {
this.paragraphsPerPage = 3;
this.currentPage = 1;
this.pagingControlsContainer = '#pagingControls';
this.pagingContainerPath = '#contained';
this.numPages = function() {
var numPages = 0;
if (this.paragraphs != null && this.paragraphsPerPage != null) {
numPages = Math.ceil(this.paragraphs.length / this.paragraphsPerPage);
}
return numPages;
};
this.showPage = function(page) {
this.currentPage = page;
var html = '';
this.paragraphs.slice((page-1) * this.paragraphsPerPage,
((page-1)*this.paragraphsPerPage) + this.paragraphsPerPage).each(function() {
html += '<div>' + $(this).html() + '</div>';
});
$(this.pagingContainerPath).html(html);
renderControls(this.pagingControlsContainer, this.currentPage, this.numPages());
}
var renderControls = function(container, currentPage, numPages) {
var pagingControls = 'Page: <ul>';
for (var i = 1; i <= numPages; i++) {
if (i != currentPage) {
pagingControls += '<li>' + i + '</li>';
} else {
pagingControls += '<li>' + i + '</li>';
}
}
pagingControls += '</ul>';
$(container).html(pagingControls);
}
}
index.php (displays all the divs and buttons)
<div id="content">
<div id="mastercontrols">
<div id="show_likes" style="position:absolute;">
<a id="hidelikedbtn" class="hidelikedimgoff" href="#"><span></span></a>
</div>
<div id="show_dislikes" style="position:absolute; right: 0em;">
<a id="hidedislikedbtn" class="hidedislikedimgoff" href="#"><span></span></a>
</div>
</div>
<div id="contained">
<?php
$data = mysql_query("SELECT * FROM Posts") or die(mysql_error());
while($row = mysql_fetch_array( $data )){
?>
<div class="z">
<div id="post_<?php echo $row['postID']; ?>" class="post">
<div id="post_<?php echo $row['postID']; ?>_inside" class="inside">
<div id="like_<?php echo $row['postID']; ?>" class="like" style="position:absolute; right: 2.5em;">
<a id="likebtn_<?php echo $row['postID']; ?>" class="likeimgoff" href="#"><span></span></a>
</div>
<div id="dislike_<?php echo $row['postID']; ?>" class="dislike" style="position:absolute; right: 0em;">
<a id="dislikebtn_<?php echo $row['postID']; ?>" class="dislikeimgoff" href="#"><span></span></a>
</div>
<b><?php echo $row['Title']; ?></b><br>
<?php echo $row['Description']; ?><br>
<div id="postleft">
</div>
<div id="postright">
</div>
</div>
</div>
<div id="Message_<?php echo $row['postID']; ?>" class="reminder"></div>
</div>
<?php
}
?>
</div>
<div id="pagingControls"></div>
</div>
<script type="text/javascript">
var pager = new Imtech.Pager();
$(document).ready(function() {
pager.paragraphsPerPage = 5; // set amount elements per page
pager.pagingContainer = $('#container'); // set of main container
pager.paragraphs = $('div.z', pager.pagingContainer); // set of required containers
pager.showPage(1);
});
</script>
So any ideas? This perplexes me to no end! The variables are all different, everything formats properly. The divs do get paginated and the pagination buttons (page 1, 2, 3, etc) all work. There's just something inside imtech_pager.js that stops the rest of my code from working as it should.
Again:
Toggling some posts does not result in repopulating the paginated pages. (Hiding 3 of 5 posts results in leaving 2 posts on the page instead of bringing in the next 3 posts for a total of 5 posts on the page).
I think the issue is probably that the elements are being added and removed from the DOM which is then making them lose their handlers. You should be able to just delegate the events.
Since you are using 1.7, I believe the syntax would be:
$(document).on("click", ".dislike", function(){
instead of
$('.dislike').on('click', function() {
This is the equivilent to live pre-1.7. You can refine the delegation for better performance by replacing document with a more specific selector which is the parent of all of the elements you are trying to attach the handler to, but which is not being added and removed.

Resources