Change background color of cell using Angular - javascript

I am using Angular in my application.
<td ng-click="selectTime(this)" >
I have a Table with lots of cells and I want to change background color of the cell when it is selected. I am passing the current element (this) to my function selectTime.
$scope.selectTime = function (element) {
$(element).addClass("active");
}
.active {
background-color:orangered;
}
For some reason even if I am adding a class the background color is not changing.

It's best not to use jQuery to manipulate the DOM inside a controller function.
Use ng-class.
<td ng-click="selectTime($event)" ng-class="{'orange': event.selected, 'red': !event.selected }"> </td>
Remember to pass in $event as a parameter to your ng-click directive.
Your controller function would look like this
$scope.selectTime = function (event) {
$(event).selected = true;
}
Credit should be attributed to this answer
Accessing clicked element in angularjs

Straightforward vanilla JS approach, though Richard Hamilton's answer is much better in terms of handling this in an Angular way:
<td ng-click="select($event)"></td>
and the JS:
$scope.select = function(event) {
var elements = document.getElementsByClassName('active');
for(var i = 0; i < elements.length; i++) {
elements[i].classList.remove('active');//clear old active cells
}
event.currentTarget.classList.add("active");
}

I made a bin for this.
(function() {
'use strict';
angular
.module('app',[])
.controller('tableController', tableController);
function tableController() {
var vm = this;
vm.items = [1,2,3,4,5,6];
vm.changebgColor = changebgColor;
function changebgColor(item){
vm.selectedIndex = item;
}
}
})();
table tr td{
border:1px solid #ccc;
width:100px;
text-align:center;
}
.red{
background-color:red;
}
.blue{
background-color:blue;
}
<!DOCTYPE html>
<html data-ng-app="app">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body data-ng-controller="tableController as vm">
<table>
<tr data-ng-repeat="item in vm.items">
<td
data-ng-class="{ 'red': $index == vm.selectedIndex }"
data-ng-click="vm.changebgColor($index)">{{item}}
</td>
</tr>
</table>
</body>
</html>
hope this helps you.

Related

How to build array contains conditional

