Building Calculator, getting Cannot set property 'value' of null - javascript

I am building a Calculator and I keep getting this error, I've tried typing it a few different ways but I couldn't figure it out, help, please!
const calculator = {
displayValue: '0',
firstOperand: null,
waitingForSecondOperand: false,
operator: null,
};
function updateDisplay() {
const display = document.querySelector('.calculator-screen');
display.value = calculator.displayValue;
}
updateDisplay();
I get the error on the
display.value = calculator.displayValue;
this is the html for the file
<div class="calculator">
<input type="text" class="calculator-screen" value = "0" disabled />
<div class="calculator-keys">
<button type="button" class="operator" value="+">+</button>
<button type="button" class="operator" value="-">-</button>
<button type="button" class="operator" value="*">×</button>
<button type="button" class="operator" value="/">÷</button>

That error means that this line:
const display = document.querySelector('.calculator-screen');
Is returning null. So when you do this:
display.value = calculator.displayValue;
You're really saying:
null = calculator.displayValue;
Try logging the value and check for yourself:
function updateDisplay() {
const display = document.querySelector('.calculator-screen');
console.log('display: ', display); // this is probably 'null'
display.value = calculator.displayValue;
}
I'm guessing you don't have a selector with the class .calculator-screen. Double-check the spelling or post the relevant HTML so I can confirm.
Here is your code, it seems to work fine I don't get an error so I'm not sure what's going on on your end:
const calculator = {
displayValue: '0',
firstOperand: null,
waitingForSecondOperand: false,
operator: null,
};
function updateDisplay() {
const display = document.querySelector('.calculator-screen');
display.value = calculator.displayValue;
}
updateDisplay();
<div class="calculator">
<input type="text" class="calculator-screen" value = "0" disabled />
<div class="calculator-keys">
<button type="button" class="operator" value="+">+</button>
<button type="button" class="operator" value="-">-</button>
<button type="button" class="operator" value="*">×</button>
<button type="button" class="operator" value="/">÷</button>
</div>
</div>

It seems your document.querySelector is not finding the element you need.
This error means probably display is null when you try to set it's value, and the only thing that could cause this is the corrector not finding the selection you wanted.

It is probably due to the disabled property of the input html tag. Remove the disabled attribute and try if it works.

Related

parameters passed to function is not working

I generated a random number called listingid in function createpost and pass it as an input to function showproductmodal as shown below
function creatpost(){
var index;
splitinput.forEach((num, index) => {
var listingid = (Date.now().toString(36) + Math.random().toString(36).substr(2, 5)).toUpperCase()
console.log(index)
return CatalogueDB.ref( splitinput[index]).once('value').then(function(snapshot) {
var resultcard = `
<form id="myform${index}">
<tr class="tr-shadow">
<td>
<button type="button" class="btn btn-primary btn-md" onclick="postitem(${key},${index},${listingid});">Submit</button>
</td>
</tr>
</form>
`
container.innerHTML += resultcard;
})
.catch(function(error) {
container.innerHTML += "";
var errorcard = `
<form id="myform${index}">
<tr class="tr-shadow">
<td style="width: 90px;">
<div id="ItemID${index}">${splitinput[index]}
</div>
<div>
<br>
<button type="button" class="btn btn-secondary mb-1 btn-sm" data-toggle="modal" data-target="#productModal" onclick="showproductmodal(${splitinput[index]},${index},${listingid})">
Add Photos
</button>
</div>
</td>
<td>
<button type="button" class="btn btn-primary btn-md" onclick="postitem(${splitinput[index]},${index},${listingid})">Submit</button>
</td>
</tr>
</form>
`
container.innerHTML += errorcard;
})
});
})
function showproductmodal(id, index, listingid) {
console.log(id,index)
}
the problem now is whenever the button is clicked which triggers showproductmodal it says lisitingid is undefined
this is the console error output
index.html:1 Uncaught ReferenceError: JJLQ23008PJX0 is not defined
at HTMLButtonElement.onclick (index.html:1)
this is the sample parameters passed to the showproductmodal retrieved from the console
showproductmodal(42,0,JJLQ23008PJX0)
why is the listingid causing error even when it has been passed to the function? How do I correct this so that I can retrieve listingid in showproductmodal?
If the listingid is not a variable with the name JJLQ23008PJX0 it will throw an error.
Generally one need to make such id/value be treated as a string, and enclose it in quotes, likes this, where I added single quote's '
onclick="postitem(${splitinput[index]},${index},'${listingid}')"
Some value types works though, as numbers, the boolean keywords true/false, etc.,
You need to quote the random string:
<button type="button" class="btn btn-primary btn-md" onclick="postitem(${key},${index},'${listingid}');">Submit</button>

