localStorage loadVote when refresh page (broken) - javascript

I cannot show voteUp/Down when I refresh page, because if I do voteUp/Down(+1 or -1) and refresh page, this return voteUp/Down (0) again. In this past I was using JSON, but the community recommended without JSON. So I have it, in this moment. Thanks.
var voteUp = document.getElementById('vote-up');
var voteDown = document.getElementById('vote-down');
var handUp = once(function() {
var total = Number(voteUp.innerHTML);
total += 1;
voteUp.innerHTML = total;
saveVote();
});
voteUp.addEventListener('click', handUp);
var handDown = once(function() {
var total = Number(voteDown.innerHTML);
total -= 1;
voteDown.innerHTML = total;
saveVote();
});
voteDown.addEventListener('click', handDown);
function once(fn, context) {
var result;
return function() {
if(fn) {
result = fn.apply(context);
fn = null;
}
return result;
};
}
function saveVote() {
var votes = voteUp, voteDown;
localStorage.setItem('data', votes);
console.log('saveVote');
}
function loadVote() {
var votes = localStorage.getItem('data');
if(!votes){
return;
}
console.log(localStorage.getItem('data'));
}
loadVote();

var voteUp = document.getElementById('vote-up');
function handUp() {
var total = Number(voteUp.innerHTML);
total += 1;
voteUp.innerHTML = total;
}
voteUp.addEventListener('click',handUp,false);
It increments each one value by a click.

