I have a simple table:
Column A | Column B
--------------------
A | Item1
B | Item2
C | Item3
I want to make the first column non-copyable. When user selects table rows and presses Ctrl+C, he should get just
Item1
Item2
Item3
but not
A Item1
B Item2
C Item3
I tried -moz-user-select: none; -webkit-user-select: none; user-select: none;
but it doesn't work. Text is not being selected but still copied. It is working in Firefox but not in Chrome and Opera.
SOLUTION which works for me: It's still flickering and slightly modifing row height because of height() being not accurate but it is OK for me.
$(document).on('copy', function(e) {
if (navigator.userAgent.indexOf("Firefox")==-1) {
var nonCopyable = $('.nonCopyable:not(.empty)');
nonCopyable.each(function(index,el) {
var $el = $(el);
if ( $el.hasClass('empty') ) {
return;
}
var width = $(el).width();
var height = $(el).height();
$el.data('content', $el.html()).css({"width" : width+'px', "height": height + 'px'} ).html('');
}).addClass('empty');
setTimeout(function() {
nonCopyable.each(function(index,el) {
$(el).html($(el).data('content')).removeClass('empty').css({"width":'auto', height:'auto'}).data('content',null);
}); });
}
} );
.nonCopyable {
-moz-user-select: none;
-webkit-user-select: none;
user-select: none;
}
Off course if you have more than just text and images in non-copyable cell such as event handlers, your need another workaround.
I'm not sure if this fits your needs (because of incompatibility with Internet Explorer) but one option is to use ::before
/::after
pseudo-elements to generate the first column content and prevent it from being selected/copied.
Also to follow DRY principle, we can use data-*
attributes to define the contents and then use attr()
expression to assign that to the pseudo-elements.
table > tbody td:first-child::before {
content: attr(data-content);
}
table > thead th:first-child::before {
content: attr(data-content);
}
<table>
<thead>
<tr>
<th data-content="Column A"></th>
<th>Column B</th>
</tr>
</thead>
<tbody>
<tr>
<td data-content="This"></td>
<td>
Item #1
</td>
</tr>
<tr>
<td data-content="is"></td>
<td>
Item #2
</td>
</tr>
<tr>
<td data-content="a"></td>
<td>
Item #3
</td>
</tr>
<tr>
<td data-content="demo"></td>
<td>
Item #4
</td>
</tr>
</tbody>
</table>
I've figured out a rather crazy solution to this problem. When you detect a Ctrl+C keydown event, you can completely hide the left column, which removes it from the selection (at least it does that in Firefox 36.0.1, IE11, Safari 5.1.7, and Chrome 41), and set a timeout to re-show the column immediately. The end result is the copy operation gets just the text in the right column. The user might see a weird little flicker as the left column disappears and then reappears, but I'm finding that it's not noticeable most of the time.
$(document).keydown(function(e) {
if (e.ctrlKey && e.keyCode == 67) {
$('.cellNumber').hide();
setTimeout(function() { $('.cellNumber').show(); });
} // end if
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table border="1">
<tr><td class="cellNumber">Column A</td><td>Column B</td></tr>
<tr><td class="cellNumber">A</td><td>Item1</td></tr>
<tr><td class="cellNumber">B</td><td>Item2</td></tr>
<tr><td class="cellNumber">C</td><td>Item3</td></tr>
</table>
It should also be noted that this only works for a Ctrl+C keypress. You could extend it to also work for the Cmd+C keypress for Mac users, but that still wouldn't cover other means of copying, such as mouse right-click-Copy, and menubar Edit-Copy.
Edit: Awesome! I just discovered that you can actually use the copy event to get all of the above methods of copying:
$(document).on('copy', function(e) {
$('.cellNumber').hide();
setTimeout(function() { $('.cellNumber').show(); });
} );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table border="1">
<tr><td class="cellNumber">Column A</td><td>Column B</td></tr>
<tr><td class="cellNumber">A</td><td>Item1</td></tr>
<tr><td class="cellNumber">B</td><td>Item2</td></tr>
<tr><td class="cellNumber">C</td><td>Item3</td></tr>
</table>
This works on every browser/system I've tested (Firefox, Chrome, and Safari on Mac, and Firefox, Chrome, Safari, and IE on Windows) and every method of copying (mouse, menubar, and Ctrl+C/Cmd+C).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With