How to make a partially un-editable table cell? - javascript

This might be kind of a weird question, but is it possible to build table cells that are partially editable, but also partially un-editable? By this I mean, I want to use JavaScript to make a majority of the cell editable by setting .contentEditable = true in JavaScript (already done). However, I also want a portion (preferably on the right side) to be text that cannot be written over or edited.
What I'm trying to do here is make most of the table cell editable to put in raw data, i.e. numbers. But to leave an stagnate section with a unit, so that the unit doesn't actually get taken as input (it's more just like decoration).
I've drawn a mock-up of what I'm imagining, if this helps:
So far, I've tried adding a <input> element after the initial input following <td>, then style the input to set point-events: none. But this does not look good and ends up creating an input form inside of a content editable cell, which isn't really what I want, and ends up looking like this:
I think it would have to use some CSS overlay and not actually be apart of the table HTML. Either way, how would I go about this?

You could just use two span elements, make one of them contenteditable. Example:
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid black;
}
.input {
display: flex;
justify-content: space-between
}
span {
padding: 0.5em;
}
.value {
flex-grow: 1;
}
<table>
<thead>
<tr>
<th>Heading 1</th>
<th>Heading 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Entry 1</td>
<td class="input"><span class="value" contenteditable="">10</span><span class="unit">kg</span></td>
</tr>
<tr>
<td>Entry 1</td>
<td class="input"><span class="value" contenteditable="">20</span><span class="unit">kg</span></td>
</tr>
</tbody>
</table>
Alternatively, you could use the after pseudo-selector to add the unit. Example:
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid black;
}
.value::after {
content: " kg";
}
<table>
<thead>
<tr>
<th>Heading 1</th>
<th>Heading 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Entry 1</td>
<td class="input"><span class="value" contenteditable="">10</span></td>
</tr>
<tr>
<td>Entry 1</td>
<td class="input"><span class="value" contenteditable="">20</span></td>
</tr>
</tbody>
</table>

Related

Copy ( to clipboard ) only one required column contents of html data table

My requirement is simple.
I have a table with four columns. Have some mobile numbers in 2nd column "Mobile No.". I just want to copy ( to clipboard ) All the mobile numbers in the "Mobile No." column on button click.
Tried some javascript samples for the same, not worked as required. Please give some suggestions.
<html>
<head>
<style>
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
</style>
</head>
<body>
<h2>HTML Table</h2>
<button id="copy-table-button" data-clipboard-target="#datatable"> Copy Mobile No. </button>
<table id="myTable">
<thead>
<tr>
<th>Sl No</th>
<th>Mobile No.</th>
<th>Name</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>1234567890</td>
<td>Maria</td>
<td>Active</td>
</tr>
<tr>
<td>2</td>
<td>2223330</td>
<td>Ruma</td>
<td>Active</td>
</tr>
<tr>
<td>3</td>
<td>3334440</td>
<td>Kumar</td>
<td>Not-Active</td>
</tr>
<tr>
<td>4</td>
<td>44455500</td>
<td>Subba</td>
<td>Active</td>
</tr>
<tr>
<td>5</td>
<td>555666111</td>
<td>Orayyo</td>
<td>Not-Active</td>
</tr>
<tr>
<td>6</td>
<td>555666111</td>
<td>Orayyo</td>
<td>Active</td>
</tr>
<tr>
<td>7</td>
<td>555666111</td>
<td>Orayyo</td>
<td>Not-Active</td>
</tr>
</tbody>
</table>
</body>
</html>
I just need to copy them as plain text, to paste in other websites or forms.
Should paste like this after copy..
1234567890
2223330
3334440
44455500
555666111
555666111
555666111
Thanks in advance.
This works for me, let me know if you have any troubles with it:
const copyButton = document.querySelector('#copy-table-button');
const copyToClipboard = (_) => {
const dataElements = document.querySelectorAll('tr > td:first-child + td');
const data = Array.from(dataElements).map(element => element.textContent).join('\n');
const blob = new Blob([data], {type: 'text/plain'});
const clipboardItem = new ClipboardItem({'text/plain': blob});
navigator.clipboard.write([clipboardItem]);
}
copyButton.addEventListener('click', copyToClipboard);

Applying CSS class to all rows but not the table heading

