Navigate through form with arrow keys - html

I have a html form, which is created like a table (with rows and columns). Basically it looks like excel.
And now I would like to navigate just like in excel with the arrow keys. Is that possible?
<table>
<tr>
<td/>
<td/>
</tr>
<tr>
<td/>
<td/>
</tr>
</table>

Yes, it was easy, once I got your tips. This is my solution:
var UP = 38;
var DOWN = 40;
var LEFT = 37;
var RIGHT = 39;
var TAB = 9;
$('#tab-columns').on('keydown', 'input', function (event) {
var $focused = $(':focus');
var id = ($focused.parents("td").attr('id'));
if (id.startsWith("field_")) {
idArr = id.replace("field_", "").split("_");
row = Number(idArr[0]);
col = Number(idArr[1]);
newId = id;
switch (event.which) {
case UP:
newId = "field_"+(row-1)+"_"+col;
break;
case DOWN:
newId = "field_"+(row+1)+"_"+col;
break;
case TAB:
case RIGHT:
newId = "field_"+row+"_"+(col+1);
break;
case LEFT:
newId = "field_"+row+"_"+(col-1);
break;
default:
// nothing
}
$("#"+newId).find("input").focus();
}

Related

How to export multiple HTML tables into a single excel file, along with the html table's css/style?

I know there are a lot of this type of question in this site, but i cant find any working solution for this that suit my need. What i need is
1. export multiple html table to excel
2. the table in the excel look exactly like the html table (the css, styling are the same. e.g background-color)
Is there any way to do this using javascript,etc.?
I found one question for this problem here, but the solution shown there did not solve the css problem. Means that the excel table not have the css like the html table (e.g The excel table doesnt have yellow background eventhough the html table have it)
So basically the main problem is I need the format for the excel file to be same as the html table (css,etc.). Sorry I am new to programming..
Here you can access the jsfiddle. Or if the link doesnt work, you can just try it below (The codes are taken from the original post , but with an addition of a simple yellow-colored background css in it's tr)Thanks in advance.
var tablesToExcel = (function() {
var uri = 'data:application/vnd.ms-excel;base64,'
, tmplWorkbookXML = '<?xml version="1.0"?><?mso-application progid="Excel.Sheet"?><Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">'
+ '<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"><Author>Axel Richter</Author><Created>{created}</Created></DocumentProperties>'
+ '<Styles>'
+ '<Style ss:ID="Currency"><NumberFormat ss:Format="Currency"></NumberFormat></Style>'
+ '<Style ss:ID="Date"><NumberFormat ss:Format="Medium Date"></NumberFormat></Style>'
+ '</Styles>'
+ '{worksheets}</Workbook>'
, tmplWorksheetXML = '<Worksheet ss:Name="{nameWS}"><Table>{rows}</Table></Worksheet>'
, tmplCellXML = '<Cell{attributeStyleID}{attributeFormula}><Data ss:Type="{nameType}">{data}</Data></Cell>'
, base64 = function(s) { return window.btoa(unescape(encodeURIComponent(s))) }
, format = function(s, c) { return s.replace(/{(\w+)}/g, function(m, p) { return c[p]; }) }
return function(tables, wsnames, wbname, appname) {
var ctx = "";
var workbookXML = "";
var worksheetsXML = "";
var rowsXML = "";
for (var i = 0; i < tables.length; i++) {
if (!tables[i].nodeType) tables[i] = document.getElementById(tables[i]);
for (var j = 0; j < tables[i].rows.length; j++) {
rowsXML += '<Row>'
for (var k = 0; k < tables[i].rows[j].cells.length; k++) {
var dataType = tables[i].rows[j].cells[k].getAttribute("data-type");
var dataStyle = tables[i].rows[j].cells[k].getAttribute("data-style");
var dataValue = tables[i].rows[j].cells[k].getAttribute("data-value");
dataValue = (dataValue)?dataValue:tables[i].rows[j].cells[k].innerHTML;
var dataFormula = tables[i].rows[j].cells[k].getAttribute("data-formula");
dataFormula = (dataFormula)?dataFormula:(appname=='Calc' && dataType=='DateTime')?dataValue:null;
ctx = { attributeStyleID: (dataStyle=='Currency' || dataStyle=='Date')?' ss:StyleID="'+dataStyle+'"':''
, nameType: (dataType=='Number' || dataType=='DateTime' || dataType=='Boolean' || dataType=='Error')?dataType:'String'
, data: (dataFormula)?'':dataValue
, attributeFormula: (dataFormula)?' ss:Formula="'+dataFormula+'"':''
};
rowsXML += format(tmplCellXML, ctx);
}
rowsXML += '</Row>'
}
ctx = {rows: rowsXML, nameWS: wsnames[i] || 'Sheet' + i};
worksheetsXML += format(tmplWorksheetXML, ctx);
rowsXML = "";
}
ctx = {created: (new Date()).getTime(), worksheets: worksheetsXML};
workbookXML = format(tmplWorkbookXML, ctx);
console.log(workbookXML);
var link = document.createElement("A");
link.href = uri + base64(workbookXML);
link.download = wbname || 'Workbook.xls';
link.target = '_blank';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
})();
<table id="tbl1" class="table2excel">
<tr style="background-color:yellow;">
<td>Product</td>
<td>Price</td>
<td>Available</td>
<td>Count</td>
</tr>
<tr>
<td>Bred</td>
<td>1
</td>
<td>2
</td>
<td>3
</td>
</tr>
<tr>
<td>Butter</td>
<td>4
</td>
<td>5
</td>
<td >6
</td>
</tr>
</table>
<hr>
<table id="tbl2" class="table2excel">
<tr>
<td>Product</td>
<td>Price</td>
<td>Available</td>
<td>Count</td>
</tr>
<tr>
<td>Bred</td>
<td>7
</td>
<td>8
</td>
<td>9
</td>
</tr>
<tr>
<td>Butter</td>
<td>14
</td>
<td>15
</td>
<td >16
</td>
</tr>
</table>
<button onclick="tablesToExcel(['tbl1','tbl2'], ['ProductDay1','ProductDay2'], 'TestBook.xls', 'Excel')">Export to Excel</button>
Found the solution for this. I use the DataTables. Read more here DataTables forum

How to get the value of the table using HtmlAgilityPack

i Need to get the content of the table. Below is my table
<tr class="oddRow" id="activeFiles25472825Row">
<td>Author Photo</td>
<td></td>
<td>
<div id="active_25472825_CALLOUT" class="fileTruncateCallout" style="position:absolute; display:none">JCS.jpg</div>
</td>
<td>01/28/2017</td>
<td>30.7 KB</td>
<td>Member</td>
<td>
download
</td>
</tr>
Here is my code. But i don't know what's next. I tried getting the value i need but i can't make it work. it didn't give me output, or error
HtmlAgilityPack.HtmlDocument newdoc = new HtmlAgilityPack.HtmlDocument();
newdoc.LoadHtml(htmlString);
GeckoElementCollection links = wb.Document.GetElementsByTagName("td");
foreach (var itm in links)
{
}
And the output
is
Name: JCS.jpg
Link: https://google.com.download
You can try something like this, I didn't test it but hopefully you understand the idea behind
foreach (var td in newDoc.DocumentNode.Descendants("td"))
{
var div = td.ChildNodes.FirstOrDefault(c => c.Name.Equals("div") && c.GetAttributeValue("class", "").Equals("fileTruncateCallout"));
if (div != null)
{
var name = div.InnerText;
}
else
{
var aNode = td.ChildNodes.FirstOrDefault(c => c.Name.Equals("a"));
if(aNode != null)
{
var href = aNode.GetAttributeValue("href", "");
}
}
}

json results only showing one thing in table

I am havign an issue where there is only one item being shown in my table (usually the most recent bug entered)
could you let me know if there is an error with my code?
Here is it
//Web service call to get the data
var getAllBugsData = $.get("https://m2052626.scm.tees.ac.uk/AST_14/Bugg.ly2/index.php/bug/GetAllBugs",
function(data)
{
var j = 0;
var myTotal = data.length ;
for(var i =0; i < data.length;i++)
{
var item = data[i];
bug_id = item.bug_id;
BugType = item.BugType;
Bugaddress = item.Bugaddress;
admin_id = item.admin_id;
status = item.status;
Description = item.description;
type = item.type;
var bugDetails = '<div class="PropDetails">Bug Id: '+bug_id+'</div><div class="PropDetails">Type of Bug: '+BugType+'</div><div class="PropDetails">Admin Number :'+admin_id+'</div><div class="PropDetails">Type Of Bug: '+type+'</div>';
$('.listAllBugs').append('<tr class="table-stroke"><td>'+bugDetails+'</td><td>Edit</tr>');
And the table code is this
<!--Data Table Goes HERE-->
<table data-role="table" data-mode="reflow" class="ui-responsive table-stroke">
<thead>
<tr>
<th width="100%">Bug Details</th>
</tr>
</thead>
<tbody class="listAllBugs">
</tbody>
</table>

How to make HTML table "Excel-like" editable for multiple cells, i.e. simultaneous copy-paste features?

I need my HTML table to be editable so that user inserted data could be sent to the server. However due to the table's size (50 rows) it would not be convenient for users to insert data points one-by one if I introduce contenteditable attribute as following:
<table>
<tr><td><div contenteditable>editable</div></td><td><div contenteditable>editable</div></td></tr>
//...........
</table>
How can I make my table be editable similar to excel spreadsheet, if possible without using dojo etc?
I have done this in Java using ExcelAdapter class. Is there any way I could do it in HTML?
You can add a listener to the input event of each cell, and if the cell contains multiple data items split them across the next cells.
function init()
{
var tables = document.getElementsByClassName("editabletable");
var i;
for (i = 0; i < tables.length; i++)
{
makeTableEditable(tables[i]);
}
}
function makeTableEditable(table)
{
var rows = table.rows;
var r;
for (r = 0; r < rows.length; r++)
{
var cols = rows[r].cells;
var c;
for (c = 0; c < cols.length; c++)
{
var cell = cols[c];
var listener = makeEditListener(table, r, c);
cell.addEventListener("input", listener, false);
}
}
}
function makeEditListener(table, row, col)
{
return function(event)
{
var cell = getCellElement(table, row, col);
var text = cell.innerHTML.replace(/<br>$/, '');
var items = split(text);
if (items.length === 1)
{
// Text is a single element, so do nothing.
// Without this each keypress resets the focus.
return;
}
var i;
var r = row;
var c = col;
for (i = 0; i < items.length && r < table.rows.length; i++)
{
cell = getCellElement(table, r, c);
cell.innerHTML = items[i]; // doesn't escape HTML
c++;
if (c === table.rows[r].cells.length)
{
r++;
c = 0;
}
}
cell.focus();
};
}
function getCellElement(table, row, col)
{
// assume each cell contains a div with the text
return table.rows[row].cells[col].firstChild;
}
function split(str)
{
// use comma and whitespace as delimiters
return str.split(/,|\s|<br>/);
}
window.onload = init;
Demo: http://jsfiddle.net/yRnkF/
you can achieve this easily by adding handsontable
change any div to a excel table
var $container = $("#divid");
$container.handsontable({
data: getData(),
rowHeaders: true,
colHeaders: true,
contextMenu: true //forces dom to use custom right click functionality like add row delete row add column etc
});
jsFiddle : http://jsfiddle.net/jwtskyLa/
Pure javascript. Just mark a table with 'editabletable' class.
index.html:
<table class="editabletable" border="1">
<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="index.js"></script>
index.js:
function makeeditable(table) {
for (let i = 0; i < table.rows.length; i++) {
for (let j = 0; j < table.rows[i].cells.length; j++) {
// with contenteditable in each cell, it is possible to navigate through them with tab key
table.rows[i].cells[j].setAttribute("contenteditable", "true");
}
}
}
function addpastelistener(table) {
table.addEventListener('paste', (event) => {
event.preventDefault();
let paste = (event.clipboardData || window.clipboardData).getData('text');
let col = event.target;
while (col && col.tagName != 'TD') col = col.parentElement;
let row = col;
while (row && row.tagName != 'TR') row = row.parentElement;
let tab = row;
while (tab && tab.tagName != 'TBODY' && tab.tagName != 'TABLE') tab = tab.parentElement;
let rows = paste.replace(/(\r\n)|\r|\n/g, '\n').split("\n");
for (let i = 0, r = row.rowIndex; i < rows.length && r < table.rows.length; i++) {
let cells = rows[i].split("\t");
for (let j = 0, c = col.cellIndex; j < cells.length && c < table.rows[r].cells.length; j++) {
table.rows[r].cells[c].innerHTML = cells[j].trim();
c++;
}
r++;
}
});
}
function init() {
const editabletables = document.getElementsByClassName('editabletable');
for (let i = 0; i < editabletables.length; i++) {
makeeditable(editabletables[i]);
addpastelistener(editabletables[i]);
}
}
init();

How can i get the position number of an element?

Is there any plugin in firefox or function in firebug or something else, that lets me se the position number of a specific element?
If i for example want to know the what position a specific TD element has compared to all the TD's in the document.
EXAMPLE:
<html>
<head>
<body>
<table>
<tr>
<td></td> (0)
<td></td> (1)
<td></td> (2)
<td></td> (3)
<td></td> (And so on...)
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td> <------ WHAT IS THE POSITION NUMBER OF THIS TD?
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
</body>
</html>
The webdeveloper toolbar in firefox has a tool that lets you see the index number of all DIV's. This is what i need but for other elements, not just DIV.
PS. I was inspired by the correct answer and i made my own solution:
var dom = document.getElementsByTagName('td');
var x;
for(x = 0; x < dom.length; x++)
{
dom[x].innerHTML = dom[x].nodeName + '[' + x + '] ' + '(' + dom[x].innerHTML + ')';
dom[x].style.color = 'blue';
}
Well, the following will do as you need:
$('li').each(
function(i) {
$(this).text('list element ' + i);
});
function indexAmongSiblings(elem) {
if (!elem) {
return false;
}
var that = elem;
var parent = that.parentNode;
var siblings = parent.childNodes;
var elemSiblings = [];
for (var s = 0, numberOf = siblings.length; s < numberOf; s++) {
if (siblings[s].nodeName != '#text' && siblings[s].tagName != undefined) {
elemSiblings.push(siblings[s]);
}
}
for (var e=0,l=elemSiblings.length; e<l; e++){
if (elemSiblings[e] == elem){
console.log('Element number: ' + e + ' among its siblings.');
}
}
}
var elements = document.getElementsByTagName('*');
for (var i = 0, len = elements.length; i < len; i++) {
elements[i].onclick = function(e) {
e.stopPropagation();
indexAmongSiblings(this);
};
}
JS Fiddle demo.
Edited the above in order to show how to assign the element's index, amongst its siblings, to a variable:
$('li').each(
function(i) {
$(this).text('list element ' + i);
});
function indexAmongSiblings(elem) {
if (!elem) {
return false;
}
var that = elem;
var parent = that.parentNode;
var siblings = parent.childNodes;
var elemSiblings = [];
for (var s = 0, numberOf = siblings.length; s < numberOf; s++) {
if (siblings[s].nodeName != '#text' && siblings[s].tagName != undefined) {
elemSiblings.push(siblings[s]);
}
}
for (var e=0,l=elemSiblings.length; e<l; e++){
if (elemSiblings[e] == elem){
// the following returns the index-point amongst siblings
return e;
}
}
}
var elements = document.getElementsByTagName('*');
for (var i = 0, len = elements.length; i < len; i++) {
elements[i].onclick = function(e) {
e.stopPropagation();
var thisIndex = indexAmongSiblings(this);
// the thisIndex variable now holds the returned index-point
};
}
Edited in response to comments left on other answers, by OP:
I want the number/sequence position of a specific element(e.g ) compared to equal elements(e.g ) in the whole DOM.
Citation.
The following function will get, and return, the index position of the clicked element amongst other tags of the same type in the document (which is actually somewhat easier than the above):
function indexAmongSameTags(elem) {
if (!elem || !elem.tagName) {
return false;
}
var thisIs = elem.tagName.toLowerCase(),
sameAs = document.getElementsByTagName(thisIs);
for (var i=0,len=sameAs.length; i<len; i++){
if (sameAs[i] == elem){
console.log('You clicked ' + thisIs + ' of index position "' + i + '" among ' + len + ' other ' + thisIs + ' elements');
return i;
}
}
}
var elements = document.getElementsByTagName('*');
for (var i = 0, len = elements.length; i < len; i++) {
elements[i].onclick = function(e) {
e.stopPropagation();
var indexPosition = indexAmongSameTags(this);
console.log(indexPosition);
};
}
JS Fiddle demo.
References:
childNodes.
e.preventDefault().
e.stopPropagation().
getElementsByTagName().
parentNode.
push().
Dom-tree. Every element have number if you try to get it by their XPath.
EDIT
Sorry, I've misunderstood your question. Here is the answer then:
Open your firebug
Select your element with the inspect tool
Once you clicked, one the right side click the dom link
See the cell index there.
Like this:
With javascript you can get the numbers of tds.
var tds = document.getElementsByTagName('td'); // this will return every td in the document.
if (console && console.log)
console.log(tds.length);
else
alert(tds.length);
The example above will print the totoal number of td elements in your document. However, if you want a particular td, you should give that td an identifier. For instance assume your html file is like:
...
<td id="your_td"></td>
...
Now with javascript you can:
var td = document.getElementById('your_td'); // this will return the td
// if you want its position you can:
var tds = document.getElementsByTagName('td');
for (var i = 0; i < tds.length; i++) {
if (tds[i] === td)
alert(i);
}
This example will give your td's position.