Knockout: how to validate object observale

I am binding to an observable object as follows:
<input data-bind="value: currentSelected().Title" type="text" placeholder="Title" class="form-control" autocomplete="off" />
I want the field on the object to be required and the save button below not to work unless the Title has been filled in:
<button class="btn btn-default" type="button" data-bind="click: saveBlogEntries">Save</button>
This is how I am setting currentSelected:
var newBlogEntry = new NewBlogEntry();
var newBlogEntryObservable = new NewBlogEntryObservable(newBlogEntry);
self.currentSelected(newBlogEntryObservable);
The definition for the function NewBlogEntry() is:
function NewBlogEntry()
{
return { "Id": 0, "Title": "", "Description": "", "Tags": [] };
}
What is the best way to disable the save button, or when clicked show a validation message next to the Title field?
You could use the knockout disable binding on your button:
<button class="btn btn-default" type="button" data-bind="disable: currentSelected().Title() == '', click: saveBlogEntries">Save</button>
To simplify the data-bind, you could have a computed observable for the empty title condition:
<button class="btn btn-default" type="button" data-bind="disable: currentSelected().HasNoTitle(), click: saveBlogEntries">Save</button>
HasNoTitle = ko.computed(function () { this.Title() == '' });
To get this binding to work, you would need the Title property to be observable.
Title = ko.observable('');

Deleting dynamic input fields in Vue

Noob question but I can get fields to render in Vue but not sure how to delete my fields. I added an index option in the v-for directives but not sure what to do after that. Thanks!
Here is a working JSFiddle: https://jsfiddle.net/xu55npkn/
<body>
<div id="app"></div>
<script>
const createNewOption = () => {
return {
text: '',
isAnswer: false
}
}
const createNewQuestion = () => {
return {
text: '',
options: [createNewOption()]
}
}
var vm = new Vue({
el: '#app',
template: `<div class="quiz-builder container">
<div v-for="question in questions">
<div class="input-group">
<input type="text" class="form-control" v-model="question.text" placeholder="Enter a question">
<span class="input-group-btn">
<button class="btn btn-danger" type="button">X</button>
</span>
<span class="input-group-btn">
<button class="btn btn-secondary" type="button" #click="addOption(question)">Add an option</button>
</span>
</div>
</br>
<div class="input-group" v-for="(option, index) in question.options" style="margin-bottom: 20px">
<span class="input-group-addon">
<input type="checkbox" v-model="option.isAnswer">
</span>
<input type="text" class="form-control" v-model="option.text" placeholder="Enter an option">
<span class="input-group-btn">
<button class="btn btn-danger" type="button">X</button>
</span>
</div></br>
</div>
<button class="btn btn-default" #click="addQuestion" :disabled="questions.length >= 5 ? true : false">
Add another question
</button>
<button class="btn btn-primary" style="background-color: #ffcc00; border: #ffcc00">
Create quiz
</button>
</div>`,
data () {
return {
questions: [createNewQuestion()],
showQuestions: false,
}
},
methods: {
addQuestion () {
this.questions.push(createNewQuestion())
},
removeQuestion (index) {
this.questions.shift(index)
},
addOption (question) {
question.options.push(createNewOption())
}
}
})
</script>
Based on your updated question, you have already solved for removing questions, although yev's answer is a much better way for removing questions.
To remove options, you need to add a new handler for removeOption that takes in both the question (which you are iterating over) and the option (which you are iterating over. Vue handles both of these scenarios for you. You can then find the index of the option and splice the array. See this fiddle.
template:
<button class="btn btn-danger" type="button" #click="removeOption(question, option)">
X
</button>
component:
removeOption (question, option) {
var index = question.options.indexOf(option);
if (index > -1) {
question.options.splice(index, 1);
}
}
Your delete button should look like:
<div v-for="(question, i) in questions">
<div>
<input v-model="question.text">
<span>
<button #click=removeQuestion(i)>X</button>
</span>
<span>
<button #click="addOption(question)">Add an option</button>
</span>
</div>
</div>
Notice I've added i (index) in your for loop and click handler for X button.
Your remove function will look like:
removeQuestion (index) {
this.questions.splice(index, 1);
}
Array.shift will remove only first item in the array which is not exactly what you want :)

