Getting inner HTML from different ids - javascript

I'm just now starting to try to learn Javascript, so bear with me. I'm trying to get information from a list on one part of my page to a new section with three places at the click of a button.
Each item in the list has its own button, and I need my script to know which place to put the list item based on the number of times the button has been clicked (which should coincide with how many list items have already been added to the list).
I've tried created a script to increase i and take the id of the paragraph into a function, but I can't seem to make it work. I'm hoping that by "counting" the number of times the button has been clicked, it will put each new list item that has been added in the next place in the new section.
I'm not sure how to make the counting part work, though, and it has just occurred to me that maybe the first part of my function constantly remains at zero.
I would really appreciate any help that I can get with this.
Thanks in advance!
Here's my code:
<script>
function increase(place) {
var i = 0;
addToDilly(i, place);
i++;
}
function addToDilly(num, place) {
if num = 0 {
document.getElementById("firstStop").innerHTML = document.getElementById(place).innerHTML;
}
if num = 1 {
document.getElementById("secondStop").innerHTML = document.getElementById(place).innerHTML;
}
if num = 2 {
document.getElementById("thirdStop").innerHTML = document.getElementById(place).innerHTML;
}
}
</script>
<p id="firstStop">This is a paragraph.</p>
<p id="secondStop">This is another paragraph.</p>
<p id="thirdStop">This is another paragraph.</p>
<hr/>
<p id="1">Royal Oak <button onclick="increase(1)">Add To Dilly</button></p>
<p id="2">Ferndale <button onclick="increase(2)">Add To Dilly</button></p>
<p id="3">Chesterfield <button onclick="increase(3)">Add To Dilly</button></p>

Try this script:
<script>
var i = 0;
function increase(place) {
console.log(place);
addToDilly(i, place);
i++;
}
function addToDilly(num, place) {
if (num == 0) {
document.getElementById("firstStop").innerHTML = document.getElementById(place).innerHTML;
}
if (num == 1) {
document.getElementById("secondStop").innerHTML = document.getElementById(place).innerHTML;
}
if (num == 2) {
document.getElementById("thirdStop").innerHTML = document.getElementById(place).innerHTML;
}
}
</script>
Here's the running example

I would suggest a complete re-write. If your aim is to update a list of items, just update a list of items (literally) :)
Note: You originally tagged your question as jQuery, so this initial answer is in jQuery.
The text you wish to add needs to been in an element related to the button, but not containing the button itself. For this example I placed them before the buttons.
e.g. http://jsfiddle.net/TrueBlueAussie/t13h54bu/3/
$('button').click(function () {
var $button = $(this);
var text = $button.prev('p').html();
var $target = $('#list');
$target.append($('<li>').html(text));
});
and simpler HTML:
<ul id="list"></ul>
<hr/>
<p>Royal Oak</p>
<button>Add To Dilly</button>
<p>Ferndale</p>
<button>Add To Dilly</button>
<p>Chesterfield</p>
<button>Add To Dilly</button>
Then if you want to limit the items to 3 add this:
if ($target.children().length < 3) {
$target.append($('<li>').html(text));
}
http://jsfiddle.net/TrueBlueAussie/t13h54bu/4/

Related

javascript/jquery incrementation check