There's no such thing as an =+ operator, there is an += operator, however.
+=
Addition assignment.
Also, I'm pretty sure the typeof val is undefined since it's value is never defined in the argument passing of the method.
A variable which's type is undefined can certainly not contain a value which's a number (it's NaN) and thus the error message makes sense.

Related

How to create a counter with a plus and minus button which passes a parameter so that I don't have two use two separate functions?

I have created a counter with a plus and minus button. The counter works fine but I would like to simplify my code by passing a parameter to my function that performs both the plus and minus calculations depending on which button is clicked. At the moment I have two separate functions doing this but I would like to pass the 'result' variable as this is the part that tells my script whether I want to add 1 or minus 1, however I am unsure on how to do this?
I have attached my JavaScript below to show what I have so far.
document.getElementById('minus').onclick = function() {
var counter = document.getElementById('counter').innerHTML;
var parsed = parseInt(counter);
var result = parsed -1;
document.getElementById('counter').innerHTML = result;
}
document.getElementById('plus').onclick = function() {
var counter = document.getElementById('counter').innerHTML;
var parsed = parseInt(counter);
var result = parsed +1;
document.getElementById('counter').innerHTML = result;
}
You can make a curried function to "bake" your delta value into the click handlers:
function changeCount(delta) {
return function () {
var counter = document.getElementById('counter').innerHTML;
var parsed = parseInt(counter);
var result = parsed + delta;
document.getElementById('counter').innerHTML = result;
}
}
document.getElementById('minus').onclick = changeCount(-1);
document.getElementById('plus').onclick = changeCount(1);
You can use the same function to modify the counter element and then just pass a negative or positive integer as the parameter to the function, like so:
document.getElementById('minus').onclick = modifyCount(-1);
document.getElementById('plus').onclick = modifyCount(1);
//Just pass the integer into the function to modify the counter element
function modifyCount(val){
const counter = document.getElementById('counter');
counter.innerHTML = parseInt(counter.innerHTML) + val;
}
Possible solution with onclick event:
function count(clicked_id)
{
var counter = document.getElementById('counter').innerHTML;
var parsed = parseInt(counter);
let result = clicked_id == "minus" ? parsed - 1 : parsed + 1;
document.getElementById('counter').innerHTML = result;
}
<button onclick="count(this.id)" id="minus">-</button>
<div id="counter">0</div>
<button onclick="count(this.id)" id="plus">+</button>
You can use the first and only parameter of the click handler, to get the ID of the element. Then use a ternary command to decide, if the result should be incremented or decremented.
function clickHandler(e) {
var counter = document.getElementById('counter').innerHTML;
var parsed = parseInt(counter);
var result = e.target.id === 'plus' ? parsed + 1 : parsed - 1;
document.getElementById('counter').innerHTML = result;
}
document.getElementById('minus').onclick = clickHandler;
document.getElementById('plus').onclick = clickHandler;
You could also rewrite the method to use an if instead of the result variable.
Here's what I would consider an optimized version:
const counterElem = document.getElementById('counter');
function clickHandler(e) {
counterElem.innerHTML =
parseInt(counterElem.innerHTML) +
(e.target.id === 'plus' ? 1 : -1);
}
document.getElementById('minus').onclick = clickHandler;
document.getElementById('plus').onclick = clickHandler;
You could use curried functions.
The following should make your code simple and as required:
function getCounter(multiplier = 1) {
return function () {
var counter = document.getElementById('counter').innerHTML;
var parsed = parseInt(counter);
var result = parsed + (multiplier * 1);
document.getElementById('counter').innerHTML = result;
}
}
document.getElementById('minus').onclick = getCounter(-1);
document.getElementById('plus').onclick = getCounter(); // 1 is the default value
Curried functions are basically, functions that return another function. The inner functions have access to the variables defined in the wrapping function. read more about them here: https://medium.com/javascript-scene/curry-and-function-composition-2c208d774983
I have modified your code to a function, you just need to use that function on the event you want.
function counterFunction(action) {
var counter = document.getElementById('counter').innerHTML;
var parsed = parseInt(counter);
var result = '';
if (action == 'minus') {
result = parsed -1;
}
else if (action == 'plus') {
result = parsed +1;
}
document.getElementById('counter').innerHTML = result;
}
If you need any help please let me know.
In Button tag call the below method in OnClick event
In 'action' parameter , pass the button value as '+' or '-'.
Eg : <button type='button' onClick='return CounterUpdate("+")'>+</Button>
function CounterUpdate(action) {
var counter = document.getElementById('counter').innerHTML;
var parsed = parseInt(counter);
var result =parsed ;
if(action=='+')
{
result = parsed +1;
}
else if(action=='-')
{
result = parsed -1;
}
document.getElementById('counter').innerHTML = result;
}

javascript function return "undefine" from jsp page

i have a jsp page and call a JS function which is in some abc.js file from this JSP page.
i have included this js file to jsp page.
JSP JavaScript Code:-
function doFinish(tableId, col, field)
{
var oldselectedCells = "";
var selItemHandle = "";
var selRightItemHandle = "";
var left = -1;
var right = -1;
// Get the table (tBody) section
var tBody = document.getElementById(tableId);
// get field in which selected columns are stored
var selectedCellsFld = document.getElementById(tableId + datatableSelectedCells);
selectedCellsFld.value = oldselectedCells;
for (var r = 0; r < tBody.rows.length; r++)
{
var row = tBody.rows[r];
if (row.cells[col].childNodes[0].checked == true)
{
selectedCellsFld.value = oldselectedCells +
row.cells[col].childNodes[0].id;
selItemHandle = row.cells[col].childNodes[0].value
oldselectedCells = selectedCellsFld.value + datatableOnLoadDivider;
left = selItemHandle.indexOf("=");
right = selItemHandle.length;
selRightItemHandle = selItemHandle.substring(left+1,right);
var index=getColumnIndex(tBody,"Name");
if(index!=null)
{
if(field == 1)
{
window.opener.document.TemplateForm.eds_asbactionscfg_item_handle_child_physpart.value = selRightItemHandle;
window.opener.document.TemplateForm.ChildPhysicalPart.value = row.cells[index].childNodes[0].innerHTML;
}
else if (field == 2)
{
window.opener.document.TemplateForm.eds_asbactionscfg_dev_doc_item_handle_name.value = selRightItemHandle;
window.opener.document.TemplateForm.DeviationObject.value = row.cells[index].childNodes[0].innerHTML;
}
else if (field == 3)
{
window.opener.document.TemplateForm.eds_asbactionscfg_dev_doc_item_handle_name.value = selRightItemHandle;
window.opener.document.TemplateForm.DeviationObject.value = row.cells[index].childNodes[0].innerHTML;
}
}
}
}
window.close();
}
JS Code:-
function getColumnIndex(tBody,columnName)
{
var cells = tBody.parentNode.getElementsByTagName('th');
for (var i=0;i<cells.length; i++)
{
if(cells[i].hasChildNodes())
{
if(cells[i].childNodes[0].innerHTML.replace(/(\r\n|\n|\r)/gm ,"").trim() == columnName)
{
return i;
}
}
}
}
i had debug this code with firebug & calling getColumnIndex(tBody,columnName) function works fine but when it return to caller the var index=getColumnIndex(tBody,"Name"); the index value is "undefine".
suggest some solution.
getColumnIndex(tBody,columnName) function works fine.
as if it matches this if condition
if(cells[i].childNodes[0].innerHTML.replace(/(\r\n|\n|\r)/gm ,"").trim() == columnName)
{
return i;
}
so that it returns something.
but when you replace this
var index=getColumnIndex(tBody,"Name"); so that coulmnName would be "Name" in String.
And it doesn't match with any columnName so that your condition going to be wrong and function doesn't return anything.
var index=getColumnIndex(tBody,"Name"); the index value is "undefine".
suggestion is put some else condition on that and return some error message like this :
if(cells[i].childNodes[0].innerHTML.replace(/(\r\n|\n|\r)/gm ,"").trim() == columnName)
{
return i;
} else{
// put some error message
// return null
}
i had debug this code with firebug & calling getColumnIndex(tBody,columnName) function works fine
From this, I'm assuming that there isn't anything wrong with the implementation of your getColumnIndex function, so your issue with getting an undefined value must have to do with when this function is returning a value.
but when it return to caller the var index=getColumnIndex(tBody,"Name"); the index value is "undefine".
This leads me to assume that your tBody variable is not being set correctly, given that the "function works fine".
I'm assuming there is a case in your code where the conditions of your getColumnIndex function is not met.
function getColumnIndex(tBody,columnName)
{
var cells = tBody.parentNode.getElementsByTagName('th');
for (var i=0;i<cells.length; i++)
{
if(cells[i].hasChildNodes())
{
if(cells[i].childNodes[0].innerHTML.replace(/(\r\n|\n|\r)/gm ,"").trim() == columnName)
{
return i;
}
}
}
// If your code reaches this point, then the prior conditions have not been met
// You can choose to do something else here for return false/undefined etc.
return undefined;
}

Debugging a push method in Javascript with an object

I am a beginner at js and have a project due by the end of day. I have to display an array with temps added and have set up an object to hold this array. My problem is that the message won't display and the for statement doesn't increment. When passed through both the var i and count come back undefined. I know there is a lot missing from this code but at this point I have tried to stream line it so that I can debug this issue. The date I will deal with later.
Here is my code:
var temps = [];
function process() {
'use strict';
var lowTemp = document.getElementById('lowTemp').value;
var highTemp = document.getElementById('highTemp').value;
var output = document.getElementById('output');
var inputDate = (new Date()).getTime();
var temp = {
inputDate : inputDate,
lowTemp : lowTemp,
highTemp : highTemp
};
var message = '';
if (lowTemp == null) {
alert ('Please enter a Low Temperature!');
window.location.href = "temps.html";
} else if (highTemp == null) {
alert ('Please enter a High Temperature!');
window.location.href = "temps.html";
} else {
lowTemp = parseFloat(lowTemp, 10);
highTemp = parseFloat(highTemp, 10);
}
if (temp.value) {
temps.push(temp.inputDate, temp.lowTemp, temp.highTemp)
var message = '<h2>Temperature</h2><ol>';
for (var i = 0, count = temps.length; i < count; i++) {
message += '<li>' + temps[i] + '</li>'
}
message += '</ol>';
output.innnerHTML = message;
}
return false;
}
function init() {
'use strict';
document.getElementById('theForm').onsubmit = process;
}
window.onload = init;
Here is my new code:
var temps = [];
function process() {
'use strict';
var lowTemp = document.getElementById('lowTemp').value;
var highTemp = document.getElementById('highTemp').value;
var output = document.getElementById('output');
var inputDate = (new Date()).getTime();
var temp = {
inputDate : inputDate,
lowTemp : lowTemp,
highTemp : highTemp
};
var message = '';
if (lowTemp == null) {
alert ('Please enter a Low Temperature!');
window.location.href = "temps.html";
} else if (highTemp == null) {
alert ('Please enter a High Temperature!');
window.location.href = "temps.html";
} else {
lowTemp = parseFloat(lowTemp, 10);
highTemp = parseFloat(highTemp, 10);
}
if (temp.value) {
temps.push(temp.inputDate, temp.lowTemp, temp.highTemp)
var message = '<h2>Temperature</h2><ol>';
for (var i = 0, count = temps.length; i < count; i++) {
message += '<li>' + temps[i] + '</li>'
}
message += '</ol>';
output.innnerHTML = message;
}
return false;
}
function init() {
'use strict';
document.getElementById('theForm').onsubmit = process;
}
window.onload = init;
There are some big issues with your code:
You should never compare anything to NaN directly. The correct comparison should be:
if (isNaN(lowTemp)) {
You're using curly braces when not needed. You should remove both curly braces:
{window.location.href = "temps.html";}
The function parseFloat expects only one parameter: the string to be converted. You're probably confusing it to parseInt which expects both the string and the radix of the conversion.
You're using the temp's property value, but you have never setted it, so, the condition where you check if it exists will always return false, and the push method that you want to debug will never be called, since it's inside that if statement.
Finally, you're closing a li tag at the end, but you have never opened it. You should probably be closing the ol tag you have opened in the begining.
The rest of your code seems pretty OK for me.
Talking about debugging, you should read the Google Chrome's Debugging Javascript Tutorial.

JSON return value to global variable

Simply my code looks like this:
var thevariable = 0;
For(){
//somecode using thevariable
$.getJSON('',{},function(e){
//success and i want to set the returned value from php to my variable to use it in the forloop
thevariable = e.result;
});
}
my main problem that the variable value stays "0", during the whole For loop, while i only want it to be "0" at the first loop, then it takes the result returned from PHP to use it on for loop.
here it my real code if you need to take a look:
var orderinvoice = 0;
for(var i=0; i<table.rows.length; i++){
var ordername = table.rows[i].cells[5].innerText;
var orderqty = ((table.rows[i].cells[1].innerText).replace(/\,/g,'')).replace(/Qty /g,'');
var orderprice = (table.rows[i].cells[2].innerText).replace(/\$/g,'');
var ordertype = table.rows[i].cells[3].innerText;
var orderlink = table.rows[i].cells[4].innerText;
$.getJSON('orderprocess.php', {'invoice': orderinvoice, 'pay_email': email, 'ord_name': ordername, 'ord_qty': orderqty, 'ord_price': orderprice, 'ord_type': ordertype, 'ord_link': orderlink}, function(e) {
console.log();
document.getElementById("result").innerText= document.getElementById("result").innerText + "Order #"+e.result+" Created Successfully ";
document.getElementById("invoker").innerText = ""+e.invoice;
orderinvoice = e.invoice;
if(i+1 == table.rows.length){
document.getElementById("result").innerText= document.getElementById("result").innerText + "With invoice #" + e.invoice;
}
});
in a loop block, before one ajax complete other one will be run and this's javascript natural treatment. For your case you can call a function at the end of success event. Do something like this:
var i = 0;
doSt();
function doSt() {
var orderinvoice = 0;
var ordername = table.rows[i].cells[5].innerText;
var orderqty = ((table.rows[i].cells[1].innerText).replace(/\,/g, '')).replace(/Qty /g, '');
var orderprice = (table.rows[i].cells[2].innerText).replace(/\$/g, '');
var ordertype = table.rows[i].cells[3].innerText;
var orderlink = table.rows[i].cells[4].innerText;
$.getJSON('orderprocess.php', { 'invoice': orderinvoice, 'pay_email': email, 'ord_name': ordername, 'ord_qty': orderqty, 'ord_price': orderprice, 'ord_type': ordertype, 'ord_link': orderlink }, function(e) {
console.log();
document.getElementById("result").innerText = document.getElementById("result").innerText + "Order #" + e.result + " Created Successfully ";
document.getElementById("invoker").innerText = "" + e.invoice;
orderinvoice = e.invoice;
if (i + 1 == table.rows.length) {
document.getElementById("result").innerText = document.getElementById("result").innerText + "With invoice #" + e.invoice;
}
i++;
if (i < table.rows.length) doSt();
});
}
I think you need a recursive function that always deals with the first element in your rows array and then splices it off and calls itself. For example, something like this:
function getStuff(rows, results) {
if (rows.length > 0) {
var ordername = rows[0].cells[5].innerText;
$.getJSON('orderprocess.php', { 'ord_name': ordername }, function (e) {
// do some stuff
results.push('aggregate some things here?');
rows.splice(0, 1);
return getStuff(rows, results);
});
} else {
return results;
}
}
When the array is spent, results will be returned with whatever aggregate you wanted at the end of the cycle. Then, you can do as you please with the results. I think you can also manipulate the DOM inside the function as you see fit if that makes more sense. Hope this helps.

Why won't this object method return a boolean value Javascript

My app's js file includes this bit here:
var drawer = document.getElementById('b_001');
drawer.isOpen = function() {
this.classList.contains('open');
};
When I call it in the console, drawer.isOpen(), I expect a boolean value, true or false. However, undefined is returned instead. Why is this?
you need a return statement
return this.classList.contains('open');
You'll have to return it:
drawer.isOpen = function() {
return this.classList.contains('open');
//^ here
};
If a function doesn't return anything, the return value is considered undefined, as this snippet demonstrates:
var report = document.querySelector('#result');
report.innerHTML += doStuff(5); // nothing returned
report.innerHTML += '<br>'+addFive(5); // a result is returned
function doStuff(val) {
val = val || 0;
val += 5;
}
function addFive(val) {
val = val || 0;
val += 5;
return val;
}
<div id="result"></div>

Categories

Resources