I wasn't quite sure how to word this in the title, so thank you for clicking to on this.
So now to my problem:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<style>
.block {
background-color: black;
}
</style>
<table border='1px'>
<tr>
<td id='11'></td>
<td id='12'></td>
<td id='13'></td>
<td id='14'></td>
<td id='15'></td>
</tr>
<tr>
<td id='21'></td>
<td id='22'></td>
<td id='23'></td>
<td id='24'></td>
<td id='25'></td>
</tr>
<tr>
<td id='31'></td>
<td id='32'></td>
<td id='33' class="block"></td>
<td id='34'></td>
<td id='35'></td>
</tr>
<tr>
<td id='41'></td>
<td id='42'></td>
<td id='43'></td>
<td id='44'></td>
<td id='45'></td>
</tr>
<tr>
<td id='51'></td>
<td id='52'></td>
<td id='53'></td>
<td id='54'></td>
<td id='55'></td>
</tr>
</table>
<button onclick="blockUp()">Up</button>
<button onclick="blockDown()">Down</button>
<button onclick="blockLeft()">Left</button>
<button onclick="blockRight()">Right</button>
<script>
var blockUp = function() {
var oldBlock = document.getElementsByClassName("block")[0].id;
var newBlock = Math.floor(oldBlock + 1);
document.getElementById(newBlock).classList.add("block");
document.getElementById(oldBlock).classList.remove("block");
}
</script>
</body>
</html>
This code is not complete, as I want to fix this problem first.
I want to use Math.floor to get a certain ID (thus, IDs as numbers), and manipulate them. More specifically, I want to find the ID of the cell that currently has the .block class, find the ID of the cell above that using Math.floor(oldBlock + 1), remove the class from the original cell, and add the class to the new cell. I used variables so that the function would always be able to run, rather than making a million if/else if/else statements.
Unfortunately, this doesn't work with my current code. How would I be able to do this?
Any help is appreciated!
You have to make sure that "oldBlock" contains a number before trying to do math with it (like adding 1):
var oldBlock = +document.getElementsByClassName("block")[0].id;
That's one way of doing it. You could also use parseInt():
var oldBlock = parseInt(document.getElementsByClassName("block")[0].id, 10);
The value of the "id" property will be a string, so if you involve that in an addition operation JavaScript will treat it as string concatenation. By forcing it to be a number first, you'll get the effect you want.
Related
so I'm very new to Javascript ;I'm trying so hard to learn it but it's difficult for me especially because I'm coming from an OOP standpoint (C++/Java) . Anyway ,I'm building a calculator and my question is I'm trying to set a single global variable to a long reference . Here's what i mean .
Here is what i have tried in order to make a single global variable to work instead of writing ( document.form.textview.value ) every single time.
1. var number = document.form.textview.value;
2. var number = newFunction();
function newFunction() {
return document.form.textview.value;
}
3. i also tried using document.getelementbyID and queryselector but none of them worked.
what i have and is working :-
function insert(num) { // inserts a number into the textbox or form
document.form.textview.value = document.form.textview.value + num;
}
function equal() { // calculates numbers
var exp = document.form.textview.value;
if (exp) {
document.form.textview.value = eval(exp);
}
}
function Squareroot() {
document.form.textview.value =
eval(Math.sqrt(document.form.textview.value));
}
as you can see i have to write 'document.form.textview.value' every single time in order to get it to work instead i want a single global variable to do that for me.
This is what i want :-
var number = document.form.textview.value;
function insert(num) {
return number+num;
}
function equal() {
if (number) {
eval(number);
}
}
function Squareroot() {
eval(Math.sqrt(number));
}
html :-
<form name="form">
<input class="textview" name="textview">
<table>
<caption>
<h1>↻</h1>
</caption>
<tr>
<td onclick="Clearview()">C</td>
<td>←</td>
<td onclick="Takepercentage('')">%</td>
<td onclick="insert('/')">/</td>
</tr>
<tr>
<td onclick="insert('.')">.</td>
<td onclick="exponents()">x<sup>2</sup></td>
<td onclick="Squareroot()">√</td>
<td onclick="insert('*')">*</td>
</tr>
<tr>
<td onclick="insert(6)">6</td>
<td onclick="insert(7)">7</td>
<td onclick="insert(8)">8</td>
<td onclick="insert('-')">-</td>
</tr>
<tr>
<td onclick="insert(3)">3</td>
<td onclick="insert(4)">4</td>
<td onclick="insert(5)">5</td>
<td onclick="insert('+')">+</td>
</tr>
<tr>
<td onclick="insert(0)">0</td>
<td onclick="insert(1)">1</td>
<td onclick="insert(2)">2</td>
<td onclick="equal()">=</td>
</tr>
</table>
</form>
The DOM is very much like any other OOP system you might be familiar with. You can very easily make a reference to document.form.textview, acting as an object you can change by accessing or mutating its value property. But if you create a reference to that property, getting or setting it simply changes the reference, and not the underlying object.
Think of it as similar to
var r = new Rectangle(5, 3);
r.area() //=> 15
r.width //=> 5
r.width + 7 //=> 12, but doesn't change the rectangle.
So by using number.value where you were hoping to use number, and setting number to document.form.textview, you should be able to get things to work:
const number = document.form.textview;
function insert(num) {
return number.value += '' + num;
}
function equal() {
if (number.value) {
eval (`number.value = ${number.value}`);
}
}
function Squareroot() {
number.value = Math.sqrt(number.value);
}
<form name="form">
<input class="textview" name="textview">
<table>
<caption>
<h1>↻</h1>
</caption>
<tr>
<td onclick="Clearview()">C</td>
<td>←</td>
<td onclick="Takepercentage('')">%</td>
<td onclick="insert('/')">/</td>
</tr>
<tr>
<td onclick="insert('.')">.</td>
<td onclick="exponents()">x<sup>2</sup></td>
<td onclick="Squareroot()">√</td>
<td onclick="insert('*')">*</td>
</tr>
<tr>
<td onclick="insert(6)">6</td>
<td onclick="insert(7)">7</td>
<td onclick="insert(8)">8</td>
<td onclick="insert('-')">-</td>
</tr>
<tr>
<td onclick="insert(3)">3</td>
<td onclick="insert(4)">4</td>
<td onclick="insert(5)">5</td>
<td onclick="insert('+')">+</td>
</tr>
<tr>
<td onclick="insert(0)">0</td>
<td onclick="insert(1)">1</td>
<td onclick="insert(2)">2</td>
<td onclick="equal()">=</td>
</tr>
</table>
</form>
You can use the onkeyup event listener to update the global variable. That way any time you want to reference globalVal you'll have the right value. This is also called one way binding. That is, any time you change the input value, the global variable will get updated, but not the other way around. In two way binding, a change made to the global variable or the input would result in both of them being updated.
var globalVal = "";
function update(val) {
globalVal = val;
console.log(globalVal);
}
<input id="textview" onkeyup="update(this.value)" class="textview" name="textview">
In this reactjs app I have a table with the following body:
<tbody>
{results.map(result =>
<tr key={result.metric} onClick={this.handleClick}>
<td className="inpt-td">{result.t00}</td>
<td className="inpt-td">{result.t01}</td>
<td className="inpt-td">{result.t02}</td>
<td className="inpt-td">{result.t03}</td>
<td className="inpt-td">{result.t04}</td>
<td className="inpt-td">{result.t05}</td>
<td className="inpt-td">{result.t06}</td>
<td className="inpt-td">{result.t07}</td>
<td className="inpt-td">{result.t08}</td>
<td className="inpt-td">{result.t09}</td>
<td className="inpt-td">{result.t10}</td>
<td className="inpt-td">{result.t11}</td>
<td className="inpt-td">{result.t12}</td>
<td className="inpt-td">{result.t13}</td>
<td className="inpt-td">{result.t14}</td>
<td className="inpt-td">{result.t15}</td>
<td className="inpt-td">{result.t16}</td>
<td className="inpt-td">{result.t17}</td>
<td className="inpt-td">{result.t18}</td>
<td className="inpt-td">{result.t19}</td>
<td className="inpt-td">{result.t20}</td>
<td className="inpt-td">{result.t21}</td>
<td className="inpt-td">{result.t22}</td>
<td className="inpt-td">{result.t23}</td>
</tr>
)}
</tbody>
The header does not exist for this particular table, but I was wondering if there was a way to obtain the column name of a clicked cell. So for example if you clicked on the second cell in a given row, it would return "t01", which is the column name.
My searches online did not provide an efficient way of doing this. Is there a method to retrieve this info?
In your handleClick you can get access to the event.target property, which is a cell.
After that you can do:
var child = event.target;
var parent = child.parentNode;
// equivalent of parent.children.indexOf(child)
var index = Array.prototype.indexOf.call(parent.children, child);
var value = 't' + index // this will be value what you are looking for
If you need information how to use event.target - here is an example.
The problem is explained in the picture below. Once clicking the expanding function of "Parameter 1", the level of "Parameter 2" will change as seen in the middle picture. But actually it should remain in the same level.
Any suggestion is highly appreciated. Thanks in advance.
JAVASript
$('.P1').click(function() {
$(this).find('span').text(function(_, value) {
return value == '-' ? '+' : '-'
});
$(this).closest('tr').nextUntil('tr:has(.P2)').slideToggle(100, function() {});
});
$('.Sub-parameter-1').click(function() {
$(this).find('span').text(function(_, value) {
return value == '-' ? '+' : '-'
});
$(this).closest('tr').nextUntil('tr:has(.Sub-parameter-2)').slideToggle(100, function() {});
});
HTML
<table width="200" border="1">
<tr>
<td rowspan="6">Summary </td>
<td colspan="3">
<div align="center">1 st level</div>
</td>
</tr>
<tr>
<td colspan="3">
<div class="P1"><span>-</span>Parameter 1</div>
</td>
</tr>
<tr>
<td rowspan="3">L1</td>
<td colspan="2"><div class="Sub-parameter-1"><span>-</span>Sub parameter (1)</div></td>
</tr>
<tr>
<td>L2</td>
<td>description</td>
</tr>
<tr>
<td colspan="2"><div class="Sub-parameter-2"><span>-</span>Sub parameter (2)</td>
</tr>
<tr>
<td colspan="3">
<div class="P2">Parameter 2</div>
</td>
</tr>
</table>
JSFiddle: https://jsfiddle.net/gft08cmb/4/
EDIT based on answer
When applying the answer to more than 1 row of sub parameter, then the "Parameter 2" still changes its level seen in following link.
https://jsfiddle.net/gka7312L/ or https://jsfiddle.net/p2a2wxfv/1/
Your rowspan attribute in L1 is making problems since it should change from 3 to 2 and back in your case.
This works as you would want I think: https://jsfiddle.net/gft08cmb/6/
You should of course make it dynamic if your data is going to be dynamic also.
So probably a count of rows etc. and then manipulate based on this.
Let me know if you need further help.
I've a table like this:
<table>
<tr>
<td class="type">Order</td>
<td class="orderid">1002</td>
<td><button class="copy">Copy Row</button></td>
</tr>
<tr>
<td class="type">Order</td>
<td class="orderid">1004</td>
<td><button class="copy">Copy Row</button></td>
</tr>
<tr>
<td class="type">Refund</td>
<td class="orderid">1004</td>
<td><button class="copy">Copy Row</button></td>
</tr>
</table>
I've a script to copy data from a particular "#id" or ".class" element. What, I needed is to find a way to get the data of that particular row whenever, the Copy button is pressed. I want the columns 'orderid' and 'type' values of that particular row to be copied, but I'm not able to find a way to extract the data between the <td> tags with same class names.
Simple answer:
$('.copy').click(function(){
var order_id = $(this).parent().parent().find('.orderid').text();
var type = $(this).parent().parent().find('.type').text();
alert(order_id); ///this wil get you the value
});
I made the result here: http://codepad.viper-7.com/ahsVfB
check it.
<tr>
<td class="type">Refund</td>
<td class="orderid">1004</td>
<button class="copy">Copy Row</td>
</tr>
$(".copy").click(
function(event)
{
var copy=($(event.target).parent().find('.type'));
var order=($(event.target).parent().find('.orderid'));
}
);
You must paste that copied date somewhere. Make this copy and order as global variables. When you click paste, use this variable's value
take a look on this fiddle http://jsfiddle.net/3p29x2s9/11/
var buttons=document.getElementsByClassName("copy");
console.log(buttons);
for(var i=0;i<buttons.length;i++){
buttons[i].onclick=function(){
var columns = this.parentElement.parentElement.getElementsByTagName("td");
var type= columns[0].innerText;
var orderid=columns[1].innerText;
alert(type + " "+orderid);
}
}
So I have a below, the code can be seen below:
<table>
<tr>
<td id="first">itemOne</td>
<td id="firstClicked">itemOneInfo</td>
</tr>
<tr>
<td id="second">itemTwo</td>
<td id="secondClicked">itemTwoInfo</td>
</tr>
</table>
I want #firstClicked and #secondClicked to be hidden when #first and #second are clicked, I want #firstCLicked and #secondClicked to appear. How would I make that happen? So far I have
$('#firstClicked').css('visiblilty','hidden');
$('#first').click(function() {
$('#firstClicked').css('visibility','visible');
});
But this isn't working. Plus, even if this works, I'd have to do the same thing for #second, and i'm planning on creating more 's as well so I dont want to repeat the same code several times. Is there any better way of doing this?
I'd recommend using jQuery's hide and show functions, as well as the on function for event handling. jQuery's main power is that it makes things "just work" across browsers, so using hide will let the library choose what to do in order to make that action happen, rather then you having to second guess yourself. Example:
$('#firstClicked').hide();
$('#first').on('click',function() {
$('#firstClicked').show();
});
In addition, in your original code, you have a few mistakes:
$('firstClicked').css('visiblilty','hidden');
// should be:
$('#firstClicked').css('visibility','hidden');
However, as you're worried about having to duplicate your code, you could do the following:
HTML:
<table>
<tr>
<td id="first" class="clickable">itemOne</td>
<td id="firstClicked"><div class="initiallyHidden">itemOneInfo</div></td>
</tr>
<tr>
<td id="second" class="clickable">itemTwo</td>
<td id="secondClicked"><div class="initiallyHidden">itemTwoInfo</div></td>
</tr>
</table>
JS:
$('.initiallyHidden').hide();
$('.clickable').on('click',function() {
$(this).siblings("td").children(".initiallyHidden").show();
});
This way any element with a class clickable, when clicked, will look for a sibling with class initiallyHidden and show it
Edit: Updated example to deal with the issue raised in Christophe's comment.
Updated:
using display none on a table cell is a really bad idea – Christophe
Solution: use <span> or <div> element inside <td>
Try this:
$('#firstClicked span').css('display','none');
$('#first').click(function() {
$('#firstClicked span').css('display','block');
});
Or this:
$('#firstClicked span').hide();
$('#first').click(function() {
$('#firstClicked span').show();
});
Working full code:
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(e) {
$('#firstClicked span').css('display','none');
$('#first').click(function() {
$('#firstClicked span').css('display','block');
});
$('#secondClicked span').hide();
$('#second').click(function() {
$('#secondClicked span').show();
});
});
</script>
</head>
<body>
<table>
<tr>
<td id="first">itemOne</td>
<td id="firstClicked"><span>itemOneInfo</span></td>
</tr>
<tr>
<td id="second">itemTwo</td>
<td id="secondClicked"><span>itemTwoInfo</span></td>
</tr>
</table>
</body>
</html>
$('tr').find('td:first').next().css('visibility','hidden');
$('tr').find('td:first').css('cursor','pointer');
$('tr').find('td:first').click(function() {
$(this).next().css('visibility','visible');
});
find('td:first') points to the first cell of each row.
find('td:first').next() points to the second cell of each row.
This addresses the last part of your question:
i'm planning on creating more 's as well so I dont want to repeat the same code several times
What about:
<script>
function show(div) {
document.getElementById(div).style.display = 'block';
}
</script>
<table>
<tr>
<td id="first" onclick="show('firstClicked')">itemOne</td>
<td id="firstClicked" style="display:none">itemOneInfo</td>
</tr>
<tr>
<td id="second" onclick="show('secondClicked')">itemTwo</td>
<td id="secondClicked" style="display:none">itemTwoInfo</td>
</tr>
</table>