Replace div contents javascript (no jquery) - javascript

Every time a selection is made from a dropdown menu, specific data is pulled from facebook and added to different divs. I am trying to update the contents of the div every time a different selection is made, however at the minute, the contents are just appended on after the initial contents.
This is the code that gets data based on a selection and creates the list from the returned data
<script>
city = document.getElementById("citySelection")
city.addEventListener("change", function() {
var selected = this.value;
var eventsList = document.getElementById("events");
if (selected == "None") {
eventsList.style.display = "none";
} else {
eventsList.style.display = "block";
};
if (selected == 'Bristol') {
getBristolEvents();
};
if (selected == 'Leeds') {
getLeedsEvents();
};
if (selected == 'Manchester') {
getManchesterEvents();
};
if (selected == 'Newcastle') {
getNewcastleEvents();
};
});
function createList(response, listId) {
var list = document.createElement('UL')
for (var i = 0; i < 10; i++) {
var events = response.data[i].name
var node = document.createElement('LI');
var textNode = document.createTextNode(events);
node.appendChild(textNode);
list.appendChild(node)
listId.appendChild(list);
}};
</script
This is the div being targeted:
<html>
<div id="events" style="display: none">
<div id="eventsDiv" style="display: block">
<div id="eventsListOne">
<h3 id='headerOne'></h3>
</div>
<div id="eventsListTwo">
<h3 id='headerTwo'></h3>
</div>
<div id="eventsListThree">
<h3 id='headerThree'></h3>
</div>
</div>
</div>
</div>
</html>
I have tried resetting the innerHtml of the div every time the function to get the data from facebook is called:
<script>
function getEventsThree(fbUrl, title) {
var listId = document.getElementById('eventsListThree');
var headerThree = document.getElementById('headerThree');
listId.innerHtml = "";
headerThree.append(title)
FB.api(
fbUrl,
'GET', {
access_token
},
function(response) {
listId.innerHtml = createList(response, listId)
}
)};
</script>
However, that still doesn't reset the contents of the div.
I've looked at other response but they all use jquery which I am not using.
Can anyone advise on the best way to fix this? Thanks.

I think your Hennessy approach is fine. Generate the inner content, then set .innerHTML.
At least one of your problems, maybe the only one, appears to be that you set .innerHTML to the return value of createList, but that function does not return anything.

Related

Javascript can't get content of element

