Calling a javascript function with parameters from a dynamically created element - javascript

I'm trying to dynamically load pictures to a profile page like site from MySQL with PHP and
then add them to an unordered list with javascript. I would like each list item to also have
a like button, which upon clicking calls a javascript function, passing the image name as
its parameter. I've searched and found answers on how to call a function without passing it
any variables, but every time I add the image name to the function call, the console log reads
"undefined".
The pictures show up fine and the imgArray[i] is a string containing the file's name (e.g. photo.jpg)
But
console.log(imgArray[i])
in the onclick function reads undefined. I've also tried
like.setAttribute()
without any results.
function showGallery(imgArray) {
for(var i=0; i < imgArray.length; i++){
var list = document.getElementById("image-list"),
li = document.createElement("li"),
img = document.createElement("img"),
like = document.createElement("a");
img.src = "user_images/" + imgArray[i];
like.className = "button-like";
li.appendChild(img);
li.appendChild(like);
list.appendChild(li);
like.href = "javascript:void(0);";
like.onclick = function() {
console.log(imgArray[i]);
addLike(imgArray[i]);
};
}
}
function addLike(img) {
console.log("Liking.. " + img);
$.ajax({
url: 'like.php',
type: 'POST',
data: {
'photo': img
},
success: function(likes){
console.log(likes);
}
});
}

The problem is that by the time the click event fires, imgArray[i] doesn't exists.
try doing it like this...
like.href = "javascript:void(0);";
like.imgArray = imgArray[i];
like.onclick = function() {
console.log(this.imgArray);
addLike(this.imgArray);
};
Hope that helps

Related

How to run a function from a link created in javascript

I have a function in a javascript file that adds a link to a paragraph that I created in the HTML file. I want to call a function that is defined in the javascript file when the user clicks the link.
My HTML:
<p id="para"></p>
My JavaScript:
var paraHTML = document.getElementById("para");
function addLink(id) {
paraHTML.innerHTML += '<a id="' + id + '" onclick="clickedTest(); return false;">Click me!</a>'
}
function clickedTest() {
console.log('here');
}
I have also tried using href e.g.
paraHTML.innerHTML += '<a id="' + id + '" href="javascricpt:clickedTest();">Click me!</a>'
But both ways give me an error saying: ReferenceError: clickedTest is not defined
I have tried using the following code from this question but the number of links is constantly changing whilst my code is running which makes it difficult to use:
var elements = document.getElementsByTagName('a');
for(var i = 0, len = elements.length; i < len; i++) {
elements[i].onclick = function () {
console.log('here')
}
}
The addLink() function is called elsewhere in my javascript program several times
Using innerHTML to create content is usually slow and is usually discouraged, a more organic approach will be to create the element pragmatically and then adding event listener to that element. For example,
var elem = document.createElement('a');
elem.addEventListener('click', myClickHandler);
elem.innerText = 'My Tag';
paraHTML.appendChild(elem)
function myClickHandler(e) {
console.log('a is clicked')
}
This will not only fix your problem but will make your code more manageable
You can do something like this:
function callMe(){
}
var newLink = document.createElement('a');
newLink.href="javascript:callMe();";
newLink.innerHTML="this is a link";
paraHTML.appendChild(newLink);

How to make a thumbnail created by a function clickable in html?

