Event listener not triggering? - javascript

I am trying to push array elements gathered from an input to a HTML table. The event listener is not triggering for some reason, here is the HTML.
<form id="frm1">
<input id='keyword-input' type="text" placeholder="Keywords"></input>
<input id="color-input" type="text" placeholder="Color"></input>
<input id="size-input" type="text" placeholder="Size"></input>
<input id="profile-input" type="text" placeholder="Profile"></input>
<input id="proxy-input" type="text" placeholder="Proxy"></input>
<input id="category-input" type="text" placeholder="Category"></input>
<input id="tasks-input" type="number" placeholder="# Of Tasks"></input>
<input id="schedule-input" type="time" placeholder="Schedule Task"></input>
<input id="search-input" type="text" placeholder="Search Method"></input>
<button type="submit" form="frm1" class="add-button" id='addTask'>Add Task</button>
</form>
I have tried moving the listener further down the script, and I have tried embedding it in an onload function, but neither have solved the issue.
var submitButton = document.getElementById('addTask');
submitButton.addEventListener('submit', displayTable);
let taskModel = [{
taskKeyword : value,
taskSize : value,
taskProfile : value
}];
function displayTable(taskModel) {
var table = document.getElementById('taskTable');
for (var i = 0; i < taskModel.length; ++i) {
var tasks = tasks[i];
var row = document.createElement('tr');
var properties = ['taskKeyword', 'taskSize', 'taskProfile'];
for (var j = 0; j < properties.length; ++j) {
var cell = document.createElement('td');
cell.innerHTML = taskModel[properties[j]];
row.appendChild(cell);
}
table.appendChild(row);
}
}
I expected the function to be executed once the 'addTask' button is pressed, but it is not appearing in the dev tools event listener.

You have to add the listener to your form instead of the button.
From the official docs:
The submit event is fired when a form is submitted.
Note that submit is fired only on the form element, not the button or submit input.
Forms are submitted, not buttons.
Important changes to your code:
No.1: In your displayTable handler function, change the parameter to a different name instead of taskModel.
Why? You're trying to use taskModel assuming that it holds the task data. However, the actual value of taskModel when the function is called is the event data. The handler function, by default, when executed is passed the event object (that was created when the event/action you are interested in happened) as an argument.
No.2: Change taskModel[properties[j]] to taskModel[0][properties[j]]
Why? You have to specify the index of the taskModel when accessing it since you declared it as an array.
var taskForm = document.getElementById('frm1');
taskForm.addEventListener('submit', displayTable);
function displayTable(event) {
let taskModel = [{
taskKeyword: document.getElementById('keyword-input').value,
taskSize: document.getElementById('size-input').value,
taskProfile: document.getElementById('profile-input').value
}];
var table = document.getElementById('taskTable');
for (var i = 0; i < taskModel.length; ++i) {
//var tasks = tasks[i];
var row = document.createElement('tr');
var properties = ['taskKeyword', 'taskSize', 'taskProfile'];
for (var j = 0; j < properties.length; ++j) {
var cell = document.createElement('td');
cell.innerHTML = taskModel[0][properties[j]]; // You have to specify the index of the taskModel since you declared it as an array
row.appendChild(cell);
}
table.appendChild(row);
}
// added event.preventDefault(); for demo purposes
event.preventDefault();
}
<form id="frm1">
<input id='keyword-input' type="text" placeholder="Keywords"></input>
<input id="color-input" type="text" placeholder="Color"></input>
<input id="size-input" type="text" placeholder="Size"></input>
<input id="profile-input" type="text" placeholder="Profile"></input>
<input id="proxy-input" type="text" placeholder="Proxy"></input>
<input id="category-input" type="text" placeholder="Category"></input>
<input id="tasks-input" type="number" placeholder="# Of Tasks"></input>
<input id="schedule-input" type="time" placeholder="Schedule Task"></input>
<input id="search-input" type="text" placeholder="Search Method"></input>
<button type="submit" form="frm1" class="add-button" id='addTask'>Add Task</button>
</form>
<table id="taskTable">
</table>
Note: I modified the taskModel implementation on this answer for demo purposes.

Related

increment in the function name and id javascript

