Change textarea into <li> element when done editing - javascript

I have the following code:
var counter=0;
function appendText(){
var text = $("#text").val();
if ( $("#text").val() ){
var textArea = "<div class='divex'> <textarea id='t"+counter+"'>"+text+"</textarea><button id='b"+
counter+"'name='t"+counter+"' >edit</button> <button onClick='moveUp()' id='updiv'>Up:></button></div>";
$("#text").val();
$("#addedText").after(textArea);
$("#t"+counter).clear;
$("#t"+counter).attr('readonly','readonly');
$("#b"+counter).bind('click',makeAreaEditable);
$("#text").val('');
counter++;
}
else{
}
};
var makeAreaEditable = function()
{
var target = event.target || event.srcElement || event.originalTarget;
var button = $("#"+target.id);
button.text("OK");
button.unbind('click');
button.bind('click',saveEdit);
var targetArea = $("#"+target.name);
targetArea.removeAttr('readonly');
};
var saveEdit = function()
{
var target = event.target || event.srcElement || event.originalTarget;
var button = $("#"+target.id);
button.text("edit");
button.unbind('click');
button.bind('click',makeAreaEditable);
var targetArea = $("#"+target.name);
targetArea.attr('readonly','readonly');
};
The html looks like this:
Add text
<div id="addedText" style="float:left">
</div>
I want to change this script so that : when i click the add text button - the text will be added as an li element when i click ok it will bring the textarea and at save back to li. Thanks!
I've done it! here is the final code:
var makeAreaEditable = function()
{
var liid = $(this).parent().find('li').attr('id');
var text = $("#"+liid).html();
var target = event.target || event.srcElement || event.originalTarget;
var button = $("#"+target.id);
button.text("OK");
button.unbind('click');
button.bind('click',saveEdit);
var targetArea = $("#"+target.name);
targetArea.replaceWith('<textarea>'+text+'</textarea>');
};
var saveEdit = function()
{
var target = event.target || event.srcElement || event.originalTarget;
var button = $("#"+target.id);
var textarea = $(this).parent().find('textarea');
var text = textarea.val();
button.text("edit");
button.unbind('click');
var targetArea = button.parent().find('textarea');
var textid = target.name;
targetArea.replaceWith("<li id='"+textid+"' style='list-style-type:none;'>"+text+"</li>");
};

Related

How to have a div open by a button closed by clicking off when there are multiple buttons?