I've written code using Javascript to format the following section of a webpage based on the values:
<div class="col-md-auto mx-auto">
<h3>Average price</h3>
<p id="avgPrice"></p>
<br>
<div>Average change</div>
<div class="change" id = "avgChange"></div>
</div>
<div class="col-md-auto mx-auto">
<h3>Max price</h3>
<p id="maxPrice"></p>
<br>
<div>Max change</div>
<div class="change" id="maxChange"></div>
</div>
(The values for the text within each of the id's are getting pulled from a database, and appear correctly on the webpage when I start the server)
Here is my Javascript to format the HTML based on positive/negative values:
function changeFormatter() {
var elements = document.getElementsByClassName("change");
for (var i = 0; i < elements.length; i++) {
var change = elements[i]; //this is where the problem is
console.log(change);
if (change > 0) {
elements[i].innerHTML = "▴ " + change + "%";
elements[i].classList.add("text-success");
}
if (change < 0) {
elements[i].innerHTML = "▾ " + change + "%";
elements[i].classList.add("text-danger");
}
}
}
This code is being called by the following eventlistener:
window.addEventListener('load', (event) => {
console.log('page is fully loaded');
getData(); //gets values from database and adds them to HMTL
changeFormatter();
});
The issue is the line where I'm defining the var change. The output of the console.log on the line below it shows the text I want is there, see image below:
But no matter what I try I cannot get the text contained within this div. I've tried elements[i].value, .textContent, .innerHTML, .innerText, parseFloat(elements[i].innerHTML)... but they all return 'undefined' when I try and log them. I would really appreciate any suggestions!
Output of console.log(elements[i], elements[i].innerHTML)
.innerHTML should be correct as seen here: https://jsfiddle.net/awLynp28/3/. All I did was copy your script, have it run on page load (since it looks like you have something like that in there, I am assuming your function is getting called after the data is fully called in), and change
var change = parseFloat(elements[i].innerHTML);
document.addEventListener('DOMContentLoaded', function() {
var elements = document.getElementsByClassName("change");
for (var i = 0; i < elements.length; i++) {
var change = parseFloat(elements[i].innerHTML); //this is where I put innerHTML
console.log(change);
if (change > 0) {
elements[i].innerHTML = "▴ " + change + "%";
elements[i].classList.add("text-success");
}
if (change < 0) {
elements[i].innerHTML = "▾ " + change + "%";
elements[i].classList.add("text-danger");
}
}
}, false);

How do I get cell values on click event from webpage tabs after the first one?

I have tried javascript and JQuery. I know how to write the code to get the cell values from my first tab but the same function does not work on the other tabs on my webpage. It seems as if the table in my other tabs is just a view. I am new to javascript and JQuery so think I might be missing something easy. I have used ".on" in my click function and that doesn't help. Here is the Javascript code and JQuery code, both work by grabbing the cell value I click but only for the first tab:
JavaScript
init();
function init(){
addRowHandlers('customerTable');
}
function addRowHandlers(tableId) {
if(document.getElementById(tableId)!=null){
var table = document.getElementById(tableId);
var rows = table.getElementsByTagName('tr');
var cid = '';
var name = '';
for ( var i = 1; i < rows.length; i++) {
rows[i].i = i;
rows[i].onclick = function() {
cid = table.rows[this.i].cells[0].innerHTML;
name = table.rows[this.i].cells[1].innerHTML;
alert('cid: '+cid+' name: '+name);
};
}
}
}
JQuery
$('#customerTable').find('tr').click(function() {
var $id = $(this).closest("tr")
.find(".custId")
.text();
var $name = $(this).closest("tr")
.find(".custName")
.text();
alert($name);
$('.defaultTextBox.text_custId:text').val($id);
$('.defaultTextBox.text_custName:text').val($name);
});
In the end my goal is to get the elements clicked and set the text in my text boxes to those values, which you can see I did in the JQuery, but it only works on my first page. I need the click in my table to work on all tabs. Thanks in advance!
Edit
<div id="removeCustomer" class="tabcontent">
<h3>Pick a customer to remove!</h3>
<div class="container">
<br />
<h2 align="center">Search here to find the customer you want to remove</h2><br />
<div class="form-group">
<div class="input-group">
<span class="input-group-addon">Search</span>
<input type="text" name="search_text" id="search_text" placeholder="Search by name, phone number, email, or state" class="form-control" />
</div>
</div>
<br />
<div class="result"></div>
</div>
</div>
The "removeCustomer" id is one of the tabs. So I have multiple tabs using the same, "result", which I think is the problem I just do not know how to solve it. If I Left out "result" it would not generate a table.
Here is the JQuery which uses a php file to connect to my database and get my data. And this is what generates result.
JQuery
$(document).ready(function(){
load_data();
function load_data(query)
{
$.ajax({
url:"fetchCustomers.php",
method:"POST",
data:{query:query},
success:function(data)
{
$('div.result').html(data);
}
});
}
$('input.form-control').keyup(function(){
var search = $(this).val();
if(search != '')
{
load_data(search);
}
else
{
load_data();
}
});
});
Thanks again.

How to do local storage for to-do list?

I am currently working on making the to-do list app shown [here][1] work better. I have done things like change the font, but want to use Javascript cookies to make it so that the user's to-dos are properly saved and still there when the page is reopened.
All I need now (which I can't seem to get the idea of how to do) is the part where 1. the browser saves the data and 2. where the browser retrieves the data.
Any help would be greatly appreciated.
<body>
<!--To-Do Header, where you add tasks-->
<div id="myDIV" class="header">
<!--Change one: Make to-do list name different-->
<h2>To-Do</h2>
<input type="text" id="myInput" placeholder="Title..." style="padding-bottom: 20px;">
<span onclick="newElement();" class="addBtn">Add</span>
</div>
<!--To-do list-->
<ul id="myUL">
</ul>
var myNodelist = document.getElementsByTagName("LI");
var i;
for (i = 0; i < myNodelist.length; i++) {
var span = document.createElement("SPAN");
var txt = document.createTextNode("\u00D7");
span.className = "close";
span.appendChild(txt);
myNodelist[i].appendChild(span);
}
// Click on a close button to hide the current list item
var close = document.getElementsByClassName("close");
var i;
for (i = 0; i < close.length; i++) {
close[i].onclick = function() {
var div = this.parentElement;
div.style.display = "none";
};
}
// Add a "checked" symbol when clicking on a list item
var list = document.querySelector('ul');
list.addEventListener('click', function(ev) {
if (ev.target.tagName === 'LI') {
ev.target.classList.toggle('checked');
}
}, false);
// Create a new list item when clicking on the "Add" button
function newElement() {
var li = document.createElement("li");
var inputValue = document.getElementById("myInput").value;
var t = document.createTextNode(inputValue);
li.appendChild(t);
if (inputValue === '') {
alert("You must write something to create a task.");
} else {
document.getElementById("myUL").appendChild(li);
}
document.getElementById("myInput").value = "";
var span = document.createElement("SPAN");
var txt = document.createTextNode("\u00D7");
span.className = "close";
span.appendChild(txt);
li.appendChild(span);
for (i = 0; i < close.length; i++) {
close[i].onclick = function() {
var div = this.parentElement;
div.style.display = "none";
};
}
}
Using local storage, as it lasts longer then cookies:
// Store
localStorage.setItem("lastname", "Smith");
// Retrieve
document.getElementById("result").innerHTML = localStorage.getItem("lastname");
https://developer.mozilla.org/en/docs/Web/API/Window/localStorage
EDIT: #MichaelMior pointed out that local storage may not last longer then cookies, but the cookies are sent with browser requests so it's unnecessary in this case.
You want to store the text content, so you need to get them first
var values=[...document.getElementsByTagName("li")].map(el=>el.textContent);
Now you can store this array
localStorage.setItem("todos",values);
If the page is loaded, add it back to the page:
localStorage.getItem("todos").forEach(fumction(value){
//create elem
elem.textContent=value;
});
You could also store a HTML collection, but i wouldnt, storing just the text is.much easier...
Here is a quick example where I store an item and give it a name in localStorage called input. This shows how to setItem() and getItem().
Looks like this example doesn't work in the SO sandbox, so here's a codepen - http://codepen.io/anon/pen/KaNZxX
$('button').on('click',function() {
localStorage.setItem("input", $('input').val());
fetch();
});
function fetch() {
$('#storage').html(localStorage.getItem('input'));
}
fetch(); // fetch on load
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text"> <button>add</button>
<div id="storage"></div>

container hasChildNodes() showing null value. Why

<div id="history">
<div id="histheading" class="pull-left">History</div>
<div id='hist'><canvas id="test"></canvas></div>
</div>
var left=100;
var t=-150;
function doHistory_double()
{
var data = localStorage.getItem('HTML5TTT');
data = JSON.parse(data);
data.reverse();
var container = document.getElementById('hist');
// Clear the container
while (container.hasChildNodes())
{
container.removeChild(container.firstChild);
}
// Loop through the data
canvID = 0;
for(x in data)
{
var i=1;
var hist = data[x];
if(hist.datetime == undefined)
break;
var elem = document.createElement('div');
elem.style.marginLeft=lef + "px";
if(i==1){
elem.style.marginTop=t + "px";
}
else
elem.style.marginTop="0px";
i++;
elem.innerHTML = "<p><strong>"+hist.datetime+"</strong><br>Winner: "+hist.winner+"<br><canvas id='can"+canvID+"' width='100px' height='100px' ></canvas>";
container.appendChild(elem);
drawMiniBoard_double(document.getElementById("can"+canvID),hist.board);
canvID++;
lef+=310;
}
}
This is my javscript code. hist is a div showing history of the game.I am getting error as Cannot call method 'hasChildNodes' of null.I am getting this error after i did something using the variable left and t i.e margin-top and margin-left. Help me to solve this.
write it in a function and call it onload of document.
function deleteChildren() {
var container = document.getElementById('hist');
// Clear the container
while (container.hasChildNodes())
{
container.removeChild(container.firstChild);
}
}
<body onload="deleteChildren()">
<div id="history">
<div id="histheading" class="pull-left">History</div>
<div id='hist'><canvas id="test"></canvas></div>
</div>
</body>
its working perfectly.. check the fiddle
I have bind the click method then calling the code you provided and alert to show either we got a child inside the container or not..
--HTML--
<div id="history">
<div id="histheading" class="pull-left">History</div>
<div id='hist' onclick=f()><canvas id="test"></canvas></div>
</div>
-- JS --
function f()
{
var container = document.getElementById('hist');
// Clear the container
alert(container.hasChildNodes());
while (container.hasChildNodes())
{
container.removeChild(container.firstChild);
}
}
http://jsfiddle.net/FLC3R/

How to loop same javascript code for more than one div elements?

I have made three "boxes" and each box contains a button. When I click the button, box hiding, when click again, box appears.
This is my html code:
<div id="SC1_A_"> <!-- BOX -->
<div id="SC1_B_" onClick="SC1();" class="something"> </div> <!-- BUTTON -->
</div>
<div id="SC2_A_">
<div id="SC2_B_" onClick="SC2();" class="something"> </div>
</div>
<div id="SC3_A_">
<div id="SC3_B_" onClick="SC3();" class="something"> </div>
</div>
This is my javascript code:
<script type="text/javascript">
function SC1(){
var SC1_A = document.getElementById('SC1_A_);
var SC1_B = document.getElementById('SC1_B_);
if (SC1_A.style.display == 'block' || SC1_A.style.display == ''){
SC1_A.className = 'something';
SC1_B.className = 'something else';}
else {SC1_A.className = 'something else';
SC1_B.className = 'something';}
}
}
</script>
The example above works, but I have to make three similar scripts for each button. So I though to make something like this script below, using for loop. As you can imagine it didn't work. Any idea how can I make it work???
<script type="text/javascript">
for (i=1; i<10; i++){
function SCi(){
var SCi_A = document.getElementById('SC'+i+'_A_');
var SCi_B = document.getElementById('SC'+i+'_B_');
if (SCi_A.style.display == 'block' || SCi_A.style.display == ''){
SCi_A.className = 'something';
SCi_B.className = 'something else';}
else {SCi_A.className = 'something else';
SCi_B.className = 'something';}
}
}
</script>
Please don't down-vote if you think question is too easy, but just give me your help here!!! Thank you in advance!!!
You're on the right track, you just need to learn the right syntax for what you are trying to express:
var SC = [];
First off, to have a lot of different functions, so instead of attempting to name them differently (which you were trying to do), we are going to just store each function in a different index in the SC array.
for (var i = 1; i < 10; i++) {
SC[i] = (function () {
var SC_A = document.getElementById('SC' + i + '_A_');
var SC_B = document.getElementById('SC' + i + '_B_');
return function () {
if (SC_A.style.display === 'block' || SC_A.style.display === '') {
SC_A.className = 'something';
SC_B.className = 'something else';
} else {
SC_A.className = 'something else';
SC_B.className = 'something';
}
}
})();
}
Now, to call these functions you would do SC[1](), SC[2](), ... So you can either put that in each onclick in your HTML, or you could bind the events from the javascript.
Edit: I forgot to mention this because it isn't directly related to the syntax of the code, but the calls to 'document.getElementByIdwill not work until the document is fully loaded. So if you just put the script directly between to` tags it won't work. You have two choices. You either can keep the current code, but run it when the page loads. Or, you could restructure the code like this:
var SC = [];
for (var i = 1; i < 10; i++) {
SC[i] = (function (i) {
return function () {
var SC_A = document.getElementById('SC' + i + '_A_');
var SC_B = document.getElementById('SC' + i + '_B_');
if (SC_A.style.display === 'block' || SC_A.style.display === '') {
SC_A.className = 'something';
SC_B.className = 'something else';
} else {
SC_A.className = 'something else';
SC_B.className = 'something';
}
}
})(i);
}
What's happening here is you are calling document.getElementById every time the button is clicked, instead of just once when the function is created. Slightly less efficient, but it works.
You define each section on the page as calling the one function and passing in the name of the other .
<div id="SC1_A_"> <!-- BOX -->
<div id="SC1_B_" onClick="SC('SC1_A_');" class="something"> </div> <!-- BUTTON -->
</div>
<div id="SC2_A_">
<div id="SC2_B_" onClick="SC('SC2_A_');" class="something"> </div>
</div>
<div id="SC3_A_">
<div id="SC3_B_" onClick="SC('SC3_A_');" class="something"> </div>
</div>
There is just one function used for all of them
function SC(nameOfA){
var SCi_A = document.getElementById(nameOfA);
var SCi_B = this;
if (SCi_A.style.display == 'block' || SCi_A.style.display == ''){
SCi_A.className = 'something';
SCi_B.className = 'something else';
} else {
SCi_A.className = 'something else';
SCi_B.className = 'something';}
}
}
here you can use this function on every click:
<div id="SC1_A_"> <!-- BOX -->
<div id="SC1_B_" onClick="SC(event)" class="something"> </div> <!-- BUTTON -->
</div>
<script type="text/javascript">
function SC(event){
var SCA = event.currentTarget.parentNode;
var SCB = event.currentTarget;
................
}
</script>
Your code is defining a function named SCi 8 times. I think if you swap the first two lines you will get what you want.
You're redefining the same function (function SCi) eight times. The only version of the function that is retained is the version that's defined last. Going by your code, you're only creating a function that can work with the 8th box.

Categories

Resources