I have number of input types and buttons....every button on click increment the value in the relevant input types. But rather than creating a separate function for every button i want to do it by loop....where loop will increase in the function name and id......
<input type="number" id="s1"> <button onclick="increment_s1();">Add</button>
<input type="number" id="s2"> <button onclick="increment_s2()">Add</button>
<input type="number" id="s3"> <button onclick="increment_s3">Add</button>
here is JavaSc code
<script>
var i = 1;
for (i = 0; i < 5; i++) {
var data = 0;
document.getElementById("s"+i).innerText = data;
function ['increment_'+i]() {
data = data + 1;
document.getElementById("s"+i).placeholder = data;
i++;
}
}
</script>
You can't program the function name. You can set up a parameter in the function to make a difference. The param would be the identifier and you can put the whole input element id there.
After that, if you want to have the id s1, s2, and so on, you should initialize the i to start from 1 to 5 instead of 0 to less than 5.
Another thing is, you need to understand the role of placeholder and value attributes in input element. The placeholder works only when the value is empty and it doesn't count as the form value.
// This is for handling onclick
function increment(id) {
var elem = document.getElementById(id);
elem.value = parseInt(elem.value) + 1;
}
// This is to initialize the 0 values
for (var i = 1; i <= 5; i++) {
var data = 0;
document.getElementById("s"+i).value = data;
}
<input type="number" id="s1"> <button onclick="increment('s1');">Add</button>
<input type="number" id="s2"> <button onclick="increment('s2')">Add</button>
<input type="number" id="s3"> <button onclick="increment('s3')">Add</button>
<input type="number" id="s4"> <button onclick="increment('s4')">Add</button>
<input type="number" id="s5"> <button onclick="increment('s5')">Add</button>
What if you would like to generate whole input and button with loops? You can get them by adding div and use the innerHTML, i.e.
// This is for handling onclick
function increment(id) {
var elem = document.getElementById(id);
elem.value = parseInt(elem.value) + 1;
}
var divElem = document.querySelector('div');
// Set up empty first
divElem.innerHTML = "";
for(var i=1; i<=5; i++) {
// Create elements here
var innerElem = `<input type="number" id="s${i}" value="0"> <button onclick="increment('s${i}')">Add</button>`;
// Push them all into innerHTML
divElem.innerHTML += innerElem;
}
<div></div>
You can try these two workarounds. Perhaps you may need to learn more about basic HTML elements and their attributes also Javascript.

Creating a compressing function in HTML

So i've been asked for creating a function that compress a string.
I tried to create a javascript function to do that. But it seems, it is not doing anything for the moment. I don't understand why, regardless of the input, my function is not doing anything.
function compression(input) {
var charsToEscape = "#/%&+,!()*':;<=>?";
var escaped = [];
for (var i = 0; i < input.length; i++) {
var testChar = input.substr(i, 1);
if (charsToEscape.indexOf(testChar) > -1) {
escaped.push("%" + testChar.charCodeAt(0).toString(16).toUpperCase());
} else {
escaped.push(testChar);
}
}
return escaped.join("");
}
<label for="input">Input: Uncompressed Link URI</label>
<input type="text" id="input" class="form-control" name="input" value="">
<button onclick="compression(input)" name="button">Compressed </button>
<br><br>
<label for="compression">Output: Compressed Link URI</label>
<input type="text" id="compression" class="form-control" name="compression" value="">
You can see above, the html function is where i put my input, and the output, and the javascript function that is supposed to do the compression.
But for the moment he is not doing anything.
Thank you all in advance for any advice you could provide
1st: You didn't use the value of the input element, but the element itself. So input hase to be replaced with input.value
2nd: You returned a value, but didn't do anything with it.. So you could create a new function that will get the value and put it in the second input
3rd: Your ids' names are too generic. I changed them to be more specific and telling names which will not interfere with other elements in the same page.
function compression(input) {
var charsToEscape = "#/%&+,!()*':;<=>?";
var escaped = [];
for (var i = 0; i < input.value.length; i++) {
var testChar = input.value.substr(i, 1);
if (charsToEscape.indexOf(testChar) > -1) {
escaped.push("%" + testChar.charCodeAt(0).toString(16).toUpperCase());
} else {
escaped.push(testChar);
}
}
return escaped.join("");
}
function insertCompressed(output, value) {
output.value = value
}
<label for="input">Input: Uncompressed Link URI</label>
<input type="text" id="compressionInput" class="form-control" name="input" value="">
<button onclick="insertCompressed(compressionOutput, compression(compressionInput))" name="button">Compressed </button>
<br><br>
<label for="compression">Output: Compressed Link URI</label>
<input type="text" id="compressionOutput" class="form-control" name="compression" value="">
I've created an onCompress function which takes html element as input. The function gets the desired input element, compression and assigns the compressed value to it.
function onCompress(input) {
document.getElementById('compression').value = compression(input.value);
}
function compression(text) {
var charsToEscape = "#/%&+,!()*':;<=>?";
var escaped = [];
for (var i = 0; i < text.length; i++) {
var testChar = text.substr(i, 1);
if (charsToEscape.indexOf(testChar) > -1) {
escaped.push("%" + testChar.charCodeAt(0).toString(16).toUpperCase());
} else {
escaped.push(testChar);
}
}
return escaped.join("");
}
<label for="input">Input: Uncompressed Link URI</label>
<input type="text" id="input" class="form-control" name="input" value="">
<button onclick="onCompress(input)" name="button">Compressed </button>
<br><br>
<label for="compression">Output: Compressed Link URI</label>
<input type="text" id="compression" class="form-control" name="compression" value="">