getting a default value to display in a div

currently when the page loads the defualt value of 10 displays which is what I want like so:
the custom amount shows:
but if I type something in the custom area and then delete it no default value is displayed. As shown here:
How can I get 10 to show up even if the user deletes their custom amount. I basically want 10 to always show if the user doesn't enter an amount or click a another button
here is my js:
$(document).ready(function() {
$('#donation-amount').keyup(function() {
$('#display-amount').text($(this).val());
});
$( ".selectvalue" ).click(function() {
$('#display-amount').text($(this).val());
});
$(".buttons .btn").click(function(){
$(".buttons .btn").removeClass('active');
$(this).toggleClass('active');
});
$('#display-amount').text($('#default').val());
});
and my html:
<div class="choose-pricing">
<div class="btn-group">
<div class="buttons">
<button type="button" id="default" class="btn btn-default selectvalue hover-color active" value="10">10</button>
<button type="button" class="btn btn-default selectvalue hover-color" value="15">15</button>
<button type="button" class="btn btn-default selectvalue hover-color" value="20">20</button>
<input type="Custom" name="donation-amount" class="inpt-first form-control" id="donation-amount" onclick="if(this.defaultValue == this.value) this.value = ''" onblur="if(this.value=='') this.value = this.defaultValue" value="Custom">
</div>
<input type="hidden" name="donation-amount-value" id="donation-amount-value">
</div>
<div class="money-donate">
<div class="display-amount" id="display-amount">
</div>
</div>
</div>
any help would be appreciated!
You can do this
store default in global and then apply when value is empty.
var defaultValue = 10;
$('#donation-amount').keyup(function() {
if($(this).val()) {
$('#display-amount').text($(this).val());
} else {
$('#display-amount').text(defaultValue );
}
});
See in action here http://jsbin.com/guxukodace/edit?html,js,output

Generate json array with javascript

I am looking to generate a json string based on the button selection on a html page.
<div id="btnStudios" >
<button type="button" id="01" value="warner" class="btn btn-default">Warner</button>
<button type="button" id="02" value="tf1" class="btn btn-default">TF1</button>
<button type="button" id="03" value="gaumont" class="btn btn-default">Gaumont</button>
<button type="button" id="04" value="pathe" class="btn btn-default">Pathe</button>
<button type="button" id="05" value="studiocanal" class="btn btn-default">StudioCanal</button>
<button type="button" id="06" value="francetv" class="btn btn-default">FranceTV</button>
<button type="button" id="07" value="m6snd" class="btn btn-default">M6SND</button>
</div>
<div id = "btnplatforms" class="btn-group">
<button type="button" id = "11" value="orange" class="btn btn-default">Orange</button>
<button type="button" id = "12" value="itunes" class="btn btn-default">iTunes</button>
<button type="button" id = "13" value="sfr" class="btn btn-default">SFR</button>
</div>
$(".btn").click(function() {
$(this).toggleClass('active');
});
Based on the active state of the button i want the result to be for example
{Studios : Warner, Gaumont
Platform : Orange, iTunes}
Is this possible to achive this with javascript? If yes how?
Thanks in advance for your help.
You can try this :
var btn_active_array = {
"Studios" : [],
"Platform":[]
};
$('#btnStudios .btn.active').each(function(index,btn_active){
btn_active_array["Studios"].push($(btn_active).text());
});
$('#btnplatforms .btn.active').each(function(index,btn_active){
btn_active_array["Platform"].push($(btn_active).text());
});
jsfiddle link : https://jsfiddle.net/5kb5fdyz/
You can try this:
var output = {
Studios: $('#btnStudios button.active').map(function() {
return $(this).val();
}).get(),
Platform: $('#btnplatforms button.active').map(function() {
return $(this).val();
}).get()
};
here is jsFiddle.

Categories