Add onfocus listener instead of onload - javascript

I have such script in js file wich I'm calling from jsp, and I need to add listener instead of "onload".
What important for me:
1) It must be pure js without jQuery or anything
2) Input tags would be created dynamically(Maybe this is important)
3) It must be external js file(<script src="<c:url value="/js/focus.js" />"></script>), but not the tag <script>function.....</script> inside jsp page
onload = function () {
var allInput = document.getElementsByTagName("input");
for (i = 0; i < allInput.length; i++) {
allInput[i].onfocus = showHint
}
};
function showHint() {
var hint = document.getElementById("hint");
hint.innerHTML = this.name + " " + this.value;
hint.style.display = "block";
};

The page can get focus before is't loaded. And if the page is not loaded your inputs don't exist so window.onfocus can't set allInput[i].onfocus. When the page is refreshed with the focus on the devtools the page gets a chance to create inputs before window.onfocus call.
Put your window.onfocus inside window.onload so that it is always called after the page is loaded. If you don't want to override window.onload use addEventListener instead:
addEventListener('load', function () {
addEventListener('focus', function() {
var allInput = document.getElementsByTagName("input")
for (i = 0; i < allInput.length; i++) {
allInput[i].addEventListener('focus', showHint)
}
}
})
function showHint() {
var hint = document.getElementById("hint")
hint.innerHTML = this.name + " " + this.value
hint.style.display = "block"
}

replace onload with onfocus
onfocus = function () {
var allInput = document.getElementsByTagName("input");
for (i = 0; i < allInput.length; i++) {
allInput[i].onfocus = showHint
}
};

That works for me
window.addEventListener('load', function () {
var allInput = document.getElementsByTagName("input");
for (i = 0; i < allInput.length; i++) {
allInput[i].onfocus = showHint
}
});
function showHint() {
var hint = document.getElementById("hint");
hint.innerHTML = this.name + " " + this.value;
hint.style.display = "block";
};

Related

dynamic list in javascript how to call function from specific <li>

I get the message list from the API and create a dynamic array using javascript. I would like a new page with message details to be started when a specific row is pressed.
How do I implement a call to showMessage () on a specific table row?
var list = document.getElementById("listOfMessage");
init();
function init() {
for (var i = 0; i < messageList.length; i++) {
var message = messageList[i];
var li = document.createElement("li");
var a = document.createElement("a");
var text = document.createTextNode("Nadawca: " + message.fullName);
a.appendChild(text);
a.setAttribute('onclick', showMessage(message));
list.appendChild(li);
//list.innerHTML += "<li><a href="showMessage(message)"><h2>Nadawca: " + message.fullName + "
//</h2></a></li>";
}
//list = document.getElementById("listOfTask");
}
function showMessage(message) {
window.sessionStorage.setItem("message", JSON.stringify(message));
window.location.href = 'message.html';
}
In the code above, the showMessage () function is immediately called when the array is initialized. How to make it run only after clicking on a row?
I could add an id attribute to the (a) or (li) element in the init () function, but how to find it later and use it in this code:
var a = document.getElementById('1');
a.addEventListener('click', function() {
window.sessionStorage.setItem("message", JSON.stringify(messageList[0]));
window.location.href = 'message.html';
});
I found a way to solve this problem.
Using this code fragment, we can call a function for a specific element in a dynamically created list.
function init() {
for (var i = 0; i < messageList.length; i++) {
var message = messageList[i];
list.innerHTML += "<li id="+i+"><a onClick="+
"><h2>Nadawca: " + message.fullName + "</h2></a></li>";
}
//$(document).on("click", "ui-content", function(){ alert("hi"); });
$(document).ready(function() {
$(document).on('click', 'ul>li', function() {
var idName = $(this).attr('id');
showMessage(messageList[idName]);
});
});
}

Stop output printing multiple times if function activated more than once

I'm activating a javascript function with a Jquery onclick button:
$('#on').click(function() {
var a = document.getElementsByTagName('a');
for (i = 0; i < a.length; i++) {
a[i].addEventListener('click', function() {
var span = document.createElement('span');
var text = document.createTextNode(this.innerHTML + " ");
span.appendChild(text);
document.getElementsByClassName('output')[0].appendChild(span);
})
}
});
The problem is if the button is clicked more than once the function will repeat more than once. In this case it will print the output multiple times. How can I modify the javascript function to only print one character per click?
Example:
http://jsfiddle.net/874Ljaq1/
Use the jQuery event binding method one
$('#on').one("click", function() {
var a = document.getElementsByTagName('a');
for (i = 0; i < a.length; i++) {
a[i].addEventListener('click', function() {
var span = document.createElement('span');
var text = document.createTextNode(this.innerHTML + " ");
span.appendChild(text);
document.getElementsByClassName('output')[0].appendChild(span);
})
}
});
You can use the jQuery .data() function to set a flag when the button has been clicked once, and only proceed if the flag is not set.
The code:
$('#on').click(function () {
// if we have a flag that indicates this button has been clicked before,
// don't do anything.
if ($(this).data('clicked'))
return;
$(this).data('clicked', true); // set the flag
var a = document.getElementsByTagName('a');
for (i = 0; i < a.length; i++) {
a[i].addEventListener('click', function () {
var span = document.createElement('span');
var text = document.createTextNode(this.innerHTML + " ");
span.appendChild(text);
document.getElementsByClassName('output')[0].appendChild(span);
})
}
});

Passing One's Self to OnClick Event JavaScript

The on click event that I add to an input in javascript isn't working in the proper manner.
My code so far looks like so:
function order(option) {
if(option.checked) {
document.getElementId("col_order").value = document.getElementById("col_order").value + " " + option.value;
}
}
...//somewhere further down
for(var i = 0; i < options.length; i++) {
var check = document.createElement("input");
var label = document.createElement("label");
var description = document.createTextNode(options[i]);
check.type = "checkbox";
check.name = "order_list[]";
check.value = options[i];
check.onclick = "order(check)"; //Problem here
label.appendChild(check);
label.appendChild(description);
element.appendChild(label);
}
I have also tried:
check.onclick = (function() { var option = check; return function() {order(option);}})();
The problem that I am having is the check.onlick line of code. When I add this with normal HTML:
<input type = "checkbox" name = "order_list[]" onclick = "order(this)" value = "randVal">randVal</input>
I don't have any problem whatsoever; the method executes with the intended results. Any thoughts?
Let me clarify: I make it to the order function just fine, but I never get into the if statement, even though the checkbox was just clicked
Use addEventListener instead, and even if it looks like it should work, you're overwriting the same variables on each iteration as there is no closure in for loops, so I would probably add a closure to avoid issues.
For a checkbox you would listen for the change event, not click
for(var j = 0; j < options.length; j++) {
(function(i) {
var check = document.createElement("input");
var label = document.createElement("label");
var description = document.createTextNode(options[i]);
check.type = "checkbox";
check.name = "order_list[]";
check.value = options[i];
check.addEventListener('change', function() {
if (this.checked) {
var col_order = document.getElementById("col_order");
col_order.value = col_order.value + " " + this.value;
}
}, false);
label.appendChild(check);
label.appendChild(description);
element.appendChild(label);
})(j);
}
FIDDLE
check.onclick = "order(check)"; assigns a String as an on-click handler. That doesn't work; the browser expects a function there:
check.onclick = function() {
order(check);
}

Unable to define a click event on a href tag

I am trying to write a click event for an anchor tag in my tampermonkey script.
var contentTag = document.getElementsByTagName("pre")[0];
var fileContents = contentTag.innerHTML;
contentTag.innerHTML = "";
var lines = fileContents.split("\n");
window.alert("Number of lines:"+lines.length);
for(var i=0; i<20; i++) {
if(i!==15)
contentTag.innerHTML+=(lines[i]+"<br>");
else {
contentTag.innerHTML+=("<a id=link1>Click me</a>");
var link = document.getElementById('link1');
link.addEventListener("click", function() {
window.alert('I am clicked');
}, false);
}
}
The alert message never gets triggered when I click on the link in the page dispalyed, even though I have a a click event listener defined. What am I doing wrong here?
It's the way you're adding HTML, you're reappending the link when you do this in the next iteration.
link.innerHTML += something
So the event handler is lost, and you can actually prove that by adding the event handler to the last element instead.
If you do it the proper way, creating elements and appending them, it works fine
var contentTag = document.getElementsByTagName("pre")[0];
var fileContents = contentTag.innerHTML;
contentTag.innerHTML = "";
var lines = fileContents.split("\n");
for (var i = 0; i < 20; i++) {
if (i !== 15) {
var txt = document.createTextNode(lines[i] || ''),
br = document.createElement('br');
contentTag.appendChild(txt);
contentTag.appendChild(br);
} else {
var link = document.createElement('a');
link.id = 'link1';
link.innerHTML = 'Click me';
link.addEventListener("click", function () {
alert('clicked')
}, false);
contentTag.appendChild(link)
}
}
FIDDLE
Shoud be contentTag.innerHTML+=("<a id='link1'>Click me</a>");
Try this:
<script>
var contentTag = document.getElementsByTagName("pre")[0];
var fileContents = contentTag.innerHTML;
contentTag.innerHTML = "";
var lines = fileContents.split("\n");
window.alert("Number of lines:"+lines.length);
for(var i=0; i<20; i++) {
if(i!==15)
contentTag.innerHTML+=(lines[i]+"<br>");
else {
contentTag.innerHTML+=("<a id=link"+i+">Click me</a>");
var link = document.getElementById('link'+i);
var att=document.createAttribute('onclick');
att.value="alert('Clicked !')";
link.setAttributeNode(att);
}
}
</script>
Demo: http://jsfiddle.net/TmJ38/

Passing parameters in Javascript onClick event

I'm trying to pass a parameter in the onclick event. Below is a sample code:
<div id="div"></div>
<script language="javascript" type="text/javascript">
var div = document.getElementById('div');
for (var i = 0; i < 10; i++) {
var link = document.createElement('a');
link.setAttribute('href', '#');
link.innerHTML = i + '';
link.onclick= function() { onClickLink(i+'');};
div.appendChild(link);
div.appendChild(document.createElement('BR'));
}
function onClickLink(text) {
alert('Link ' + text + ' clicked');
return false;
}
</script>
However whenever I click on any of the links the alert always shows 'Link 10 clicked'!
Can anyone tell me what I'm doing wrong?
Thanks
This happens because the i propagates up the scope once the function is invoked. You can avoid this issue using a closure.
for (var i = 0; i < 10; i++) {
var link = document.createElement('a');
link.setAttribute('href', '#');
link.innerHTML = i + '';
link.onclick = (function() {
var currentI = i;
return function() {
onClickLink(currentI + '');
}
})();
div.appendChild(link);
div.appendChild(document.createElement('BR'));
}
Or if you want more concise syntax, I suggest you use Nick Craver's solution.
This is happening because they're all referencing the same i variable, which is changing every loop, and left as 10 at the end of the loop. You can resolve it using a closure like this:
link.onclick = function(j) { return function() { onClickLink(j+''); }; }(i);
You can give it a try here
Or, make this be the link you clicked in that handler, like this:
link.onclick = function(j) { return function() { onClickLink.call(this, j); }; }(i);
You can try that version here
link.onclick = function() { onClickLink(i+''); };
Is a closure and stores a reference to the variable i, not the value that i holds when the function is created. One solution would be to wrap the contents of the for loop in a function do this:
for (var i = 0; i < 10; i++) (function(i) {
var link = document.createElement('a');
link.setAttribute('href', '#');
link.innerHTML = i + '';
link.onclick= function() { onClickLink(i+'');};
div.appendChild(link);
div.appendChild(document.createElement('BR'));
}(i));
Try this:
<div id="div"></div>
<script language="javascript" type="text/javascript">
var div = document.getElementById('div');
for (var i = 0; i < 10; i++) {
var f = function() {
var link = document.createElement('a');
var j = i; // this j is scoped to our anonymous function
// while i is scoped outside the anonymous function,
// getting incremented by the for loop
link.setAttribute('href', '#');
link.innerHTML = j + '';
link.onclick= function() { onClickLink(j+'');};
div.appendChild(link);
div.appendChild(document.createElement('br')); // lower case BR, please!
}(); // call the function immediately
}
function onClickLink(text) {
alert('Link ' + text + ' clicked');
return false;
}
</script>
or you could use this line:
link.setAttribute('onClick', 'onClickLink('+i+')');
instead of this one:
link.onclick= function() { onClickLink(i+'');};
Another simple way ( might not be the best practice) but works like charm. Build the HTML tag of your element(hyperLink or Button) dynamically with javascript, and can pass multiple parameters as well.
// variable to hold the HTML Tags
var ProductButtonsHTML ="";
//Run your loop
for (var i = 0; i < ProductsJson.length; i++){
// Build the <input> Tag with the required parameters for Onclick call. Use double quotes.
ProductButtonsHTML += " <input type='button' value='" + ProductsJson[i].DisplayName + "'
onclick = \"BuildCartById('" + ProductsJson[i].SKU+ "'," + ProductsJson[i].Id + ")\"></input> ";
}
// Add the Tags to the Div's innerHTML.
document.getElementById("divProductsMenuStrip").innerHTML = ProductButtonsHTML;
It is probably better to create a dedicated function to create the link so you can avoid creating two anonymous functions. Thus:
<div id="div"></div>
<script>
function getLink(id)
{
var link = document.createElement('a');
link.setAttribute('href', '#');
link.innerHTML = id;
link.onclick = function()
{
onClickLink(id);
};
link.style.display = 'block';
return link;
}
var div = document.getElementById('div');
for (var i = 0; i < 10; i += 1)
{
div.appendChild(getLink(i.toString()));
}
</script>
Although in both cases you end up with two functions, I just think it is better to wrap it in a function that is semantically easier to comprehend.
onclick vs addEventListener. A matter of preference perhaps (where IE>9).
// Using closures
function onClickLink(e, index) {
alert(index);
return false;
}
var div = document.getElementById('div');
for (var i = 0; i < 10; i++) {
var link = document.createElement('a');
link.setAttribute('href', '#');
link.innerHTML = i + '';
link.addEventListener('click', (function(e) {
var index = i;
return function(e) {
return onClickLink(e, index);
}
})(), false);
div.appendChild(link);
div.appendChild(document.createElement('BR'));
}
How abut just using a plain data-* attribute, not as cool as a closure, but..
function onClickLink(e) {
alert(e.target.getAttribute('data-index'));
return false;
}
var div = document.getElementById('div');
for (var i = 0; i < 10; i++) {
var link = document.createElement('a');
link.setAttribute('href', '#');
link.setAttribute('data-index', i);
link.innerHTML = i + ' Hello';
link.addEventListener('click', onClickLink, false);
div.appendChild(link);
div.appendChild(document.createElement('BR'));
}
This will work from JS without coupling to HTML:
document.getElementById("click-button").onclick = onClickFunction;
function onClickFunction()
{
return functionWithArguments('You clicked the button!');
}
function functionWithArguments(text) {
document.getElementById("some-div").innerText = text;
}

Categories

Resources