Copy paste element test tool
by Hugo Carneiro
HTML
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
<div class="container">
<div class="alert alert-primary" role="alert">
Paste using CMD/CTRL + V
</div>
<hr>
</div>
<div id="container" class="container">
<div class="element" data-id="1">
<div class="placeholder-screen">
<p>
Copying
</p>
</div>
<small>Element 1</small>
<p>
Click me and copy me with CMD/CTRL + C
</p>
</div>
<div class="element" data-id="2">
<div class="placeholder-screen">
<p>
Copying
</p>
</div>
<small>Element 2</small>
<p>
Click me and copy me with CMD/CTRL + C
</p>
</div>
</div>
<hr>
<div id="settings" class="container">
<h3>
Tweak delay of pasting
</h3>
<p>
This will simulate an API response time.
</p>
<div class="slidecontainer">
<input type="range" min="0" max="10000" value="130" class="slider" id="timeDelayRange">
<input type="text" value="130" class="fomr-control" id="timeDelay">
</div>
</div>
<div class="toast toast-copy" role="alert" aria-live="assertive" aria-atomic="true" data-delay="2000" style="position: fixed; bottom: 15px; right: 50%; margin-right: -102px;">
<div class="toast-header">
<strong class="mr-auto">Copied</strong>
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="toast-body">
Your element was copied.
</div>
</div>
SCSS
.element {
position: relative;
display: flex;
align-items: center;
justify-content: center;
flex-flow: column wrap;
border: 1px solid rgba(51, 51, 51, 0.2);
padding: 15px;
margin: 15px 0;
cursor: pointer;
p {
margin: 0;
}
&.active {
border: 1px solid rgba(#F3D5B1, 0.5);
background: rgba(#F3D5B1, 0.4);
}
.placeholder-screen {
display: none;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1;
background-image: linear-gradient(45deg,rgba(#F3D5B1,1) 25%,transparent 25%,transparent 50%,rgba(#F3D5B1,1) 50%,rgba(#F3D5B1,1) 75%,transparent 75%,transparent);
border: 2px solid #F3D5B1;
background-size: 1rem 1rem;
animation: progress-stripes 1s linear infinite;
}
&.placeholder {
border: 1px solid rgba(#F3D5B1, 0.5);
.placeholder-screen {
display: flex;
align-items: center;
justify-content: center;
p {
margin: 0;
background: #fff;
padding: 6px 12px;
}
}
}
}
hr {
margin: 50px 0;
}
.container {
.alert {
margin-top: 15px;
}
hr {
margin: 15px 0;
}
}
#settings {
.slider {
-webkit-appearance: none;
width: 100%;
height: 25px;
background: #d3d3d3;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
&:hover {
opacity: 1;
}
&::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 25px;
height: 25px;
background: #4CAF50;
cursor: pointer;
}
&::-moz-range-thumb {
width: 25px;
height: 25px;
background: #4CAF50;
cursor: pointer;
}
}
}
@keyframes progress-stripes {
0% { background-position: 1rem 0; }
100% { background-position: 0 0; }
}
JavaScript
let selectedElementId;
let copiedElementId;
let timeDelay = 130;
let acceptableTimeWithoutUI = 300;
function insertAfterSelected($copiendElement) {
$('#container').find(`[data-id="${selectedElementId}"]`).removeClass('active').after($copiendElement);
// Fake endpoint response time
setTimeout(function() {
$copiendElement.removeClass('placeholder').addClass('active');
selectedElementId = $copiendElement.data('id');
}, timeDelay);
}
function appendElement() {
$('#container').append($copiendElement);
// Fake endpoint response time
setTimeout(function() {
$copiendElement.removeClass('placeholder').addClass('active');
selectedElementId = $copiendElement.data('id');
}, timeDelay);
}
function onKeyDown(evt) {
const key = evt.keyCode;
const isControlOrCommand = evt.ctrlKey || evt.metaKey;
// CTRL + C
if (isControlOrCommand && key === 67) {
if (!selectedElementId) {
return;
}
$('.toast-copy').toast('show');
copiedElementId = selectedElementId;
}
// CTRL + V
if (isControlOrCommand && key === 86) {
if (!copiedElementId) {
return;
}
// Processing copied element
const length = $('#container').find('.element').length;
const $copiendElement = $('#container').find(`[data-id="${copiedElementId}"]`).clone();
const elementText = $copiendElement.find('small').html();
$copiendElement.attr('data-id', length + 1).addClass('active').find('small').html(`Copy of ${elementText}`);
// Checks if loading UI needs to be added
if (timeDelay > acceptableTimeWithoutUI) {
$copiendElement.removeClass('active').addClass('placeholder');
}
// Insert element
if (selectedElementId) {
insertAfterSelected($copiendElement);
} else {
appendElement($copiendElement);
}
}
}
$(document)
.on('click', '.element', function() {
$('.element.active').not($(this)).removeClass('active');
$(this).toggleClass('active');
if...