I need to create 4 checkboxes, which will get textarea value and execute some functions from the module. However, checkboxes dont get the value, and that is my problem. Ive tried to put text.addEventListener to each function and to checkbox eventListeners as well, but it doesn`t work.
Hope, you could give me some kind of solution.
Thanks in advance!
let text = document.querySelector('#text');
;(function() {
let a = (text.value.split(' ').filter(elem => elem != ''));
let b = a.join('').split('');
function wordsNumber() {
console.log(a);
console.log('The number of words is ' + a.length + '!');
}
function symbolsNumber() {
length = 0;
for (let elem of a) {
length += elem.length;
}
console.log('The number of symbols without backspace is ' + length + '!');
}
function symbolsNumberWithBackspace() {
console.log('The number of symbols with backspace is ' + text.value.length + '!');
}
function counter() {
let count = {};
for (let elem of b) {
if (count[elem] === undefined) {
count[elem] = 1;
}
else {
count[elem]++;
}
}
for (let elem in count) {
count[elem]=(Number(count[elem]/b.length)*100).toFixed(2) + '%';
}
console.log(count);
}
window.func = {wordsNumber, symbolsNumber, symbolsNumberWithBackspace, counter}
})();
let checkbox1 = document.querySelector('#check1');
let checkbox2 = document.querySelector('#check2');
let checkbox3 = document.querySelector('#check3');
let checkbox4 = document.querySelector('#check4');
checkbox1.addEventListener('click', function () {
if (checkbox1.checked) {
func.wordsNumber();
}
})
checkbox2.addEventListener('click', function () {
if (checkbox2.checked) {
func.symbolsNumber();
}
})
checkbox3.addEventListener('click', function () {
if (checkbox3.checked) {
func.symbolsNumberWithBackspace();
}
})
checkbox4.addEventListener('click', function () {
if (checkbox4.checked) {
func.counter();
}
})
A solution is to update variables a and b on text input, like this:
let text = document.querySelector('#text');
;(function() {
let a, b;
text.addEventListener('input', function () {
a = (text.value.split(' ').filter(elem => elem != ''));
b = a.join('').split('');
});
function wordsNumber() {
console.log(a);
console.log('The number of words is ' + a.length + '!');
}
function symbolsNumber() {
length = 0;
for (let elem of a) {
length += elem.length;
}
console.log('The number of symbols without backspace is ' + length + '!');
}
function symbolsNumberWithBackspace() {
console.log('The number of symbols with backspace is ' + text.value.length + '!');
}
function counter() {
let count = {};
for (let elem of b) {
if (count[elem] === undefined) {
count[elem] = 1;
}
else {
count[elem]++;
}
}
for (let elem in count) {
count[elem]=(Number(count[elem]/b.length)*100).toFixed(2) + '%';
}
console.log(count);
}
window.func = {wordsNumber, symbolsNumber, symbolsNumberWithBackspace, counter}
})();
let checkbox1 = document.querySelector('#check1');
let checkbox2 = document.querySelector('#check2');
let checkbox3 = document.querySelector('#check3');
let checkbox4 = document.querySelector('#check4');
checkbox1.addEventListener('click', function () {
if (checkbox1.checked) {
func.wordsNumber();
}
})
checkbox2.addEventListener('click', function () {
if (checkbox2.checked) {
func.symbolsNumber();
}
})
checkbox3.addEventListener('click', function () {
if (checkbox3.checked) {
func.symbolsNumberWithBackspace();
}
})
checkbox4.addEventListener('click', function () {
if (checkbox4.checked) {
func.counter();
}
})
<textarea id="text"></textarea>
<input type="checkbox" id="check1">
<input type="checkbox" id="check2">
<input type="checkbox" id="check3">
<input type="checkbox" id="check4">
Related
so i have a function that's meant to remove an element tag when its clicked on and remove its respective content/ingredient from a separate list. Everything works fine as it should, partially, on the browser, when i check the console there is a TypeError and i can't seem to find out why. I've been at it for the past 3 hours and can't find a solution, someone please help. Below is the code. You will need to input "," after each word to create a new tag, and due to the no css added you will need to click on the word to remove it (words in the row directly after the input).
const ingredientsInput = document.querySelector('#ingredients'),
ingredientsContainer = document.querySelector('.ingredients__tag');
let ingredientsArray = [];
ingredientsInput.addEventListener('input', () => {
if (ingredientsInput.value.includes(',')) {
let v = ingredientsInput.value.replace(',', '');
if(v != '' && v != ',') {
let s = document.createElement('span');
s.setAttribute('class', 'tag__item');
s.innerHTML = v;
ingredientsContainer.appendChild(s);
ingredientsArray.push(v);
recipesInclude(v, true);
ingredientsInput.value = "";
} else if(v = ',') {
ingredientsInput.value = "";
}
removeItem();
console.log(ingredientsArray);
}
});
function removeItem() {
const ingredientsItem = ingredientsContainer.querySelectorAll('.tag__item');
ingredientsItem.forEach(e => {
e.addEventListener('click', () => {
recipesInclude(e.innerHTML, false);
removeArray(ingredientsArray, e.innerHTML, false);
e.remove();
console.log(ingredientsArray);
});
});
}
function removeArray(array, index, result) {
for(i = 0; i < array.length; i++){
if(array[i] === index) {
array.splice(i, 1);
if(result) {
return array;
}
}
}
}
function recipesInclude(ingredient, statement) {
ingredientLead = document.querySelector('.list');
if(statement) {
if(ingredientLead.innerText.length > 0) {
ingredientLead.innerHTML += ', ' + ingredient;
} else {
ingredientLead.innerHTML += ingredient;
}
} else {
ingredientSplit = ingredientLead.innerText.split(", ");
if(ingredientSplit.length > 1) {
ingredientLead.innerHTML = removeArray(ingredientSplit, ingredient, true).join(", ");
} else {
ingredientLead.innerHTML = removeArray(ingredientSplit, ingredient, true);
}
}
}
<input type="text" name="ingredients" id="ingredients" onkeyup="this.setAttribute('value', this.value);" placeholder="" class="form__control">
<div class="ingredients__tag"></div>
<p class="list"></p>
Check this code this may Help
I added return array when no condition is matched
const ingredientsInput = document.querySelector('#ingredients'),
ingredientsContainer = document.querySelector('.ingredients__tag');
let ingredientsArray = [];
ingredientsInput.addEventListener('input', () => {
if (ingredientsInput.value.includes(',')) {
let v = ingredientsInput.value.replace(',', '');
if (v != '' && v != ',') {
let s = document.createElement('span');
s.setAttribute('class', 'tag__item');
s.innerHTML = v;
ingredientsContainer.appendChild(s);
ingredientsArray.push(v);
recipesInclude(v, true);
ingredientsInput.value = "";
} else if (v = ',') {
ingredientsInput.value = "";
}
removeItem();
//console.log(ingredientsArray);
}
});
function removeItem() {
const ingredientsItem = ingredientsContainer.querySelectorAll('.tag__item');
ingredientsItem.forEach(e => {
e.addEventListener('click', () => {
recipesInclude(e.innerHTML, false);
removeArray(ingredientsArray, e.innerHTML, false);
e.remove();
console.log(ingredientsArray);
});
});
}
function removeArray(array, index, result) {
for (i = 0; i < array.length; i++) {
if (array[i] === index) {
array.splice(i, 1);
if (result) {
return array;
}
}
}
return array;
}
function recipesInclude(ingredient, statement) {
ingredientLead = document.querySelector('.list');
if (statement) {
if (ingredientLead.innerText.length > 0) {
ingredientLead.innerHTML += ', ' + ingredient;
} else {
ingredientLead.innerHTML += ingredient;
}
} else {
ingredientSplit = ingredientLead.innerText.split(", ");
if (ingredientSplit.length > 1) {
ingredientLead.innerHTML = removeArray(ingredientSplit, ingredient, true).join(", ");
} else {
ingredientLead.innerHTML = removeArray(ingredientSplit, ingredient, true);
}
}
}
<input type="text" name="ingredients" id="ingredients" onkeyup="this.setAttribute('value', this.value);" placeholder="" class="form__control">
<div class="ingredients__tag"></div>
<p class="list"></p>
Iam a new bee to javascript , i tried to get the boolean value in side the if condition.Below are the code snippet ,
view.prototype.searchCustomer = function (customername) {
var customerFound = false;
var res = element.all(by.repeater('page in pages')).count().then(function (count) {
console.log("count of page count is " + count);
for (var i = 1; i <= count - 4; i++) {
element(by.xpath('//a[#class="ng-binding" and contains(text(),"rs")]'.replace("rs", i))).click();
element(By.xpath("//div[#class='cardHeader']/a[contains(text(),'" + customername + "')]")).isPresent().then(function (result) {
if (result) {
customerFound = true;
return result;
}
});
}
});
console.log("result is - "+customerFound);
};
Here console.log always returns false when the customerFound flag is true.Can any one help me on this please.I do have better knowledge on Java and learning javascript.
Thanks
Try to change var to let in a loop:
view.prototype.searchCustomer = function (customername) {
let customerFound = false;
const res = element.all(by.repeater('page in pages')).count().then(function (count) {
console.log("count of page count is " + count);
for (let i = 1; i <= count - 4; i++) {
element(by.xpath('//a[#class="ng-binding" and contains(text(),"rs")]'.replace("rs", i))).click();
element(By.xpath("//div[#class='cardHeader']/a[contains(text(),'" + customername + "')]")).isPresent().then(function (result) {
if (result) {
customerFound = true;
return result;
}
});
}
});
console.log("result is - "+customerFound);
};
This is a program to find the nth fibonacci number.
var fib = (function() {
var save = [];
var i = 0;
return {
"getNum": function(input) {
this.input = input;
if (input === 0) {
console.log("Invalid input");
}
save[i] = i;
save[i + 1] = i + 1;
save[i + 2] = i + 1;
i = 2;
for (i >= 2; i < input; i = i + 1) {
save[i + 1] = save[i] + save[i - 1];
}
console.log(save[i - 1]);
}
}
}());
fib.getNum(4);
My question is when I implement this problem in the following way, it doesn't work. I understand this is because I am not calling the sub-functions and only calling the main function. Is there a better pattern we can use that will keep the code organised and we won't have to make calls to so many functions?
var fib = (function() {
var save = [];
var i = 0;
return {
"getNum": function(input) {
this.input = input;
function valid() {
if (input === 0) {
console.log("Invalid input");
}
}
function config() {
save[i] = i;
save[i + 1] = i + 1;
save[i + 2] = i + 1;
i = 2;
}
function nthNum() {
for (i >= 2; i < input; i = i + 1) {
save[i + 1] = save[i] + save[i - 1];
}
console.log(save[i - 1]);
}
}
}
}());
fib.getNum(4);
You can think of using closure to create private and public functions.If you see the below code only _getNum function is exposed.
var fib = (function() {
var save = [];
save[0] = 0;
save[1] = 1;
var i = 0;
//This will validate the number
// This function can be avoided and make _getNum do the same
function _valid(input){
console.log("Method Executing:_valid");
input === 0 ? console.log('Invalid Input') : _nthNum(input);
}
// Will calualte the series.
// This is a private function
function _nthNum(input) {
console.log('Method Executing:_nthNum');
for (i = 2; i<=input; i++) {
save[i] = save[i-2] + save[i - 1];
}
console.log(save.pop());
}
// Private Function
function _getNum(input){
console.log("Method Executing :_getNum" ,input);
_valid(input);
}
//Expose the private function
return {
getNum :_getNum // Expose _getNum
}
}());
fib.getNum(0);
fib.getNum(4);
fib.getNum(7);
WORKING COPY
My suggestion:
var Fibonacci = (function() {
var _Fibonacci = {
// set initial values
result: [0, 1, 1],
input: 0,
// main function
find: function (number) {
this.input = number;
if (this.isValid()) {
this.calculate();
return this.result.pop();
}
return 'Invalid input';
},
// sub functions
isValid: function () {
return this.input != 0
},
calculate: function () {
for (var i=2; i<this.input; i++) { // fix your code here
this.result[i+1] = this.result[i] + this.result[i-1];
}
}
};
// return the main function
return _Fibonacci.find.bind(_Fibonacci);
}());
console.log(
Fibonacci(0),
Fibonacci(4),
Fibonacci(6)
);
In trying to learn more about JavaScript patterns I created the following 2 "Meters" based on an example I found. Is Meter1 better because it uses the Observable Property (or so I think) pattern? Would this pattern be used real-world or not really because of all the frameworks available?
//Meter1 - Observable Property Pattern
var Meter1 = function (count) {
var countChanging = [],
countChanged = [];
this.count = function (val) {
if (val !== undefined && val !== count) {
for (var i = 0; i < countChanging.length; i++) {
if (!countChanging[i](this, val)) {
return count;
}
}
count = val;
for (var i = 0; i < countChanged.length; i++) {
countChanged[i](this);
}
}
return count;
};
this.increment = function () {
return count = count + 1;
}
this.onCountChanging = function (callback) {
countChanging.push(callback);
};
this.onCountChanged = function (callback) {
countChanged.push(callback);
};
};
var meter = new Meter1(5);
var btnClick = document.getElementById('btnClick');
btnClick.addEventListener('click', function () {
meter.count(meter.count() + 1);
}, false);
meter.onCountChanging(function (b, count) {
if (count > 10) {
document.getElementById('numClicks').innerHTML = "Enough already!!!!!";
return false;
}
return true;
});
meter.onCountChanged(function () {
document.getElementById('numClicks').innerHTML = "Test " + meter.count();
});
//Meter2 - Does the same thing, is Observable Property pattern better?
var Meter2 = function (count) {
this.count = 0;
};
var meter2 = new Meter2(5);
var btnClick2 = document.getElementById('btnClick2');
btnClick2.addEventListener('click', function () {
meter2.count = meter2.count + 1;
if (meter2.count > 10) {
document.getElementById('numClicks2').innerHTML = "Enough already!!!!!";
} else {
document.getElementById('numClicks2').innerHTML = "Test " + meter2.count;
}
}, false);
<body>
<div id="numClicks">Test</div>
<div id="numClicks2">Test</div>
<button id="btnClick">Click - Meter</button>
<button id="btnClick2">Click - Meter 2</button>
</body>
</html>
<script src="../js/generalTesting.js"></script>
I've tried this a thousand different ways in a thousand different times and my JS code won't come out the way I want it. When I run it in the Mozilla scratchpad, I get "userHand is undefined" and the second printHand shows as undefined, too. Could someone show me where are the errors in my blackjack game?
function Card (s, n) {
var suit = s;
var number = n;
this.getNumber = function () {
return number;
};
this.getSuit = function () {
return suit;
};
this.getValue = function () {
if (number > 10) {
return 10;
} else if (number === 1) {
return 11;
} else {
return number;
}
};
}
var cardNames = {1:"Ace", 2:"2", 3:"3", 4:"4", 5:"5", 6:"6", 7:"7", 8:"8", 9:"9", 10:"10", 11:"Joker", 12:"Queen", 13:"King"};
var suitNames = {1:"Clubs", 2:"Diamonds", 3:"Hearts", 4:"Spades"};
var deal = function () {
var s = Math.floor(Math.random() * 4 + 1);
var n = Math.floor(Math.random() * 13 + 1);
return new Card(s, n);
};
function Hand(){
var cards = [];
cards.push(deal());
cards.push(deal());
this.getHand = function () {
return cards;
};
this.score = function () {
var score;
for (i = 0; i < cards.length; i++) {
score = score + cards[i].getValue();
}
for (i = 0; i < cards.length; i++) {
if (score > 21 && cards[i].getValue() === 11) {
score = score - 10;
}
} return score;
};
this.printHand = function () {
for (i = 0; i < cards.length; i++) {
var hand;
if (i === 0) {
hand = cardNames[cards[i].getNumber()] + " of " + suitNames[cards[i].getSuit()];
} else {
hand = hand + " and a " + cardNames[cards[i].getNumber()] + " of " + suitNames[cards[i].getSuit()];
}
} alert(hand);
};
this.hitMe = function () {
cards.push(deal());
};
}
var playAsDealer = function () {
var playDealer = new Hand();
while (playDealer.score() < 17) {
playDealer.hitMe();
}
this.printHand = function () {
return playDealer.printHand();
};
this.score = function () {
return playDealer.score();
};
};
var playAsUser = function () {
var playUser = new Hand();
this.printHand = function () {
return playUser.printHand();
};
this.score = function () {
return playUser.score();
};
var decision = confirm("Your hand is " + playUser.printHand() + ". Click OK to hit or Cancel to stand");
for (i = 0; decision !== false; i++) {
playUser.hitMe();
decision = confirm("Your hand is " + playUser.printHand() + ". Click OK to hit or Cancel to stand");
}
};
var declareWinner = function (userHand, dealerHand) {
if ((userHand.score < dealerHand.score) || userHand.score > 21) {
return "You lose.";
} else if (userHand.score > dealerHand.score) {
return "You win.";
} else {
return "You tied.";
}
};
var playGame = function () {
var user = playAsUser();
var dealer = playAsDealer();
declareWinner(user, dealer);
console.log("User got " + user.printHand());
console.log("Dealer got " + dealer.printHand());
};
playGame();
You aren't returning nothing on printHand()
I just added the return statement and worked. See this fiddle
this.printHand = function () {
for (i = 0; i < cards.length; i++) {
var hand;
if (i === 0) {
hand = cardNames[cards[i].getNumber()] + " of " + suitNames[cards[i].getSuit()];
} else {
hand = hand + " and a " + cardNames[cards[i].getNumber()] + " of " + suitNames[cards[i].getSuit()];
}
}
//alert(hand); //remove this alert
return hand; // <----- solution
};