I am trying to make clickable thumbnails in my html code but I cannot figure out how to do it. I know <a href = ""> won't work. How can I make each thumbnail clickable so that it directs to another page?
Here are the functions I used to get data from the database and to create the thumbnail
`
<script>
$(function(){
$.ajax({
url: '/getMovies',
type: 'GET',
success:function(response) {
console.log(response);
var data = JSON.parse(response);
var itemsPerRow = 0;
var div = $('<div>').attr('class','row');
for(var i=0;i<data.length;i++){
console.log(data[i].Title);
if(itemsPerRow<3){
console.log(i);
if(i==data.length-1){
div.append(CreateThumb(data[i].Id,data[i].Name,data[i].Type,data[i].Copies));
$('.well').append(div);
}
else{
div.append(CreateThumb(data[i].Id,data[i].Name,data[i].Type,data[i].Copies));
itemsPerRow++;
}
}
else{
$('.well').append(div);
div = $('<div>').attr('class','row');
div.append(CreateThumb(data[i].Id,data[i].Name,data[i].Type,data[i].Copies));
if(i==data.length-1){
$('.well').append(div);
}
itemsPerRow = 1;
}
}
},
error:function(error){
console.log(error);
}
});
});
})
function CreateThumb(id,name,type,copies){
var mainDiv = $('<div>').attr('class','col-sm-4 col-md-4');
var thumbNail = $('<div>').attr('class','thumbnail');
var caption = $('<div>').attr('class','caption');
var title = $('<h3>').text(name);
var title = $('<h5>').text(type);
var title = $('<h4>').text(copies);
var p = $('<p>');
caption.append(name);
caption.append(p);
caption.append(type);
thumbNail.append(caption);
mainDiv.append(thumbNail);
return mainDiv;
}
</script>
`.
After you've added the thumbnails use:
$(".thumbnail").onclick(function(){
document.location.href = newUrl;
}
You can listen to clicks with jQuery by using:
// Change the selector used below
$('#some-id-here').click(function(){
// Your code here
});
There's also another way, using "on". This might be more useful to you, because it also triggers on items added dynamically to the page, which looks to be your case.
// Change the selector used below
$('#some-id-here').on('click', 'img', function(){
// Your code here.
});
Also, you can select the document with $(document) (instead of #some-id-here) to apply it globally on your page, so every img tag would trigger this function.

array is not working in a function which is inside for loop of jquery

I am stuck at a point,its worpress mediauploader. I want to upload images, one function is for one image but I have several upload buttons with unique id so I want only one function for all thats why I created the loop, on click of each button media uploader open up but there is problem saving the selected image, I am not getting that image url in the value. pls help new to jquery and javascript. Tried various methods this is one of them
this is screenshot of thing that I want->here
jQuery(document).ready(function($){
var b = ["#upload-button-1", "#upload-button-2", "#upload-button-3","#upload-button-4","#upload-button-5","#upload-button-6","#upload-button-7","#upload-button-8"];
var d =[".procircle-1", ".procircle-2",".procircle-3",".procircle-4",".procircle-5",".procircle-6",".procircle-7",".procircle-8"];
var j;
var c = ["#grid-image-1", "#grid-image-2", "#grid-image-3","#grid-image-4","#grid-image-5","#grid-image-6","#grid-image-7","#grid-image-8"];
var i;
for(i=0; i<=b.length; i++)
{
for(j=0;j<=c.length;j++){
$(b[i]).on('click',function(e){
e.preventDefault();
if( mediaUploader ){
mediaUploader.open();
return;
}
mediaUploader = wp.media.frames.file_frame= wp.media({
title:'Choose a Picture for Procedure ',
button:{
text:'Choose Picture'
},
multiple:false
});
mediaUploader.on('select',function(){
attachment= mediaUploader.state().get('selection').first().toJSON();
$(c[j]).val(attachment.url);
$('.procircle-2').css({'background':'url(' + attachment.url + ')','background-repeat': 'no-repeat'});
});
mediaUploader.open();
});
}
}
});
I would suggest doing the following (if you must keep your ids etc):
$(document).on('click', '#upload-button-1, #upload-button-2, #upload-button-3, #upload-button-4, #upload-button-5, #upload-button-6, #upload-button-7, #upload-button-8', function(e) {
var match = e.target.id.match(/(\d+)/g);
e.preventDefault();
if(mediaUploader) {
mediaUploader.open();
return;
}
mediaUploader = wp.media.frames.file_frame = wp.media({
title:'Choose a Picture for Procedure ',
button:{
text:'Choose Picture'
},
multiple:false
});
mediaUploader.on('select', function(){
var attachment = mediaUploader.state().get('selection').first().toJSON();
var id = '#grid-image-' + match[1];
$(id).val(attachment.url);
$('.procircle-2').css({'background':'url(' + attachment.url + ')','background-repeat': 'no-repeat'});
});
mediaUploader.open();
});
This removes the loop and delegates your handler so you only create one click handler rather than one per loop iteration as you are currently, and also creates a single mediauploader select handler. Finally, match the corresponding input with the event target that performed the click. Should work, although you might need to play around with it a bit, and it could definitely be refactored to be nicer. Hope it helps.

jQuery Mobile Load external HTML that contains an ajax call to servlet script and execute them only once

i have an iphone style menu for a web app POS, when i press the Clients Button it shows a page with all the clients, this is made making an ajax call to a java servlet, i use the load() function in the Main page to bring the GetCustomers.html file with a script containing the jquery code with ajax and the UL tag, when i call it (load it) in my main page it only format the UL and its respectively generated LI when i use firebug debugger with with a breakpoint in the trigger('create'); which is the last instruction inside the "pagebeforeshow" function. BUT! if i run it without debugging it does format and stylize it and show it 2 milisecons then it shows it without the jquery-mobile Listview style. im using $(this).trigger('create'); and that.listview('refresh'); and it still does not work well... any suggestions?
HERE IS THE MAIN PAGE CODE:
$(document).on("pagebeforeshow", "#pagewelcomeclientes", function(){
if( navigationInitialized == 'X'){
var newItems = '<li data-role="list-divider">Page Options</li>';
newItems += '<li>Time</li>';
newItems += '<li>Agregar Cliente</li>';
$(".pageOpts").empty();
$(".pageOpts").append(newItems).listview("refresh");
$.ajaxSetup ({
cache: false
});
var loadUrl = "GetCustomers.html";
$("#contentwelcomeclientes").load(loadUrl,function(){
BringClientes();
$(this).trigger('create');
});
var list = $('ul[data-autodividers="true"][data-sort="true"]');
list.each(function (i, item) {
var that = $(item);
// Gel all the list items into an array (excluding te dividers)
var lis = that.find('li').not('.ui-li-divider').get();
// Sort the list items alphabetically, descending
lis.sort(function (a, b) {
var valA = $(a).text(),
valB = $(b).text();
if (valA < valB) {
return -1;
}
if (valA > valB) {
return 1;
}
return 0;
});
// Remove all list items
that.empty();
// Rebuild the list with the ordered items
$.each(lis, function (i, li) {
that.append(li);
});
// Refresh/rebuild the listview
that.listview('refresh');
});
$(this).trigger('create');
}
});
HERE THE CALLED HTML:
<script type='text/javascript'>
BringClientes = function() {
$.ajax({
type: "POST",
url: "GetCustomers",
dataType: "json",
success: function (data) {
if (data.Customers.length) {
$.each(data.Customers, function (i, data) {
var temp = null;
var temp = "#cd-dropdown";
var temp = temp+data.msg_id;
var msg_data =
'<li>'+data.first_name+'</li>';
$(msg_data).appendTo("#juntar");
});
} else {
$("#content").html("No Results");
}
}
});
}
</script>
<ul data-role="listview"
data-inset="true"
data-filter="true"
data-autodividers="true"
data-sort="true"
data-theme="c"
data-divider-theme="c"
data-split-icon="grid"
data-split-theme="d"
id="juntar"
>
</ul>
i think it is executing twice the script in second page, what i try to do to fix it, is naming the function and then call it only once, but it still does not work... if you need sample images i can send it by mail, this is my first question here and stacky doesn't let me upload images...
thanks in advance!! =)
Lets change following line $(document).on("pagebeforeshow", "#pagewelcomeclientes", function(){}); into as below
$('#pagewelcomeclientes').on('pagebeforeshow',function(event){
// your code goes here
});
Also change $(this).trigger('create'); this into $('#pagewelcomeclientes').trigger('create'); and see what happens
If you suspect that the service is being called twice then better way to tackle is using .html() than using .append().
You may chagne your script as below
$.ajax({
type: "POST",
url: "GetCustomers",
dataType: "json",
success: function (data) {
if (data.Customers.length) {
var myListstring = "";
$.each(data.Customers, function (i, data) {
var temp = null;
var temp = "#cd-dropdown";
var temp = temp+data.msg_id;
myListstring += '<li>'+data.first_name+'</li>';
});
$("#juntar").html(myListstring);
$("#juntar").listview();
} else {
$("#content").html("No Results");
}
}
});
I would suggest that you should not complicate things using .load() instead u can call the service in the page itself and render the listview. Which will produce much readable code.
Hope this might get u somewhere closer to the fix.

JQuery-Javascript looping issue

I'm working on a banner for a website and I need it to loop through the images. My problem is that it plays through the images once and then stops. I've tried everything that I can think of with no luck. I'm sure this is simpler than I'm making it, but some help would be greatly appreciated. The latest version is below.
$(document).ready(function(){
// Variables required by script
var currentimage;
// Load Gallery XML file
$.ajax({
url: 'banner.xml',
type: 'GET',
dataType: 'xml',
error: function(){
alert('Error loading XML document');
},
success: function(xmlData){
// do something with xml
setupImages(xmlData);
}
});
// Display images
function setupImages(xmlData) {
// read xml and use it to populate page
//get first image
currentimage = $(xmlData).find("image:first");
// Fade in image after countdown
var t = setTimeout(function(){showNewImage()}, 1000);
}
// Display the image, caption, rating and label
function showNewImage() {
var image = $(currentimage).find("path").text();
var caption = $(currentimage).find("caption").text();
$("#imagelabel").removeClass("active");
// Fade out current image and fade in new image
$("#bannerimgholder").animate({opacity:0},500,
function(){
$(this).css({"backgroundImage":"url("+image+")"}).animate({opacity:1},1000,
function(){
$("#imagelabel").addClass("active");
});
});
// Add caption
$("#imagelabel").text(caption);
var to = setTimeout(function(){getNextImage()}, 5000);
}
function getNextImage(){
var tmp = $(currentimage).next();
if ($(tmp).find("path").text()=="") {
currentimage = $(xmlData).find("image:first");
} else {
currentimage = tmp;
}
showNewImage();
}
});
Your code is using next(), which will return nothing once you reach the last image.
You need to use a different test to close the loop, for example:
tmp.length==0
Note that tmp is already a jQuery object, so you don't need to wrap it in $().
This page offers an example of nextOrFirst() function that does what you want.
Here is a solution that I came up with.
First I added an element to the end of my xml file with just a 'path' attribute of "last".
Next, I add the following variable to save the path name of the first element:
var imagepathtext;
Then, in the setupImages(xmlData) function I added the following:
imagepathtext = $(currentimage).find("path").text();
Lastly, I changed the getNextImage() function from
function getNextImage(){
var tmp = $(currentimage).next();
if ($(tmp).find("path").text()=="") {
currentimage = $(xmlData).find("image:first");
} else {
currentimage = tmp;
}
showNewImage();
}
to
function getNextImage(){
var tmp = $(currentimage).next();
if ($(tmp).find("path").text()=="last") {
while ($(tmp).find("path").text()!=firstimagepath)
{
var tmp1 = $(tmp).prev();
tmp = tmp1;
}
currentimage = tmp;
} else {
currentimage = tmp;
}
showNewImage();
}
And just like magic it loops correctly now!

Categories

Resources