I have this JavaScript: http://jsfiddle.net/Lanti/4454ve0n/11/
The working code is commented out. I want to move out some lines and make them "global" under use strict creating nested functions, following this tutorial: http://www.w3schools.com/js/tryit.asp?filename=tryjs_function_counter3
I'm new to JavaScript.
Someone can explain why my solution is not working in the widthHeightUnit() function? It's not refreshing on click, just only if I press F5.
(function(){
////////////////////////// START OF: NESTED FUNCTIONS //////////////////////////
var widthHeightUnitVar = (function () {
var widthHeightUnitResult = document.getElementById('units').value;
return function () {return widthHeightUnitResult;}
})();
console.log(widthHeightUnitVar());
/////////////////////////// END OF: NESTED FUNCTIONS ///////////////////////////
window.onload = widthHeightUnit;
document.getElementById('units').addEventListener('click', widthHeightUnit);
function widthHeightUnit() {
//var widthHeightUnitResult = document.getElementById('units').value;
widthHeightUnitVar();
//document.querySelector('.width-unit').innerHTML = widthHeightUnitResult;
//document.querySelector('.height-unit').innerHTML = widthHeightUnitResult;
document.querySelector('.width-unit').innerHTML = widthHeightUnitVar();
document.querySelector('.height-unit').innerHTML = widthHeightUnitVar();
}
})();
(function() {
////////////////////////// START OF: NESTED FUNCTIONS //////////////////////////
var widthHeightUnitVar = (function() {
var widthHeightUnitResult = document.getElementById('units').value;
return function() {
return widthHeightUnitResult;
}
})();
console.log(widthHeightUnitVar());
/////////////////////////// END OF: NESTED FUNCTIONS ///////////////////////////
window.onload = widthHeightUnit;
document.getElementById('units').addEventListener('click', widthHeightUnit);
function widthHeightUnit() {
//var widthHeightUnitResult = document.getElementById('units').value;
widthHeightUnitVar();
//document.querySelector('.width-unit').innerHTML = widthHeightUnitResult;
//document.querySelector('.height-unit').innerHTML = widthHeightUnitResult;
document.querySelector('.width-unit').innerHTML = widthHeightUnitVar();
document.querySelector('.height-unit').innerHTML = widthHeightUnitVar();
}
document.getElementById('submit').addEventListener('click', dofCalc);
function dofCalc() {
var dofCalcWidth = document.getElementById('width').value;
if (dofCalcWidth.length === 0) {
alert('Please enter a real value to width!');
return;
}
var dofCalcHeight = document.getElementById('height').value;
if (dofCalcHeight.length === 0) {
alert('Please enter a real value to height!');
return;
}
var result = (+dofCalcWidth + +dofCalcHeight) / 2 // The + before the variables is "string to number conversion"
//document.getElementById('result').innerHTML = result + ' ' + document.getElementById('units').value;
document.getElementById('result').innerHTML = result + ' ' + widthHeightUnitVar();
}
})();
<form>
Select your width/height unit:
<br>
<select id="units">
<option value="feet">feet</option>
<option value="inches">inches</option>
<option value="meters">meters</option>
<option value="centimeters">centimeters</option>
<option value="milimeters" selected="selected">milimeters</option>
</select>
<br>
<br>Width:
<input type="number" id="width" /><span class="width-unit"></span>
<br>
<br>Height:
<input type="number" id="height" /><span class="height-unit"></span>
<br>
<br>
<input type="button" value="Submit" id="submit" />
<form/>
<br>
<br>Calculation:
<div id="result"></div>
Do it this way
var widthHeightUnitVar = function () {
var widthHeightUnitResult = document.getElementById('units').value;
return widthHeightUnitResult;
};
You were using IIFE so it was running immediately and only once, so it was not refreshing..
////////////////////////// START OF: NESTED FUNCTIONS //////////////////////////
var widthHeightUnitVar = (function () {
var widthHeightUnitResult = document.getElementById('units').value;
return function () {return widthHeightUnitResult;}
})();
console.log(widthHeightUnitVar());
/////////////////////////// END OF: NESTED FUNCTIONS ///////////////////////////
Related
i am building a configuration utility and having a problem with the js.
I am very new to javascript so i apologize in advance for the request for help.
in my HTML i have multiple divs that are structured like this:
<div id="options" class="opt">
<h2 id="optionName">Power Button Options</h2>
<label for="pwrAvl">Power Button Available</label>
<input type="checkbox" name="pwrAvl" id="pwrAvl"/ >
<br /><br />
<label for="pwrLabel">Power Button Label</label>
<input type="text" name="pwrLabel" id="pwrLabel"/ >
<br /><br />
<label for="pwrGraphic">Power Button Graphic</label>
<select name="pwrGraphic" id="pwrGraphic">
<option value="" selected>
----- Please select a graphic -----
</option>
<option value="power.jpeg">Power</option>
<option value="light.jpg">Light</option>
<option value="help.jpg">Help</option>
<option value="camera.jpg">Camera</option>
</select>
<br /><br />
<label for="pwrIndex">Power Button Menu Index</label>
<input type="text" name="pwrIndex" id="pwrIndex"/ >
</div>
i have between 5-10 divs that will all be structured the same way just with different labels and input values.
i tried adding all the divs to an array and then enumerate through the array but that did not work.
here is my js file what i have tried:
{
const bar = document.querySelector('options');
var opts = document.querySelectorAll('.opt')
var option = {}
var nCount = $(".opt").length;
var divArray = [];
var optName = document.getElementById('optionName');
function addArray() {
for (let i = 0; i < nCount; i++) {
divArray[i] = opts[i];
}
}
const saveBtn = document.getElementById('submit');
saveBtn.addEventListener('click', (e) => {
putSettings();
});
function SystemOptions(optionName, optionAvailable, optionLabel, optionGraphic, optionIndex) {
this.optionName = optionName;
this.optionAvailable = optionAvailable;
this.optionLabel = optionLabel;
this.optionGraphic = optionGraphic;
this.optionIndex = optionIndex;
}
async function putSettings() {
let info = {
"SystemConfiguration": {
"Options": [],
}
}
addArray()
console.log(`Divarray = ${divArray.length}`)
//The following would never work
opts.forEach(label => {
$('[id=optionName]').each(function () {
var atId = this.id;
console.log(`Searched Name = ${atId.innerHTML}`)
});
});
divArray.forEach(element => {
var name = divArray.getElementById('optionName').innerHTML;
console.log(name)
option = new SystemOptions(name, "yes", "Help Label", "Option.jpeg", 3);
info.SystemConfiguration.Options.push(option);
});
for (let i = 0; i < nCount; i++) {
// console.log(` ${$(".opt").find("h2[id=optionName").each.text()}`)
console.log(` ${divArray[i].querySelector(optName[i]).innerHTML}`)
}
// i did this once to see if the SystemsOptions function worked
// obviosly it added the same data 7 times but i was trying to be sure the function worked and created the json objects
for (let i = 1; i < nCount; i++) {
option = new SystemOptions("Power", "yes", "Help Label", "Option.jpeg", 3);
info.SystemConfiguration.Options.push(option);
}
let data = JSON.stringify(info, 0, 4);
console.log(data);
}
}
any help would be greatly appreciated.
not the most eloquent but this does work.
sure there are better ways:
var opts = document.querySelectorAll('.opt');
var option = {};
const saveBtn = document.getElementById('submit');
saveBtn.addEventListener('click', (e) => {
putSettings();
});
function SystemOptions(optionName, optionAvailable, optionLabel, optionGraphic, optionIndex) {
this.optionName = optionName;
this.optionAvailable = optionAvailable;
this.optionLabel = optionLabel;
this.optionGraphic = optionGraphic;
this.optionIndex = optionIndex;
}
async function putSettings() {
let info = {
"SystemConfiguration" :{
"Options": [],
}
};
for(var opt of opts)
{
var name = opt.getElementsByTagName('h2')[0].innerHTML;
let isAvailable = opt.getElementsByTagName("input")[0].value;
let optLabel = opt.getElementsByTagName("input")[1].value;
let optGraphic = opt.getElementsByTagName('select')[0].value;
let index = opt.getElementsByTagName("input")[2].value;
option = new SystemOptions(name, isAvailable, optLabel, optGraphic, index);
info.SystemConfiguration.Options.push(option);
}
console.log(`Number of options = ${opts.length}`)
let data = JSON.stringify(info, 0, 4);
console.log(data);
};
How do I set the text box value from javascript return value? I tried the below code it's not working- where am I wrong?
function getname(name) {
var subindex = name.indexOf(" ") + 1;
return (name.substring(subindex));
}
var res = (getname("Harpreet Kaur"));
document.getElementById("lname").value = res;
//alert(res);
<body>
<input type="text" id="lname">
</body>
It works perfectly:
function getname(name) {
var subindex = name.indexOf(" ") + 1;
return (name.substring(subindex));
}
var res = getname("Harpreet Kaur");
document.getElementById("lname").value = res;
<input type="text" id="lname">
I have an angular form. only 2 input box. I am taking the
values from input box and then saving them in an array.
then the problem begins.
I want to show the array wrapped with <pre></pre> tag
how do I do that. Code sample is like this.
<input type="text" class="form-control" id="qus" placeholder="Enter Question" ng-model="qus">
<input type="text" class="form-control" id="op1" placeholder="Option 1" ng-model="op1">
<label><input type="checkbox" ng-model="correct1">Correct</label>
<button class="form-control btn btn-primary" ng-click = "save()">Save</button>
<pre ng-bind="dataShow"></pre>
Script:
var app = angular.module('qApp', []);
app.controller('qCtrl', function($scope) {
var set = [];
var op1 = [];
$scope.save = function (){
if($scope.correct1!==true){$scope.correct1=false;}
op1.push($scope.op1, $scope.correct1);
var qus = [$scope.qus, op1];
set.push(qus);
console.log(qus);
console.log(set);
return set;
};
$scope.dataShow = set.toString();
});
Move $scope.dataShow = set.toString(); inside the function and remove the return:
$scope.save = function () {
var set = [];
var op1 = [];
if ($scope.correct1 !== true) {
$scope.correct1 = false;
}
op1.push($scope.op1, $scope.correct1);
var qus = [$scope.qus, op1];
set.push(qus);
console.log(qus);
console.log(set);
$scope.dataShow = set.toString();
};
So I'm trying to add an option on my options page for people to set 1-3 letters as a link to a website. Currently I'm getting a NaN value for the linkNumber when I run the function.
The Function:
function addLink () {
chrome.storage.local.get('linkNumber', function (x) {
if (x.linkNumber == undefined) {
chrome.storage.local.set({'linkNumber': '0'}, function() {
addLink();
});
} else {
var linkNumberInteger = parseInt(x.linkNumber);
var handle = document.getElementById("short");
var link = document.getElementById("long");
var handleValue = handle.value;
var linkValue = link.value;
var handleNumber = x.linkNumber + '-handle';
var urlNumber = x.linkNumber + '-link';
var objectOne = {};
var objectTwo = {};
objectOne[handleNumber] = x.linkNumber + '-handle';
objectTwo[urlNumber] = x.linkNumber + '-link';
console.log(x.linkNumber);
console.log(handleNumber);
chrome.storage.local.set({handleNumber: handleValue}, function(y) {
console.log(y.handleNumber + ' handle saved');
});
chrome.storage.local.set({urlNumber: linkValue}, function(z) {
console.log(z.handleNumber + ' link saved');
});
var linkNumberIntegerNext = linkNumberInteger++;
var n = linkNumberIntegerNext.toString();
chrome.storage.local.set({'linkNumber': n}, function() {
});
alert('Link Added');
}
});
}
The Html:
<h3 class="option">Add Quick Link:</h3>
<input contenteditable="true" type="text" class="short-quicklink" id="short" maxlength="3">
<span>http://</span><input contenteditable="true" type="text" class="long-quicklink" id="long">
<button class="add">Add Quick Link</button>
This is my code in html and java script. I coded same things thrice, I want to do it once... what to do...............
<input type="text" name="option1" id="option1" onblur="calc_amt(1);">
<input type="text" name="price1" id="price1" onblur="calc_amt(1);">
<input type="text" name="amount1" id="amount1" readonly>
<input type="text" name="option2" id="option2" onblur="calc_amt(2);">
<input type="text" name="price2" id="price2" onblur="calc_amt(2);">
<input type="text" name="amount2" id="amount2" readonly>
<input type="text" name="option3" id="option3" onblur="calc_amt(3);">
<input type="text" name="price3" id="price3" onblur="calc_amt(3);">
<input type="text" name="amount3" id="amount3" readonly>
<script>
function calc_amt(val){
if(val==1){
var option1 = document.getElementById("option1").value;
var pri1 = document.getElementById("price1").value;
....
document.getElementById("amount1").value=amoun1 ;
}
if(val==2){
var option2 = document.getElementById("option2").value;
var pri2 = document.getElementById("price2").value;
...
document.getElementById("amount2").value=amoun2;
}
if(val==3){
var option3 = document.getElementById("option3").value;
var pri3 = document.getElementById("price3").value;
....
document.getElementById("amount3").value=amoun3;
}
var amoun1=document.getElementById("amount1").value;
var amoun2=document.getElementById("amount2").value;
var amoun3=document.getElementById("amount3").value;
var tot = Number(amt1)+Number(amt2)+Number(amt3);
document.getElementById("amount").value=tot;
}
</script>
how do solve it by coding only once... I am beginner please help me.... any other ideas to solve this.. i need a solution like inheritance.
You can further reduce above script like this. Your amoun is unclear for though. However you can reduce the code like this. This is just an idea and make sure you match the variables with correct statement.
<script>
function calc_amt(val){
var option1 = document.getElementById("option"+val).value;
var pri1 = document.getElementById("price"+val).value;
....
document.getElementById("amount"+val).value=""+amount+val ;
var amoun1=document.getElementById("amount1").value;
var amoun2=document.getElementById("amount2").value;
var amoun3=document.getElementById("amount3").value;
var tot = Number(amt1)+Number(amt2)+Number(amt3);
document.getElementById("amount").value=tot;
}
</script>
Replace:
if(val==1){
var option1 = document.getElementById("option1").value;
var pri1 = document.getElementById("price1").value;
document.getElementById("amount1").value=amoun1 ;
}
with:
var amoun = document.getElementById("amount" + val).value;
var option = document.getElementById("option" + val).value;
var pri = document.getElementById("price" + val).value;
document.getElementById("amount" + val).value=amoun;
TRY...
Remove all inline handler and use blur handler like in demo
$("input[type=text]").on("blur", function () {
var id = this.id;
var last = id.charAt(id.length - 1); // get last id string value
var optionValue = $("#option" + last).val();
var priceValue = $("#price" + last).val();
var option = isNaN(optionValue) ? 0 : +optionValue; // check is nan
var price = isNaN(priceValue) ? 0 : +priceValue;
$("#amount" + last).val(option * price); // display multiply value
$("#amount").text($("input[type=text][id^=amount]").map(function () { // collect all amount1,2,3 values
var value = $(this).val();
return isNaN(value) ? 0 : +value;
}).get().reduce(function (a, b) { // add total value
return a + b;
}));
});
DEMO
OPTIMIZED CODE
$("input[type=text]:not([readonly])").on("blur", function () {
var obj = $();
obj = obj.add($(this)).add($(this).prevUntil('[readonly]')).add($(this).nextUntil('[readonly]'));
$(this).nextAll('[readonly]').first().val($.map(obj, function (val, i) {
return parseInt(val.value, 10) || 0;
}).reduce(function (a, b) {
return a * b
}, 1));
$("#amount").text($("input[type=text][id^=amount]").map(function () {
var value = $(this).val();
return isNaN(value) ? 0 : +value;
}).get().reduce(function (a, b) {
return a + b;
}));
});
DEMO