Selecting child elements with JS/jQuery - javascript

I've created a click to copy function so that users can click a button to copy the text content of another element. I've set this up so users can copy their serial number (which is generated dynamically from a shortcode - in Wordpress).
I had this working where the target container (that contains the text to be copied) was #copyTarget2 and the trigger button was #copyButton2. I then had this Javascript that was working:
<script>
document.getElementById("copyButton2").addEventListener("click", function() {
copyToClipboardMsg(document.getElementById("copyTarget2"), "msg");
});
document.getElementById("pasteTarget").addEventListener("mousedown", function() {
this.value = "";
});
function copyToClipboardMsg(elem, msgElem) {
var succeed = copyToClipboard(elem);
var msg;
if (!succeed) {
msg = "Copy not supported or blocked. Press Ctrl+c to copy."
} else {
msg = "Text copied to the clipboard."
}
if (typeof msgElem === "string") {
msgElem = document.getElementById(msgElem);
}
msgElem.innerHTML = msg;
setTimeout(function() {
msgElem.innerHTML = "";
}, 2000);
}
function copyToClipboard(elem) {
// create hidden text element, if it doesn't already exist
var targetId = "_hiddenCopyText_";
var isInput = elem.tagName === "INPUT" || elem.tagName === "TEXTAREA";
var origSelectionStart, origSelectionEnd;
if (isInput) {
// can just use the original source element for the selection and copy
target = elem;
origSelectionStart = elem.selectionStart;
origSelectionEnd = elem.selectionEnd;
} else {
// must use a temporary form element for the selection and copy
target = document.getElementById(targetId);
if (!target) {
var target = document.createElement("textarea");
target.style.position = "absolute";
target.style.left = "-9999px";
target.style.top = "0";
target.id = targetId;
document.body.appendChild(target);
}
target.textContent = elem.textContent;
}
// select the content
var currentFocus = document.activeElement;
target.focus();
target.setSelectionRange(0, target.value.length);
// copy the selection
var succeed;
try {
succeed = document.execCommand("copy");
} catch(e) {
succeed = false;
}
// restore original focus
if (currentFocus && typeof currentFocus.focus === "function") {
currentFocus.focus();
}
if (isInput) {
// restore prior selection
elem.setSelectionRange(origSelectionStart, origSelectionEnd);
} else {
// clear temporary content
target.textContent = "";
}
return succeed;
}
</script>
But now I've had to adjust the html so that I can dynamically display a 'NO VALID SERIAL NUMBER' message for any users who don't have an active serial number. This has meant that the element containing the text is different and is a child element of #copyTarget2.
What I need to know is:
Using the following screenshot from Console can anyone tell me the best way to keep the copy functionality and select the input container inside #copyTarget2?
I have already tried #copyTarget2 input, #copyTarget2.input to no avail.
Please bare in mind that my JS is using GetElementbyID() so simply replacing #copytarget2 with input[type="text"] won't work either.

change GetElementbyID to querySelector and try this selector
querySelector('input[name="_AFXSERIAL"]')

Either traverse the element you have by getElementsByTagName
document.getElementById('copyTarget2').getElementsByTagName('input')[0].value
or switch to querySelector
document.querySelector('#copyTarget2 input').value

If you want to experiment, you can try this Web API, https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent
This will help you remove the entire script you have written and will give you additional features as well like cut and paste.
Do check the compatibility chart though.
Also, putting the "#copyTarget2" to the input would have worked too.
DOM would have become,
<span>
<strong>
<input id="copyTarget2" />
</strong>
</span>

Related

How to keep extra fields added by js on refresh

var container = document.createElement("lastExp");
container.innerHTML = 'html code new form field';
document.getElementById("lastExp").appendChild(container);
It's simple i click button extra form field is added.
Question: When i refresh page how to not lose this extra fields on my form.
Stack Overflow is not the place to write code, but this will sits here in case someone besides OP need.
It's a minimal example--getting started--with localStorage. As I mentioned, under the hood, you have to append that element every time the page is loaded.
The snippet won't work here, unfortunately because the iframe is sandbox'd. Head over to my hub to experiment it.
var container = document.getElementById('container'),
toggle = document.getElementById('toggle');
element = null;
// initial check
init();
// add click event and listen for clicks
toggle.onclick = function() {
// both cases will update localStoage _inputIsThere
// if element is null -- doesn't exists, then add it
if (element == null) {
add();
} else {
// remove the element
remove();
}
}
// check if key exists in localStorage; this is where all the "magic" happens.
function init() {
var exists = localStorage.getItem('_inputIsThere');
if (exists && exists == 'true') {
add();
}
}
function remove() {
element.remove();
element = null;
// update key in localStorage to false
localStorage.setItem('_inputIsThere', false);
}
// adds the input and updates
function add() {
var e = document.createElement('input');
e.type = 'text';
element = e;
container.appendChild(e);
// update key in localStorage to true
localStorage.setItem('_inputIsThere', true);
}
<button id="toggle">Add/Remove</button>
<div id="container"></div>

