This question already has answers here:
InnerHTML append instead of replacing
(3 answers)
Closed 6 years ago.
i've a div container and a button. Whenever i click the button, an empty textbox is added to the div. Now, my problem is whenever i click the button, the textbox is added, but the values of all others are removed.
The function is made like this:
function addTextBox() {
document.getElementById("txtList").innerHTML += "<input type='text'>";
}
I think it help you:
var child = document.createElement('input')
document.getElementById("txtList").appendChild(child);
You could achieve the same thing as the snippet below:
function addTextBox() {
var input = document.createElement("input");
input.type = "text"
document.getElementById("txtList").appendChild(input);
}
document.getElementById("addTxtBoxBtn").addEventListener("click",addTextBox);
<input type="button" id="addTxtBoxBtn" value="add TextBox"/>
<div id="txtList">
</div>
Why you can't achieve the same thing with innerHTML?
This happens because:
The Element.innerHTML property sets or gets the HTML syntax describing the element's descendants.
While the valueof an ipunt element is not an attribute of the element but a property (please have a look here).
If you want to check it in action, please try the following snippet:
function addTextBox() {
var txtList = document.getElementById("txtList");
console.log(txtList.innerHTML);
txtList.innerHTML += "<input type='text'/>" ;
}
document.getElementById("addTxtBoxBtn").addEventListener("click",addTextBox);
<input type="button" id="addTxtBoxBtn" value="add TextBox"/>
<div id="txtList">
</div>
What is happening under the hood here is that when you append the DOM as text using innerHTML you are simply rewriting that section of HTML. Editing your textList innerHTML will execute a new paint of that element and all information will be parsed again. This means you loose your user interaction.
To update your DOM elements successfully there are methods which enable you to do that. namely document.createElement and document.appendChild.
By appending the DOM element as opposed to concatenating the innerHTML(text) your are forcing a limited paint of the specific area. This leaves the rest of the DOM in tact.
Your code here
function addTextBox() {
document.getElementById("txtList").innerHTML += "<input type='text'>";
}
Becomes more like the following
function addTextBox() {
var textEl = document.getElementById("txtList");
var input = document.createElement("input");
input.type = 'text';
textEl.appendChild(input);
}
When you change append to innerHTML as a string, another string gets created (they are immutable). Browser than has to re-render the whole thing.
The other answers show appendChild, but since in your original question you used a string, maybe you want to keep doing so. If that's the case, you can use insertAdjacentHTML with 'beforeend' as first argument.
document
.getElementById('button')
.addEventListener('click', () => {
document.getElementById('txtList')
.insertAdjacentHTML('beforeend', '<input type="text">');
});
JSBin link is here.
Related
How to get the html of element itself using Jquery html. In the below code I would like get the input element inside div using JQuery as shwon below
<div id="content">content div</div>
<input type='text' id="scheduledDate" class="datetime" />
$(function() {
console.log($('#scheduledDate').html('dsadasdasd'));
$('#content').html($('#scheduledDate').html());
});
EDIT:
Can I get the $("#scheduledDate") as string which represent the real html code of the input box, because my final requirement is I want to pass it to some other SubView( I am using backboneJS) and eventually use that html code in a dust file.
My original requirement was to get that input field as string so that I can pass it to some other function. I know, if I keep it inside a DIV or some other container, I can get the html by using .html method of JQuery. I dont want use some other for that purpose. I am just trying to get html content of the input box itself using it's id.
If you want to move the input element into div, try this:
$('#content').append($('#scheduledDate'));
If you want to copy the input element into div, try this:
$('#content').append($('#scheduledDate').clone());
Note: after move or copy element, the event listener may need be registered again.
$(function() {
var content = $('#content');
var scheduledDate = $('#scheduledDate');
content.empty();
content.append(scheduledDate.clone());
});
As the original author has stated that they explicitly want the html of the input:
$(function() {
var scheduledDate = $('#scheduledDate').clone();
var temporaryElement = $('<div></div>');
var scheduleDateAsString = temporaryElement.append(scheduledDate).html();
// do what you want with the html such as log it
console.log(scheduleDateAsString);
// or store it back into #content
$('#content').empty().append(scheduleDateAsString);
});
Is how I would implement this. See below for a working example:
https://jsfiddle.net/wzy168xy/2/
A plain or pure JavaScript method, can do better...
scheduledDate.outerHTML //HTML5
or calling by
document.getElementById("scheduledDate").outerHTML //HTML4.01 -FF.
should do/return the same, e.g.:
>> '<input id="scheduledDate" type="text" value="" calss="datetime">'
if this, is what you are asking for
fiddle
p.s.: what do you mean by "calss" ? :-)
This can be done the following ways:
1.Input box moved to the div and the div content remains along with the added input
$(document).ready(function() {
var $inputBox = $("#scheduledDate");
$("#content").append($inputBox);
});
2.The div is replaced with the copy of the input box(as nnn pointed out)
$(document).ready(function() {
var $inputBox = $("#scheduledDate");
var $clonedInputBox = $("#scheduledDate").clone();
$("#content").html($clonedInputBox);
});
Div is replaced by the original input box
$(document).ready(function() {
var $inputBox = $("#scheduledDate");
$("#content").html($inputBox);
});
https://jsfiddle.net/atg5m6ym/4485/
EDIT 1:
to get the input html as string inside the div itself use this
$("#scheduledDate").prop('outerHTML')
This will give the input objects html as string
Check this js fiddle and tell if this is what you need
https://jsfiddle.net/atg5m6ym/4496/
I'm trying to allow users to edit the text of a paragraph in a website. I take a paragraph and replace the <p> tags with <textarea> tags using the .replaceWith() function. When I try to take the value of the textarea, it returns blank. Here's a JSfiddle.
HTML:
<p><a class="edit">Edit</a>I'm going to change this into a textarea field and retrieve the value.</p>
JS:
$(document).ready(function() {
$('.edit').hide();
var object = $('p');
object.on("mouseenter", function() {
$('.edit').show();
object.on('click','.edit',function(){
var oldText = object.text();
oldText = oldText.substr(4); // Exclude the word 'Edit'
object.replaceWith($("<textarea>").val(oldText).css("width",object.css('width')).css('height',object.css('height')));
var value = object.val();
alert("Value: "+value);
});
});
});
I'm a programming beginner, so if you have style or implementation tips, feel free to share. This is just my gut reaction to solving the problem; there may be a simpler way to accomplish the same thing.
EDIT: I should also mention that in my website, each paragraph comes from a database table that I'm displaying using an AJAX function. When the user is done editing, he can click a button, and the website will take the new value of the textarea field and UPDATE *table* SET *text*=newText WHERE *text* LIKE oldText;
Try just using contenteditable='true' instead of changing to a textarea. It will make the <p> editable.
Like this:
<p contenteditable='true'><a class="edit">Edit</a>
I'm going to change this into a textarea field and retrieve the value.</p>
If you want to make your text area editable when someone clicks 'Edit', you can create a function that sets the contenteditable attribute to true and then gives focus to the <p> element.
Your code is not trying to get the value of the <textarea>. Your call:
object.replaceWith( ... )
does not change the value of the variable "object" — it's still the jQuery object for the <p> tag, but after that it's out of the DOM. <p> tags don't have a "value" property.
It's almost always a bad idea to set up event handlers inside another event handler (well, an event handler for interaction events anyway). Event handlers accumulate, so each "mouseenter" event will add another "click" handler.
ckersch is right about an easier method being to use contenteditable, but if you're looking to a solution for your specific problem, change your selector from this:
var value = object.val();
To this:
var value = $("textarea").val();
Full code:
$(document).ready(function() {
$('.edit').hide();
var object = $('p');
object.on("mouseenter", function() {
$('.edit').show();
object.on('click','.edit',function(){
var oldText = object.text();
oldText = oldText.substr(4); // Exclude the word 'Edit'
object.replaceWith($("<textarea>").val(oldText).css("width",object.css('width')).css('height',object.css('height')));
var value = $("textarea").val();
alert("Value: "+value);
});
});
});
Fiddle
There are many ways you could make it more robust, including adding a class or id to your textarea, and then using it to be selected, such as this way:
object.replaceWith($("<textarea class='selectMe'>").val(oldText).css("width",object.css('width')).css('height',object.css('height')));
var value = $(".selectMe").val();
You are using the method replaceWith() wrong. The argument must be a string or a function that returns a string, not a jquery selector. Also, you should place the onclick event outside of the mouseenter event (this is valid for any event, never nest them)
$(document).ready(function() {
function makeTextarea(e) {
e.preventDefault();
var edit = $(e.currentTarget);
var parent = edit.parent();
edit.remove();
parent.replaceWith('<textarea>' + parent.text() + '</textarea>');
}
$('.edit').on('click', makeTextarea);
});
Fiddle: http://jsfiddle.net/U57v2/4/
"When the document is ready listen for clicks on .edit class. When clicked store a reference to the parent element (<p>) and then remove the edit element. Finally replace the parent element (<p>) with a textarea with the contents of the <p> element."
ckersh is absolutely right about the contenteditable, but if you're looking for a specific answer to your code, there are a few things you could improve.
There are a couple of issues with your code. First, you're rebinding the on('click') handler every time you mouse over the paragraph, so if you mouse over 5 times, you're executing the anonymous function 5 times. You only need to bind the on routine once. Second, the variable object never changes, so when you replace it with a textarea, you need a new selector to get the value.
I've updated your fiddle with the enhancements I've mentioned above. I also added a mouseleave event, because I figure you want to hide the "Edit" button when you leave the paragraph. The updated javascript can be seen below:
$(document).ready(function () {
$('.edit').hide();
var object = $('p');
object.on("mouseenter", function () {
$('.edit').show();
}).on("mouseleave", function () {
$('.edit').hide();
}).on("click", '.edit', function () {
var oldText = object.text();
oldText = oldText.substr(4); // Exclude the word 'Edit'
object.replaceWith($("<textarea>").val(oldText).css("width", object.css('width')).css('height', object.css('height')));
var value = $("textarea").val();
alert("Value: " + value);
});
});
This question already has answers here:
Escape quotes in JavaScript
(13 answers)
Closed 8 years ago.
this should be simple but I can't figure it out.
I want to let user edit a value. To do so, upon click, the value changes into a textbox. However, if the user puts a quote mark in the user input within the text box the value="" attribute of the text box closes prematurely and the quote mark and anything after it gets lost. Escape (deprecated) and encodeURI merely replace the quote mark with asci does which don't look good in the textbox.
Would appreciate anyone's solution to this problem:
Here is javascript:
function editText() {
var text = document.getElementById('text').innerHTML;
var edittext = '<input type="text" size=60 name="name" id="name" value="'+text+'"><input type="button" value="Save" onclick="storeText(\'name\');">';
document.getElementById('text').innerHTML = edittext
return false;
}
html:
Text: <span id="text" onclick="editText()";>He said "that's cool"</span>
jsfiddle
http://jsfiddle.net/2s9v2/6/
UPDATE:
Contrary to what those who marked this as a duplicate say, the duplicate question does not provide an answer to my question. They might want to re-read my question and the so-called duplicate and mentally register the word "programmatic" in my question and actually look at the code in the duplicate relaive to the code here.... Just saying.
I ended up changing the textbox to a textarea as a workaround as there does not seem to be a straightfoward way to programmatically escape a quote within a textbox.
The answer from Merlin below is a possible approach but calling the second function is more complex than just replacing textbox with textarea. In any case, I could not get that to work but I thank Merlin for his answer and upvoted it.
Try: text.replace(/"/g,""")
Ideally, though, you should be creating the elements with createElement, at which point you can do elem.value = text with no need for escaping.
Why not just set the value directly instead of rebuilding the input?
document.getElementById('name').value = edittext
Of course, this assumes that the input element with id=name already exists in your DOM, but I see no particular reason you could not ensure that it is already there (either writing directly in HTML or generating in Javascript on page load).
Update: It seems that the OP wants the element to be dynamically created in the onClick, by turning the text that is currently in a div into an input field with the contents of that div as its value.
I believe the following might do the trick, assuming id is unique as it should be.
function editText() {
var text = document.getElementById('text').innerHTML;
var edittext = '<input type="text" size=60 name="name" id="name" value="" /><input type="button" value="Save" onclick="storeText(\'name\');">';
document.getElementById('text').innerHTML = edittext;
document.getElementById('name').value = text;
document.getElementById('text').onclick = function() {}; //
return false;
}
Note that you will need to disable the onClick inside the above function as well, and then re-enable it inside storeText, because otherwise every click will cause extra buttons to be added.
Update 2: Here is a fully working example without parameter passing (for simplicity).
<html>
<body>
<script>
function editText() {
var text = document.getElementById('text').innerHTML;
var edittext = '<input type="text" size=60 name="name" id="name" value="" /><input type="button" value="Save" onclick="storeText();">';
document.getElementById('text').innerHTML = edittext;
document.getElementById('name').value = text;
document.getElementById('text').onclick = function() {};
return false;
}
function storeText() {
document.getElementById('text').innerHTML = document.getElementById('name').value;
document.getElementById('text').onclick = "editText();";
}
</script>
<div id="text" onclick="editText();">HelloWorld</div>
</body>
</html>
I am aiming to add a button to the screen through the click of another button.
I can successfully add them but they are blank (i.e, No text).
I tried setting the value with this technique:
addButton.setAttribute("value", "Click Me");
This failed, the strange thing is I was able to successfully set the
elements ID with the setAttribute function.
I then tried the following:
var x = document.getElementById("buttonId");
x.value="Click Me";
The above caused the button not to add at all.
Maybe I'm missing something but I can't think why the first method
wouldn't work.
Note: These buttons are all created on the fly so the standard:
<input type="button" value="click me"/>
won't suffice.
Any help appreciated.
function addButton(elementId, value, name, type) {
//Create an input type dynamically.
var element = document.createElement("input");
//Assign different attributes to the element.
element.type = type;
element.value = value; // Really? You want the default value to be the type string?
element.name = name; // And the name too?
var foo = document.getElementById(elementId);
//Append the element in page (in span).
foo.appendChild(element);
}
Try this.
Example fiddle: http://jsfiddle.net/kailashyadav/4Q8Fd/
Here is the code for a button, associated jsfiddle:
$('#createButton').on('click', function () {
var button = document.createElement('button');
button.innerHTML = 'hello';
button.setAttribute('type', 'button');
$('#placeForButton').html(button);
});
Note I set the innerHTML, because an input relies on a value attribute, a button relies on an open and closing HTML attribute. Therefore, the value in between the tags is what sets the button text. This translates into innerHTML.
I only used JQuery to bind an event to the button click.
My first SO question! Here's what I am trying to do:
I'm rewriting a tool that generates some code a user can paste directly into Craigslist and other classified ad posting websites. I have created a list of websites (they populate from a database with PHP) the user can choose from with a radio button, and I want their choice to populate as bare text (not a link) between some <p></p> elements in a textarea. I'm using jQuery for this.
Textarea before the user chooses:
<p id="thing"></p>
Textarea after the user chooses:
<p id="thing">www.somewebsite.com</p>
HTML
<input type="radio" name="sitechoice" value="www.websiteone.com">www.websiteone.com<br />
<input type="radio" name="sitechoice" value="www.secondwebs.com">www.secondwebs.com
<textarea>
Some stuff already in here
Here is the website you chose:
<p id="thing"></p>
More stuff already here.
</textarea>
JS
$(document).ready(function () {
$("input").change(function () {
var website = $(this).val();
alert(website);
$("#thing2").html(website);
});
});
JS Fiddle (With comments)
If you see the JS Fiddle, you can see that I put another p element on the page outside the textarea, and it updates just fine, but the one inside the textarea does not. I have read many other like questions on SO and I'm starting to think that I can't change an element that's between textarea tags, I can only change the entire textarea itself. Please, lead me to enlightenment!
You actually can fairly easily manipulate the text contents of the textarea like it is part of the DOM, by transforming its contents into a jQuery object.
Here is a jsFiddle demonstrating this solution: http://jsfiddle.net/YxtH4/2/
The relevant code, inside the input change event:
// Your normal code
var website = $(this).val();
$("#thing2").html(website);
// This turns the textarea's val into a jQuery object ...
// And inserts it into an empty div that is created
var textareaHtml = $('<div>' + $("#textarea").val() + '</div>');
// Here you can do your normal selectors
textareaHtml.find("#thing").html(website);
// And this sets the textarea's content to the empty div's content
$("#textarea").val(textareaHtml.html());
The empty div wrapping your HTML is so that you can easily retrieve it as a string later using jQuery's .html() method, and so the parse does not fail if additional text is entered around the p element inside the textarea.
The real magic is $($("#textarea").val()), which takes your textarea's text and parses it into an HTML node contained in a jQuery object.
It can't do it the way that you are thinking (i.e., manipulate it as if it were a DOM element), but it is still accessible as the value of the textarea, so you can retrieve it like that, use basic string manipulation to alter it, and then set the updated string as the new value of the textarea again.
Something like this . . . first give the <textarea> an id value:
<textarea id="taTarget">
Some stuff already in here
Here is the website you chose:
<p id="thing"></p>
More stuff already here.
</textarea>
Then alter your script like this:
$(document).ready(function () {
$("input").change(function () {
var website = $(this).val();
var currentTAVal = $("#taTarget").val();
$("#taTarget").val(currentTAVal.replace(/(<p id="thing">)([^<]*)(<\/p>)/, "$1" + website + "$3"));
});
});
Unless you need the <p> element in there, you might consider using a more simple placeholder, since it won't actually act as an HTML element within the textarea. :)
EDIT : Fixed a typo in the .replace() regex.
I know that this answer is a little bit late, but here it goes =)
You can do exactly the way you want to do. But for that, you need to implement a small trick.
by having this HTML
<input type="radio" name="sitechoice" value="www.websiteone.com">www.websiteone.com
<br />
<input type="radio" name="sitechoice" value="www.secondwebs.com">www.secondwebs.com
<p id="thing2"></p>
<textarea id="textarea">
<p id="thing"></p>
</textarea>
you can edit textarea content, as a DOM by implementing something like the function changeInnerText
$(document).ready(function () {
$("input").change(function () {
var website = $(this).val(); // Gets value of input
changeInnerText(website);
//$("#thing").html(website); // Changes
//$("#thing2").html(website); // Does not change
});
var changeInnerText = function(text) {
var v = $("#textarea").val();
var span = $("<span>");
span.html(v);
var obj = span.find("#thing")[0];
$(obj).html(text);
console.log(obj);
console.log(span.html());
$("#textarea").val(span.html());
}
});
As you can see, I just get the information from the textarea, I create a temporary variable span to place textarea's content. and then manipulate it as DOM.
Instead of attempting to insert the text into the <p> element, insert the text into <textarea> element and include the <p> tag. Something like this should do the trick:
Change:
$("#thing").html(website);
to:
$("textarea").html('<p id="thing">'+website+'</p>');
And here is a fiddle: http://jsfiddle.net/nR94s/