jQuery for each item assign content on click - javascript

I am currently using the following code to loop through an array of objects and to display the name of each object in html code:
var doors = [
{
name: "1",
link: "#1"
},
{
name: "2",
link: "#2"
}
];
$('.object').each(function(i) {
this.innerHTML = '<p>' + doors[i].name + '</p>';
});
Now, clicking on the div opens a popup containing an iframe (using the class "popup-iframe").
Is there a way to change the link of the iframe corresponding to the selection on click? So if I click on "2", I would like to change the link to the corresponding link.
I've tried the following but it does not work:
$('.object').each(function(i) {
var link = doors[i].link;
$(this).click(function(){
$('.popup-iframe').innerHTML = '<iframe src="'+ link +'" title="Test"></iframe>';
});
});
The simplified html code looks as follows:
<div id="grid">
<div class="object item-1"></div>
<div class="object item-2"></div>
</div>
Thanks for your help!

Use html() function in jquery instead of innerHTML.
innerHTML is a DOM Element property.
JS :
const doors = [
{
name: "1",
link: "#1"
},
{
name: "2",
link: "https://jsfiddle.net/"
}
];
$(document).ready(function () {
$('.object').each(function(i) {
let link = doors[i].link;
$(this).click(function(){
$('.popup').html('<iframe src="'+ link +'" title="Test"></iframe>');
});
});
});
HTML :
<html>
<head>
<title> Sandbox</title>
<meta charset="UTF-8"/>
</head>
<body>
<div class="object item-1">item1</div>
<div class="object item-2">item2</div>
<div class="popup"></div>
</body>
</html>

Related

Track which button was clicked; clear data if the current button clicked was different than the previous button clicked