I have very delicate problem, I'll make an example. What am i doing is that I'm basically prepending elements and differentiating them by incrementing (i need to do it this way for certain reasons), then there is an option to click on any element and delete it.
This is only stupid example of what it looks like:
$(function () {
var i = 0;
$("#new").click(function(){
i++;
$("#container").prepend("<div class='prepended "+i+"'>blah blah blah</div>")
$(".prepended").click(function(){
$(this).remove();
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="new">click here</button>
<div id="container"></div>
When I delete any element, I need to somehow manage to make the incrementing "i" variable fill the missing element. I don't know how to explain in words so I'll explain in "code":
Let's say I prepended 6 elements so the "i" variable is now 6:
if(deleted_divs_class == 1)
{
i = 1; // fill the missing "1"
next_click_i = 6; // variable i on next click should be 6 in order to continue in right order
}
else if (deleted_divs_class !== 1 || 6) // deleted element is somewhere from middle so it's not 1 or 6
{
i = fill_missing_number; // fill the removed number
next_click_i = 6; // continue in right order
}
else
{
i--;
// deleted element is the last element of line so continue normally by incrementing
}
i know how to get deleted_divs_class variable and apply the next_click_i variable but i don't know how make the whole thing work dynamically
I know that this question might seems very weird but this is just an example, it's part of much much much bigger code and i just need to make logic of this "incrementation" in order to make the whole thing work properly as i need.
So i just can not figure out the logic.
I suppose I created the code you are looking for, but I’m not sure if I understood your question correctly. Look at this code. Is this what you wanted or not?
$(function () {
var missed=[]; //Here will be stored missed numbers
var i = 0;
$("#new").click(function(){
var n=0;
if(missed.length>0) {
n=missed.shift(); //get next missed number from the array
} else
n=++i;
$("#container").prepend("<div data-i='"+n+"' class='prepended "+n+"'>"+n+"blah blah blah</div>")
});
$('#container').on('click',".prepended",[], function(){
missed.push($(this).data('i')); //save removed number into missed numbers array
$(this).remove();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="new">click here</button>
<div id="container"></div>
To backfill the deleted i values, you'll need to store them. In this example, deleted_i holds all deleted values, and attempts to retrieve the new value from there first when creating a new element. If it's empty, it defaults to incrementing the value of i.
Note also that the click event is now bound to the container so that it only fires once - in your example, it was getting re-bound to all .prepended elements, so that when you clicked on one, it was firing that function as many times as the loop had run so far.
$(function () {
var i = 0,
deleted_i = []
$("#new").click(function(){
var idx;
console.log(deleted_i)
if(deleted_i.length) idx = deleted_i.shift() //grab the first deleted index, if one exists
else idx = ++i;
$("#container").prepend("<div data-index='"+idx+"' class='prepended "+idx+"'>blah blah blah this is "+idx+"</div>")
});
$("#container").click(function(e){
var $target = $(e.target)
if($target.hasClass('prepended')){
$target.remove();
deleted_i.push($target.attr('data-index'))
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="new">click here</button>
<div id="container"></div>

In a pinch, stuck in a simple onclick text cycle

For a project, I'm trying to highlight the logical fallacy of circular reasoning and have precious few lines of code later to be inserted into a separate webpage.
I am trying to create a simple process of clicking the displayed text to switch back and forth between the two questions. I've tried buttons and it only complicates and make no progress. Half a day gone, still banging my head on desk, as the phrase goes.
I read elsewhere that creating a var tracker facilitates, though I see it only for images, rather than displayed text. It feels like approaching my wits end, but I lack the time to walk away and try again.
This is my code thus far:
<!doctype html>
<head>
<script>
function change() {
var paragraph = document.getElementById("whytrust");
paragraph.innerHTML="I am trustworthy, but how can you be sure?";
}
</script>
</head>
<body>
<p id="whytrust" onclick="change();">You can trust me, but how can you be sure?</p>
</body>
</html>
You need some place to hold the old message so you can put it back again after you toggle the contents.
<!doctype html>
<head>
<script>
var newMsg = "I am trustworthy, but how can you be sure?";
function change() {
var paragraph = document.getElementById("whytrust");
var oldMsg = paragraph.innerHTML;
paragraph.innerHTML = newMsg;
newMsg = oldMsg;
}
</script>
</head>
<body>
<p id="whytrust" onclick="change();">You can trust me, but how can you be sure?</p>
</body>
</html>
This a quick and dirty implementation of what you want. I added a data-textindex attribute to the html element. There I stored an index for the currently shown text. In the javascript I check the current value, update data-textindex and replace it with new text.
function change() {
let paragraph = document.getElementById("whytrust");
let currentlyshown = paragraph.getAttribute('data-textindex');
if(currentlyshown == 0){
paragraph.innerText="I am trustworthy, but how can you be sure?";
paragraph.setAttribute('data-textindex', '1');
}else if(currentlyshown == 1){
paragraph.innerText="You can trust me, but how can you be sure?";
paragraph.setAttribute('data-textindex', '0');
}
}
<p id="whytrust" data-textindex="0" onclick="change();">You can trust me, but how can you be sure?</p>
On a sidenote: You can improve this code a lot. Like storing your text in a json-object. Or maybe using the ternary operator if you are 100% sure there will always be 2 choices. maybe give the function some arguments so you can apply it in a more general scenario.
Try tracking some sort of 'state' for your paragraph -- be it on/off, active/inactive...
Each time the change() function gets called, it doesn't remember what the paragraph was or was supposed to be. So, by setting a state of some sort (in my example a data-state attribute assigned to the paragraph element) the code can know how to behave.
function change() {
var paragraph = document.getElementById("whytrust");
var output = '';
// data-* can be anything, but handy for referencing things
var state = paragraph.getAttribute('data-state');
// check if data-state even exists
if( !state ){
// set it to the default/original state
paragraph.setAttribute('data-state', 'inactive');
state = 'inactive';
}
// toggle the state
// and assign the new text
if( state === 'inactive' ){
paragraph.setAttribute('data-state', 'active' );
output = "I am trustworthy, but how can you be sure?";
}else{
paragraph.setAttribute('data-state', 'inactive');
output = "You can trust me, but how can you be sure?";
}
paragraph.innerHTML = output;
}
<p id="whytrust" onclick="change();">You can trust me, but how can you be sure?</p>
Another option, without tracking state could be hiding and showing the paragraph you want displayed. You don't really need to track state or save the alternating text...
// get the elements from the DOM that you want to hide/show
// you can get tricky and add alternative ways to track
// the paragraph elements, but this works nice for a demo
const whytrust = document.getElementById('whytrust'),
answer = document.getElementById('whytrust-answer');
function change( element ){
// the element parameter being passed is the paragraph tag
// that is present/visible
if( element.id === 'whytrust' ){
answer.className = ''; // clear the .hide class
whytrust.className = 'hide'; // add the .hide class
}else{
whytrust.className = ''; // clear the .hide class
answer.className = 'hide'; // add the .hide class
}
}
.hide{ display: none; }
<p id="whytrust" onclick="change(this);">I am trustworthy, but how can you be sure?"</p>
<p id="whytrust-answer" class="hide" onclick="change(this);">You can trust me, but how can you be sure?</p>
What I like about this solution is that it keeps the content in the HTML and the JavaScript just worries about what to hide/show.

using OOP on .click function in javascript

I am making a webpage that has a baseball strikezone with 25 buttons that will be clickable in 25 locations. I need to know if there is a easier way to do this then what I am doing. Maybe something that will take up far less lines. The button is clicked and then the counter is added by one to another table.
$('#one').click(function(){
counter++;
$('#ones').text(counter);
});
var countertwo = 0;
$('#two').click(function(){
countertwo ++;
$('#twos').text(countertwo);
});
A bit of a guess here, but:
You can store the counter on the button itself.
If you do, and you give the buttons a common class (or some other way to group them), you can have one click handler handle all of them.
You can probably find the other element that you're updating using a structural CSS query rather than id values.
But relying on those ID values:
$(".the-common-class").click(function() {
// Get a jQuery wrapper for this element.
var $this = $(this);
// Get its counter, if it has one, or 0 if it doesn't, and add one to it
var counter = ($this.data("counter") || 0) + 1;
// Store the result
$this.data("counter", counter);
// Show that in the other element, basing the ID of what we look for
// on this element's ID plus "s"
$("#" + this.id + "s").text(counter);
});
That last bit, relating the elements by ID naming convention, is the weakest bit and could almost certainly be made much better with more information about your structure.
You can use something like this:
<button class="button" data-location="ones">One</button>
...
<button class="button" data-location="twenties">Twenty</button>
<div id="ones" class="location">0</div>
...
<div id="twenties" class="location">0</div>
$('.button').on('click', function() {
var locationId = $(this).data('location')
, $location = $('#' + locationId);
$location.text(parseInt($location.text()) + 1);
});
Also see this code on JsFiddle
More clean solution with automatic counter
/* JS */
$(function() {
var $buttons = $('.withCounter'),
counters = [];
function increaseCounter() {
var whichCounter = $buttons.index(this)+1;
counters[whichCounter] = counters[whichCounter] ? counters[whichCounter] += 1 : 1;
$("#counter"+whichCounter).text(counters[whichCounter]);
}
$buttons.click(increaseCounter);
});
<!-- HTML -->
<button class="withCounter">One</button>
<button class="withCounter">Two</button>
<button class="withCounter">Three</button>
<button class="withCounter">Four</button>
<p id="counter1">0</p>
<p id="counter2">0</p>
<p id="counter3">0</p>
<p id="counter4">0</p>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

show() method removes the html element from dom instead of displaying it

I have this code,
HTML and php
<?php for($i = 1; $i <= 5; $i++) { ?>
<div class="file-add-row" style="display:none;">Some content</div>
<?php } ?>
<div id="add-file-plus">Add File</div>
and the JS is
$('#add-file-plus').live('click', function () {
if($('div.file-add-row:visible').length == 0) {
$('div.file-add-row:hidden:first').show();
} else {
$('.file-add-row:hidden:first').removeAttr("style").insertAfter($('.file-add-row:visible:last'));
}
});
Now, my problem is, when I click the add button for the first time, the first 'file-add-row' div is displayed. But when I click the add button the second time, nothing happens on the page. Instead, it just completely removes that div from the dom.
I am just a beginner in jquery, so there might be things I overlooked. Anyone got any idea about what's going on ?
When you do:
$('.file-add-row:visible:last')
Just after:
$('.file-add-row:hidden:first').removeAttr("style")
They both refer to the same object. And if you try to insert an object after itself, it will end up removing itself from the DOM.
Change the JS to:
$('#add-file-plus').live('click', function () {
if($('div.file-add-row:visible').length == 0) {
$('div.file-add-row:hidden:first').show();
} else {
var last_visible = $('.file-add-row:visible:last')
$('.file-add-row:hidden:first').removeAttr("style").insertAfter(last_visible);
}
});
Demo (Click on 'Add File'):
https://jsfiddle.net/woxd2jbf/1/
Here's a version without jQuery just plain JavaScript, it will work with divs just as it does with button, ul, and li. The details are commented within the source.
Key Methods
cloneNode()
appendChild()
PLUNKER
SNIPPET
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<!--This <li> is a template to clone-->
<li class="row" style='display:none'>Some content</li>
<!--This is the empty list to be populated with clones-->
<ul id='list'>
</ul>
<!--This button will have an eventListener
that will execute a function when it is clicked-->
<button id="add">Add File</button>
<script>
/* Reference each element involved in process */
// The button
var add = document.getElementById('add');
// The list
var list = document.getElementById('list');
// The first li
var row = document.querySelector('.row:first-of-type');
/*
1. Button will listen for a `click`
2. Create a clone of the first li
3. Add clone as the last child of list
4. Set clone's display property to block
so it's visible
*/
add.addEventListener('click', function(e) {
var clone = row.cloneNode(true);
list.appendChild(clone);
clone.style.display = 'block';
}, false);
</script>
</body>
</html>
$('.file-add-row:hidden:first').removeAttr("style").insertAfter($('.file-add- row:visible:last'));, due to this line the issue is happening. because it first removes the style attribute which makes it visible so $('.file-add- row:visible:last') is returning itself. refactor to store the visible el's reference like below:
$(function () {
$('#add-file-plus').live('click', function () {
if ($('div.file-add-row:visible').length == 0) {
$('div.file-add-row:hidden:first').show();
} else {
var $el = $('.file-add-row:visible:last');
$('.file-add-row:hidden:first').removeAttr("style").insertAfter($el);
}
});
})

Back button after a slide

i need to have a back button on my slide to return to the previous div. I did several test but without success.
there is my JS
function SlideOut(element) {
$(".opened").removeClass("opened");
$("#" + element).addClass("opened");
$("#content").removeClass().addClass(element);
}
$("#content div").click(function () {
var move = $(this).attr('data-move');
SlideOut(move);
});
There is the demo link:
http://jsfiddle.net/VA5Pv/
thanks
You could create a history. I edited the fiddle with some dirty code but the idea is there:
var history = [];
var last;
$("#content div").click(function () {
var move = $(this).attr('data-move');
if (last) history.push(last);
last = move;
SlideOut(move);
});
$("#back").click(function () {
SlideOut(history.pop());
return false;
});
http://jsfiddle.net/VA5Pv/1/
Basically: store the "move" variable in a history array. When you want to go back, pop the last value out of the history array.
Reset
If you just want to return to the initial state (no slides opened), just add the following:
$('button.close').click(function() {
$('.opened').removeClass('opened');
});
Tracking a full history is overkill in this case.
Demo: http://jsfiddle.net/VA5Pv/4/
History
Several answers suggested using a history. Most of them used an array which keeps track of the slides the user opened and then simply pop from that to "go back".
var history = [];
$('#content div').click(function() {
var move = $(this).attr('data-move');
history.push(move);
SlideOut();
});
$('button.close').click(function() {
history.pop();
SlideOut();
});
function SlideOut() {
var element = history[history.length - 1];
// ... same as before ...
}
This would be necessary if you wanted to allow the user to open any number of slides in any order and always present them with a button to go back to the previously opened slide.
Sequence
Another solution could have been to store all the slide IDs in an array and keep a counter that tells you at which slide you are. Going back would mean decrementing the counter if it is not already at zero and then switching to that particular slide.
This would be useful if you were trying to create something like a presentation where each slide is opened in sequence and the transitions are entirely linear.
This is why I asked you to clarify what you were trying to build. Depending on the use case, the solutions could have been vastly different and far more complex than what you were actually looking for.
Thanks for accepting my answer and welcome to StackOverflow. Feel free to upvote any answers you found helpful even if they did not answer your question sufficiently.
try the following:
$('.anim button').click(function(){$(this).parent().removeClass('opened');});
I assigned this to the button in div rouge. But the target could be anything in that div you want the user to click on ...
see here: JSfiddle
Here is the DEMO
<div id="fullContainer">
<div id="right" class="anim"></div>
<div id="rouge" class="anim">Hello world!
<button class="close">Close</button>
</div>
</div>
<div id="centerContainer">
<div id="relativeContainer">
<div id="content">
<div data-move="right">Open Right</div>
<div data-move="rouge">Open Rouge</div>
<div id="back">Back</div>
</div>
function SlideOut(element) {
if(element == undefined) {
$('#back').hide();
}
$(".opened").removeClass("opened");
$("#" + element).addClass("opened");
$("#content").removeClass().addClass(element);
}
$("#content div").click(function () {
var move = $(this).attr('data-move');
$('#back').show();
SlideOut(move);
});

Categories