I am trying to apply a css style to change color of clicked rows of an HTML table. On the click event, I am adding the class (selected-row). Now, my table has a sorting functionality when clicking on the heading of each column. The heading gets colored which is not what I want. I want only rows but not the heading. So, I changed my style to (not first child). Now, the heading AND first row don't get color changed. I need only the heading to NOT change color and all other rows to change color when I add selected-row class.
.selected-row:not(:first-child) {
background-color: brown;
color: #FFF;
}
$("#example tr").click(function () {
$(this).addClass('selected-row').siblings().removeClass('selected-row');
});
If you mark up your table with a <thead> to contain the header row, and <tbody> to contain the data rows, you can specifically target only rows in the table body - like this in CSS:
tbody > tr { }
And like this in jQuery:
$('#example tbody > tr')...
Table mark-up:
<table>
<caption>This table contains...</caption>
<thead>
<tr>
<th>Heading</th>
<th>Heading</th>
</tr>
</thead>
<tfoot>
<tr>
<td>Total</td>
<td>$50</td>
</tr>
</tfoot>
<tbody>
<tr>
<td>Item 1</td>
<td>$20</td>
</tr>
<tr>
<td>Item 2</td>
<td>$30</td>
</tr>
</tbody>
</table>
One way to potentially do it would be to wrap your table header in <thead></thead> and body in <tbody></tbody> and then apply whatever selector as
$("#example tbody tr").click(function () {...});
You can target "td" tags:
$("#example tr td").click(function () {
$(this).parent().addClass('selectedrow').siblings().removeClass('selected-row');
If you are using "th" tags in your table:
<table style="width:100%">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
</table>
If you don't want to modify your header using the th or tbody tags, you could do something like this.
$("table tr:gt(0)").click(function(){
$(this).siblings().removeClass('selected-row');
$(this).addClass('selected-row');
})
You can see this working in this jsfiddle
Use th for the header row element.

Move and delete data from one table to another table using javascript or jquery

Step 1 : In table 1st table i want to copy table row the 2nd table, when click on the "copy" button after inputting the value in input text field.(value should be copied instead of input text field)
Step 2 : After click on the "copy" button the button should be change to "Undo" to remove the table row from 2nd table.
Step 3 : after deleting the row from 2nd table the button should be changed again to "copy" button with step 1 functionality in table 1.
Step 4 : the copied row in 2nd table should have "Delete" button.When click on the delete button the row should be deleted from 2nd table and the button should be changed again to"copy" button with step 1 functionality in table 1.
$(function() {
$('#myTable tbody tr').each(function(){
$(this).append('<td><button class="copy">Copy</button></td>');
});
$(document).on('click', 'button.copy', function(){
var $tr = $(this).parents('tr:first').clone();
$tr.appendTo($('#stopsTable > tbody'));
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div style="height: 700px;width: 100%;overflow: auto; float: left;">
<table id="myTable" border="1px" style="width: 24%; font-size: 10px; float :left;" >
<thead>
<tr>
<th>S No</th>
<th>Stop Name</th>
<th>Longitude</th>
<th>Latitude</th>
<th>ETA</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr >
<td >1</td>
<td>The Indian Heights School</td>
<td><input type="text" width="70"/></td>
<td>77.05249</td>
<td>06:06:12</td>
<td>Ignition_On</td>
</tr>
<tr >
<td >2</td>
<td>The Indian Heights School</td>
<td><input type="text" width="70"/></td>
<td>77.05246</td>
<td>06:06:23</td>
<td>Ignition_On</td>
</tr>
<tr >
<td >3</td>
<td>The Indian Heights School</td>
<td>28.56135</td>
<td>77.05242</td>
<td>06:06:31</td>
<td>Start</td>
</tr>
<tr >
<td >4</td>
<td>The Indian Heights School</td>
<td>28.56139</td>
<td>77.05245</td>
<td>06:06:41</td>
<td>Ignition_On</td>
</tr>
</tbody>
</table>
<table id="stopsTable" border="1px" style="width: 24%; margin-left: 10px; font-size: 10px; float :left;">
<thead>
<tr>
<th>S No</th>
<th>Stop Name</th>
<th>Longitude</th>
<th>Latitude</th>
<th>ETA</th>
<th>Status</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
jsfiddle or codepen example will be very appriciated.Thanks in advance.
not exactly what you wanted but might give you the idea.
Append button 'copy' to table #myTable
copy row from table #myTable to #stopsTable and append button remove while hiding button copy.
add class .remove to button remove with remove() function. (It will remove table row when clicking the remove button.)
$(function() {
$('#myTable tbody tr').each(function() {
$(this).append('<td><button class="copy">Copy</button></td>');
});
$(document).on('click', 'button.copy', function() {
var $tr = $(this).parents('tr:first').clone();
$tr.appendTo($('#stopsTable > tbody'));
$tr.append('<td><button class="remove">Remove</button></td>');
var $td = $('#stopsTable > tbody > tr').find('td:eq(6)').hide();
});
$(document).on('click', 'button.remove', function() {
$(this).closest('tr').remove()
});
});

TableSorter sorting empty input in Td

I'm testing tablesorter and my table is :
Table
It contains list of products and one product has 2 rows, one row contains its name and the other is the input field for the user to make changes.
I would like to do a tablesorter to sort the products with the empty input fields to the top of the table.
Table Expected Result
It means the products which don't have text in the input fields will be displayed on top.
I'm using tablesorter jquery.
my HTML Table: Tr1 holds first 'data' line, TR2 holds the input fields;
<table class="tablesorter">
<thead>
<tr>
<th class="sorter-inputs empty-top code">Code</th>
<th class="sorter-inputs empty-top designation">Designation</th>
</tr>
</thead>
<tbody>
<tr class='tr1'>
<td>
<div class='code'> </div>
</td>
<td>
<div class='designation'>abc 111</div>
</td>
</tr>
<tr class='tr2'>
<td>
<input type="text" class='CodeInput'/>
</td>
<td>
<input type="text" class='designationInput'/>
</td>
</tr>
...
</tbody> </table>
If you are using my fork of tablesorter, you have two options.
1) Leave out the input rows and use the editable widget, which actually makes the table cell editable using contenteditable. This does require a modern browser.
2) Use the input parser & set the emptyTo option to keep empty rows at the top (demo)
NOTE: the parser-input-select.js file used in the demo is actually pointing to the master branch of the repository.
HTML
<table class="tablesorter">
<thead>
<tr>
<th class="sorter-inputs empty-top code">Code</th>
<th class="sorter-inputs empty-top designation">Designation</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div> </div>
<input type="text" />
</td>
<td>
<div>abc 111</div>
<input type="text" />
</td>
</tr>
...
</tbody>
</table>
* Note *: I don't think using child rows will work in this case because the sort would occur based on the parent row content. So I added a <div> to each cell with the labels.
CSS
html { box-sizing: border-box; }
*, *:before, *:after { box-sizing: inherit; }
.code { width: 20%; }
.designation { width: 80%; }
input { width: 90%; margin: 4px; background: #fc7565; border: solid 1px #999; }
table { border-collapse: collapsed; border-spacing: 0; }
.tablesorter-blue tbody td { padding: 0; vertical-align: bottom; }
td div { background: #ccc; padding: 4px; }
Script
$(function () {
$('table').tablesorter({
theme: 'blue'
});
});

Resizable table columns with bz code

I've created a resizable table columns code by following bz's demo
But when I create more than 30 columns, the code does not work. The table I'm creating is pretty simple:
<table class="resizable" border="1">
<tr>
<td name="col1" align="center">Column 1</td>
<td name="col2" align="center">Column 2</td>
<td name="col3" align="center">Column 3</td>
<td name="col4" align="center">Column 4</td>
<td name="col5" align="center">Column 5</td>
<td name="col6" align="center">Column 6</td>
</tr>
</table>
Does anyone have any ideas which line should I change to make the code work?
Why not doing it on your own? Make a Table resizeable is pretty simple:
First add this to your onLoad:
$(".gridTableSeparator").bind("mousedown", function () {
var that = $(this).parent();
$("body").bind("mousemove", function (event) {
that.attr("width", event.pageX - that.offset().left);
});
$("body").bind("mouseup", function (event) {
$(this).unbind("mousemove mouseup");
});
});
Your table Header should look like this:
<td>
<div class="gridTableSeparator"></div>
<div class="gridTableHeadline">Tableheadline</div>
</td>
And format the separator and the headline like this:
.gridTableSeparator
{
width: 3px;
right:-4px;
height:40px;
float:right;
position:relative;
cursor: e-resize;
}
.gridTableHeadline
{
line-height: 40px;
overflow: hidden;
}
benefits of doing it on your own is that you have the full control and can change the look and functionality for your needs. Otherwise it would be great if you can post a fiddle, so we can see what went wrong if you add more than 30 rows.

Categories

Resources