I'm dynamically adding text inputs to a form. The new input also receives focus. On adding an onblur event however the onblur event seems to be firing as soon as the input is added. To test this I added an alert for the onblur event. The alert appears, and only after clicking OK is the new input created. This happens in IE, Firefox and Opera.
The following is the code I am using. I have removed all other code to for ease of reading.
<head><title>""</title>
<script type="text/javascript">
var count = 1;
function addinput () {
var inpmaster = document.getElementById("inpMaster");
var myinput = document.createElement("input");
myinput.id = "myfield"+count;
myinput.name = "myfield"+count;
myinput.type = "text";
myinput.onblur = alert("woot");
inpmaster.parentNode.insertBefore(myinput,inpmaster);
inpmaster.disabled="disabled";
myinput.focus();
count++;
};
</script>
</head>
<body>
<form action="" method="post" id="admin">
<input id="inpMaster" type="text" name="prodDesccc" onfocus="addinput();" />
</form>
</body>
It is because you are using alert("woot") to assign to onblur event instead of function(){ alert("woot") ;}.
Change your code to:
function addinput () {
var inpmaster = document.getElementById("inpMaster");
var myinput = document.createElement("input");
myinput.id = "myfield"+count;
myinput.name = "myfield"+count;
myinput.type = "text";
myinput.onblur = function(){alert("woot");};
inpmaster.parentNode.insertBefore(myinput,inpmaster);
inpmaster.disabled="disabled";
myinput.focus();
count++;
};
Related
I want to append an li when the enter key is pressed using keydown. However, when I press the enter key the new li appears momentarily and then disappear.
How can I make it save the change or how can I fix the code?
var submitBtn = document.querySelector("input[type = 'submit'");
var enterTodo = document.querySelector("input[type = 'text']");
var todoList = document.querySelector("#todoList");
enterTodo.addEventListener('keydown', (event)=>{
if(event.which == 13){
var todo = enterTodo.value;
todoList.append("<li>" + todo + "</li>");
};
})
The reason why it was showing up and dissapearing almost immediately is because forms automatically refresh the page on submit. Which is why you have to use preventDefault in the onSubmit event.
I set up two working samples based on your code. In both, I went ahead and got your code to to append the proper li elements rather than the text `<li>${todo}</li>` to the todoList. I also made the enterTodo clear after being added to the list.
This uses the code about how you had it with the event listener on keydown, but it prevents the refresh.
var submitBtn = document.querySelector("input[type = 'submit'");
var enterTodo = document.querySelector("input[type = 'text']");
var todoList = document.querySelector("#todoList");
var form = document.querySelector("form");
form.onsubmit = (evt) => evt.preventDefault();
function addTodo() {
var todo = enterTodo.value;
var li = document.createElement('li');
li.textContent = todo;
todoList.appendChild(li);
enterTodo.value = "";
}
enterTodo.addEventListener('keydown', (event) => {
if (event.which == 13) {
addTodo();
};
})
<body>
<form>
<input type="text" onsubmit="" />
<input type="submit" />
<ul id="todoList"></ul>
</form>
</body>
This uses the from's onSubmit handler to perform the addition to the todoList instead of directly handling the enter key in the text input. This has the added benefit of also supporting the submit button click as well.
var submitBtn = document.querySelector("input[type = 'submit'");
var enterTodo = document.querySelector("input[type = 'text']");
var todoList = document.querySelector("#todoList");
var form = document.querySelector("form");
function addTodo() {
var todo = enterTodo.value;
var li = document.createElement('li');
li.textContent = todo;
todoList.appendChild(li);
enterTodo.value='';
}
form.onsubmit = (evt) => {evt.preventDefault();
addTodo();
}
<body>
<form>
<input type="text" onsubmit="" />
<input type="submit" />
<ul id="todoList"></ul>
</form>
</body>
I am very new to javascripts and trying to create a dynamic html form where there are multiple button, and each button click map to a corresponding form input. Here is my code:
<html>
<head>
<title>Create Group</title>
<script src="/js/jquery-3.4.1.min.js"></script>
<script>
$(document).ready(function(){
$("#generate_form").click(function(){
var number = document.getElementById("number_of_groups").value;
var container = document.getElementById("container");
while (container.hasChildNodes()) {
container.removeChild(container.lastChild);
}
var i;
for (i=1;i<=number;i++){
var p = document.createElement("p");
var node = document.createTextNode("group " + i + " :");
p.appendChild(node);
container.appendChild(p);
var input = document.createElement("input");
input.type = "text";
var thisID = 'group_'+i;
input.id = thisID;
input.name=thisID;
container.appendChild(input);
var button = document.createElement("button");
button.id = "button_"+i;
button.type = "button";
container.appendChild(button);
button.onclick = function(){ document.getElementById(thisID).value = "hello world";};
var buttonLabel = document.createTextNode("Generate");
button.appendChild(buttonLabel);
container.appendChild(document.createElement("br"));
}
})
});
</script>
</head>
<body>
<h2>Create some group(s)</h2>
<br>
Create <input type="text" id="number_of_groups" name="number_of_groups" value="1"> group(s).
<button id="generate_form" type="button">GO</button>
<div id="container"/>
</body>
</html>`
So, the user would input number of groups to create and click 'Go' button, then the code should dynamically generate the form with the number the user choose. Each group of the form includes a input textbox and a 'Generate' button. When the button is clicked, the input textbox will show "hello world". However, the "hello world" only show up in the last input textbox no matter which 'Generate' button I click. So I changed the onclick function of the button to:
button.onclick = function(){ alert(thisID);};
Then I found that thisID is always the id of the last input textbox no matter which 'Generate' button I click. I guess that is because the binding of the click event does not happen till the script is done when 'thisID' would always be its latest value.
Would anyone please help me to realize the functionality I want? Thank you very much!
You would need to wrap the code within the for loop in a separate function, passing in the value of i as a parameter. This would create a closure, creating a new execution scope for your code. Otherwise what is happening is that your var is being hoisted, and is not exclusive to each iteration of the for loop, so your DOM is reflecting only the last value it was assigned.
for (i=1;i<=number;i++){
(function (i) {
var p = document.createElement("p");
var node = document.createTextNode("group " + i + " :");
p.appendChild(node);
container.appendChild(p);
var input = document.createElement("input");
input.type = "text";
var thisID = 'group_'+i;
input.id = thisID;
input.name=thisID;
container.appendChild(input);
var button = document.createElement("button");
button.id = "button_"+i;
button.type = "button";
container.appendChild(button);
button.onclick = function(){ document.getElementById(thisID).value = "hello world";};
var buttonLabel = document.createTextNode("Generate");
button.appendChild(buttonLabel);
container.appendChild(document.createElement("br"));
})(i);
}
You can check out an article on closures here:
https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-closure-b2f0d2152b36
EDIT: As one of your commenters mentioned, you can also set your vars to 'let' to achieve a similar effect. This is because let scopes the variable to the current code block, rather than being hoisted to the scope of the function, so each for loop iteration has a private let variable. It is still recommended to get a good understanding of closures and how they work, however.
Since you are already using JQuery, you can reduce some of the logic.
Let me know if this helps-
<html>
<head>
<title>Create Group</title>
</head>
<script src="/js/jquery-3.4.1.min.js"></script>
<script>
$(document).ready(()=>{
var txtGroup='<input type="text" id="txt_group_{0}" value="">';
var btnGroup='<button id="btn_group_{0}" type="button">Click Me</button>';
var container=$('#container');
$('#generate_form').click((e)=>{
var groupCount=parseInt($('#number_of_groups').val());
var idToStart=$('#container').children('div').length+1;
for(let i=idToStart;i< idToStart+groupCount;i++){
var divGroup=`<div id="div_group_${i}">`+
txtGroup.replace('{0}',i)+
btnGroup.replace('{0}',i)+`</div>`;
container.append(divGroup);
$('#btn_group_'+i).on('click',(e)=>{
console.log('#txt_group_'+i);
$('#txt_group_'+i).val('Hello World');
});
}
});
});
</script>
<body>
<h2></h2>
<br>
Create <input type="text" id="number_of_groups" name="number_of_groups" value="1"> group(s).
<button id="generate_form" type="button">GO</button>
<div id="container"></div>
</body>
</html>
I'm new to Javascript and am trying to write code for a simple greeting. The user will have an input box to type their name in to and below a button for them to click that outputs a value of "Hello {name}!". If you could help me out I would appreciate it!
You could start doing something like this:
(function() {
// Creates <input id="myTextBox" type="text" />
var textBox = document.createElement("input");
textBox.id = "myTextBox";
textBox.type = "text";
// Creates <button id="myButton" type="button">Show</button>
var btnShow = document.createElement("button");
btnShow.id = "myButton";
btnShow.type = "button";
btnShow.innerHTML = "Show";
// When you click in the button, show the message.
btnShow.onclick = function showMessage() {
alert("Hello " + textBox.value + "!");
};
// Add created elements.
document.body.appendChild(textBox);
document.body.appendChild(btnShow);
})();
You can find more information about createElement function in this site: Document.createElement().
I am trying to create a form which will take the user input to create a query for database. I have three buttons: And, Or, Run.
I am creating dynamic elements on click of buttons And and Or.
The div search_list is the container for containing the elements.
I need the form to be submitted on click of Run.
The weird thing is, whenever I click on any button the form gets submitted. How do I stop it ? Please let me know If you need more info.
Thanks
<html>
<head>
<script type="text/javascript">
var count = 0;
function loadfirst(){
count=1;
addFilter('');
}
function addFilter(flag){
var div = document.querySelector("#search_list");
tr = document.createElement("tr");
select = document.createElement("select");
var sear_value = document.createElement("input");
var and_or = document.createTextNode(flag);
tr.id='tr_'+count;
select.id='sl_'+count;
sear_value.id='sear_value_'+count;
select.options.add( new Option("user id","user_id", true,true) );
select.options.add( new Option("First name","first_name"));
select.options.add( new Option("Last name","last_name"));
select.options.add( new Option("Course","course"));
sear_value.type="text";
if(count<=1){
var bt_and= document.createElement("button");
bt_and.id='and';
var bt_label = document.createTextNode("And");
bt_and.appendChild(bt_label);
bt_and.addEventListener('click', function() {
addFilter('and');
return false;
});
var bt_or= document.createElement("button");
bt_or.id='or';
var bt_label = document.createTextNode("Or");
bt_or.appendChild(bt_label);
bt_or.addEventListener('click', function() {
addFilter('or');
return false;
});
}
else{
var bt_rem= document.createElement("button");
bt_rem.id='rem_'+count;
var bt_label1 = document.createTextNode("x");
bt_rem.appendChild(bt_label1);
var tr_id = 'tr_'+count;
bt_rem.addEventListener('click', function() {
var element= document.getElementById(tr_id);
element.parentNode.removeChild(element);
return false;
});
}
tr.appendChild(and_or);
tr.appendChild(select);
tr.appendChild(sear_value);
if(count<=1){
tr.appendChild(bt_and);
tr.appendChild(bt_or);
}
else{
tr.appendChild(bt_rem);
}
div.appendChild(tr);
count++;
}
function getFilter(){
alert();
}
</script>
</head>
<body onload="loadfirst()">
<span id='manage_stud_header' class= 'list_header'>
<label><?php echo $module_name;?></label>
<center>
<form>
<div id='search_list' class='search'></div>
<button id="run_filter" type="submit">Run</button>
</form>
</center>
</span>
</body>
</html>
The default type for buttons is "submit", so you have to explicitly say you want a plain button:
var bt_and= document.createElement("button");
bt_and.type = "button";
This way it won't submit the form when clicked. (unless of course you tell it to :))
you have to change
<button id = "run_filter" type = "submit" > Run </button>
in
<input id = "run_filter" type = "submit" value="Run" />
and then if the behaviour of click on button is forced to reload the page try to change button on other form element or see e.preventdefaulT of jquery
I'm writing a simple javascript form that checks the input value against the value "blue". Now if you enter "blue", it says it's incorrect, but then if add any additional character, it says correct. It seems like there's a one-character delay, so when I enter "blue" it's only getting "blu". Here is the code:
<html>
<head>
<title>Favorite Color</title>
</head>
<body>
<h1>Quiz Time</h1>
<h2>What is your favorite color?</h2>
<p>Your Answer: <input type="text" id="txtinput" /></p>
<p id="message"></p>
<script type = "text/javascript">
function init() {
var inp = document.getElementById("txtinput");
inp.onkeypress=checkAnswer;
checkAnswer();
}
onload = init;
function checkAnswer() {
var text = document.getElementById("txtinput");
var msg = document.getElementById("message");
var sol = "blue";
var ans = text.value;
ans = ans.toLowerCase();
if (ans.length <=0) {
msg.innerHTML="<span style=\"color:blue;\">Enter Something.</span>";
}
else if (ans == sol) {
msg.innerHTML="<span style=\"color:green;\">Correct!</span>";
} else {
msg.innerHTML="<span style=\"color:red;\">Wrong!</span>";
}
}
</script>
</body>
</html>
Change the event to onkeyup instead of onkeypress
inp.onkeyup=checkAnswer;
Use the HTML5 input event with a fallback to the propertychange event in IE < 9. I've written about this many times on SO; here are two examples:
jQuery keyboard events
Catch only keypresses that change input?