I am trying to create a dynamic web page that populates with gifs of my choice.Below is a screenshot of the page.
Summary :
Clicking on the buttons above grabs the giphy images and displays on the screen. Let's say I click on Chris Pratt, it should display all the images on the screen for Chris Pratt. Clicking on Chris Pratt each subsequent time should grab 10 more images and append to the screen. New clicking on Tom Cruise should empty $('#actors-view') and displays giphys for Tom Cruise. Again clicking on Tom Cruise should append 10 images to the exisiting Tom cruise giphy.
Issue:The issue I am having is what needs to be done to empty $('#actors-view') when a new button is clicked. Currently, when the $('#actors-view') is empty,I call https://api.giphy.com/v1/gifs/search?q=${actor}&api_key=[API_KEY]. This grabs the initial number of giphys; each additional clicks to the same button grabs additional giphys on the screen. The issue is when I click on a different button, it appends all the current giphys to the new giphys. Example, I will have all the pictures of Dwayne Johnson mixed with Chris Hemsworthh; which is not what I want.
#Index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
crossorigin="anonymous"
/>
<link rel="stylesheet" href="assets/css/style.css"" />
<title>Document</title>
</head>
<body class="container-fluid">
<div class="row">
<div class="mb-5" id="buttons-view"></div>
</div>
<div class="row mt-5">
<div class="col-sm-9">
<div id="actors-view"></div>
</div>
<div class="col-sm-3">
<div class="input-group mb-2">
<div class="input-group-prepend">
<button
class="btn btn-outline-secondary"
type="button"
id="add-actor"
>
Add
</button>
</div>
<input
id="actor-input"
class="form-control"
type="text"
placeholder="Add an actor"
aria-describedby="basic-addon1"
/>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="assets/javascript/app.js"></script>
</body>
</html>
#app.js
let topics = [
'Tom Cruise',
'Arnold Schwarzenegger',
'Tom Hanks',
'Chris Hemsworth',
'Chris Pratt',
'Dwayne Johnson',
'Will Smith',
'Vin Diesel',
'Pamela Anderson',
'Shahrukh khan',
'Hrithik Roshan'
];
//initial call of the function to render the buttons on screen
renderButtons();
function renderButtons() {
$('#buttons-view').empty();
for (var i = 0; i < topics.length; i++) {
var a = $('<button>');
a.addClass('actor btn btn-info');
a.attr('data-name', topics[i]);
a.text(topics[i]);
$('#buttons-view').append(a);
}
}
function ajaxCall(queryURL) {
$.ajax({
url: queryURL,
method: 'GET'
}).then(function(response) {
console.log(response);
var actors = response.data;
//for each of the JSON data
actors.forEach(actor => {
//grab the images.fixed_height.url
imgURL = actor.images.downsized.url;
//grab the rating
rating = actor.rating;
// Creating an element to have the rating displayed
pOne = $('<p>').text('Rating: ' + rating);
//create a new div
giphyDiv = $("<div class='giphy'>");
//append the p element to the giphyDiv
giphyDiv.append(pOne);
//create an image tag and define the src
image = $('<img>').attr('src', imgURL);
//append the image to the div
giphyDiv.prepend(image);
//append the div to the image in the div
$('#actors-view').prepend(giphyDiv);
});
});
}
// Function for dumping the JSON content for each button into the div
function displayActorInfo() {
var actor = $(this).attr('data-name');
if ($('#actors-view').is(':empty')) {
var queryURL = `https://api.giphy.com/v1/gifs/search?q=${actor}&api_key=API_KEY`;
ajaxCall(queryURL);
} else {
var queryURL = `https://api.giphy.com/v1/gifs/search?q=${actor}&api_key=API_KEY&limit=10`;
ajaxCall(queryURL);
}
}
// This function handles events where one button is clicked
$('#add-actor').on('click', function(event) {
event.preventDefault();
// This line grabs the input from the textbox
var actor = $('#actor-input')
.val()
.trim();
//If there are text in thhe textbox then push it to the topics array
if (actor) {
topics.push(actor);
console.log(topics);
}
//empty the value in the text-box
$('#actor-input').val(' ');
//call the function to re-render the buttons in the screen after the update
renderButtons();
});
// Function for displaying the actors info
// Using $(document).on instead of $(".actor").on to add event listeners to dynamically generated elements
$(document).on('click', '.actor', displayActorInfo);
$(document).ready(function() {
$('button').click(function() {
if (
$(this)
.parent()
.data('lastClicked')
) {
lastActorButtonCLicked= $(this)
.parent()
.data('lastClicked');
}
$(this)
.parent()
.data('lastClicked', this.id);
});
});
// Function for dumping the JSON content for each button into the div
function displayActorInfo() {
var actor = $(this).attr('data-name');
console.log(actor);
console.log(lastActorButtonCLicked)
if ($('#actors-view').is(':empty') || actor !== lastActorButtonCLicked) {
var queryURL = `https://api.giphy.com/v1/gifs/search?q=${actor}&api_key=BkaUZZWcFij6J7AoQj3WtPb1R2p9O6V9`;
imd = true;
ajaxCall(queryURL, imd);
} else {
var queryURL = `https://api.giphy.com/v1/gifs/search?q=${actor}&api_key=BkaUZZWcFij6J7AoQj3WtPb1R2p9O6V9&limit=10`;
imd = false;
ajaxCall(queryURL, imd);
}
}

How to display a string javascript in HTML

