why document.execCommand('copy') doesnt copy here? - javascript

There is a list that when i search colors it opens, i want to copy the color name when i click on the list item, the color name is in a input[type=hidden] but i cant copy the value of the input. execCommand('copy') works fine with input[type=hidden].
link to codepen but you will not get the list because i used ajax for getting colors.
sorry if code is messy, i'm learning!
codepen
function copy(event) {
var alertColorBox = document.querySelector('.alertCopy .color');
alertColorBox.style.backgroundColor = event.target.style.backgroundColor;
var alert = document.querySelector('.alertCopy');
alert.classList.remove('alertAnimation');
var alert_span = document.querySelector('.alertCopy span');
// my question code part
var input = event.target.querySelector('input');
input.select();
document.execCommand('copy');
// my question code part
alert_span.innerHTML = input.value;
alert.classList.add('alertAnimation');
setTimeout(removeAlert, 5000);
}

I was with the same problem some time ago. Your code probably will work on Firefox, but on Chromium not.
What I have to do is remove the type="hidden" of the inputs, the I gave then a position="absolute" and "top: -1000px";
This isn't the best way to do that, but works. The inputs will not be visible anymore (on the screen), but the browser will copy the content.
I made this class to simplify:
.inputToHide {
opacity: 0;
padding: 0;
margin: 0;
position: absolute;
top: -1000px;
}
Ps.: Try to indent your code to be easier to understand
==========================================================
EDIT
If you can control your HTML, set a data-color in your div with contain the name of the color, then in the function you just need to create a input, append in the body then copy the content, something like this:
var colorInput = document.createElement('input');
colorInput = colorName.getAttribute('data-color');
document.body.appendChild(colorInput);
colorInput.select();
document.execCommand("copy");
document.body.removeChild(colorInput);
This is a better option after all

Related

How do I access the user selected text within an element ui input?

I want to access the text within an ElInput component via Javascript in Electron. According to mozilla it is impossible to access information within an html input or textfield via window.getSelection.
I unsuccessfully tried to access the selection with the proposed selectionStart
const input = document.getElementById("input")
alert(input.selectionStart.toString)
Given that this doesn't work, what do I have to do, to get the text in my selection within my el-input?
<input value="try to select some of the text" onclick="console.log(this.value.substring(this.selectionStart, this.selectionEnd))"/>
You can use .native event handlers as described in Vue.js + Element UI: Get "event.target" at change, and then selectionStart/End of the underlying HTML element will work:
var Main = {
data() {
return {
input: 'Select something.'
}
},
methods: {
dothing(event) {
let elem=event.target;
console.log(elem.value.substring(elem.selectionStart,elem.selectionEnd));
}
}
}
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')
<script src="//unpkg.com/vue/dist/vue.js"></script>
<script src="//unpkg.com/element-ui#2.13.0/lib/index.js"></script>
<div id="app">
<el-input v-model="input" #mouseup.native="dothing"></el-input>
</div>
Checkout this short video I have made from the ELInput link you provided, the explanation in general is:
Without seeing your html is a bit hard, but I am guessing you don't even have an input with an id of 'input' which is what your javascript code is querying for:
const input = document.getElementById("input")
Looking at the html on the ElInput link you have provided, those inputs have a class of el-input__inner, you can select the input by class with
const input = document.getElementsByClass("el-input__inner")
but this will return an array of elements, you need to make sure you are selecting the one you need (you can select by Id if you have actually added an id tag to the input element, also this is the reason you see a [1] in the video, it is selecting the element in that position of the array).
from there you can select your text inside the input element, and from javascript get the range of the selection with: input.selectionStart and input.selectionEnd
Having those you can now get the substring with input.value.substr(input.selectionStart, input.selectionEnd) and from there do whatever you need with the text.
Based on this answer: How to get selected text from textbox control with javascript you can use Document.querySelectorAll() to get all elements you need. You can use class names, ids or tag names and so on. Then iterate over them with forEach and add the EventListener you need. Inside the forEach loop you can do whatever you like with any given element
UPDATE
Unfortunately the first solution did not work in Firefox. (see further down) This solution should work in more browsers.
var mySpecialSelect = function(element){
element.addEventListener('mouseup', function () {
let startPos = element.selectionStart;
let endPos = element.selectionEnd;
let field_value = element.value;
let selectedText = field_value.substring(startPos,endPos);
if(selectedText.length <= 0) {
return; // stop here if selection length is <= 0
}
// log the selection
console.log(selectedText);
// you can use "element" or "this" to do whatever like toggle a class name
element.classList.toggle('used-this-element');
});
};
var textAreaElements = document.querySelectorAll('textarea');
[...textAreaElements].forEach(mySpecialSelect);
var inputElements = document.querySelectorAll('input');
[...inputElements].forEach(mySpecialSelect);
textarea,
input {
border: solid 2px gray;
}
input {
display: block;
width: 100%;
}
.used-this-element {
border: solid 2px orange;
}
<textarea rows="4" cols="50">Select some text from here and check the console</textarea>
<textarea rows="4" cols="50">Another text Box, Select some text from here and check the console</textarea>
<input type="text" value="Select or change this value">
First solution (hidden in the "Show code snippet") unfortunately window.getSelection() did not work in Firefox. I'll keep this solution here just because maybe someday it will work and then this would be the nicer solution.
var mySpecialSelect = function(element){
element.addEventListener('mouseup', function () {
if(window.getSelection().toString().length <= 0) {
return; // stop here if selection length is <= 0
}
// log the selection
console.log(window.getSelection().toString());
// you can use "element" or "this" to do whatever like toggle a class name
element.classList.toggle('used-this-element');
});
};
var textAreaElements = document.querySelectorAll('textarea');
[...textAreaElements].forEach(mySpecialSelect);
var inputElements = document.querySelectorAll('input');
[...inputElements].forEach(mySpecialSelect);
textarea,
input {
border: solid 2px gray;
}
input {
display: block;
width: 100%;
}
.used-this-element {
border: solid 2px orange;
}
<textarea rows="4" cols="50">Select some text from here and check the console</textarea>
<textarea rows="4" cols="50">Another text Box, Select some text from here and check the console</textarea>
<input type="text" value="Select or change this value">

