How to change object property in a function with onclick in JavaScript - javascript

I am new to programming and I am trying to do something that is a bit overchallenging for me, so any help is appreciated.
I would like to use the Canvas Chess PGN viewer on a website which displays chessgames and make it possible for the users to go through the games. I want to use only one chessboard for different games, so I am trying to create onclick events that change the source property value in the chessboard script and make the script run again, but I cannot figure out how to do that.
It is the "pgn_uri" property that should be changed by clicking on the buttons, e.g. when the user clicks on "Round2" than it changes to "pgn_uri: secondGame", and so on. The script with the CHESS.PgnViewer() function should also run again so the chessboard gets updated.
<button type="button" name="button" id="round1">Round1</button>
<button type="button" name="button" id="round2">Round2</button>
<button type="button" name="button" id="round3">Round3</button>
<script src="canvaschess\canvaschess-0.1.0.min.js"></script>
<script src="canvaschess\pgnviewer-0.1.0.min.js"></script>
<script type="text/javascript">
var firstGame = 'canvaschess/pgns/round1.pgn';
var secondGame = 'canvaschess/pgns/round2.pgn';
var thirdGame = 'canvaschess/pgns/round3.pgn';
</script>
<script>
var viewer = new CHESS.PgnViewer({
pgn_uri: firstGame,
square_color_dark: '#000',
square_color_light: '#fff',
square_uri_dark: 'canvaschess/img/themes/wood/square_dark.jpg',
square_uri_light: 'canvaschess/img/themes/wood/square_light.jpg',
show_labels: false,
show_tags: true
});
</script>

try adding onclick events
eg
keep variable say chessGame as "global" and change its value onclick of buttons
$('#round2').onclick(function()
{
chessGame ='secondGame';
});
and pass "chessGame" instead of "firstGame" in new CHESS.PgnViewer

Adding click event in each button so probably this code
// Assume you have global variable name game
$('#btn1, #btn2, #btn3').on('click', function(){
var btn_clicked = $(this).attr('id'); // get id value
switch (btn_clicked) {
case 'btn1':
game = 'canvaschess/pgns/round1.pgn';
break;
case 'btn2':
game = 'canvaschess/pgns/round2.pgn';
break;
case 'btn3':
game = 'canvaschess/pgns/round3.pgn';
break;
}
});
You can now pass the global variable to new CHESS.PgnViewer
Note: I didnt test this code hehehe!

Related

How to change button background color by name using Javascript