Why is my HTML page reloading every time a new entry is submitted into a form?

I am having trouble with my HTML page. My program is meant to collect names using a form, then output them into a table below the form. It is capable of doing just that when the page doesn't reload.
The first time I enter a certain name, the page reloads. After the page has reloaded, and I enter the same name, it doesn't reload upon hitting enter any subsequent time. I don't know why this is, or how to fix it.
Here is the linked JS file
// Gloabal Variables
var enteredName,
countOutput,
count,
table,
form,
allNames = [];
function project62Part2() {
// Your code goes in here.
function getElements() {
form = document.getElementById("nameForm");
countOutput = document.getElementById("numNames");
table = document.getElementById("table");
}
function addName() {
enteredName = form.name.value;
allNames.push(enteredName);
}
function countNames() {
// Reset count
count = 0;
// Loop through and count names
for (i = 0; i < allNames.length; i++) {
count++;
}
}
function output() {
// Reset table
table.innerHTML = "<tr><th>Names</th></tr>";
// Display count
countOutput.innerHTML = "Total names entered: " + count;
// Loop through and add to table display
for (i = 0; i < allNames.length; i++) {
table.innerHTML += "<tr><td>" + allNames[i] + "</td></tr>";
}
}
// Call code
getElements();
addName();
countNames();
output();
// Prevent page from reloading
return false;
}
<form id="nameForm" action="#">
<label class="formLabel" for="name">Name: </label>
<input id="name" name="name" />
<input type="submit" name="runExample" value="Submit" class="formatSubmit" onclick="project62Part2()" />
</form>
<div id="numNames">Total names entered: </div>
<table id="table"></table>
My understanding of coding is rudimentary at best, so while I would appreciate any answer, I'd prefer it to be kept simple!
<input type='submit'> causes the page refresh. Replace it with <input type='button'>.
Read more here.
// Gloabal Variables
var enteredName,
countOutput,
count,
table,
form,
allNames = [];
function project62Part2() {
// Your code goes in here.
function getElements() {
form = document.getElementById("nameForm");
countOutput = document.getElementById("numNames");
table = document.getElementById("table");
}
function addName() {
enteredName = form.name.value;
allNames.push(enteredName);
}
function countNames() {
// Reset count
count = 0;
// Loop through and count names
for (i = 0; i < allNames.length; i++) {
count++;
}
}
function output() {
// Reset table
table.innerHTML = "<tr><th>Names</th></tr>";
// Display count
countOutput.innerHTML = "Total names entered: " + count;
// Loop through and add to table display
for (i = 0; i < allNames.length; i++) {
table.innerHTML += "<tr><td>" + allNames[i] + "</td></tr>";
}
}
// Call code
getElements();
addName();
countNames();
output();
// Prevent page from reloading
return false;
}
<form id="nameForm" action="6.2projectpart2.html#">
<label class="formLabel" for="name">Name: </label>
<input id="name" name="name" />
<input type="button" name="runExample" value="Submit" class="formatSubmit" onclick="project62Part2()" />
</form>
<div id="numNames">Total names entered: </div>
<table id="table"></table>
You can change from <input type="submit" name="runExample" /> to
<input type="button" name="runExample" />
or
Remove onclick="project62Part2()" on input tag and move to form tag onsubmit="return project62Part2()"
<form id="nameForm" onsubmit="return project62Part2()">
There are many ways to achieve this I will explain two ways:
1. Adding Event.preventDefault() method
Whenever you click <input> elements of the submit type, the user agent attempts to submit the form to the URL setup in the form.
Now, the preventDefault() method tells the user agent that if the event does not get explicitly handled, its default action should not be taken as it normally would be. This means the Form interface will not reload the page.
How it works?
well, just add the event variable to your submit call like this:
<input type="submit" name="runExample" value="Submit" class="formatSubmit" onclick="project62Part2(event)" />
Then add the event parameter to the project62Part2() method.
function project62Part2(event) {
event.preventDefault();
...
}
// Gloabal Variables
var enteredName,
countOutput,
count,
table,
form,
allNames = [];
function project62Part2(event) {
event.preventDefault();
// Your code goes in here.
function getElements() {
form = document.getElementById("nameForm");
countOutput = document.getElementById("numNames");
table = document.getElementById("table");
}
function addName() {
enteredName = form.name.value;
allNames.push(enteredName);
}
function countNames() {
// Reset count
count = 0;
// Loop through and count names
for (i = 0; i < allNames.length; i++) {
count++;
}
}
function output() {
// Reset table
table.innerHTML = "<tr><th>Names</th></tr>";
// Display count
countOutput.innerHTML = "Total names entered: " + count;
// Loop through and add to table display
for (i = 0; i < allNames.length; i++) {
table.innerHTML += "<tr><td>" + allNames[i] + "</td></tr>";
}
}
// Call code
getElements();
addName();
countNames();
output();
// Prevent page from reloading
return false;
}
<form id="nameForm" action="#">
<label class="formLabel" for="name">Name: </label>
<input id="name" name="name" />
<input type="submit" name="runExample" value="Submit" class="formatSubmit" onclick="project62Part2(event)" />
</form>
<div id="numNames">Total names entered: </div>
<table id="table"></table>
2. Replacing input with button
This is based on the previous explanation. If an <input> element of the submit type triggers a submit call then if you replace it with the button type then a submit call will not be triggered. I recommend you this to maintain the submit if you are working with server calls.
How it works?
well, just replace the type from submit to button like this:
<input type="button" name="runExample" value="Submit" class="formatSubmit" onclick="project62Part2()" />
// Gloabal Variables
var enteredName,
countOutput,
count,
table,
form,
allNames = [];
function project62Part2() {
event.preventDefault();
// Your code goes in here.
function getElements() {
form = document.getElementById("nameForm");
countOutput = document.getElementById("numNames");
table = document.getElementById("table");
}
function addName() {
enteredName = form.name.value;
allNames.push(enteredName);
}
function countNames() {
// Reset count
count = 0;
// Loop through and count names
for (i = 0; i < allNames.length; i++) {
count++;
}
}
function output() {
// Reset table
table.innerHTML = "<tr><th>Names</th></tr>";
// Display count
countOutput.innerHTML = "Total names entered: " + count;
// Loop through and add to table display
for (i = 0; i < allNames.length; i++) {
table.innerHTML += "<tr><td>" + allNames[i] + "</td></tr>";
}
}
// Call code
getElements();
addName();
countNames();
output();
// Prevent page from reloading
return false;
}
<form id="nameForm" action="#">
<label class="formLabel" for="name">Name: </label>
<input id="name" name="name" />
<input type="button" name="runExample" value="Submit" class="formatSubmit" onclick="project62Part2()" />
</form>
<div id="numNames">Total names entered: </div>
<table id="table"></table>
try adding an event parameter on project62Part2 then do an event.preventDefault() inside