Content Editable Div, appending HTML causing issue. Every text typed after programatically appending HTML gets added to the last HTML tag

I am trying to make a content editable div that can be used to generate message templates for an app. Users can append placeholders for fields like names to a template by hitting a button. The placeholders can be removed by hitting an 'x' on them as well. Here's the working snippet.
var removePlaceholder = function(e){
e.parentNode.parentNode.removeChild(e.parentNode);
}
var appendPlaceHolder = function(field){
var e = document.getElementById("t");
e.innerHTML += ('<span class="tag">{'+field+'}<span onclick=removePlaceholder(this) class="remove">x</span></span>')
}
.tag {
background-color : blue;
color : white;
}
.remove {
color : red
}
<div id="t" contenteditable="true">Hello</div>
<button onclick=appendPlaceHolder("first_name")>Add first name</button>
The contenteditable part works just fine. But after I've added a placeholder using my appendPlaceHolder function, everything I type seem to get appended to the last inserted HTML element.
How can I prevent this. I have closed the tag properly. Is there any way to change this behaviour.
To recreate issue, run the snippet and hit the "Add First Name" Button, then continue typing in the area.
Update
Have added image to explain the situation
What you can do is add a space after the placeholder has been appended:
JavaScript
var removePlaceholder = function(e){
e.parentNode.parentNode.removeChild(e.parentNode);
}
var appendPlaceHolder = function(field){
var e = document.getElementById("t");
e.innerHTML += ('<span class="tag">{'+field+'}<span onclick=removePlaceholder(this) class="remove">x</span></span> ')
}
Note: The which has been added at the end of the span just creates a space.
Live Example
JSFiddle

Why in textarea value attribute is different from JS value

Initially I was trying to change the look of a textarea when it was empty with just CSS. I thought this would work, but as you can see when writing something and clicking the button, the values are different. Does anyone know of a solution for doing this width CSS or JS is required? Could that be possible with an input??
var area = document.querySelector("textarea");
var btn = document.querySelector("button");
btn.addEventListener("click", function() {
var value = area.value;
var attr_value = area.getAttribute("value");
alert("value: " + value + "\nattr value: " + attr_value);
});
textarea {
background: red;
transition: background 0.5s ease;
}
textarea[value=""] {
background: gray;
}
<textarea value="Here I am"></textarea>
<br>
<button>Click me!</button>
Textarea HTML elements do not have a value attribute. Their value is their inner text content.
Thus, the value property will always fetch the correct input value.
getAttribute("value") will fetch the value of the textarea's value attribute, if you give it one. But since this attribute is non-standard on textarea elements, you ought not to use it, anyway.
:)
A solution for your initial question is probably to use a little js snippet, since I couldn't get it to work with :empty either.
http://jsfiddle.net/ciscoheat/hvo3h8vz/
var area = document.querySelector("textarea");
area.addEventListener("input", function() {
if(area.value) area.classList.add('has-content');
else area.classList.remove('has-content');
});