I have several buttons on my webpage and want to style the background colors when I click on them according to the button's name. I want all the "Toms" to be lightgray, all the "Dicks" to be lightgreen, and all the rest ("Harrys") to be lightyellow. I added the following code to my external Javascript page, but it's not working:
function bgColor() {
var x = document.getElementsByTagName("button").name;
if (x == "Tom") {
document.getElementsByTagName("button").style.backgroundColor=
"lightgray";
} else if (x == "Dick") {
document.getElementsByTagName("button").style.backgroundColor=
"lightgreen";
} else {
document.getElementsByTagName("button").style.backgroundColor=
"lightyellow";
}
}
The HTML reads something like this but between less than/greater than symbols, of course:
button type="button" name="Tom" onclick="bgColor()"
button type="button" name="Dick" onclick="bgColor()"
button type="button" name="Harry" onclick="bgColor()"
EDITED TO ADD
I can't figure out how to reply to Mikkel's comment directly. I tried simply posting another comment, but it wouldn't let me add code. Anyway, I tried the fix that he suggested using the following but it didn't work for me either.
function bgColor() {
var tom = document.querySelector('button[name="Tom"]')
.style.backgroundColor = 'lightgray';
var dick = document.querySelector('button[name="Dick"]')
.style.backgroundColor = 'lightgreen';
var harry = document.querySelector('button[name="Harry"]')
.style.backgroundColor = 'lightyellow';
}
What am I doing wrong?
As #Mikkel has said, your selector is wrong - You'll want to use an attribute selector to get the elements that match your name attribute
However, in this specfic case as well you've got a more weird issue - You'll have to change the name of your function - bgColor is also the name of a property on the elements which I believe is causes your further issues. - You can read more about that here
If you change the name to something like changeColors you shouldn't have this issue
As an aside, there's no need to assign your querySelectors to a variable, you can just run them in this case
function changeColors() {
document.querySelector('button[name="Tom"]').style.backgroundColor = 'lightgray';
document.querySelector('button[name="Dick"]').style.backgroundColor = 'lightgreen';
document.querySelector('button[name="Harry"]').style.backgroundColor = 'lightyellow';
}
<button type="button" name="Tom" onclick="changeColors()"> X </button>
<button type="button" name="Dick" onclick="changeColors()"> X </button>
<button type="button" name="Harry" onclick="changeColors()"> X </button>
document.getElementsByTaName("button") is getting all your buttons. What you want to do, is check each of the buttons individually and apply the color.
You can do it with the code below, that'll change the color of "Tom". You can repeat it to make it work for your other buttons.
function bgColor() {
var tom = document.querySelector('button[name="Tom"]').style.backgroundColor = 'purple'
}
First, using bgColor as a user-defined function name will throw a type error since it's a reserve keyword for JS (Object's property) though deprecated.
Second -> var x = document.getElementsByTagName("button").name; will obviously throw an error x is undefined because this syntax without '.name' should return all buttons on the page in an array, with that you can loop through and access properties of individual button eg. name
So we use this instead var x = document.getElementsByTagName("button") which returns an array of buttons on the page.
That being said, let's see how we can modify your code to achieve what you're looking for:
HTML:
<button type="button" name="Tom" onclick="buttonBgColor(event)"> Tom</button>
<button type="button" name="Dick" onclick="buttonBgColor(event)"> DicK </button>
<button type="button" name="Harry" onclick="buttonBgColor(event)"> Harry </button>
JS:
function buttonBgColor(e) {
const buttons = document.getElementsByTagName("button").name;
for(button of buttons){
const current_button = e.target;
if(current_button.name == 'Tom'){
current_button.style.backgroundColor = 'lightgray'
}else if(current_button.name == 'Dick'){
current_button.style.backgroundColor = 'lightgreen'
}else if(current_button.name == 'Harry'){
current_button.style.backgroundColor = 'lightyellow'
}
}
}
This method is useful because assuming you have two buttons with same name say 'Tom' and yet you want one of them to do something extra aside changing their background colors, you can reference their ID to achieve that using e.target.id or current_button.id in a condition to wire up another handler for that particular 'Tom' button.
Hope this helps.

Variable Id Called in JS Function