I need to build a window listener that triggers on the mouseover on a box using contains and I'm not quite sure of how to build that?
This is a test I've built:
window.addEventListener("mouseover", trial)
function trial(e) {
const contain_material = document.getElementsByClassName("item")
if(contain_material.contains(e.target)) {
alert("so far so good")
}
else {
return
}
}
See if the following works for you.
function trial(e) {
const contain_material = document.getElementsByClassName("item")
for (var i = 0; i < contain_material.length; i++) {
if(contain_material[i] == e.target) {
alert("so far so good")
}
}
}
Instead of checking hover on the window, why not just check when one of those elements is hovered over. For example:
const contain_material = document.getElementsByClassName("item")
for (mat of contain_material) {
mat.addEventListener("mouseover", trial)
}
function trial(e) {
alert("so far so good")
}
Can't you just listen to the mouseover on the box element instead of in the whole page?
function handleMouseOver() {
alert('so far so good')
}
// or you can add dynamicaly with js
var boxes = document.getElementsByClassName("item");
Array.from(boxes).forEach(function() {
this.onmouseover = () => alert('so far so good')
})
// () => this is an arrow function in case you dont know
// Array.from() is because you can't use the forEach straight with a HTMLCollection
body {
display: flex;
}
.item {
width: 300px;
height: 300px;
background-color: yellow;
margin: 10px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div class="item" onmouseover="handleMouseOver()"></div>
<div class="item" onmouseover="handleMouseOver()"></div>
<div class="item" onmouseover="handleMouseOver()"></div>
<div class="item" onmouseover="handleMouseOver()"></div>
</body>
</html>

custom data attribute on table tag is not supported?

I tried this code but in debug test is undefined for attribute associated with table tag so is attribute supported for table or is my code bugged?
<!DOCTYPE html>
<html>
<head>
<title>data attribute on table</title>
<style>
table, th, td {
border: 1px solid black;
border-collapse:collapse;
}
th, td {
padding: 5px;
}
</style>
<script>
function testData() {
var tableElement = document.getElementById("table");
var test = tableElement.getAttribute("test");
}
</script>
</head>
<body onload="testData()";>
<table id="tableElement" data-test="test">
</table>
</body>
</html>
Your function is faulty.
I usually keep things simple by matching the variable's name with the object's id value. So id of table is also the var's name tableElement.
When you are dealing with retrieving (get) a singledata-* attribute, it is usually a string exactly like the attribute's name just like your function using .getAttribute("data-test").
If you are retrieving a list of data-*like with jQuery's .data or JS.datalist you drop the data- as you did in your original code.
It will be camel cased if there's 2 or more - in the name. data-test-my-table would be testMyTable
Details on data-* attribute naming syntax.
Snippet
function testData() {
var tableElement = document.getElementById("tableElement");
var test = tableElement.getAttribute("data-test");
//Just for demo (optional)
console.log('data-test: ' + test);
var out1 = document.getElementById('out1');
out1.value = test;
//~~~~~~~~~~~~~~
return test;
}
<!DOCTYPE html>
<html>
<head>
<title>data attribute on table</title>
<style>
table,
th,
td {
border: 1px solid black;
border-collapse: collapse;
}
th,
td {
padding: 5px;
}
</style>
</head>
<body onload="testData()">
<table id="tableElement" data-test="test">
</table>
<!---Optional--->
<output id="out1"></output>
<!------------->
</body>
</html>
The property name is data-test, not test. Consider using dataset instead:
The HTMLElement.dataset read-only property allows access, both in reading and writing mode, to all the custom data attributes (data-*) set on the element. It is a map of DOMString, one entry for each custom data attribute.
Also your table element has id tableElement, not table.
This should work:
function testData() {
var tableElement = document.getElementById("tableElement");
var test = tableElement.dataset.test;
document.body.innerHTML = test;
}
document.body.onload = testData;
<table id="tableElement" data-test="test"></table>

Can't get the background color using DOM

I'm trying to get element background style which has been written on a different CSS file.
The problem is that I can't get the style which were written in a CSS file.
on the other hand, styling which has been written on the HTML document are possible to get.
CSS code
#try2
{
background-color:yellow;
}
body
{
background-color:gray;
}
td, th{
border: 1px solid black;
}
HTML code
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1255" />
<link rel="stylesheet" type="text/css" href="html.css">
<script type="text/javascript" src="external.js"></script>
</head>
<body>
<table>
<tr>
<td id = "try1" style="background-color:green;"><p id="ChosenColor3"> htmlfile</p></td>
</tr>
<tr>
<td id = "try2"><p id="ChosenColor4"> css file</p></td>
<td><button id="bestRated3" onclick = arrayTest()> ב.מ </button></td>
<td><button id="submitForm" onclick = submit()> end</button></td>
</tr>
<tr>
<td><h1 id="ChosenColor5"> text </h1></td>
</tr>
</table>
</body>
<script>
window.onload=aaa();
function aaa()
{
var x = document.getElementById("try2");
alert(x.style.background);
}
</script>
</html>
As you can see, the message I get is empty. If I will change the ID to "try1" it will be displayed.
The style property lets you read and write the value for each element's style HTML attribute (what is called its inline style) -- it does not take stylesheets into account.
To discover what the real value of a CSS attribute is you have to use window.getComputedStyle instead, for example:
alert(getComputedStyle(x, null).getPropertyValue("background-color"));
See it in action.
Please note that getComputedStyle is not supported by IE 8 or earlier.
Change your alert to alert(x.style.backgroundColor);
style.background and style.backgroundColor are two different things.
Try this
function aaa()
{
var a = document.getElementById("try2").style.backgroundcolor;
alert("Your background color is :"+a);
}
Use this instead:
alert(x.style.backgroundColor);
You have not assigned the value for background. So use something like this:
alert(x.style.background="red");
demo

pass CSS .class as a parameter to javascript function

the goal here is onclick of 1.gif, everything with .panel1 class disappears(style.display.none), and everything with a .panel2 class becomes visable (style.display.inline)
I'm new at this..so I think its just a syntax issue with ' ' or maybe " "
<!DOCTYPE html>
<html>
<head>
<title>main</title>
<meta charset="utf-8">
<style type="text/css">
.panel1 {display:inline;}
.panel2 {display:none;}
</style>
<script type="text/javascript">
function panelTransition(panelOut,panelIn)
{
document.getElementByClass(panelIn).style.display="inline";
document.getElementByClass(panelOut).style.display="none";
}
</script>
</head>
<body>
<img class="panel1" src=1.gif onclick="panelTransition(panel1,panel2)" />
<img class="panel2" src=2.gif />
</body>
</html>
There is no getElementByClass. It's getElementsByClassName, and it returns an array of items, so you'll need to modify your code to loop through them.
function panelTransition(panelOut, panelIn) {
var inPanels = document.getElementsByClassName(panelIn);
for (var i = 0; i < inPanels.length; i++) {
inPanels[i].style.display = 'inline';
}
var outPanels = document.getElementsByClassName(panelOut);
for (var i = 0; i < outPanels.length; i++) {
outPanels[i].style.display = 'none';
}
}
If you were using a JavaScript library, like jQuery, this would be much easier to do. Also, as has been mentioned, you need quotes around your arguments to panelTransition.
<img class="panel1" src=1.gif onclick="panelTransition('panel1', 'panel2')" />
<img class="panel2" src=2.gif />
<img class="panel1" src=1.gif onclick="panelTransition('panel1','panel2')" />
I think you need quotes there
<html>
<head>
<title>main</title>
<meta charset="utf-8">
<style type="text/css">
.panel1 {display:inline;}
.panel2 {display:none;}
</style>
<script type="text/javascript">
function panelTransition(panelOut,panelIn)
{
// panelIn gets turned on
setDisplay(panelIn,"inline");
// panelOut gets turned off
setDisplay(panelOut,"none");
}
function setDisplay(className,displayState)
{
// retrieve a list of all the matching elements
var list = document.getElementsByClassName(className);
// step through the list
for(i=0; i<list.length; i++) {
// for each element, set the display property
list[i].style.display = displayState;
}
}
</script>
</head>
<body>
<img class="panel1" src="1.gif" onclick="panelTransition('panel1','panel2')" />
<img class="panel2" src="2.gif" onclick="panelTransition('panel2','panel1')" />
</body>
</html>
Or you can accomplish the same in jQuery
// fires when the page is up and running
$(document).ready(function(){
// find all the panel1 elements,
// attach an on click handler
$(".panel1").bind("click", function(){
// find all the panel1 elements
// set their css display property to inline
$(".panel1").css("display","inline");
// find all the panel2 elements
// set their css display property to none
$(".panel2").css("display","none");
});
$(".panel2").bind("click", function(){
$(".panel2").css("display","inline");
$(".panel1").css("display","none");
});
});
You can learn all about jQuery here : http://www.jquery.com/
You'll only be able to get your code to run once, as soon as you click a panel1 image all of the panel2 images will disappear, you won't be able to click them back on ever again.

Select Cells On A Table By Dragging

I was looking at this question and saw the reference to the iPhone game where you drag across the screen selecting letters as you go.
I was curious to see an implimentation of this in Javascript using tables. So you'd drag the mouse over each cell they would then become highlighted.
I'm not sure what the best method would be but I hope someone has a go. Someone attempted it here, but it doesn't really work.
Thank Cacoo for the sexy diagrams. It's like an online visio, really nice. Check it out ;)
Here's a working prototype: http://jsfiddle.net/few5E/ Using jQuery for DOM hooking, but could easily be implemented with another framework.
Update: http://jsfiddle.net/Brv6J/ a slightly different version - the highlighted state will only change when you release and click again.
Update 2: http://jsfiddle.net/Brv6J/3/ - binding onselectstart so that text is not selected in IE.
A few relevant facts:
The mousedown event of the table cells is hooked to track the actual click. This event is stopped, so that text selection is hindered. Also binding ontextselect for the same effect in IE.
The mouseover event will toggle the highlighted class for the cell
The mouseout event is hooked on document. This is to ensure that it always runs. If the mouseup event was hooked on the table cell, it would not trigger if you released the mouse key with the mouse outside of the table. This state is tracked in isMouseDown.
Full source code for reference:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<style type="text/css" media="screen">
table td {
width:100px;
height:100px;
text-align:center;
vertical-align:middle;
background-color:#ccc;
}
table td.highlighted {
background-color:#999;
}
</style>
</head>
<body>
<table cellpadding="0" cellspacing="1" id="our_table">
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
</tr>
<tr>
<td>d</td>
<td>e</td>
<td>f</td>
</tr>
<tr>
<td>g</td>
<td>h</td>
<td>i</td>
</tr>
</table>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript" charset="utf-8">
$(function () {
var isMouseDown = false;
$("#our_table td")
.mousedown(function () {
isMouseDown = true;
$(this).toggleClass("highlighted");
return false; // prevent text selection
})
.mouseover(function () {
if (isMouseDown) {
$(this).toggleClass("highlighted");
}
})
.bind("selectstart", function () {
return false; // prevent text selection in IE
});
$(document)
.mouseup(function () {
isMouseDown = false;
});
});
</script>
</body>
</html>
If you're after spreadsheet-like cell selection (in column/row blocks), you need to highlight every cell in every row that is between your start & end index (both row and cell) in your mouseover event:
for (var i = rowStart; i <= rowEnd; i++) {
var rowCells = table.find("tr").eq(i).find("td");
for (var j = cellStart; j <= cellEnd; j++) {
rowCells.eq(j).addClass("selected");
}
}
As the user might start selecting cells from all directions (up-bottom, bottom-up, right-left, left-right) you need to assign the correct indexes for start & end.
Here is a jsFiddle.
http://www.jaanuskase.com/stuff/dragSelect.html
Not sure if you wanted pure-Javascript implementation, I used jQuery for convenience.

Categories

Resources