jQuery++, problems on .selection()

everybody.
I have a little problem; I'm trying to build a WYSIWYG, but I encountered some problems.
I have a contenteditable div with id = desc2, and some buttons. Let's take, for example, the button "bold".
<div class="magic" magic_id="desc2">
<div class="magicbutton one" magic="[b]%s[/b]">
<span style="font-weight:bold;">Bold</span>
</div>
</div>
And I have some jQuery++ selection application in:
$('#desc2').on('mouseup', function() {
var selection = $(this).selection(),
text = $(this).text().substring(selection.start, selection.end);
console.log(text);
});
I have erased the other part of the script, because if I manage to get this to work, I'm done :D
So, as I was saying, if I do this, everything is good: I sleect a part on the div and on the console is outputted the content.
But this is not what I want to do. I wrote this:
$('.magicbutton.uno').on('click', function(){
var id = $(this).parent().attr("magic_id");
var selection = $("#"+id).selection(),
text = $("#"+id).text().substring(selection.start, selection.end);
console.log(text);
});
Everytime I click, it takes the ID of the div to change and should output the selected text, but it doesn't.
The code is the same, and i checked that $(this) in the first script is the same as $("#"+id) in the second.
What can I do? Thanks!
EDIT: jsFiddle
When DIV loses focus, selection is nullified. As a workaround, you could use data object:
DEMO
$('.magicbutton.one').on('click', function(){
var id = $(this).parent().attr("magic_id"); //id = desc2, i used this because i could have multiple forms in a page
var selection = $("#"+id).data('selection');
alert(selection);
}); //This doesn't work
$('#desc2').on('mouseup', function() {
var selection = $(this).selection(),
text = $(this).text().substring(selection.start, selection.end);
$(this).data('selection', text);
});

javascript changing tag attributes not being executed in the right order?

I have an html file that consists of a table with fields inside. Some fields are marked by xxx, which should be converted to textareas. That has been successfully done as:
function raplace() {
var replaced = $("body").html().replace(/xxx/g,'<textarea class="textarea" id=0 style="width: 100%; height: 100%; min-height:3em; box-sizing: border-box; resize: none; border:none"></textarea>');
$('body').html(replaced);
}
The task is now to assign a name attribute that should be for the first textarea name="text1", for the second area name="text2" and so on.
To accomplish this I purposely set id=0 for all text areas, as you can see form the code above. I have tried to accomplish the goal by using this code:
var i=1;
while (document.getElementById('0')) {
//$('#0')[0].name = 'text'+i;
//$('#0')[0].id = i;
document.getElementById("0").name = "text" + i;
document.getElementById("0").id = i;
//document.getElementById("0").setAttribute("name","text"+i);
//document.getElementById("0").setAttribute("id",i);
i++;
As you may know, all three codes above are working and do the same thing. However, here comes the big problem.
When i put the code into the browser console, it does as expected, changing name and id attributes perfectly. However, if the code is put into my file, it only generates the textareas, setting all id=0. The second part of the script (to change the attribute values) is not executed. I have been looking all over the web for many days now, and have resorted to ask here at stack overflow. It If anyone can help me out, it would be amazing. Thanks!!!
NOTE: the first part needs to be executed first, or otherwise you would not have an id to target.
EDIT: After cleaning up the code a bit, here is what I have. If anyone knows why the second part does not execute, please let me know. Thanks!
function raplace() {
var replaced = $("body").html().replace(/xxx/g,'<textarea class="replacement" style="width: 100%; height: 100%; min-height:3em; box-sizing: border-box; resize: none; border:none"></textarea>');
var replacements = document.getElementsByClassName('replacement');
var txtArea;
for (var i = 0; i < replacements.length; i++) {
txtArea = replacements[i];
txtArea.id = "text" + i;
txtArea.name = "text" + i;
}
$('body').html(replaced);
}
There are a couple of bad practices at play here that may be mucking with your solution:
Your ID's do not begin with a letter. See: What are valid values for the id attribute in HTML?
You have multiple elements with the same ID.
One suggestion is to use a class to target your elements, e.g.
'<textarea class="textarea replacement"' // etc
then..
var replacements = document.getElementsByClassName('replacement'),
txtArea;
for (var i = 0; i < replacements.length; i++) {
txtArea = replacements[i];
txtArea.id = "text" + i;
txtArea.name = "text" + i;
}

Categories

Resources