Reputation: 2441
I'm having trouble when I append an element inside a div
and is that all the values from my inputs (including selected options) get cleared as is shown here:
As you can see when I click the button "Añadir tecla", the text from the textbox and the selected option "Shift" goes back to default option that is "Flechas de movimiento".
Why this happens and how can I avoid it?
My code is the next:
var controls = [{value: "flechas", text: "Flechas de movimiento"}, {value: "letras", text: "Letras (WASD)"}, {value: "enter", text: "Enter"}, {value: "control", text: "Ctrl"}, {value: "alt", text: "Alt"}, {value: "espacio", text: "Espacio"}, {value: "der", text: "Click derecho"}, {value: "izq", text: "Click izquierdo"}, {value: "mover", text: "Mover el ratón"}, {value: "shift", text: "Shift"}, {value: "customkey", text: "Especificar tecla"}];
function addControl(e)
{
e.appendChild(getControlSelect());
}
function getControlSelect()
{
var select = document.createElement('select'),
option,
i = 0,
il = controls.length,
html = document.createElement('div'),
text = document.createElement('input'),
delbtn = document.createElement('input');
text.type = "text";
delbtn.type = "button";
delbtn.value = "-";
for (; i < il; ++i)
{
option = document.createElement('option');
option.setAttribute('value', controls[i].value);
option.appendChild(document.createTextNode(controls[i].text));
select.appendChild(option);
}
html.innerHTML += "<b>Tecla</b><br>";
html.appendChild(select);
html.innerHTML += "<br><b>Acción</b><br>";
html.appendChild(text);
html.appendChild(delbtn);
return html;
}
HTML Code:
<div>
<input type="button" value="Añadir tecla" onclick="addControl(this.parentNode)" />
</div>
As you can see, when I click "Añadir tecla" I call addControl function with the parentNode as unique parameter (this will used later for append the child inside it).
So, I don't know where is the problem, I think everything is correct, but It need something to avoid the values get cleared.
EDIT: The code I shared hasn't problems, but my complete code has here:
var controls = [{value: "flechas", text: "Flechas de movimiento"}, {value: "letras", text: "Letras (WASD)"}, {value: "enter", text: "Enter"}, {value: "control", text: "Ctrl"}, {value: "alt", text: "Alt"}, {value: "espacio", text: "Espacio"}, {value: "der", text: "Click derecho"}, {value: "izq", text: "Click izquierdo"}, {value: "mover", text: "Mover el ratón"}, {value: "shift", text: "Shift"}, {value: "customkey", text: "Especificar tecla"}],
skippedIndexes = [],
sep = "<div class='sep' id='firstsep' style='width: 200px;'></div>",
oldIndex = 0;//,
//sInd = 0;
function addControl(e)
{
if(e.lastChild.className != "sep") e.innerHTML += sep;
e.appendChild(getControlSelect());
e.innerHTML += sep.replace(" id='firstsep'", "");
}
function onSelectChange(e)
{
//Modify the array
//a = e.associatedInput
//console.log(e.dataset.i);
/*var newIndex;
newIndex = e.selectedIndex;
if(skippedIndexes.length > 0 && skippedIndexes.indexOf(oldIndex) > -1) skippedIndexes.splice(skippedIndexes.indexOf(oldIndex), 1); //Delete oldIndex
if(skippedIndexes.length > 0 && skippedIndexes.indexOf(newIndex) == -1) skippedIndexes.push(newIndex);
oldIndex = newIndex;*/
//Change associated
}
function deleteFirstSep()
{
if(!document.getElementById("firstsep").nextSibling) document.getElementById("firstsep").remove();
}
function getControlSelect()
{
var select = document.createElement('select'),
option,
i = 0,
il = controls.length,
html = document.createElement('div'),
text = document.createElement('input'),
delbtn = document.createElement('input'),
ascinpt = document.createElement('input'),
html1 = document.createElement('div');
html1.style.display = "inline-block";
text.type = "text";
text.name = "accion[]";
text.style.width = "158px";
delbtn.type = "button";
delbtn.setAttribute('onclick', 'var e = this.parentNode;e.nextSibling.remove();e.remove();deleteFirstSep();');
delbtn.value = "-";
delbtn.style.padding = "0 5px";
delbtn.style.marginLeft = "5px";
delbtn.style.position = "relative";
delbtn.style.top = "-20px";
delbtn.style.left = "2px";
ascinpt.name = "tecla[]";
ascinpt.type = "hidden";
select.id = "htmlkey";
select.dataset.associatedInput = ascinpt;
//select.dataset.i = sInd;
//sInd++;
select.setAttribute("onchange", "onSelectChange(this)");
for (; i < il; ++i)
if(skippedIndexes.indexOf(i) == -1)
{
option = document.createElement('option');
option.setAttribute('value', controls[i].value);
option.appendChild(document.createTextNode(controls[i].text));
select.appendChild(option);
}
html1.innerHTML += "<b>Tecla</b><br>";
html1.appendChild(select);
html1.innerHTML += "<br><b>Acción</b><br>";
html1.appendChild(text);
html.appendChild(html1);
html.appendChild(delbtn);
return html;
}
.sep {
border-top: 4px dashed #A4A4A4;
margin: 15px 0 15px 0;
}
<div>
<input type="button" value="Añadir tecla" onclick="addControl(this.parentNode)" />
</div>
Upvotes: 3
Views: 1270
Reputation: 288080
The problem is that you overwrite the HTML code
element.innerHTML += newHTML;
This gets rid of the state of the current elements, including event listeners, input values, checkedness, etc.
Instead, you should use appendChild
or insertAdjacentHTML
:
element.insertAdjacentHTML('beforeend', newHTML);
var controls = [{value: "flechas", text: "Flechas de movimiento"}, {value: "letras", text: "Letras (WASD)"}, {value: "enter", text: "Enter"}, {value: "control", text: "Ctrl"}, {value: "alt", text: "Alt"}, {value: "espacio", text: "Espacio"}, {value: "der", text: "Click derecho"}, {value: "izq", text: "Click izquierdo"}, {value: "mover", text: "Mover el ratón"}, {value: "shift", text: "Shift"}, {value: "customkey", text: "Especificar tecla"}],
skippedIndexes = [],
sep = "<div class='sep' id='firstsep' style='width: 200px;'></div>",
oldIndex = 0; //,
//sInd = 0;
function addControl(e) {
if (e.lastChild.className != "sep") e.innerHTML += sep;
e.appendChild(getControlSelect());
e.insertAdjacentHTML('beforeend', sep.replace(" id='firstsep'", ""));
}
function onSelectChange(e) {}
function deleteFirstSep() {
if (!document.getElementById("firstsep").nextSibling) document.getElementById("firstsep").remove();
}
function getControlSelect() {
var select = document.createElement('select'),
option,
i = 0,
il = controls.length,
html = document.createElement('div'),
text = document.createElement('input'),
delbtn = document.createElement('input'),
ascinpt = document.createElement('input'),
html1 = document.createElement('div');
html1.style.display = "inline-block";
text.type = "text";
text.name = "accion[]";
text.style.width = "158px";
delbtn.type = "button";
delbtn.setAttribute('onclick', 'var e = this.parentNode;e.nextSibling.remove();e.remove();deleteFirstSep();');
delbtn.value = "-";
delbtn.style.padding = "0 5px";
delbtn.style.marginLeft = "5px";
delbtn.style.position = "relative";
delbtn.style.top = "-20px";
delbtn.style.left = "2px";
ascinpt.name = "tecla[]";
ascinpt.type = "hidden";
select.id = "htmlkey";
select.dataset.associatedInput = ascinpt;
//select.dataset.i = sInd;
//sInd++;
select.setAttribute("onchange", "onSelectChange(this)");
for (; i < il; ++i)
if (skippedIndexes.indexOf(i) == -1) {
option = document.createElement('option');
option.setAttribute('value', controls[i].value);
option.appendChild(document.createTextNode(controls[i].text));
select.appendChild(option);
}
html1.insertAdjacentHTML('beforeend', "<b>Tecla</b><br>");
html1.appendChild(select);
html1.insertAdjacentHTML('beforeend', "<br><b>Acción</b><br>");
html1.appendChild(text);
html.appendChild(html1);
html.appendChild(delbtn);
return html;
}
.sep {
border-top: 4px dashed #A4A4A4;
margin: 15px 0 15px 0;
}
<div>
<input type="button" value="Añadir tecla" onclick="addControl(this.parentNode)" />
</div>
Upvotes: 7