Select Cells On A Table By Dragging - javascript

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.

Related

Change background color of cell using Angular

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.

Changing colour of a div using jQuery

I'm trying to change the colour of a singular div using jQuery. I'm 80% sure my code should work but I'm not sure why it's not working. I've tried to use loads of different methods such as mouseenter, hover, addClass, toggleClass etc. But for the life of me I can't figure out what's going on. Help please?
JAVASCRIPT
$(document).ready(function(){
blackMode();
genDivs(10);
});
/* Black mode - changes colours of cells to black */
function blackMode() {
$('.cell').hover(
function (){
$(this).css({"background-color":"black"});
},
function (){
$(this).css({"background-color":"white"});
});
}
/* creates the divs in a 10x10 grid */
function genDivs(v) {
var e = document.getElementById('container'); //This is what we want to append the rows
for (var i = 0; i < v; i++) {
var row = document.createElement("div"); // This creates each row that is selected.
row.className="row"; // This declares the class name for the created div.
for(var j = 0; j < v; j++) {
var cell = document.createElement("div");
cell.className="cell";
row.appendChild(cell);
}
e.appendChild(row);
}
}
HTML
<html>
<head>
<script type="text/javascript" src="jquery-1.11.3.min.js"></script>
<script src="Script.js"></script>
<link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Raleway" />
<link rel="stylesheet" type="text/css" href="Stylesheet.css"></link>
</head>
<body>
<h1 class="title">Etch-a-Sketch</h1>
<div id="container">
</div>
</body>
UPDATE:
Sorry, I haven't notice you are in fact using .cell class on element you're inserting dynamically - but still give them some height and more important -> first insert elements and then use jQuery to bind events:
$(document).ready(function(){
genDivs(10);
blackMode();
});
another fiddle
The version you had before didn't work because by the time you called blackMode function that applied hover handlers none elements with class .cell were in DOM.
ORIGINAL ANSWER:
You are applying hover functions on elements that have cell class, but you haven't used that in your HTML. Also when your div has no contents it'll have 0px height and effect won't be visible.
Add .cell class to you div:
<div class="cell">
</div>
And give it some height via CSS (or add sth inside):
.cell {
height: 400px;
}
jsfiddle

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

Select and copy table to clipboard

I want to select table without headers, and it works, but I cannot get it so, that it would copy to clipboard.
Here's the page: http://tuudik.lohv.eu/Asjad/EURXML/
Here's the code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>ECB kursid seisuga: 2011-04-01 </title>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<style type="text/css">
table
{
border-collapse:collapse;
}
table, td, th
{
border:1px solid black;
}
</style>
<script type="text/javascript">
function selectElementContents(el) {
var body = document.body, range, sel;
if (body.createTextRange) {
range = body.createTextRange();
range.moveToElementText(el);
range.select();
range.execCommand('Copy');
} else if (document.createRange && window.getSelection) {
range = document.createRange();
range.selectNodeContents(el);
sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
sel.execCommand('Copy');
}
}
</script>
</head>
<body>
<table cellpadding="2">
<thead>
<tr>
<th>Valuuta</th>
<th>Kurss</th>
</tr>
</thead>
<tbody id="currencies">
<tr><td>USD</td><td>1,4141</td></tr><tr><td>JPY</td><td>118,56</td></tr><tr><td>DKK</td><td>7,4564</td></tr><tr><td>GBP</td><td>0,88150</td></tr><tr><td>NOK</td><td>7,8055</td></tr><tr><td>RUB</td><td>40,1500</td></tr><tr><td>CAD</td><td>1,3686</td></tr></tbody>
</table>
<input type="button" value="select table"
onclick="selectElementContents( document.getElementById('currencies') );">
</body>
</html>
This works for me on IE8:
var table = document.getElementById('copyHtmlToClipboard');
// Below line is essential !!!
table.contentEditable = 'true';
var controlRange = document.body.createControlRange();
controlRange.addElement(table);
controlRange.execCommand("Copy");
In most browsers it isn't possible to copy to the system clipboard. To do this you need to use a hack. The most common way is to use Flash. ZeroClipboard does this and appears to work quite well.
By the way, execCommand() is a method of document and TextRange objects, not Selection objects, so sel.execCommand("Copy") couldn't possibly work.
UPDATE
I've never actually used ZeroClipboard. Having looked at the docs, it doesn't look like it does what I had hoped (there seems to be no way to copy rich text) and is even more of a gruesome hack than I thought. You could copy the table's content as text via innerHTML using ZeroClipboard, but whether this is acceptable or not depends on what you're hoping the user can do with the copied content.

html table column width, fix width at time of page creation

If there an easy way to fix the width of the html table columns at the time the page is rendered. I DO NOT want to specify the pixel or percent width of the columns in my code. However, once the page is created and the widths determined based on the initial content in the table I do not want the widths to change, even if the size of the cell content changes.
Just so you understand what i'm trying to do, if I have the content of a cell change(from normal to bold for example), say when I hover over the row, the size of the columns will change. This looks quite odd.
To be honest I didn't understand the answer you gave to my comment, but I'll attempt at an answer anyway :-)
What you maybe need is to wrap the content of each cell in a div (or some other block element) and set it's width. That should limit the widening of the cells, however as I hinted at im my comment, the wider content will overflow, which most like look ugly. However you didn't really specify what you want the wider content to do...
<style type="text/css">
#the-table td .wrap {
overflow: hidden; /* try different values for different effects */
}
</style>
<script type="text/javascript">
$(function(){
$('#the-table th, #the-table td').wrapInner(function() {
return $("<div/>").css("width", $(this).width() + "px");
});
});
</script>
Live example: http://jsfiddle.net/Vx5Zq/
Notice how the letter F is cut off on hover.
I think this should do the trick (not checked though):
var w = $('#myTable td.leftCol').outerWidth();
$('#myTable td.leftCol').css({width: w+'px'});
[EDIT]
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(
function() {
$("table td").each(
function() {
var w = $(this).outerWidth();
alert(w+'px');
w *= 2;
$(this).css({width: w+'px'});
alert(w+'px');
}
);
}
);
</script>
</head>
<body>
<table>
<tr>
<td>abc</td>
<td>def</td>
<td>ghi</td>
</tr>
</table>
</body>
</html>
Adding some width to your current tds will stop the resizing when the the text goes bold.
First set your table using css to fixed rendering:
<style type="text/css">
#mytable{ table-layout: fixed; }
</style>
Then you can use jquery to add 2px of width to your tds like so:
<script type="text/javascript">
$(function(){
$('#mytable td').each(function(){
var $this = $(this) // cache this td
// set style to 2px wider
$this.css({ width: $this.outerWidth() + 2, height: $this.outerHeight() + 2 });
})
});
</script>

Categories

Resources