Why the following is not working? Apparently the function isn't being added!
function activatetypeinput(event, devtype){
//The function is called but it doesn't set the attribute
var dev_input = document.getElementById("device_input");
dev_input.setAttribute("onclick","add_device_input(event, this);");
}
In my HTML I have something like this (among other things):
<select class="text-input" id="device_input">
<option>--</option>
</select>
"Why the following is not working? Apparently the function isn't being added!"
dev_input.setAttribute("onclick","add_device_input(event, this);");
Look in Devtools F12 and you'll see that the onclick
attribute is added and the value as well. Although it is there and syntactically correct, it doesn't function. See section Demo - Source: #btn3
If the same attribute and value is added via JavaScript as a property it works, as a property. An attribute will not show up in markup, whilst a property does not. For all intents and purposes, the onclick
property and onclick
attribute is one and the same🟊.
This behavior is is standard with jQuery methods attr()
and prop()
. As an example I see this frequently:
👍 $(":checkbox").prop("checked", true);
👎 $(":checkbox").attr("checked", true);
On-event Attribute: Old as dirt and discouraged and frowned upon by the web developing community in general. This is the type of event handler the OP code was trying to create programmatically with setAttribute()
method. It appears that an on event is beyond the reach of set/get/removeAttribute()
methods and most likely jQuery method attr()
as well (untested and not that curious). See Section: Demo - Source: #btn0
<button onclick="funcName(event)">Discouraged</button>
⭐document.getElementById('id').onclick = funcName;
document.getElementById('id').addEventListener("event", funcName);
##Solution
Other than using an On-event Property🟊 we can parse a htmlString of the entire element with the onclick
attribute. This can be done using:
innerHTML
overwrites contentOR
insertAdjacentHTML()
** doesn't overwrite content; flexible; fast###🌟 See section: Demo - source: #btn4
🌟
var htmlString = `<button onclick="funcName(event, this)">4</button>`
document.querySelector('${selectorOfTarget}').insertAdjacentHTML("${position}", htmlString);
"div"
.......: <div id="ID" class="CLASS"></div>"#ID
".......: <div id="ID" class="CLASS"></div>".CLASS"
....: <div id="ID" class="CLASS"></div>#ID + ul
....: <div id="ID" class="CLASS"></div>
<ul></ul>#ID + ul li
.: <div id="ID" class="CLASS"></div>
<ul><li></li></ul> <!--"beforebegin"-->
<ul>
<!--"afterbegin"-->
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<!--"beforeend"-->
</ul>
<!--"afterend"-->
String Literal
'<div id="'+ID+'" class="'+CLASS+'">+CONTENT+</div>'
Template Literal
`<div id="${ID}" class="${CLASS}">${CONTENT}</div>`
var htmlString = `<button id='btn4' onclick='showHide(event)'>4</button>
<div class='content hide'>
<h4>Dynamically Registered On Event Attribute by Parsing htmlString</h4>
<pre><code>
document.querySelector('#btn3+div+hr').insertAdjacentHTML('afterend', htmlString);
</code></pre>
</div>
<hr>`;
function showHide(event) {
var tgt = event.target;
if (tgt.tagName === "BUTTON") {
var code = tgt.nextElementSibling;
code.classList.toggle('hide');
}
return false;
}
//#btn1
//On-Event Property
document.getElementById('btn1').onclick = showHide;
//#btn2
//EventListener
document.getElementById('btn2').addEventListener('click', showHide);
//#btn3
//Dynamically registered On event Attribute by setAttribute() method.
document.getElementById('btn3').setAttribute('onclick', "showHide(event, this)");
//#btn4
//Dynamically Registered On Event Attribute by Parsing htmlString
document.querySelector('#btn3+div+hr').insertAdjacentHTML('afterend', htmlString);
* {
margin: 0;
padding: 0
}
button {
padding: 2px 5px;
}
button+div {
opacity: 1;
transition: opacity 1s ease;
}
.content {
margin: 0 0 20px 0
}
button+div.hide {
opacity: 0;
transition: 1s ease;
}
code {
background: #000;
color: lime;
}
<!--#btn0-->
<button id='btn0' onclick="showHide(event, this)">0</button>
<div class='content hide'>
<h4>On-Event Attribute</h4>
<pre><code>
<button id='btn0' onclick="showHide(event, this)">On-Event Attribute</button>
</code></pre>
</div>
<hr>
<!--#btn1-->
<button id="btn1">1</button>
<div class='content hide'>
<h4>On-Event Property</h4>
<pre><code>
document.getElementById('btn1').onclick = showHide;
</code></pre>
</div>
<hr>
<!--#btn2-->
<button id='btn2'>2</button>
<div class='content hide'>
<h4>EventListener</h4>
<pre><code>
document.getElementById('btn2').addEventListener('click', showHide);
</code></pre>
</div>
<hr>
<!--#btn3-->
<button id='btn3'><del>3</del></button>
<div class='content'>
<h4>Dynamically Registered On Event Attribute by <code>setAttribute()</code> method <b>FAILED</b></h4>
<pre><code>
<del>document.getElementById('btn3').setAttribute('onclick', 'showHide(event)');</del>
</code></pre>
</div>
<hr>
<!--#btn4 is dynamically created and will be inserted here-->
<!--Selector: '#btn3+div+hr' || Position: 'afterend'-->