How to display and store button values? - javascript

very new to coding here, apologies for the basic question. trying to complete the odin project's build-a-calculator challenge (http://www.theodinproject.com/javascript-and-jquery/on-screen-calculator)
and struggling to make numbers appear after they are clicked. Also, how would I store the value in a variable or array to then be used in a calculation later?
Here's the excerpt of my JS:
$(".numbers").on("click", function() {
$+(this).text()
;});
And my HTML (note I'm using jsfiddle, hence the lack of html opening and closing tags etc:
<script src="jquery-1.11.3.min.js"></script>
<div class="numbers">
<button type="button">0</button>
<button type="button">1</button>
<button type="button">2</button>
<button type="button">3</button>
<button type="button">4</button>
<button type="button">5</button>
<button type="button">6</button>
<button type="button">7</button>
<button type="button">8</button>
<button type="button">9</button>
</div>
<div class = "operators">
<button type="button">+</button>
<button type="button">-</button>
<button type="button">*</button>
<button type="button">/</button>
<button type="button">=</button>
<button type="button">clear</button>
</div>

To store the value of the buttons in a variable you could do this.
$('button').on('click', function(){
var i = $(this).text();
console.log(i); // print the value of i in the console
});
Once you have the value you'll need to be able to put the value of each button clicked in order on the "display" of the calculator like so.
HTML
<div class="display"></div>
JavaScript
$('button').on('click', function(){
var i = $(this).text();
var display = $('.display');
display.text( display.text() + i );
});
Hopefully that helps point you in the right direction.

I am not sure how you want to display your numbers. Are you using a TextArea?
For storing values, inside your function do something like
var num=$+(this).text()
Other than that, you need to be more specific.

The following jsfiddle demonstrated how to do what you want.
// array is defined outside the click handler
var clickedArray = [];
$('button').on('click',function() {
// get the button that was clicked
var buttonClicked = $(this).html();
console.log(buttonClicked);
// store it as the last element in the array
clickedArray.push(buttonClicked);
console.log(clickedArray);
// and output it to the screen
$('.js-calc-out').append(buttonClicked);
});
Points to note:
The array is defined outside the click event handler so it can be used without being reset each time a click event is fired. This array will exist until the page is refreshed or it is purposely unset and you can access it as you need it.
The html() function retrieves the contents of any given HTML element, in this case it's the clicked button, which is retrieved using $(this) (any element an event is fired on is retrieved using this which is then converted to a jquery object using the $() function).
The push() function is used to append the latest clicked element to the end of the array mentioned in point 1.
.js-calc-out is an HTML element to which we append() the latest click to, meaning the sequence of clicks are output.
The console.log declarations output some stuff into the inspector which should help you see the process develop.
PS. this is a simplified solution that takes into account your current position on the learning curve; ideally you'd want to use objects to encapsulate data and functionality in javascript and keep out of the global namespace.

Related

passing values to a function does not work when inside for loop

I'm mapping currencies from a json file and i render the mapped currencies to a component. I have a .php file like this
<div class="currency-switch-container" id="currency_container">
<span style="font-size:12px;font-weight:bold">All currencies</span>
<div id="currency-map" style="margin-top:15px"></div>
</div>
I refer the div in the above component in my js file as follows
let currencyMap = jQuery("#currency-map");
And when my jQuery document is ready i'm doing the following
jQuery(document).ready(function($) {
$.getJSON('wp-content/themes/mundana/currency/currency.json', function(data) {
for(let c in data){
currencyMap.append(`<span onclick="onCurrencyClick(${data[c].abbreviation})"
class="currency-item">
<span>
${data[c].symbol}
</span>
<span>
${data[c].currency}
</span>
</span>`)
}
});
}
and my function is like this
function onCurrencyClick(val){
console.log("val",val);
setCookie("booking_currency", val, 14);
}
Here the function does not work. But if i do not pass anything to the function it seems to work as i can see the log in the terminal.
Hi your expression ${data[c].abbreviation} will put the value into function string without string quotes i.e. the resultant would be onCurrencyClick(abbreviation) while it should be onCurrencyClick('abbreviation').
please use onclick="onCurrencyClick('${data[c].abbreviation}')" instead.
Instead of using the inline onclick, use event delegation. This means that you have a single event listener that handles all the events from the children and grandchildren. The modification is a very minor one seeing the example here below.
A reason for doing this is that you keep your JavaScript inside your JS file. Like now, you encounter a JS error and have to look for it in your HTML. That can get very confusing. Also however inline onclick listeners are valid, they are outdated and should be avoided unless there is absolutely no other way. Compare it with using !important in CSS, same goes for that.
function onCurrencyClick(event){
var val = $(this).val();
setCookie("booking_currency", val, 14);
}
currencyMap.on('click', '.currency-item', onCurrencyClick);
This example takes the val that you try to insert from the value attribute from the clicked .current-item. <span> elements don't have such an attribute, but a <button> does and is a much more suitable element for it expects to be interacted with. It is generally a good practice to use clickable elements for purposes such as clicking.
In the example below you see the button being used and the abbreviation value being output in the value attribute of the <button> element and can be read from the onCurrencyClick function.
jQuery(document).ready(function($) {
$.getJSON('wp-content/themes/mundana/currency/currency.json', function(data) {
for(let c in data){
currencyMap.append(`
<button value="${data[c].abbreviation}" class="currency-item">
<span>
${data[c].symbol}
</span>
<span>
${data[c].currency}
</span>
</button>
`)
}
});
onclick will not work for a dynamically added div tag
Yo should follow jQuery on event
Refer: jQuery on
Stackoverflow Refer: Dynamic HTML Elements

State of element before and after editing (using contentEditable)

I would like to capture how the elements within a div change after a user edits it (as the content is contentEditable), and so have a page like the following:
before_html = $("#example_div").children();
$("#differences_button").on("click",function(){
after_html = $("#example_div").children();
console.dir(before_html[0].innerText);
console.dir(after_html[0].innerText);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="example_div" contentEditable><span id='example_span'>How it starts</span></div>
<button type="button" id="differences_button">Show differences</button>
However, as the console.dirs show, the "before_html" doesn't store the original structure of the element, but will show you the latest structure of it when running it again.
Is there a way to store the structure before the sort of changes shown in this example?
I've tried JSON.parse(JSON.stringify(before_html)) to store something that won't update, which often works when trying to store a javascript variable you don't want later update, but this fails to store the content when applied here.
The problem is that you are accessing before_html[0].innerText and after_html[0].innerText after the click. So both of them are evaluated after all changes are made.
Instead, you can save before_html (prior to attaching the event handler), and have it contain the innerHtml or innerText, and then compare with the new value during the click handler.
before_text = $("#example_div").text();
$("#differences_button").on("click",function(){
after_text = $("#example_div").text();
console.dir(before_text);
console.dir(after_text);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="example_div" contentEditable><span id='example_span'>How it starts</span></div>
<button type="button" id="differences_button">Show differences</button>
Note that I have changed the variable name from before_html to before_text as it doesn't contain HTML. You can have it contain HTML by calling before_text = $("#example_div").html(); if you prefer that.

Append value to an input field in JQuery script

I am attempting to create a simple math quiz application for a child with on screen number keys that will append to an input field for the answer. I want to use jQuery event listener linked to a class so I do not have to call an onClick function for each number. I found this question elsewhere but I am unable to comment to further ask issue I am having as I have just joined stacked overflow and it states my reputation isn't high enough.
Link to other question: append value to an input field in JQuery
When I attempt to append I get an undefined when I attempt to click my buttons and I cannot see where the error in my code is. Any assistance would be greatly appreciated.
My jQuery:
$(".userIn").click(function() {
var usrIn = $(this).data('usrIn');
$("#answer").val(function() {
return this.value + usrIn;
});
});
Sample of my buttons:
<button type="button" class="btn btn-primary btn-block userIn" data-number="0" id="zero">0</button>
Here is the JSfiddle with all my linked style sheets and external js.
Change var usrIn = $(this).data('usrIn'); to var usrIn = $(this).attr('data-number');
Fiddle: https://jsfiddle.net/969r1gp0/4/
Your data attribute is called data-number, not data-userin, so you should write:
var usrIn = $(this).data('number')
But as the text of the buttons really is what you want to add, you could do without the data attributes all together, and just do:
var usrIn = $(this).text();
try this both, it's working
document.getElementById("input_id").value = you_value;
document.getElementById("input_id").textContent = you_value;

jQuery $(this) on child selectors?

Building a similar setup to Twitters Follow/Unfollow button and can't quite get it working with jQuery.
Complete so far;
- jQuery on a single known ID for a <button> for updating all the details needed
- API powering the server side logic
- Everything else server side is working perfectly
Can't figure out;
- How to expand the functionality I have for a single known ID to multiple unknown IDs.
Here's the code I have working for the known single point;
//Update Links
$("#api-follow-button").html(buttonText);
$("#api-follow-button").attr("currentState", currentState);
The above code is wrapped in a function with a whole host of other code which is triggered by;
$(document).on("click", "#api-follow-button", followButton());
This works perfect as I know the ID. The challenge being, how to expand this when the ID that is to be updated is unknown?
I've tested so many variations using $(this) and I'm not getting anything working. I'm sure I'm just missing something blindingly obvious here.
So imagine this code as an example;
<button id="button-idxxx">Text 1</button>
<button id="button-idxxx">Text 2</button>
<button id="button-idxxx">Text 3</button>
Then whenever someone clicks on one of the <button>, then the 'Text X' would change to something else
Ideas?
This $(this) you mention probably works correct (although you did not post your relevant code).
The error seems to be in $(document).on("click", "#api-follow-button", followButton()); where the () should be missing from the followButton method.
So try with
$(document).on('click', '[id^="button-id"]', followButton);
(the [id^="button-id"] selector matches elements with an id attribute that starts with button-id text)
Your followButton should be something like this
function followButton(e){
e.preventDefault();
// define buttonText and currentState here
// unless they come from elsewhere
$(this)
.html(buttonText)
.attr("currentState", currentState);
}
(Thinking out loud) You could potentially use the Attribute Starts With Selector found in the linked article. With this selector, you can select all the buttons that may contain a specific prefix (i.e. button-id) from your example without knowing the entire id of the element.
From the attribute starts-with selector docs:
Description: Selects elements that have the specified attribute with a value beginning exactly with a given string.
For example:
jQuery(function ($) {
$(document).on('click', '[id^="button-id"]', function () {
alert($(this).text());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" id="button-id12345">
Text 1
</button>
<button type="button" id="button-id678910">
Text 2
</button>
<button type="button" id="button-id1112131415">
Text 3
</button>
Thanks all. The code in the fiddle for alert($(this).text()); works perfectly but when doing anything like updating the text on the page this didn't seem to work for some reason. With a bit of fiddling around based on the helpful info here's what I came up with which worked;
HTML Buttons
<button type="button" class="btn btn-lg btn-success" id="api-follow-button-uniqueID-xxx" currentState="NotFollowing">
<button type="button" class="btn btn-lg btn-success" id="api-follow-button-uniqueID-xxx" currentState="NotFollowing">
<button type="button" class="btn btn-lg btn-success" id="api-follow-button-uniqueID-xxx" currentState="NotFollowing">
jQuery Code
$(document).ready(function () {
$(document).on('click', '[id^="api-follow-button"]', function followButton(e) {
e.preventDefault();
var currentState = $(this).attr("currentState");
//This line below ensures that you can then use the ID selector to update the relevant part of the HTML as needed, see note below
var buttonID = $(this).attr("id");
var buttonText = "";
var currentState = "";
buttonText = "Unfollow";
currentState = "Following";
//Update Links
//This part from comment above
$("button[id=" + buttonID + "]")
.html(buttonText)
.attr("currentState", currentState);
});
}
});
});
Looks like it's all done what is needed now. I've removed a bunch of code from above to simplify things
Thanks all

How can I dynamically set an id within a Javascript loop?

I have a list of Questions, and each of those Questions has a list of Answers (which can be any integer from 1-5). I would like to dynamically create a chart for each Question, using the count of all answers that match a specific "rank"; i.e. all the answers that were a '1', '2', '3', etc.
So what I've done is set a for loop that creates an element for each question; this element is used as a placeholder for the chart. (As an aside, I am using flot charts).
The problem I'm having is trying to name the placeholders dynamically; what I really want is to create something that ends up looking like this:
<div id='chart1'/>
<div id='chart2'/>
etc
The closest I've managed is this:
<div id="'chart'#currentQuestion"/>
which of course gives an id like this: 'chart'1
Later, when I try to append the chart to the div I've created, the following doesn't work:
$("#'chart'"+i).append(div); //where i is the current loop counter
If I use
$("#chart"+i).append(div);
it correctly finds the element 'chart1', 'chart2' etc; but I'm struggling to name the div to match.
Can anyone help? It seems trivial unless you know how to solve it :-)
Edit: As requested, here is the relevant HMTL:
<div id="'chart#currentQuestion'">CHART</div>
SOLVED:
Like this: id="chart#(currentQuestion)" (via a colleague) Thanks for your efforts.
You haveen't close your div correctly. try this code
<div id='chart1' style="border:dashed">
</div>
<br />
<div id='chart2' style="border:dotted">
</div>
<script type="text/javascript" src="jquery_library.js">
</script>
<script type="text/javascript">
function fnc(value){
$("#chart"+value).append('1');
}
</script>
<input type="button" onclick="fnc(1)" value="for div1"/>
<input type="button" onclick="fnc(2)"value="for div2" />
You are using razor syntax, so here how it should be.
// Define your counter
#{long i = 0;}
// On document ready dynamically add your items
$("document").ready(function(){
// Create red divs starting by zero
// after 5 divs stop creating red divs
#for (i = 0;i<5;i++){
#:$("#form").append('<div id="chart' + #(i) + '">Red</div>');
}
});
// I made a button for action, you can choose other ways to invoke this function
$("#form>input").click(function(){
// Your counter is at 4 now
// lets change it to 2
#(i = 2;) // Now your counter is at 2
// Put a blue div into 2nd div starting by 0
$("#chart"+#(i)).append('<div class="blue">blue</div>');
});
this is how you use razor syntax with scripts

Categories

Resources