I’m a beginner, so I apologize if I’m missing something obvious.
I’m trying to write a simple web app. When you type text into a textarea and click a button, a “card” (div) is created with that textarea’s value as its innerText. When you click on a card, its innerText is then copied to the clipboard.
It works when I write out the function this way:
el.setAttribute(
"onclick",
"console.log(navigator.clipboard.writeText(this.innerText));"
);
But if I write out the function separately and call it when setting the attribute, undefined is copied to the keyboard:
el.setAttribute("onclick", "copyText()");
I’d stick with the first, working option, except for two things:
Primarily I’m just trying to learn, so avoiding difficulties because I don’t understand them doesn’t really make sense.
I want to add more lines of code to the copyText() function so that it works on mobile devices, too. Can I even do that the first way?
Here’s my code in full:
const app = document.getElementById("app");
function createCard() {
let input = document.getElementById("textarea").value;
if (input == "") {
console.log("You must enter text to create a card.");
} else {
const el = document.createElement("div");
el.innerText = document.getElementById("textarea").value;
el.setAttribute("class", "item card");
el.setAttribute("onclick", "copyText()");
app.appendChild(el);
document.getElementById("textarea").value = "";
}
}
function copyText() {
navigator.clipboard.writeText(this.innerText);
}
I expected it to work exactly the same as the following, but it doesn’t. It returns undefined.
const app = document.getElementById("app");
function createCard() {
let input = document.getElementById("textarea").value;
console.log(input);
if (input == "") {
console.log("You must enter text to create a card.");
} else {
const el = document.createElement("div");
el.setAttribute("class", "item card");
el.setAttribute(
"onclick",
"console.log(navigator.clipboard.writeText(this.innerText));"
);
el.innerText = document.getElementById("textarea").value;
app.appendChild(el);
document.getElementById("textarea").value = "";
}
}
I suspect it’s an issue with “this” and scope, but I can’t figure it out. Sorry again—I know this is very much a beginner’s question. Thanks for your help.
Calling copyText() calls it without a this context. You would need to use
el.setAttribute("onclick", "copyText.call(this)");
// ideally also pass the event object:
el.setAttribute("onclick", "copyText.call(this, event)");
However, the best practice is to install an event handler function instead of using the onclick attribute, so you should do
el.onclick = copyText;
// or
el.addEventListener("click", copyText);
Notice these refer to the copyText function that is in scope, it doesn't need to be a global variable.
const input = document.getElementById("textarea");
const app = document.getElementById("app");
function createCard() {
console.log(input.value);
if (!input.value) {
console.log("You must enter text to create a card.");
} else {
const el = document.createElement("div");
el.className = "item card";
el.onclick = function() {
console.log(navigator.clipboard.writeText(this.textContent));
};
el.textContent = input.value;
app.appendChild(el);
input.value = "";
}
}
Related
I'm having this little bump in a function, normally if the variable "receivedRDB" is undefined in the DOM, it is dynamically created in a form and if it is defined it takes the value of another variable "receivedR". But "receivedRDB" keeps being created, even when it is already defined in the DOM.
var receivedRDB = document.getElementsByName('receivedR')[0];
if (typeof receivedRDB !== "undefined") {
receivedR = JSON.parse(receivedRDB.value.split(",").slice(0));
} else {
receivedR = [];
}
if (typeof receivedRDB !== "undefined") { //never detected
receivedR.push(toRemoveR);
receivedRDB.value = JSON.stringify(receivedR).replace(/"\[\\|\\"]|\\"/g, "");
} else { //problematic part
event.preventDefault();
receivedR.push(toRemoveR);
var input = document.createElement("input");
input.type = "hidden";
input.name = "receivedR";
input.value = JSON.stringify(receivedR);
rForm.appendChild(input);
}
Here's a solution based on the fact that getElementsByName is a "live" list
Anywhere in your code you can put
var receivedRDB = document.getElementsByName('receivedR');
then change your code to
if (receivedRDB.length !== 0) {
receivedR.push(toRemoveR);
receivedRDB[0].value = JSON.stringify(receivedR).replace(/"\[\\|\\"]|\\"/g, "");
} else {
event.preventDefault();
receivedR.push(toRemoveR);
var input = document.createElement("input");
input.type = "hidden";
input.name = "receivedR";
input.value = JSON.stringify(receivedR);
rForm.appendChild(input);
}
I guess <script> tag which uses receivedRDB appears earlier than the DOM (in <head> for example). If so, there is more than one way to solve.
<script defer>
add an attribute defer to the <script> tag will make the JavaScript code be run after DOM is loaded
window.onload = function(){ /* ... */ }
window.onload will be called after DOM is loaded.
window.addEventListener('load', function(){ /* ... */ })
More compatible one (more than one function can be called individually)
If not the problem please include the minimal code to reproduce the problem.
function shortDescription(a){
var descriptionInput;
var tbl = $(document.getElementById('21.125-mrss-cont-none-content'));
tbl.find('tr').each(function () {
$(this).find("input[name$='6#if']").keypress(function (e) {
if (e.which == 13) {
descriptionInput = $(this).val();
$(this).val(descriptionInput);
$(document.getElementById('__AGIM0:U:1:4:2:1:1::0:14')).val(descriptionInput);
}
console.log(descriptionInput);
});
});
});
}
This code works perfectly but how do I write this in pure JavaScript? I'm mainly interested in this: How do I perform these tasks without jQuery?
for each row, find the input name that ends in 6#if (the column I want)
on enter, get this input value and add to the console it so I know it's there
input id = "grid#21.125#1,6#if" type="text" value"" name="grid#21.125#1,6#if
oninput = shortDescription(this);
It would be great if you could share a piece of HTML on wich we could try some things, but for the moment, here's what your code looks like written in pure JS :
var descriptionInput;
var tbl = document.getElementById('21.125-mrss-cont-none-content')
Array.from(tbl.getElementsByTagName('tr')).forEach(function(tr) {
Array.from(tr.querySelectorAll("input[name$='6#if']")).forEach(function(input) {
input.onkeypress = function(e) {
if (e.keyCode == 13) {
descriptionInput = input.value;
input.value = descriptionInput; // why ??
document.getElementById('__AGIM0:U:1:4:2:1:1::0:14').value = descriptionInput;
}
console.log(descriptionInput);
}
});
});
If you're not OK with the querySelectorAll, you can use getElementsByTagName, it returns a NodeList that you can turn into an array with the Array.from method and the use filter on the name to find the input with a name containing "6#if".
Best practices ...
Since an ID is unique and the methods getElementsByTageName or getElementsByTagName returns a Live HTMLCollection, it's better if you use these elements as unique variables, so you won't ask your browser to fetch them many times.
Since I don't know what your elements means, I will name the variables with trivial names, here's a better version of the code :
var descriptionInput;
var tbl = document.getElementById('21.125-mrss-cont-none-content');
var tr1 = tbl.getElementsByTagName('tr');
var el1 = document.getElementById('__AGIM0:U:1:4:2:1:1::0:14');
var inputsInTr = Array.from(tr1).map(function(tr) {
return Array.from(tr.getElementsByTagName('input'));
}).reduce(function(pv, cv) {
return pv.concat(cv);
});
var myInputs = inputsInTr.filter(function(input) {
return input.name.indexOf('6#if') != 0;
});
myInputs.forEach(function(input) {
input.onkeypress = function(e) {
if (e.keyCode == 13) {
descriptionInput = input.value;
el1.value = descriptionInput;
}
console.log(descriptionInput);
}
});
I didn't try it, hope it's OK.
Hope it helps,
Best regards,
I am very new to JS, but am trying to create a checkbox that when checked will reveal a div with an id of "second_row", and when unchecked will hide it (unchecked by default). Am I missing some code? Is my syntax incorrect? I could really use some help. Thanks for givin a newbie a hand!
Html:
<input type="checkbox" name="under_18" id="under_18" class="check" value="under_18" form="contest_form" onclick="parentsCheck()" />
JavaScript:
<script>
function parentsCheck()
{
var check1 = document.getElementById('under_18'),
if (check1.checked === true) {
document.getElementById('second_row').style.display = 'block';
}
else if (check1.checked === false) {
document.getElementById('second_row').style.display = 'none';
}
}
</script>
P.S. Dont know if it matters, but the checkbox is in a table cell.
Your , at the end of the var statement should be a ;.
It's causing a SyntaxError, causing the JavaScript block to be effectively ignored, so parentsCheck() is never defined.
var check1 = document.getElementById('under_18');
http://jsfiddle.net/tYv28/
As an aside, check1.checked will always return a boolean, so you don't need to do the === true and === false comparison; the following will work just fine:
function parentsCheck()
{
var check1 = document.getElementById('under_18');
if (check1.checked) {
document.getElementById('second_row').style.display = 'block';
} else {
document.getElementById('second_row').style.display = 'none';
}
}
When using event handler attributes, JavaScript only recognizes functions in the global scope. Try defining the event handler in your JavaScript, which also has the benefit of being unobtrusive:
var el = document.getElementById('under_18');
el.onclick = parentsCheck; // <---- This
jsFiddle
Also, you need to change the , into a ;.
How do i get a javascript code to only execute or be used once? example is
var stringToMatch = 'christopher';
function toggle (){
var input = document.getElementById('text').value;
if (input == stringToMatch){
document.getElementById('divColor1').style.display = 'block';
}
else {
document.getElementById('divColor1').style.display = 'none';
}
}
this code or stringToMatch i want to execute once, after that i dont care if it is deleted in the sense. for this is for coupons. and i am making multiples of this, so once someone has typed this i want it to delete
If I got you right, you could overwrite toggle() with an empty function.
if (input == stringToMatch){
document.getElementById('divColor1').style.display = 'block';
window.toggle = function() { };
}
I am trying to debug this (incomplete) script, but it is behaving inconsistently. The main problem is when I click off of an item, sometimes the $(editObj).removeAttr('style'); runs and sometimes not. Through the Chrome inspector I can see that the editObj variable in each case is properly defined, but it isn't always getting its inline style attribute removed. Sometimes, and sometimes not. Cannot determine the reason.
I'm a bit out of my element with this code. Maybe something about it is obvious; Regardless I'd appreciate some ideas on why this sort of unpredictable might be occuring!
var editObj = null;
var inputType = 'text';
var input = '#textEdit';
var formId = '#form_undefined'
$(function() {
$("#textEdit").click(function(event) {
event.stopPropagation();
});
$('body').click(function(event) {
if (editObj){
//textedit contents to editobj and
if (inputType == 'text'){
$(editObj).text($("#textEdit").val());
}
$("#textEdit").removeAttr('style').hide();
$(editObj).removeAttr('style');
var previewId = $(editObj).attr('id');
var formId = previewId.replace('bzm', 'form');
$("#" + formId).val($("#textEdit").val());
//ajax modify database
editObj = null;
}
});
$(".editable").not("video, img, textarea")
.click(function(event) {
event.stopPropagation();
loadEditor($(this));
});
});
function loadEditor(element){
$("#textEdit")
.copyCSS(element)
.offset($(element).offset())
.css("display", "block")
.val($(element).text())
.select();
$(element).css("color", "transparent");
editObj = element;
}
I've had trouble in the past with .removeAttr('style'); not actually removing all the inline styles.
Use
$(editObj).attr('style', '');
instead of
$(editObj).removeAttr('style');
I dint see any code that initializes e editobj variable.. May be Im missing Anthony.. Anyways what are the chances of the edit obj being null.. Just put a log statement in the click function to always log ur editobj and see if it is null smtimes