Is there an efficient way to have a button automatically copy text to your clipboard? (JavaScript)

So I've read this entire post on how to copy text to a clipboard, and none of it seems to match what I'm looking for. How do I copy to the clipboard in JavaScript?
The program has several fields that are going to have text entered into them, that will then be copied and dropped into several other applications. I found a quick way to do this in IE, but it won't work in any other browser. Here's the HTML.
<SPAN ID="copytext" STYLE="height:150;width:162;background-color:pink">
This text will be copied onto the clipboard when you click the button below. Try it!
</SPAN>
<TEXTAREA ID="holdtext" STYLE="display:none;">
</TEXTAREA>
<BUTTON onClick="ClipBoard();">Copy to Clipboard</BUTTON>
And then here's the JavaScript.
<SCRIPT LANGUAGE="JavaScript">
function ClipBoard()
{
holdtext.innerText = copytext.innerText;
Copied = holdtext.createTextRange();
Copied.execCommand("Copy");
}
</SCRIPT>
The program can't have something like Zero Clipboard or Clippy, because it still needs to work if I put it on a different computer without those libraries. The best shot I've had was one on the link posted at the top of this article. It uses jQuery.
var copyTextareaBtn = document.querySelector('.js-textareacopybtn');
copyTextareaBtn.addEventListener('click', function(event) {
var copyTextarea = document.querySelector('.js-copytextarea');
copyTextarea.select();
try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
console.log('Copying text command was ' + msg);
} catch (err) {
console.log('Oops, unable to copy');}});
So that works great for one field, but everything I've ever learned about programming tells me not to repeat myself over and over again. ESPECIALLY if I'm only changing one thing every time I repeat it. Is there a better way to do this? Or is jQuery and repetition my only option at this point?
I used this recently
document.getElementById("copyButton").addEventListener("click", function() {
copyToClipboard(document.getElementById("hexVal"));
});
function copyToClipboard(elem) {
// create hidden text element, if it doesn't already exist
var targetId = "_hiddenCopyText_";
var isInput = elem.tagName === "INPUT" || elem.tagName === "TEXTAREA";
var origSelectionStart, origSelectionEnd;
if (isInput) {
// can just use the original source element for the selection and copy
target = elem;
origSelectionStart = elem.selectionStart;
origSelectionEnd = elem.selectionEnd;
} else {
// must use a temporary form element for the selection and copy
target = document.getElementById(targetId);
if (!target) {
var target = document.createElement("textarea");
target.style.position = "absolute";
target.style.left = "-9999px";
target.style.top = "0";
target.id = targetId;
document.body.appendChild(target);
}
target.textContent = elem.textContent;
}
// select the content
var currentFocus = document.activeElement;
target.focus();
target.setSelectionRange(0, target.value.length);
// copy the selection
var succeed;
try {
succeed = document.execCommand("copy");
} catch(e) {
succeed = false;
}
// restore original focus
if (currentFocus && typeof currentFocus.focus === "function") {
currentFocus.focus();
}
if (isInput) {
// restore prior selection
elem.setSelectionRange(origSelectionStart, origSelectionEnd);
} else {
// clear temporary content
target.textContent = "";
}
return succeed;
}
<input type="text" id="hexVal" />
<span id="copyButton">Copy</span>

Wordpress JS copy text script

