In another post, I was advised not to use IDs, intead use classes in HTML forms for buttons.
I'm new to HTML5 and Javascript, so how I use the button class, and assign an event handler to the button?
Possible Solution:
<!DOCTYPE html>
<html>
<head>
<title>HTML Button Tag</title>
</head>
<body>
<form>
<button name="button" value="OK" type="button">Click Me</button>
</form>
</body>
</html>
I would then use document.getElementByName() and assign a button handler, correct?
Seriously, anyone saying that:
ids are considered bad practice for quite some time now in HTML, the preferred method are classes
...are plain wrong! id's and classes have their separate usage areas, which in some cases overlap. For automated testing, and css, ID's are extremely useful. Never be afraid to use them!
As an answer to your question, there are several options. Either find the element in javascript, and assign a button handler, or simply add an onclick-function, and assign it directly in your button tag, like this:
<button ... onclick="functionToBeCalled()">Click Me</button>
then you just define the function you'd like to execute in javaScript.
Related
I noticed this odd behavior while writing some demonstration code today, and I'm curious what's happening. "Button" does not work although "Button 2" does, even though they're being set in just different ways. I know it has to do with the quoting, but I'm curious why this is happening. Similarly, if I pass in a function to button 3 in quotes vs appending it directly in button 4, button 4 works but button 3 doesn't.
Also, I would think that given that button 2 works, it would do the evaluation of console.log("test") immediately (similar to how it would work without the quotes) but rather it delays until actually clicking on the button. I know this is not the best way to do it but for curiosity sake, I'm curious what's happening exactly here.
document.getElementById("app").innerHTML = `
<h1>Testing Sandbox</h1>
<div>
<button id='hello'>Button</button>
<button id='hello2' onclick='console.log("test")'>Button 2</button>
<button id='hello3' onclick='(e) => console.log("test")'>Button 3</button>
<button id='hello4'>Button 4</button>
</div>
`;
document.getElementById("hello").onclick = 'console.log("test")';
document.getElementById("hello4").onclick = (e) => console.log("test");
<!DOCTYPE html>
<html>
<head>
<title>Sandbox</title>
<meta charset="UTF-8" />
</head>
<body>
<div id="app"></div>
<script src="src/index.js">
</script>
</body>
</html>
When you assign to onclick, you invoke a setter, which does something pretty similar to calling addEventListener with the assigned expression. But both addEventListener and onclick will silently fail if the passed expression is not a function:
document.getElementById("app").innerHTML = `
<h1>Testing Sandbox</h1>
<div>
<button id='hello'>Button</button>
`;
document.getElementById("hello").onclick = 'console.log("test")';
// nearly the same thing as:
document.getElementById("hello").addEventListener('click', 'console.log("test")');
<div id="app"></div>
The string does not get implicitly coerced to a function.
In the third example, the inline handler declares a function, but never executes it:
<button id='hello3' onclick='(e) => console.log("test")'>Button 3</button>
which is like
button.addEventListener('click', function(event) {
(e) => console.log("test")
});
The listener runs, but the listener doesn't contain anything other than an unused function expression, so you don't see anything when you click. This might be clearer if you add a log statement:
<button id='hello3' onclick='console.log("listener running;"); (e) => console.log("test")'>Button 3</button>
In general, you should never use inline handlers; they require global pollution, are hard to manage, have string and HTML escaping issues, and are pretty much universally considered to be bad practice. Instead, use addEventListener, and always pass it functions, not strings, for a listener to be properly added.
Why button two works ?
It is possible to associate an action with a certain number of events
that occur when a user interacts with a user agent. Each of the
"intrinsic events" listed above takes a value that is a script. The
script is executed whenever the event occurs for that element. The
syntax of script data depends on the scripting language. HTML Specs
So onclick = script [CT] will be called whenever user interacts, in this case it is an mouse click event
Why button don't work ?
document.getElementById("hello").onclick expects a function where as you're passing string
Here we have a div with a onclick handler:
<div id="BorderContainer1282" onclick="alert('hello')">
<input id="Button925" type="button" value="Button">
</div >
When clicked it shows an alert dialog.
Does HTML support inline JavaScript in a child tag of the same name, like so:
<div id="BorderContainer1282">
<onclick>alert('hello');</onclick>
<input id="Button925" type="button" value="Button">
</div >
This question is not best practices. It is specifically about HTML supports setting events in a child tag of an HTML element as shown in the example.
NOTE: I tested the code above in example 2 and it does not work in my tests.
If it does not work, would using the following template be an acceptable alternative:
<div id="BorderContainer1282">
<script type="text/javascript">
document.getElementById('BorderContainer1282').addEventListener("click", function(event) {
(function(event) {
alert('hello');
}).call(document.getElementById("BorderContainer1282"), event);
});
</script>
<input id="Button925" type="button" value="Button">
</div >
Again, I'm not concerned about best practices now, only if this feature is supported.
I found a similar question here that is not a duplicate.
Your second example is not valid HTML; there is no <onclick> tag. The reason you are able to execute JavaScript in the first example is because of Event attributes for certain tags.
These attributes allow you to execute arbitrary JavaScript when a certain event is triggered on the given element, and although you are not concerned with best practices here, you should avoid using them if you want to keep your markup clean and organized.
What you are looking for is the <script> tag in your third example, which does allow for the insertion of JavaScript anywhere in your HTML markup, and is what you should use in this case. You can use this tag and addEventListener to attach an event handler to your div. This is the proper usage of the tag in this scenario:
<div id="BorderContainer1282">
<script type="text/javascript">
document.getElementById("BorderContainer1282").addEventListener("click", function(e) {
alert("Hello!");
});
</script>
<input id="Button925" type="button" value="Button">
</div >
Lastly, <script> tags are typically placed at the end of the <body> to ensure that all elements have been loaded before the script executes. You can also accomplish this by wrapping your JavaScript in a window.addEventListener("load", function(){ ... });.
I am learning Angular JS and I am stuck at a pretty basic step.
Here is my test code:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script>
function enable()
{
$("#test_model").attr("data-ng-model", "test");
$("#test_bind").attr("data-ng-bind", "test");
};
</script>
</head>
<body>
<div data-ng-app="">
<div>
<input type=text id=test_model />
</div>
<div>
<p id=test_bind></p>
</div>
<button onclick=enable()>Enable</button>
</div>
</body>
</html>
Here, what I expect to happen is, when the Enable button is clicked, it should enable the bind, and so if anything is typed into the #test_model input, it should update #test_bind paragraph. But it is not working.
I can see with Firebug that the attributes (data-ng-model and data-ng-bind) are being updated when the Enable button is clicked, but it is not taking effect as it would if it were statically coded (hard-coding the model and bind parameters).
If I code it statically, then I notice that 3 new classes (ng-pristine, ng-untouched and ng-valid) are automatically added to #test_model and one new class (ng-binding) is added to #test_bind. So I changed my enable() function to this:
function enable()
{
$("#test_model").attr("data-ng-model", "test");
$("#test_bind").attr("data-ng-bind", "test");
$("#test_model").addClass("ng-pristine");
$("#test_model").addClass("ng-untouched");
$("#test_model").addClass("ng-valid");
$("#test_bind").addClass("ng-binding");
};
But still, not working.
What am I missing?
If you want to dynamically add Angular directives like ng-model, ng-bind etc.
you must create your own directive and use $compile.
You can use angular ng-show or ng-switch to switch showing DOM elements without bindings and elements with ng-model and other attributes that you need.
I found this article that looked like exactly what I wanted, but I can't seem to get it to work at all. Since it is well over a year old, I thought perhaps something may have changed, or that there might be a simpler way to do it by now.
That is to say, I cannot get the method I linked above to work. I copied and pasted exactly, and used <body onLoad="javascript_needed()"> because I wasn't sure where $(document).ready(function ()... was supposed to go. I am, sadly, quite unfamiliar with Javascript.
Use something like this;
<script>
$(document).ready(function(){
//Code goes in here.
});
</script>
Don't forget to load the jQuery library at the same time from http://jquery.com/
Also, you are going to want to read up on selectors.
Using $("#myElement") will select elements that have an id of "myElement".
Using $(".myElement") will select elements that have a class of "myElement".
So;
<div class="hideMe">Content</div>
<div class="hideMe">Content</div>
<div class="hideMe">Content</div>
<div class="doNotHideMe">Content</div>
<input type="button" class="ClickMe" value="click me"/>
<script>
$(function(){
$(".ClickMe").click(function(){
$(".hideMe").hide(250);
});
});
</script>
edit
If you want to link to the jquery library online then use;
<script src="http://code.jquery.com/jquery-1.6.1.min.js" type="text/javascript"></script>
If you download the library and insert the js file into your project then use;
<script src="/yourPathToTheLibrary/jquery-1.6.1.min.js" type="text/javascript"></script>
The $ syntax is all part of jQuery. If you wish to use jQuery then somewhere in your code, use a script tag as in your post:
<script>
$(function() {
$('.selector').hide(250);
});
</script>
If you want pure JavaScript, then there is a little more overhead. Not including the document ready stuff (which can be a lot of extra code to do it right...See example: here).
<script>
elements = document.querySelectorAll('.selector');
for(int i=0,len=elements.length;i<len;++i) {
elements[i].style.display = 'none';
}
</script>
You can put that in a function if you would like. To show the elements set the display attribute to ''.
I have a form element that I want to address via javascript, but it doesn't like the syntax.
<form name="mycache">
<input type="hidden" name="cache[m][2]">
<!-- ... -->
</form>
I want to be able to say:
document.mycache.cache[m][2]
but obviously I need to indicate that cache[m][2] is the whole name, and not an array reference to cache. Can it be done?
UPDATE: Actually, I was wrong, you can use [ or ] characters as part of a form elements id and/or name attribute.
Here's some code that proves it:
<html>
<body>
<form id="form1">
<input type='test' id='field[m][2]' name='field[m][2]' value='Chris'/>
<input type='button' value='Test' onclick='showtest();'/>
<script type="text/javascript">
function showtest() {
var value = document.getElementById("field[m][2]").value;
alert(value);
}
</script>
</form>
</body>
</html>
Update: You can also use the following to get the value from the form element:
var value = document.forms.form1["field[m][2]"].value;
Use document.getElementsByName("input_name") instead. Cross platform too. Win.
Is it possible to add an id reference to the form element and use document.getElementById?
-- and in the old days (in HTML3.2/4.01 transitional/XHTML1.0 transitional DOM-binding) you could use:
form.elements["cache[m][2]"]
-- but the elements-stuff is, as Chris Pietschmann showed, not necessary as these binding-schemes also allow direct access (though I personally would prefer the extra readability !-)