I've spent the past couple hours googling and browsing W3Schools and couldn't find a way to do exactly what I wanted. I've found similar articles but they don't answer my question perfectly.
So what I'm trying to do is this, create a JS function that when called in HTML will take the information given to return the appropriate information. E.G, I want there to be two HTML buttons. If the user presses the first button, it calls the function "onclick='show(x, y)'" and x and y which stand for another paragraph and an image. If the user presses the second button, it calls the same function with different variables "onclick='show(x, z)'" which would display the same paragraph as the other button would but would display a different image.
Basically, is it possible for HTML elements to have IDs that can be variable in JS so I that I do not have to create an individual JS function for every single button?
My Javascript:
<script>
var Show = function(elID, elID2) {
var el1 = document.getElementByID(elID);
var el2 = document.getElementByID(elID2);
var both = (elID) + " " + (elID2);
document.getElementById(elID).innerHTML = both;
}
</script>
My HTML:
<p id="demo">
<button onclick="Show(77, demo)">Click to convert</button>
</p>
I am still learning the ins and outs of Javascript so any and all help would be appreciated.
yes, enclose the arguments in quotes
<button onclick="Show('77', 'demo')">Click to convert</button>
without quotes 77 will be passed correctly but demo will not be since it will look for a demo property in window scope.
You should get innerHTML before inserting. Also note that, you must pass id attributes wrapped in quotes(').
ID attributes should at least have one character and it should not start with NUMBER
function Show(elID, elID2) {
var el1 = document.getElementByID(elID).innerHTML;
var el2 = document.getElementByID(elID2).innerHTML;
var both = (elID) + " " + (elID2);
document.getElementById(elID).innerHTML = both;
}
<p id="demo">
<button onclick="Show('77', 'demo')">Click to convert</button>
</p>
You could lay aside the inline JavaScript and opt for a different way, separating your markup from your logic.
https://jsfiddle.net/tricon/p2esv818/
HTML:
<button id="button" data-parameter-one='{ "keyOne": "valueOne", "keyTwo": "valueTwo" }'>
Some button
</button>
JavaScript:
var button = document.getElementById("button");
button.addEventListener("click", function() {
var parameters = this.getAttribute("data-parameter-one");
parameters = JSON.parse(parameters);
console.log(parameters);
});

Javascript: How to get innerHTML of clicked button

Built a tip calculator but want to shorten the code by getting the innerHTML of the button that is being clicked.
Total Bill: <input id="bill" type="text">
<button type="button" onclick="tip15()">15</button>
<button type="button" onclick="tip18()">18</button>
<button type="button" onclick="tip20()">20</button>
<div id="tip">You owe...</div>
function tip15(){
var totalBill = document.getElementById("bill").value;
var totalTip = document.onclick.innerHTML
var tip = totalBill * 0.15;
document.getElementById("tip").innerHTML = "$" +tip
}
Problem with this method is that I have to write out three versions of the function to correspond with the tip amount. I want to create one function that grabs the innerHTML of the button being clicked and uses that value in the function. I want it to look something like this
function tip(){
var totalBill = document.getElementById("bill").value;
**var totalTip = GET INNERHTML OF CLICKED BUTTON**
var tip = totalBill * ("." + totalTip);
document.getElementById("tip").innerHTML = "$" +tip
}
That way I can run the same function on the different buttons.
Use HTML5 data attributes.
<button type="button" data-tip="15" onclick="getTip(this)">15</button>
The parameter this that you're passing to the function refers to the button that is being clicked. Then you get the value of the attribute like this:
function tip(button){
var tip= button.getAttribute("data-tip");
...
}
I leave the rest for you.
Change like this:Pass value to tip function.
<button id="15" type="button" onclick="tip(15)">15</button>
<button id="18" type="button" onclick="tip(18)">18</button>
<button id="20" type="button" onclick="tip(20)">20</button>
function tip(tip_value)
{
/*use here tip_value as you wish you can use if condition to check the value here*/
var totalBill = document.getElementById("bill").value;
var totalTip = tip_value;
var tip = totalBill * ("." + totalTip);
document.getElementById("tip").innerHTML = "$" +tip;
}
Pass this.innerHTML as an argument to your tip function.
So your tip function should look like this:
function tip(totalTip) {
var totalBill = document.getElementById("bill").value;
var tip = totalBill * ("." + totalTip);
document.getElementById("tip").innerHTML = "$" +tip
}
Therefore, if you have a button element that looks like this:
<button type="button" onclick="tip(this.innerHTML)">15</button>
The tip function will be called as tip(15).
I'll write up a quick solution, then explain why I did it that way.
PROPOSED SOLUTION
Part 1, the HTML
<div id="tip-wrapper">
<label for="bill">Total bill:</label>
<input name="bill" id="bill" type="text">
<br/>
<label for="tipratio">Tip ratio:</label>
<button name="tipratio" value="15" type="button">15%</button>
<button name="tipratio" value="18" type="button">18%</button>
<button name="tipratio" value="20" type="button">20%</button>
<div id="final-value">You owe...</div>
</div>
Part 2, the JavaScript
var parent = document.getElementById('tip-wrapper'),
buttons = parent.getElementsByTagName('button'),
max = buttons.length,
i;
// function that handles stuff
function calculate (e) {
var bill = document.getElementById('bill'),
tipRatio = e.target.value;
document.getElementById('final-value').textContent = bill.value * (1+tipRatio/100);
}
// append event listeners to each button
for(i = 0; i < max; i++) {
buttons[i].addEventListener('click', calculate, true);
}
EXPLANATIONS
About the HTML, not "much" has changed. The only thing being I'm using something that is a little more standards compliant.
I've added a wrapper element, this is just to isolate some DOM traversal instead of going through the whole document object to do your lookups (this will speed up your script).
Your buttons use "value" attribute, which is best. Since you can display button text one way, but use a proper value (see I added % characters).
Other than that, I mostly added proper identifiers and labels.
The JavaScript, this is where i'll go a little more in detail, I'll go step by step:
The first thing you want to do in a script is set the variables you'll need (and fetch the DOM elements you'll be using. This is what I've done on the first 4 lines of code.
Create a generic function that will handle your calculations and update your elements, no matter their numeric value. The feature I used here is adding a parameter (e) to your function, because EVENTS in javascript attach an EVENT OBJECT to your callback function (in this case calculate();). The EVENT OBJECT actually has a bunch of useful properties, of which I use:
target: this is the element that triggered the event (i.e. one of your buttons)
All we have to do is grab the target's value (e.target.value) and use that in the math that returns the final bill.
Using addEventListener. It's generally agreed on that you should keep your JavaScript outside of your HTML, so using the old event methods (onclick="") is discouraged. The addEventListener() method isn't too complicated, without going into detail it works as follows:
htmlObject.addEventListener('event type', 'callback function', 'bubbles true/false');
All I did was loop through all your buttons and append the event lsitener.
Closing notes
With this script, you can now add any "buttons" you want, the script will take them all into account and adapt accordingly. Just make sure to set their "value".
As I was writing this up a few people gave some quick answers. I can't comment yet (low reputation) so I'll leave my comments here.
Some of the proposed answers tell you to use innerHTML to fetch the tip value. This is wrong, you are using form fields and should use element.value that's what it is made for.
Some have even dared to say use the HTML5 data-* attributes. sure, you could. But why would you? HTML and the DOM already provide every necessary tool to accomplish your task WITHOUT the need to polute your HTML with unnecessary attributes. the value="" attribute is meant to be used in forms, it should be used over data-* attribute for field values.
As a general note innerHTML is meant to get HTML, not necessarily text or values. There are other methods to get the values you are seeking. In the case of form elements, it's element.value, in the case of most other HTML elements, it's element.textContent.
Hope these explanations help
function tip(o) {
var input = document.querySelector("input[id='bill']");
var total = input.value * o.innerHTML;
document.querySelector("#tip").innerHTML = "$" + total;
}
Total Bill: <input id="bill" type="text">
<button type="button" onclick="tip(this)">15</button>
<button type="button" onclick="tip(this)">18</button>
<button type="button" onclick="tip(this)">20</button>
<div id="tip">You owe...</div>

JS expand onClick multiple events

Please check this page first : Solarking - About Us
Check first 2 boxes which has a READ MORE button. On clicking them, they expand a paragraph.
Now I want it to be like when I click on it, it should expand the text and change the button value to "CLOSE" from "READ MORE". And on again clicking on "CLOSE", it should change value to "READ MORE".
I searched for long time to see how to fire multiple events on onClick, but I saw that some said to use a ; in them, some said make a new function and put 2 functions in it.
Now I tried to make a new function with 2 functions inside it (one to expand the paragraph, other to change value of button, but I failed. (I am new to JS).
Help please. Thank you in advance!
Code I have on the page :
button code:
<p style="text-align: right;"><input id="button12" style="background-color: #eca200; color: #ffffff;" onclick="return toggleMe('para1')" type="button" value="Read more" /></p>
Script :
<script type="text/javascript">
function toggleMe(a){
var e=document.getElementById(a);
if(!e)return true;
if(e.style.display=="none"){
e.style.display="block"
}
else{
e.style.display="none"
}
return true;
}
</script>
I think the easiest way to do this would be to set a boolean variable. In other words, let's say that it starts off with the dclaration at the beginning of the page.
var hasbeenclicked = false;
Then, after the first click
hasbeenclicked = true;
After a second click
hasbeenclicked = false;
When the function is called, it checks the variable and operates accordingly. The following is not real JS....
if hasbeenclicked = true {
do some stuff;
}
else {
do some other stuff;
}
That is a simple way to accomplish what you are trying to do.
Additional info:
Use two DIV tags with separate ID's. One for the paragraph and one for the "label". Use getelementbyID to alter each one appropriately.
I noticed you are using jQuery.
You could use a toggle method.
Alter the html link. Add a class of expander and use the data attribute to identify the paragraph id
<p style="text-align: right;">
<input id="button12" data-toggle="para1" class="expander" style="background-color: #eca200; color: #ffffff;" type="button" value="Read more" />
</p>
The JS
$(".expander").click(function() {
var self = $(this);
$("#" + self.data('toggle')).slideToggle(500, function () {
if ($("#" + self.data('toggle')).is(':visible')) { // paragraph is open
self.val("Close");
} else { // paragraph is closed
self.val("Read More");
}
});
});

Switch class and disable button

Is it possible to also switch the class to a loading graphic and disable the button when onClick is called and before the location.href is launched? There is a delay and I'm hoping to avoid double clicks. Can someone show me a sample of this?
<button type="button" class="MoreTides" onclick="location.href='http://www.domain.com/tides/parser_iphone.php?stats=$xml->stationid'">View Graph - Change Dates</button>
Something like this might be a start:
<script>
function loadPage(input) {
input.disabled = true;
input.className = "loadingButton"; // define how this should look in CSS
location.href='http://www.domain.com/tides/parser_iphone.php?stats=$xml->stationid';
}
</script>
<button type="button" class="MoreTides" onclick="loadPage(this)">View Graph - Change Dates</button>

Categories