create input text with loop js

I would like to know how could I create many <input type=text /> tags with a loop in JS.
I need that loop to be linked to a first input (type=number), which tell to the loops how many input text to create.
function getP () {
var nbP = Number(document.getElementById("nombreP").value);
for (var i = 0; i < nbP; i++) {
var newForm = document.createElement("input[type=text]");
newForm.id = "form"+i
document.body.appendChild(newForm);
}
}
<form method="get">
<input type="number" name="nombrePlat" id="nombreP">
<input type="submit" value="Envoyer" id="ok" onclick="getP()">
</form>
Direct answer to your question:
<script type="text/javascript">
function getP() {
var nbP = +document.getElementById("nombreP").value;
var inputContainer = document.getElementById("inutContainer");
for (var i = 0; i < nbP; i++) {
var newForm = document.createElement("input");
newForm.setAttribute("type", "text");
newForm.setAttribute("id", "form"+i);
inputContainer.appendChild(newForm);
inputContainer.appendChild(document.createElement("br"));
}
}
</script>
<form>
<input type="number" name="nombrePlat" id="nombreP">
<input type="button" value="Envoyer" id="ok" onclick="getP()">
<div id="inutContainer">
</div>
</form>
BUT: this is good question to learn about Javascript and HTML, but bad to create powerfull UI. To implement modern UI in JS/HTML i am strongly recommend to learn more abou next technologies:
https://reactjs.org/ or https://angular.io/ or https://vuejs.org/
I hope it helps:
document.querySelector('#ok').addEventListener('click', getP)
function getP(event) {
let inputsQtt = document.querySelector('input[type=number]').value
for (let i = 0; i < inputsQtt; i++) {
let input = document.createElement("input");
document.body.appendChild(input);
}
}
<form method="get">
<input type="number" name="nombrePlat" id="nombreP">
<input type="button" value="Envoyer" id="ok">
</form>
There are few problems with your code
First: syntax error, you are missing 1 curly bracket } to close function.
And second and more important as you click on button it causes to submit form and refreshes the page.To solve this you just need to change type of button from submit to button.
And also you can not use "input[type=text]" to create element.You can just create an element with following code
function getP () {
var nbP = Number(document.getElementById("nombreP").value);
for (var i = 0; i < nbP; i++) {
var newForm = document.createElement("input");
newForm.id = "form"+i;
newForm.setAttribute("type","text");
document.body.appendChild(newForm);
}
}
Here's a slightly different approach, that involves adding a wrapper container within your form.
function updateForm() {
var parent = document.getElementById('inputs'),
count = document.getElementById('inputCount').value || 0;
parent.innerHTML = '';
for (let i = 0; i < count; i++) {
parent.innerHTML += `<input placeholder="text input ${i+1}" name="form${i+1}" id="form${i+1}" /><br>`;
}
}
<form method="get" name="inputForm">
<input min="0" type="number" name="inputCount" id="inputCount">
<div id="inputs">
<!-- container for dynamic inputs -->
</div>
</form>
<!-- Notice inputs can also be associated to form with `form` attribute -->
<input form="inputForm" type="submit" value="Make" id="ok" onclick="updateForm()">