In my HTML file I have a div with id="list".
Now I want to display a string from my javascript in my html. page. but nothning
happen. In my html file, i've imported the srcipt file. Here's how it looks in my script file:
var namesArray = ["lars", "bo", "ib", "peter", "jan", "frederik"];
var list = namesArray.map(name=>"<li>"+name+"</li>");
var listAsStr ="<ul>" + list.join("") + "<ul>";
document.getElementById("list").innerHTML = listAsStr;
Whenever you're targeting DOM elements (i.e you want to use document.getElementById("my-element") or similar) you need to first check if the document has loaded.
You can do this in either of the following ways:
window.onload = function(){
//Now that the window has loaded we can target DOM elements here
}
OR
document.addEventListener('DOMContentLoaded', function () {
//Now that the contents of the DOM have loaded we can target DOM elements here
});
So a full example (putting your script code in an external file i.e list.js) would look like this:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset=utf-8">
<title>My list website</title>
<script src="list.js"></script>
</head>
<body>
<div id="list"></div>
</body>
</html>
list.js
window.onload = function(){
//We use window.onload to check the window has loaded so we can target DOM elements
var namesArray = ["lars", "bo", "ib", "peter", "jan", "frederik"];
var list = namesArray.map(name=>"<li>"+name+"</li>");
var listAsStr ="<ul>" + list.join("") + "<ul>";
document.getElementById("list").innerHTML = listAsStr;
}
place your code in this and it will work
window.onload = function() {}
You need to put the JavaScript code after your dom and also wrapped with Script tag.
Example: This will work since we rendered the HTML first and then executed the js into it.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>This Will WorK</title>
</head>
<body>
<div id="list" ></div>
<script>
var namesArray = ["lars", "bo", "ib", "peter", "jan", "frederik"];
var list = namesArray.map(name=>"<li>"+name+"</li>");
var listAsStr ="<ul>" + list.join("") + "<ul>";
document.getElementById("list").innerHTML = listAsStr;
</script>
</body>
</html>
But this will NOT work since the JavaScript is being executed before dom rendered. Also this will probably throw an error Cannot set property 'innerHTML' of null" because getElementById will not be able to find the associated dom.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>This Will Not WorK</title>
</head>
<body>
<script>
var namesArray = ["lars", "bo", "ib", "peter", "jan", "frederik"];
var list = namesArray.map(name=>"<li>"+name+"</li>");
var listAsStr ="<ul>" + list.join("") + "<ul>";
document.getElementById("list").innerHTML = listAsStr;
</script>
<div id="list" ></div>
</body>
</html>
Here is a succinct way to do it with template strings. Just wrap everything in a function you assign to window.onload:
<script>
window.onload = () => {
const namesArray = ['lars', 'bo', 'ib', 'peter', 'jan', 'frederik'];
const list = `<ul>${namesArray.map(name => `<li>${name}</li>`).join('')}</ul>`;
document.getElementById('list').innerHTML = list;
};
</script>
<div id="list"></div>

Any Event Listener