I have several buttons on my site that call a script to open the content into full screen and I also want to be able to click off the created div to close it. This works but after opening one container, which is deleted after, my program produces errors trying to click another button.
function closeDiv(evt) {
const maindiv = document.getElementById('div3');
let targetElement = evt.target;
do {
if (targetElement == maindiv.childNodes[1]) {
return;
}
targetElement = targetElement.parentNode;
} while (targetElement);
var viewpost = maindiv.childNodes[1];
viewpost.parentNode.removeChild(viewpost);
maindiv.classList.remove('viewcontainer');
};
function buttonClick(button) {
var div = button.parentElement.parentElement;
var clone = div.cloneNode(true);
var element = div.childNodes;
var username = element[1].innerText;
var title = element[7].innerText;
var contenttext = div.childNodes[3].value;
var clone = document.createElement('div');
clone.classList.add('viewcontainercon');
var viewuser = document.createElement('p');
viewuser.classList.add('viewcontaineruser');
var text = document.createTextNode(username);
viewuser.appendChild(text);
clone.appendChild(viewuser)
var viewtitle = document.createElement('p');
viewtitle.classList.add('viewcontainertitle');
var text = document.createTextNode(title);
viewtitle.appendChild(text);
clone.appendChild(viewtitle);
var viewcontent = document.createElement('p');
viewcontent.classList.add('viewcontainercontent');
var text = document.createTextNode(contenttext);
viewcontent.appendChild(text);
clone.appendChild(viewcontent);
document.getElementById('div3').classList.add('viewcontainer');
document.getElementById('div3').appendChild(clone);
document.addEventListener("click", function(event){
var isClickInside = button.contains(event.target);
if (!isClickInside) {
closeDiv(event);
}
});
}
The error is specifically `viewpost is undefined' in the closeDiv() function, which is strange since that shouldn't be called until after the click. Any ideas?

focus is not working on textarea

I am creating a page in which a user can add a question and its solution, he can delete the problem and can also edit it dynamically using DOM in javascript. I want that whenever user clicks on edit button the textbox which appears get autofocus.
This the javascript code of my page...
var questionText;
var answerText;
var questionArray=[];
var answerArray=[];
var i=0;
var j=10000;
function addProblem(){
var body = document.getElementsByTagName('body')[0];
questionText = document.getElementById('questionId').value;
answerText = document.getElementById('answerId').value;
questionArray.unshift(questionText);
answerArray.unshift(answerText);
var myContainer = document.getElementById('container');
var myDiv = document.createElement("div");
var questionLogo = document.createElement("p");
questionLogo.id = "questionLogo";
var textNode = document.createTextNode("Question:");
var question = document.createElement("p");
question.id = "question";
var questionDetail = document.createTextNode(questionArray[0]);
var deleteButton = document.createElement("button");
deleteButton.innerHTML = "Delete";
deleteButton.id = i;
var editButton = document.createElement("button");
editButton.innerHTML = "Edit";
editButton.id = j;
var answerLogo = document.createElement("p");
answerLogo.id = "answerLogo"
var ansTextNode = document.createTextNode("Answer: ");
var answer = document.createElement("p");
answer.id = "answer";
var answerDetail = document.createTextNode(answerArray[0]);
var mybr = document.createElement("br");
if(i==0){
myContainer.appendChild(myDiv);
myDiv.appendChild(questionLogo);
questionLogo.appendChild(textNode);
questionLogo.appendChild(question);
question.appendChild(questionDetail);
myDiv.appendChild(answerLogo);
answerLogo.appendChild(ansTextNode);
answerLogo.appendChild(answer);
answer.appendChild(answerDetail);
answerLogo.appendChild(mybr);
myDiv.appendChild(deleteButton);
myDiv.innerHTML += ' ';
myDiv.appendChild(editButton);
}
else if (i > 0)
{
myContainer.insertBefore(myDiv,myContainer.firstChild);
myDiv.appendChild(questionLogo);
questionLogo.appendChild(textNode);
questionLogo.appendChild(question);
question.appendChild(questionDetail);
myDiv.appendChild(answerLogo);
answerLogo.appendChild(ansTextNode);
answerLogo.appendChild(answer);
answer.appendChild(answerDetail);
answer.appendChild(mybr);
myDiv.appendChild(deleteButton);
myDiv.innerHTML += ' ';
myDiv.appendChild(editButton);
}
i++;
j++;
myDiv.childNodes[7].addEventListener("click", function(){
var deleteElement = document.getElementById(this.id);
deleteElement.parentNode.parentNode.removeChild(deleteElement.parentNode);
});
myDiv.childNodes[9].addEventListener("click",function(){
var editElement = document.getElementById(this.id);
var quesEdit = editElement.parentNode.childNodes[1];
var quesEditText = quesEdit.innerHTML;
var ansEdit = editElement.parentNode.childNodes[4];
var ansEditText = ansEdit.innerHTML;
var editDiv1 = document.createElement("div");
editDiv1.id = "editDiv1"
var quesTextArea = document.createElement("textarea");
quesTextArea.innerHTML += quesEditText;
quesTextArea.focus();
var saveButton1 = document.createElement("button");
saveButton1.innerHTML = "Save";
editDiv1.appendChild(quesTextArea);
editDiv1.innerHTML += ' ';
editDiv1.appendChild(saveButton1);
quesEdit.parentNode.replaceChild(editDiv1,quesEdit);
var editDiv2 = document.createElement("div");
editDiv2.id = "editDiv2"
var ansTextArea = document.createElement("textarea");
ansTextArea.innerHTML += ansEditText;
var saveButton2 = document.createElement("button");
saveButton2.innerHTML = "Save";
editDiv2.appendChild(ansTextArea);
editDiv2.innerHTML += ' ';
editDiv2.appendChild(saveButton2);
ansEdit.parentNode.replaceChild(editDiv2,ansEdit);
});
}
I have tried to focus the textarea using
quesTextArea.focus();
but its not working where questextArea is the name of the textarea. Please help how i can do it.
For the element could be got focused, it must be in the DOM when you invoke focus on it. You should invoke focus function after replaceChild function
editDiv1.appendChild(quesTextArea);
editDiv1.appendChild(saveButton1);
quesEdit.parentNode.replaceChild(editDiv1,quesEdit);
quesTextArea.focus();
I've created a simple sample as below link, you could check it
https://jsfiddle.net/pd9c6c7a/3/
Add autofocus attribute to the textarea element. So that whenever it is appended to the DOM, will get cursor activated in it.
The 'textarea' has not been added to window to be shown, an element must be part of the document object tree. In case that didn't work, add a 50ms delay.
setTimeout(function(){e.focus();}, 50);
Try the following approach:
var body=document.getElementsByTagName('body')[0];
var quesTextArea=document.createElement("textarea");
var button=document.createElement("button");
button.innerHTML = "click Me";
button.addEventListener("click",function(e){
e.preventDefault();
quesTextArea.focus();
});
body.appendChild(quesTextArea);
body.appendChild(button);
<html>
<body>
<body>
</html>
Try to add preventDefault.
var div = document.getElementById('parent');
var txt = document.createElement('textarea');
div.appendChild(txt);
txt.focus();
<html>
<head></head>
<body>
<div id="parent">
<input type="text" value="" />
</div>
</body>
</html>
The element must be in the DOM when you invoke the focus function. Move your focus() function after the appendChild() is invoked.
quesTextArea.innerHTML += quesEditText;
var saveButton1=document.createElement("button");
saveButton1.innerHTML="Save";
editDiv1.appendChild(quesTextArea);
quesTextArea.focus();

Javascript: How to implement the "enter/return key" to save a value?

Sorry, I am not really good with JS.
The code is essentially the user double clicks on the text, textbox appears, changes text, and saves a new value. However, I want the user to be able to also click enter to save the new value.
In addition, if possible, to have a dedicated "Save" button to save the new value and "discard" to keep the old value.
Also, if I double click many times, the text appears as "(input type="text")". Is there a way to remove that?
Please help if you can.
The HTML + JS code
<html>
<head>
<script type="text/javascript">
window.onload = function() {
var elements = getElementsByClassName('text-edit', '*', document);
for(var i = 0; i < elements.length; i++) {
elements[i].ondblclick = function() {
this.setAttribute('oldText', this.innerHTML); // not actually required. I use this just in case you want to cancel and set the original text back.
var textBox = document.createElement('INPUT');
textBox.setAttribute('type', 'text');
textBox.value = this.innerHTML;
textBox.onblur = function() {
var newValue = this.value;
this.parentNode.innerHTML = newValue;
}
this.innerHTML = '';
this.appendChild(textBox);
}
}(i);
}
function getElementsByClassName(className, tag, elm) {
var testClass = new RegExp("(^|\\s)" + className + "(\\s|$)");
var tag = tag || "*";
var elm = elm || document;
var elements = (tag == "*" && elm.all) ? elm.all : elm.getElementsByTagName(tag);
var returnElements = [];
var current;
var length = elements.length;
for(var i = 0; i < length; i++) {
current = elements[i];
if(testClass.test(current.className)) {
returnElements.push(current);
}
}
return returnElements;
}
</script>
</head>
<div><span class="text-edit">Some text</span></div>
</html>
The snippet below allows you to modify the value of a textbox using save button or enter key and discarding any changes using cancel button.
<!-- HTML -->
<h1 id="editable">Lorem Ipsum</h1>
// JavaScript
window.onload = function(){
var h1 = document.getElementById('editable');
h1.onclick = function(){
var old = this;
var input = document.createElement("INPUT");
input.type = "text";
input.value = this.innerHTML;
input.onkeyup = function(e){
var code = (e.keyCode ? e.keyCode : e.which);
if(code == 13) {
old.innerHTML = input.value;
input.parentNode.replaceChild(old, input);
save.parentNode.removeChild(save);
cancel.parentNode.removeChild(cancel);
}
};
this.parentNode.replaceChild(input, this);
var save = document.createElement("INPUT");
save.type = "button";
save.value = "Save";
(function(old, input){
save.onclick = function(){
old.innerHTML = input.value;
input.parentNode.replaceChild(old, input);
this.parentNode.removeChild(this);
cancel.parentNode.removeChild(cancel);
};
})(old, input);
input.parentNode.insertBefore(save, input.nextSibling);
var cancel = document.createElement("INPUT");
cancel.type = "button";
cancel.value = "Cancel";
(function(old, input){
cancel.onclick = function(){
input.parentNode.replaceChild(old, input);
this.parentNode.removeChild(this);
save.parentNode.removeChild(save);
};
})(old, input);
input.parentNode.insertBefore(cancel, input.nextSibling);
};
};
Working jsBin

How to access elements(inputs, selects) of a dynamic form

I am having a dynamic form which creates fields dynamically by pressing "+" button.
This form is not binded in the document but generated when we click the + button.
I need to access the form values, how do I achieve that.
what should I use form "get" or "post" .
I have tried by using formdata object or jQuery serialize() but with no success or actually I couldn't figure out a way how to use it correctly .
JSFIDDLE LINK :
code:
HTML :
<body>
<div id="main1">
<input type="button" onclick="addSelectBox ()" name="clickme" value="+" />
<input type="button" onclick="removeSelect();" value="-" />
<input type="button" onclick="xmlData();" value="XML" />
</div>
<form id="autoPopulation_form" method='post'>
<div id="main"></div>
<input type="submit" />
</form>
</body>
JS :
var selele = 0;
var brindex = 0;
function addSelectBox() {
selele = selele + 1;
var spantag = document.createElement("span");
spantag.setAttribute("id", selele);
var parentDiv = document.getElementById("main");
var selectElement = document.createElement("select");
var selectElement1 = document.createElement("select");
var selectElement2 = document.createElement("select");
var selectElement3 = document.createElement("select");
var textbox = document.createElement('input');
textbox.setAttribute("name", "text" + selele);
var arr = new Array("Stocks", "MutualFunds");
var arr2 = new Array("individual", "401k", "IRA");
var arr3 = new Array("contains", "equals");
var arr4 = new Array("scrapedaccounttype", "scrapedtransactiontype");
for (var i = 0; i < arr.length; i++) {
var option = new Option(arr[i]);
selectElement.options[selectElement.options.length] = option;
selectElement.setAttribute("name", "tag" + selele);
}
for (var i = 0; i < arr2.length; i++) {
var option = new Option(arr2[i]);
selectElement1.options[selectElement1.options.length] = option;
selectElement1.setAttribute("name", "acctType" + selele);
}
for (var i = 0; i < arr3.length; i++) {
var option = new Option(arr3[i]);
selectElement2.options[selectElement2.options.length] = option;
selectElement2.setAttribute("name", "compare" + selele);
}
for (var i = 0; i < arr4.length; i++) {
var option = new Option(arr4[i]);
selectElement3.options[selectElement3.options.length] = option;
selectElement3.setAttribute("name", "match_name" + selele);
}
spantag.appendChild(selectElement);
spantag.appendChild(selectElement1);
spantag.appendChild(selectElement2);
spantag.appendChild(selectElement3);
spantag.appendChild(textbox);
parentDiv.appendChild(spantag);
linebreak();
};
function removeSelect() {
var parentDiv = document.getElementById("main");
var removetg = document.getElementById(selele);
if (selele != 1) {
parentDiv.removeChild(removetg);
selele = selele - 1;
} else {
parentDiv.removeChild(removetg);
parentDiv.innerHTML = "";
selele = selele - 1;
}
removeBreak();
};
function linebreak() {
brindex = brindex + 1;
var brtag = document.createElement("br");
brtag.setAttribute("id", brindex);
var parentDiv = document.getElementById("main");
parentDiv.appendChild(brtag);
};
function linespace() {
var myElement = document.createElement("span");
myElement.innerHTML = "&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp";
var parentDiv = document.getElementById("main");
parentDiv.appendChild(myElement);
};
function removeBreak() {
var myElement = document.getElementById(brindex);
var parentDiv = document.getElementById("main");
brindex = brindex - 1;
parentDiv.removeChild(myElement);
};
function xmlData() {
xmlDoc = loadXMLDoc("data.xml");
newel = xmlDoc.createElement("edition");
x = xmlDoc.getElementsByTagName("span")[0];
x.appendChild(newel);
};
window.onload = function () {
$( "autoPopulation_form" ).on( "submit", function( event ) {
event.preventDefault();
console.log( $( this ).serialize() );
});
};
You are going to find this funny, but your code is fine exept that your selector is wrong when serializing. You forgot the # because you are selecting an ID. Check your updated Fiddle here: http://jsfiddle.net/veritas87/3542N/8/
window.onload = function () {
$( "#autoPopulation_form" ).on( "submit", function( event ) {
event.preventDefault();
console.log( $( this ).serialize() );
});
};
I'm going to take a guess here that you are trying to access them from within Javascript.
If that is the case, the easiest way to give the elements a unique id.
var selectElement = document.createElement("select");
selectElement.id = "select_0";
var selectElement1 = document.createElement("select");
selectElement1.id = "select_1";
var selectElement2 = document.createElement("select");
selectElement1.id = "select_2";
var selectElement3 = document.createElement("select");
selectElement1.id = "select_3";
var desiredSelect = document.getElementById("select_3");
You can also give them a name property, in which case you can access them through the form element, or document.getElementsByName. Just be aware the second one will return an array of items, or null.

How to create dynamic instances of JQueryTE text editor

I am attempting to create a small program that incorporates dynamically created instances of this editor.
I have it working except for the ability to create a button that opens/closes the editor.
jsFiddle of what I've got so far.
"use strict";
$(document).ready(function() {
var createPad = $("#createPad").click(function () {
var body = document.getElementById("body");
var editorNumberCounter = 1;
var toggleOnOffCounter= 1;
var editorName = '.'+ (editorNumberCounter++);
var status = document.createElement('div');
status.className = "status";
status.id = "status";
var editorName= document.createElement('span');
editorName.className = "status";
editorName.id = "status";
$(body.appendChild(status));
$(body.appendChild(editorName));
var toggle = status.id + toggleOnOffCounter++;
$(editorName).jqte();
// settings of status
var jqteStatus = true;
$(toggle).click(function()
{
jqteStatus = jqteStatus ? false : true;
$(editorName).jqte({toggle : jqteStatus})
});
});
});
I made up some changes to your code an now seems to work.
I try to explain them point by point:
variabiles editorNumberCounter and toggleOnOffCounter must be globally scoped or you lose the incremented value
ID of elements (dynamically created or not) MUST be unique, so I create the div and span element considering the counter
for dynamically created elements you must use the bind method or the event will not be bind
the toggle property not exist! You must use the status property
the element onto JQTE is binded is get as next element after the clicked element
Code:
var editorNumberCounter = 0;
var toggleOnOffCounter = 0;
$(document).ready(function () {
var createPad = $("#createPad").click(function () {
var body = document.getElementById("body");
var editorName = '.' + editorNumberCounter++;
toggleOnOffCounter++;
var status = document.createElement('div');
status.className = "status";
status.id = "div_status" + editorNumberCounter;
var editorName = document.createElement('span');
editorName.className = "status";
editorName.id = "span_status" + editorNumberCounter;
$(body.appendChild(status));
$(body.appendChild(editorName));
$(editorName).jqte();
// settings of status
var jqteStatus = true;
$("#div_status" + editorNumberCounter).bind("click",function () {
jqteStatus = jqteStatus ? false : true;
$(this).next().jqte({
status: jqteStatus
})
});
});
});
Here is a working fiddle: http://jsfiddle.net/IrvinDominin/UfhNQ/14/

Categories

Resources