I want to create a textarea where you can copy its contents to your clipboard. I found a script on this board that explains the code but im having a hard time getting it to work on wordpress. The button doesnt perform the action correctly, nothing copies to the clipboard. The only thing I did different was the tag on the text. The original script uses <input> and i used <textarea>. I have this JS script running on the page only. Its not attached to the theme.
JS
document.getElementById("copyButton").addEventListener("click", function() {
copyToClipboard(document.getElementById("copyTarget"));
});
function copyToClipboard(elem) {
// create hidden text element, if it doesn't already exist
var targetId = "_hiddenCopyText_";
var isInput = elem.tagName === "INPUT" || elem.tagName === "TEXTAREA";
var origSelectionStart, origSelectionEnd;
if (isInput) {
// can just use the original source element for the selection and copy
target = elem;
origSelectionStart = elem.selectionStart;
origSelectionEnd = elem.selectionEnd;
} else {
// must use a temporary form element for the selection and copy
target = document.getElementById(targetId);
if (!target) {
var target = document.createElement("textarea");
target.style.position = "absolute";
target.style.left = "-9999px";
target.style.top = "0";
target.id = targetId;
document.body.appendChild(target);
}
target.textContent = elem.textContent;
}
// select the content
var currentFocus = document.activeElement;
target.focus();
target.setSelectionRange(0, target.value.length);
// copy the selection
var succeed;
try {
succeed = document.execCommand("copy");
} catch(e) {
succeed = false;
}
// restore original focus
if (currentFocus && typeof currentFocus.focus === "function") {
currentFocus.focus();
}
if (isInput) {
// restore prior selection
elem.setSelectionRange(origSelectionStart, origSelectionEnd);
} else {
// clear temporary content
target.textContent = "";
}
return succeed;
}
HTML
<textarea type="text" id="copyTarget" class="">It's not that I'm so smart, it's just that I stay with problems longer.Albert Einstein</textarea>
<button id="copyButton" type="button" class="btn btn-primary">Copy & Share</button>

Storing document.getElementById in a variable?

I have this script that is supposed to change the text of the button when the button is clicked.
<body>
<button onclick="toggleText(this);" id="id">Edit</button>
</body>
function toggleText(element){
var text = document.getElementById(element.id).textContent;
if (text == 'Edit') {
text = 'Done';
} else {
text = 'Edit';
}
}
But it doesn't work. It only works when you put document.getElementById(element.id).textContent directly into the if statements.
How do I get the variable to store properly?
Since you already get the element, you don't need to get it again. You can just use element.
But the reason why you can't change it is that you're only changing the variable that contains the text. It does not point to the element's properties. You need to use this:
function toggleText(element){
var text = element.textContent;
if (text == 'Edit') {
element.textContent = 'Done';
} else {
element.textContent = 'Edit';
}
}
When you access document.getElementById(element.id).textContent you get the value of it, not the reference. So changes to it won't affect the element.
But when you assign element to variable, it gets reference to it.
var element = document.getElementById(element.id);
if (element.textContent == 'Edit') {
element.textContent = 'Done';
} else {
element.textContent = 'Edit';
}
Just use:
index.js
var mainText = document.getElementById("mainText").value;
document.write(mainText);
index.html
<textarea id="mainText"></textarea>
As tymeJV commented, you can store by reference the element you get by id. Its property is stored by value. Instead store the element in a variable and access its property from the variable.
var text = document.getElementById(element.id);
if (text.textContent == 'Edit') {
text.textContent = 'Done';
} else {
text.textContent = 'Edit';
}
Is jquery an option ?
I used to do something like :
var a = $('#theid');
A.something

CKeditor Inline: repeats paragraph ids

I have turned on allowedContent property in config.
config.allowedContent = "true"
This allows me to add ids to paragraphs inside contenteditable div.
However, now whenever I hit enter key inside the contenteditable div a new paragraph with same id is generated. I would assume after hiiting enter key a new paragraph should be inserted without any ids but it looks like the ids are copied from previously generated paragraph.
Is there any way to avoid this?
Try this. It's not bullet proof but works well enough. Even though I wrote it, I kind of hate it so if you improve on it, please share the love ;)
editor.on('key', function (evt) {
// Only if editor is not in source mode.
if (editor.mode === 'source') { return; }
// Enter is keyCode 13
if (evt.data.keyCode === 13) {
// if we call getStartElement too soon, we get the wrong element sometimes
setTimeout(function () {
var selection = editor.getSelection();
if (typeof selection === 'undefined') { return; }
var startElement = selection.getStartElement();
// If there are spans nested in the paragraph preserve them
// And we need to find the parent paragraph
// This could be optimized...
if (startElement.getName() == 'span') {
var text = "";
while (startElement.getName() == 'span') {
text += startElement.getHtml();
startElement = startElement.getParent();
}
if (text.length === 0) {
startElement.setHtml(' ');
} else {
startElement.setHtml(text);
}
}
// HERE I remove the "id" attribute.
startElement.removeAttribute("id");;
}, 10);
}
});

Categories

Resources