Are there any Event Listeners that can be attached to a word. So when the word is clicked, information like a definition can be displayed on the page. Using jQuery
Thanks,
Adam
Sorry for not posting code. I have to make it so that when the user clicks on the name of a person in the list, the box of data on the right side of the screen fills with the description of the location of the artwork. Which is in my JSON file.
Here is my code so far
<!DOCTYPE html>
<hmtl lang="en">
<head>
<meta charset="utf-8" />
<title>AJAX</title>
<link rel="stylesheet" href="styles.css" type="text/css" />
<script src="jquery.js" type="application/javascript"></script>
<script src="ajax.js" type="application/javascript"></script>
</head>
<body>
<div id="loaded-data"></div>
<div id="result-box"></div>
</body>
</hmtl>
$(function() {
let request = $.ajax({
method: 'GET',
url : 'people.json',
dataType: 'json',
});
request.done(function(data) {
let list = data.body.list;
let resultBox = $('#result-box');
let unorderedList = $('<ul>');
resultBox.append(unorderedList);
for (let person of list) {
let listItem = $('<li>');
listItem.text(person.name);
listItem.attr('data-url', person.links[0].href);
unorderedList.append(listItem);
}
});
request.fail(function(response) {
console.log('ERROR: ' + response.statusText);
});
});
{
"links":[{"rel":"self","href":"http://www.philart.net/api/people.json"},{"rel":"parent","href":"http://www.philart.net/api.json"}],
"head":{"title":"People","type":"listnav"},
"body":{
"list":[
{"name":"Adam","links":[{"rel":"self","href":"http://www.philart.net/api/people/325.json"}]},
{"name":"Abigail Adams","links":[{"rel":"self","href":"http://www.philart.net/api/people/157.json"}]},
{"name":"John Adams","links":[{"rel":"self","href":"http://www.philart.net/api/people/410.json"}]},
{"name":"Samuel Adams","links":[{"rel":"self","href":"http://www.philart.net/api/people/439.json"}]},
{"name":"Lin Zexu","links":[{"rel":"self","href":"http://www.philart.net/api/people/347.json"}]},
{"name":"James A. Zimble","links":[{"rel":"self","href":"http://www.philart.net/api/people/345.json"}]},
{"name":"Doris Zimmerman","links":[{"rel":"self","href":"http://www.philart.net/api/people/171.json"}]}
]
}
}
Teemu has already mentioned a way to accomplish this behavior in the comment. You can do it as follows
// handle click and add class
$(".word").click(function() {
var word = $(this).text()
alert(word);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<p class="word">Hello</p>
</div>
You could replace the word and wrap it with a div.
$('p').html(function(index, value) {
return value.replace(/\b(here)\b/g, '<div class ="event">here</div>');
});
$('.event').click(function() {
console.log('definition');
});
<p>This is the information: Click here.</p>

How to toggle between 'ui-body-a' & 'ui-body-b' on button click [duplicate]

This question already has answers here:
jQuery mobile dynamically added theme to page
(2 answers)
Closed 5 years ago.
Trying to get a jQuery Mobile button to behave like a toggle but it's not working fully. Trying to toggle between ui-body-a and ui-body-b. When I click the button, the page's colours change to dark. However when I click the button again, the page doesn't change back to light colours and is stuck on dark colours.
Whenever the button is clicked, I want the following to happen:
If the colours are light, change them to ui-body-b (to show the dark colours), then change the button text to 'Light colours'
Else if the colours are dark, change them to ui-body-a (to show the light colours), then change the button text to 'Dark colours'
HTML
<div data-role="header">
<h1>Hello World</h1>
Dark colours
</div>
JavaScript
function changeColour() {
if ($("#page").attr("data-theme", "a")) {
$("#page").attr("data-theme", "a");
$("#page").removeClass("ui-body-a").addClass("ui-body-b");
$("#btn-right").text("Light colours");
} else if ($("#page").attr("data-theme", "b")) {
$("#page").attr("data-theme", "b");
$("#page").removeClass("ui-body-b").addClass("ui-body-a");
$("#btn-right").text("Dark colours");
}
}
It depends from your page markup. TBH, I haven't understand if you try to create a whole theme switcher or just need to change the page background.
Anyway, JQM has hard-coded overall the default theme "a" but offers a lot of possibilities to customize just only sections of the page, or even more single elements by applying the desired data-theme attribute just to one of them.
Moreover, please think what shall be if you are creating some elemnts dynamically? You should use the -inherit attributes to keep the same page theme, or set it explicitly (for instance, Popups).
Again, what if you navigate to an external page? Shall be styled or not...? So, it really depends from how your markup is, and what look and feel You are trying to achieve.
Here is an example how to change the theme of some page sections, You only need to keep the function toggleTheme():
function toggleTheme() {
var themes = {"a":"Light","b":"Dark"},
oldTheme = $(":mobile-page").page("option", "overlayTheme"),
newTheme = oldTheme == "a" ? "b" : "a";
$("div[data-role='page']").each(function(index) {
$(this).removeClass("ui-page-theme-"+oldTheme).addClass("ui-page-theme-"+newTheme);
});
$(".ui-bar-"+oldTheme).each(function(index) {
$(this).removeClass("ui-bar-"+oldTheme).addClass("ui-bar-"+newTheme);
});
$(".ui-body-"+oldTheme).each(function(index) {
$(this).removeClass("ui-body-"+oldTheme).addClass("ui-body-"+newTheme);
});
$(":mobile-page").page("option", "overlayTheme", newTheme);
$(":mobile-page").page("option", "theme", newTheme);
$(":mobile-page").page("option", "contentTheme", newTheme);
$("#btn-theme").text(themes[oldTheme]);
}
var all = [], current = {};
var listTemplate = [
'<li class="ui-first-child ui-last-child">',
'<a href="#page-card" data-id="{id}" class="ui-btn ui-btn-icon-right ui-icon-carat-r">',
'<h2>{name}</h2>',
'<p><strong>{address.city}</strong></p>',
'<p>{email}</p>',
'<p class="ui-li-aside">id: <strong>{id}</strong></p>',
'</a>',
'</li>'
].join("");
var cardTemplate = [
'<h3 class="ui-bar ui-bar-inherit ui-corner-all">{name}</h3>',
'<div class="ui-body ui-body-inherit ui-corner-all">',
'<p>{email}</p>',
'<p>{website}</p>',
'<p>{phone}</p>',
'<p>{address.street}</p>',
'<p>{address.city}</p>',
'</div>'
].join("");
function nano(template, data) {
return template.replace(/\{([\w\.]*)\}/g, function(str, key) {
var keys = key.split("."), v = data[keys.shift()];
for (i = 0, l = keys.length; i < l; i++) { v = v[keys[i]]; }
return (typeof v !== "undefined" && v !== null) ? v : "";
});
}
$(document).on("vclick", "#page-list li>a", function() {
var id = $(this).data("id");
current = $.grep(all, function(item) {
return item.id == id;
})[0];
});
$(document).on("pagecreate", "#page-list", function() {
var $ul = $(this).find("ul");
$.ajax({
url: "https://jsonplaceholder.typicode.com/users",
method: 'GET',
crossDomain: true,
dataType: "jsonp",
complete: function() {
$ul.listview().listview("refresh");
},
success: function(result) {
all = result;
$.each(all, function(i, item) {
$ul.append(nano(listTemplate, item))
});
}
});
});
$(document).on("pagebeforeshow", "#page-card", function() {
$(this).find("[data-role=content]").empty().append(nano(cardTemplate, current)).trigger("updatelayout");
});
$(document).on("vclick", "#btn-theme", function() {
toggleTheme();
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.css">
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
</head>
<body>
<div data-role="page" id="page-list">
<div data-theme="a" data-role="header" data-position="fixed">
Dark
<h3>Users</h3>
</div>
<div data-role="content">
<ul data-role="listview" data-inset="true" data-filter="true">
</ul>
</div>
</div>
<div data-role="page" id="page-card">
<div data-theme="a" data-role="header" data-position="fixed">
<h3>Details</h3>
Back
</div>
<div data-role="content">
</div>
</div>
</body>
</html>
UPDATE:
This fix need to be added: https://stackoverflow.com/a/16136992/4845566 for a bug in the page widget (thanks to Omar).

Show hidden div after so many seconds breaks code?

setTimeout breaks code what I want to do if after a random text and image has been choosen (that works)
I have a div called quote where the random text and image goes and i want that to fade in say like in 3 seconds time ....
But it just isnt working Im a nooby so any help would be great heres the code I have so far:
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Random</title>
<script src="jquery-2.1.1.min.js"></script>
</head>
<body>
<div id="quote"></div>
<script>
(function() {
var quotes = [
{
text: "text1",
img: "http://i.stack.imgur.com/FqBE6.jpg?s=32&g=1"
},
{
text: "text2",
img: "https://www.gravatar.com/avatar/ca3e484c121268e4c8302616b2395eb9?s=32&d=identicon&r=PG",
},
{
text: "text3",
img: "https://www.gravatar.com/avatar/ca3e484c121268e4c8302616b2395eb9?s=32&d=identicon&r=PG",
}
];
var quote = quotes[Math.floor(Math.random() * quotes.length)];
document.getElementById("quote").innerHTML =
'<p>' + quote.text + '</p>' +
'<img src="' + quote.img + '">';
})();
$('#quote').hide();
setTimeout(function(){
$('#quote').show();
$('#quote').fadeIn(1000);
}, 3000);
</script>
</body>
</html>
I also want the quote div to be hidden at 1st hide();
any idea's ? thanks.
If you remove $('#quote').show(); from your setTimeout, it will fade in properly.
setTimeout(function(){
$('#quote').fadeIn(1000);
}, 3000);

Categories