I am new to JavaScript and I need some help. I am making a website and I have several images of team members that if clicked (so I'm guessing the onclick event) will change the variable values corresponding to that team member. For instance, if I click on a picture of Bill Gates, in a separate div, I need to have a variable (let's say Name) change value to Bill Gates. Then, if I click on an image of Steve Jobs, the variables containing Bill Gates' data will get overwritten with the data of Steve Jobs. How do I do this?
Assuming mark-up like the following:
<div id="gallery">
<img class="people" data-subject="Steve Jobs" src="path/to/imageOfSteve.png" />
<img class="people" data-subject="Bill Gates" src="path/to/imageOfBill.png" />
</div>
<span id="caption"></span>
Then a relatively simple, and plain JavaScript, approach:
function identifySubject(image, targetEl) {
if (!image) {
return false;
}
else {
var targetNode = document.getElementById(targetEl) || document.getElementById('caption'),
person = image.getAttribute('data-subject');
text = document.createTextNode(person);
if (targetNode.firstChild.nodeType == 3) {
targetNode.firstChild.nodeValue = person;
}
else {
targetNode.appendChild(text);
}
}
}
var images = document.getElementsByClassName('people');
for (var i=0, len=images.length; i<len; i++) {
images[i].onclick = function(e){
identifySubject(this, 'caption');
};
}
JS Fiddle demo.
Onclick attribute is right. You need to add the name of a javascript function to the image's onclick attribute (eg <img src="" onclick="changeVariable()"...).
If you want text on the page to change depending on who you click on, you'll need to look at selecting divs in Javascript using getElementById() or similar and look at the InnerHTML property.
See: http://woork.blogspot.co.uk/2007/10/how-to-change-text-using-javascript.html
Hope this helps
<img src="path/to/image1" onclick="getValue('bill gates')" />
<img src="path/to/image2" onclick="getValue('steve jobs')"/>
<div id="show_value"></div>
<script>
function getValue(val){
document.getElementById('show_value').innerHTML = val
}
</script>
HTML:
<div class="member"><img src="billgates.jpg" /><span>Bill Gates bla bla</span></div>
<div class="member"><img src="stevejobs.jpg" /><span>Steve Jobs bla bla</span></div>
<div id="variables"></div>
JS:
$(function(){
$('.member img').click(function(){
$('#variables').html($(this).closest('span').html());
});
});
Related
So I'm working on a website that has a lot of movies, and people can choose what movies are they favorite, and for that, I have a star image that can be clicked and when clicked that image will change to another one
Like this:
To this:
The problem I have is that the only image that change is the first one, When I click, for example on the star next to the Ratatouille movie, it will change the first star
This is the HTML:
const getMovieHtml = (movie) => `<div class="movie">
<h2>${movie.title}</h2>
<img onclick="bottonclick()" id="estrelinhas" src="./icons/empty-star.png" alt="estrela vazia" width=40>
<div class="content">
<img src="${movie.posterUrl}" alt="${movie.title}" />
<div class="text">
<p>${movie.summary}</p>
<div class="year">${movie.year}</div>
<div><strong>Directors:</strong> ${movie.director}</div>
<div><strong>Actors:</strong> ${movie.actors}</div>
</div>
</div>
</div>`;
And this is the arrow function I used to make the star change:
const bottonclick = () => {
if (document.getElementById("estrelinhas").src.includes("empty-star.png")) {
document.getElementById("estrelinhas").src = "./icons/filled-star.png";
} else {
document.getElementById("estrelinhas").src = "./icons/empty-star.png";
}
};
ID attributes of HTML elements should be unique. If you don't have unique ID's the code doesn't know which star to update. Read more about IDs here: https://www.w3schools.com/html/html_id.asp
To fix this, a solution would be to use a unique identifier for each image, so that when you click "favourite" it knows which star to reference.
Assuming for example that the movie.posterURL is unique you can use that as the ID, however the data from wherever you are getting the movie from might already have a unique identifier that you could pass to the id attribute of the image instead
Your code could look something like this:
const getMovieHtml = (movie) => `<div class="movie">
<h2>${movie.title}</h2>
<img onclick="bottonclick(e)" id="${movie.posterUrl}" src="./icons/empty-star.png" alt="estrela vazia" width=40>
<div class="content">
<img src="${movie.posterUrl}" alt="${movie.title}" />
<div class="text">
<p>${movie.summary}</p>
<div class="year">${movie.year}</div>
<div><strong>Directors:</strong> ${movie.director}</div>
<div><strong>Actors:</strong> ${movie.actors}</div>
</div>
</div>
</div>`;
const buttonClick = (e) => {
const star = document.getElementById(e.target.id);
if (star.src.includes("empty-star.png")) {
star.src = "./icons/filled-star.png";
} else {
star.src = "./icons/empty-star.png";
}
}
beacuse you getElementById, so you not take all containers,
but you get 1, first,
change getElementById for querySelectorAll and give there some id,
to localizate in DOM ,
buttonClick(e)
and in
function buttonClick(e) {
e.target.value/id/or something
}
I have a page where a teacher can select a class (of school students). Then the teacher can create groups of students from this class by dragging avatars of the students.
I have a drop down list of classes and a div filled with avatars of the students.
The HTML:
<select name="chosenClass" onchange="chooseClass(this.value)">
<option ng-repeat="(key, value) in techerClasses">{{key}}</option>
</select>
...
<div id="div0" ondrop="drop(event)" ondragover="allowDrop(event)" class="groupDiv">
<img ng-repeat="(key, value) in classStudents" id={{key}} src="http://placehold.it/30x30/{{value}}" draggable="true" ondragstart="drag(event)">
</div>
The controller code:
chooseClass = function (classInfo) {
if (classInfo > 0){
$rootScope.classesRef.child(classInfo).on('value', function (dataSnapshot){
$rootScope.classStudents = dataSnapshot.val().members;
});
}
}
If I add data manually to the $rootScope.classStudents before
the page loads the avatars will show correctly.
console.log($rootScope.classStudents) after
$rootScope.classStudents = dataSnapshot.val().members; confirms
that the right data is in there.
But the avatars are not showing.
If I click "back" in the browser and then "forward" - the avatars
will show. This leads me to think that I need something that will
tell the <img ng-repeat... to refresh?
You're missing a $rootScope.$apply as you've done something outside of angular:
chooseClass = function (classInfo) {
if (classInfo > 0){
$rootScope.classesRef.child(classInfo).on('value', function (dataSnapshot){
$rootScope.classStudents = dataSnapshot.val().members;
$rootScope.$apply();
});
}
}
Alternatively look into using $firebaseArray:
chooseClass = function (classInfo) {
if (classInfo > 0){
$rootScope.classStudents = $firebaseArray($rootScope.classesRef.child(classInfo).child('members'))
}
}
set src="http://placehold.it/30x30/{{value}}" to ng-src="http://placehold.it/30x30/{{value}}" to add the src attribute to the digest.
Also $rootScope.$apply or $timeout(angular.noop) if you need a "save digest"
Hi i'm trying to replace some divs with other divs, this works fine but when i try to replace the second load of divs they don't change anymore.
Basicaly I'm trying to create a "winetour" that lets a user choose some options and generates the perfect wine to go along with it.
You get presented with a couple of options (img links) and if you click one the div's content changes and presents another set of clickable images taking you deeper in your process of choosing a great wine.
HTML:
<div id"Gelegenheid">
<img src="Images/Ontbijt.jpg" id="ontbijt" alt="Ontbijt">
<img src="Images/Borrel.jpg" id="borrel" alt="Borrel">
<img src="Images/Dinner.jpg" id="feest" alt="Diner">
<img src="Images/Feest.jpg" id="diner" alt="Feest">
</div>
<div id"Ontbijt" style="display: none"> Some content that shows trough the "tour"</div>
<div id"Borrel" style="display: none"> Some content that shows trough the "tour"</div>
<div id"Dinner" style="display: none">
<img src="Images/White.jpeg" id="ontbijt-licht" alt="ontbijt-licht">
</div>
<div id"Dinner-detail-voor" style="display: none"> Some content that shows trough the "tour"</div>
<div id"Dinner-detail-head" style="display: none"> Some content that shows trough the "tour"</div>
JavaScript:
function continueTour(i) {
if (i==1) {
document.getElementById("Gelegenheid").innerHTML = document.getElementById("Ontbijt").innerHTML;
} else if (i==2) {
document.getElementById("Gelegenheid").innerHTML = document.getElementById("Borrel").innerHTML;
} else if (i==3) {
document.getElementById("Gelegenheid").innerHTML = document.getElementById("Diner").innerHTML;
} else if (i==4) {
document.getElementById("Gelegenheid").innerHTML = document.getElementById("Feest").innerHTML;
} else {
document.getElementById("Dinner").innerHTML = document.getElementById("Dinner-detail-voor").innerHTML;
}
}
So basically if you click on a link that's inside the "Gelegenheid" div you will be taken to for example Dinner, but the problem is, inside dinner there are some more links and i want to link them for example to "Dinner-detail-voor"
I want to make this working with core JavaScript (so no JQuery) but i don't know what's going on?
Thanks in advance!
Found the answer.
Added
document.getElementById("from").style.display = "none" ;
document.getElementById("to").style.display = "table" ;
to each of the javscript index functions, now it works where 'from' is the father and 'to' is the child that is being linked to, not very neat but it works,
If someone has a shorter or alternative solution feel free to post!
first we create an array for all the content, array is base 0 so we start from function myFunction(0); next we create a tag with updated variable in them. the if statement is use to reset the variable when hit max. hope this help.
http://jsfiddle.net/xgay3f83/3/
function continueTour(i) {
var content = ['content 1', 'content 2', 'content 3', 'content 4'];
var target = document.getElementById('target');
var next = i + 1;
var end = content.length;
if(next>end) {
i = 0;
next = 1;
}
var openTag = '<a href="#" class="hvr-grow" onClick = "continueTour('+next+')">';
var closeTag = '</a>';
target.innerHTML = openTag+content[i]+closeTag;
}
I need to be able to store certain elements separately in a database, but on retrieval rebuild the HTML for display. Our solution to this (open to suggestions) is to store leadingHTML and trailngHTML properties of the entry.
This should provide us the ability to be as flexible as we want-- but there's just one catch. I'm banging my head against the wall trying to write the code to parse the HTML. Take the following HTML for example:
<h1>this is leadingHTML</h1>
<h2>this is leadingHTML2</h2>
<p class='select' id='1'>A1</p>
<h1 >this is trailngHTML</h1>
<h2>this is trailngHTML2</h2>
<p class='select' id='2'>A2</p>
<h1>this is trailngHTML3</h1>
<h2>this is trailngHTML4</h2>
<p class='select' id='3'>A3</p>
<figure id='fig'>
<figCaption>
this is some text
<span class='select'>B1</span>
<div>some text <span class='select'>B2</span></div>
</figCaption>
<img class='select' alt='test' src='test.jpg'/>
<img class='select' alt='test' src='test.jpg'/>
<img class='select' alt='test' src='test.jpg'/>
</figure>
<p class="select">A4</p>
It's easy to get all the elements with class "select." But I could really use help getting the string of HTML to go between those elements. For the the element <p class='select' id='3'>A3</p> , I need a function that can return to me the following string:
values:
element
<p class='select' id='3'>A3</p>
leadingHTML
leadingHTML= '<h1>this is trailngHTML3</h1><h2>this is trailngHTML4</h2>'
trailingHTML
trailingHTML= '<figure id='fig><figCaption>this is some text'
This way, I can store the elements the way that is required of the project but still reconstruct the HTML for display.
We are using Node.js for a backend, so this will need to be written in Javascript. After lots of frustration, I'm pretty convince there's no way to do this without some ugly code?
Any help is much appreciated.
So far, this is what I've got (can't say I'm proud):
var checkChildren = function walk(node,state,func){
if (state.isPt===false){
var state=func(node,state);
}
else if(state.isPt===true){
return state;
}
node=$(node).children().first();
while (node.length>0 && state.isPt!==true){
state=walk(node,state,func);
node=$(node).next();
}
return state;
};
function getTrailing(start,html){
var checkFind = $(start).find('.pt');
if (checkFind.length>0){
//selector is in the child somewhere
state= { html: html, isPt: false};
var getChildHTML = checkChildren(start,state,function(node,state){
if ($(node).is($(checkFind).first())){
return { html: html, isPt: true,};
} else{
html=html+'<'+$(node)[0].name;
for (var key in $(node)[0].attribs){
html=html+" "+key+"='"+$(node)[0].attribs[key]+"'";
};
html=html+'>';
return { html: html, isPt: false,};
}
});
return getChildHTML;
} else{
return html;
}
}
var start1 = $("#fig");
var html = '';
test=getTrailing(start1,html);
and it's returning this:
{ html: '<figure id=\'fig\' class=\'test\' style=\'color:red;\'><figcaption class=\'test\' style=\'color:red;\'><span><div>',
isPt: true }
Update
To clarify-- the output may be invalid HTML. I simply need string of all the HTML between two elements of interest. If the second element of interest is a descendant, then the result will be invalid HTML (since the string is supposed to stop as soon as it finds the next element).
I'm in need of a bit of help. I have a current script that switches div's between being visible and hidden depending on a dropdown selector, it works as it was originally designed absolutely fine.
The problem i have is that i need to modify it to change more than 1 div on the page. Currently i'm using the same ID for the div's but only the first item on the page is updated. Reading over the JS this makes sense, but i can't figure out how to modify it to get the desired result?
Javascript:
var lastDiv = "";
var lastProd = "";
function showDiv(divName, productID) {
if (productID == lastProd) {
$("#"+lastDiv).hide();
$("#"+divName).fadeIn(".visible-div-"+productID);
}
else {
$(".visible-div-"+productID).hide();
$("#"+divName).fadeIn(".visible-div-"+productID);
}
lastProd = productID;
lastDiv = divName;
}
The selector:
<select onchange="showDiv('pxo_'+this.value,2);" name="pre_xo_id">
<option value="3">Blue - £120.00</option>
<option value="4">Red - £120.00</option>
<option value="5">Yellow - £120.00</option>
The DIV's:
<div id="pxo_3" class="visible-div-2" style="display: none;">RED</div>
<div id="pxo_4" class="hidden-div visible-div-2" style="display: none;">BLUE</div>
<div id="pxo_5" class="hidden-div visible-div-2" style="display: block;">YELLOW</div>
<div id="pxo_3" class="visible-div-2" style="display: none;">1 In Stock</div>
<div id="pxo_4" class="hidden-div visible-div-2" style="display: none;">1 In Stock</div>
<div id="pxo_5" class="hidden-div visible-div-2" style="display: none;">0 In Stock</div>
id's must be unique, that's why only the first item is being update. You may put those values to class instead to allow multiple selection.
First you can not use one id for morethan one element.They must be unique.Apply same css class to those elements.
We can use same class instead to allow multiple selection.
IDs are supposed to be used for only a single element on the page. You want to use css selectors.
Thank you for the help all, I have modified the JS to look for both ID and Class as i am unable to change part of the code due to it being protected by ioncube.
This seems to have the desired result:
var lastDiv = "";
var lastProd = "";
function showDiv(divName, productID) {
if (productID == lastProd) {
$("#"+lastDiv).hide();
$("#"+divName).fadeIn(".visible-div-"+productID);
$("."+lastDiv).hide();
$("."+divName).fadeIn(".visible-div-"+productID);
} else {
$(".visible-div-"+productID).hide();
$("#"+divName).fadeIn(".visible-div-"+productID);
$(".visible-div-"+productID).hide();
$("."+divName).fadeIn(".visible-div-"+productID);
}
lastProd = productID;
lastDiv = divName;
}