JS: Push to array and update select without getting duplicates

I am populating a SELECT with an array. The array contains strings with employee-names.
I want to be able to add a new employee name in the array and then update the SELECT. I've made this, but I keep getting duplicates as I call the function. I kind of understand why, but I haven't quite figured out yet how to make this code better so that I only add the one employee name that is written in the text input.
I don't want to have a function that removes all duplicates, as I think it should be possible to have several employees with the name "John".
My HTML:
<section id="sidebar">
<form onSubmit="return false">
<label for="Name">Name:</label>
<input id="nameInput" type="text" value="Your name here..." name="name" />
<input type="submit" value="Add to list" name="Add" onClick="addToArray();"><br>
<label for="Default">List over employees:</label>
<select id="employeeSelect">
</select>
</form>
</section>
My JS:
var employeeList = ['Sarah', 'Louse', 'Dan', 'John', 'Peter'];
function listEmployees(){
var select = document.getElementById('employeeSelect');
for (var i = 0; i < employeeList.length; i++)
{
var option = employeeList[i];
var newOption = document.createElement("option");
newOption.textContent = option;
newOption.value = option;
select.appendChild(newOption);
}
}
listEmployees();
function addToArray(){
var txtbox = document.getElementById('nameInput');
var value = txtbox.value;
employeeList.push(value);
listEmployees();
}
You're calling listEmployees() (which adds, and re-adds, everything in your list) each time a new name is added.
I'd move the add-a-new-option code out to its own function. Call it for each name in the original list, then call it again when a new name is added.
var employeeList = ['Sarah', 'Louse', 'Dan', 'John', 'Peter'];
function addEmployee(name) {
var select = document.getElementById('employeeSelect');
var newOption = document.createElement("option");
newOption.textContent = name;
newOption.value = name;
select.appendChild(newOption);
}
function listEmployees() {
for (var i = 0; i < employeeList.length; i++) {
addEmployee(employeeList[i])
}
}
listEmployees();
function addToArray() {
var txtbox = document.getElementById('nameInput');
var value = txtbox.value;
employeeList.push(value); // update the list
addEmployee(value); // update the select
}
<section id="sidebar">
<form onSubmit="return false">
<label for="Name">Name:</label>
<input id="nameInput" type="text" placeholder="Your name here..." name="name" />
<input type="submit" value="Add to list" name="Add" onClick="addToArray();">
<br>
<label for="Default">List over employees:</label>
<select id="employeeSelect">
</select>
</form>
</section>

Categories