Mouseover function on dynamically created list items - javascript

I'm working on a simple user input form that has users input their ID, first name, and last name into 3 separate input boxes. My main objective is to get the data input by user, add it to the "person" object, and display to an unordered list. I've figured that much out.
What I'm trying to do now, is somehow style the content of the list item that was dynamically created, using a mouseover function. I have been trying simple color changes, but I'm super rusty with javascript, and must do this without any jQuery. Any help is appreciated. Just need a push in the right direction, can't get mouseover to work at all for some reason.
Here's what I've got so far:
<form>
ID Number:<br>
<input type="text" id="idNumber">
<br>
First name:<br>
<input type="text" name="firstName" id="fName">
<br>
Last name:<br>
<input type="text" name="lastName" id="lName">
</form>
<br>
<button type ="submit" onclick="myFunction(list)">Submit</button>
<div id = "container">
<ul id="list"></ul>
</div>
<script>
function myFunction(list){
var text = "";
var person = {idNo:"", firstName:"", lastName:""};
var inputs = document.querySelectorAll("input[type=text]");
for (var i = 0; i < inputs.length; i++) {
idNo = inputs[0].value;
firstName = inputs[1].value;
lastName = inputs[2].value;
text = " "+idNo+" "+firstName+" "+lastName;
}
var li = document.createElement("li");
li.addEventListener("mouseover", mouseOver, false);
li.addEventListener("click", mouseClick, false);
var node = document.createTextNode(text);
li.appendChild(node);
document.getElementById("list").appendChild(li);
}
function mouseOver(){
li.style.backgroundColor="red";
}
</script>

li is not defined in the function mouseover use this instead -> this.style.backgroundColor = "red";
Variables are defined at function scope therefore var li is available in myFunction but not in mouseover function.
Try this sinppet:
function myFunction(list) {
var text = "";
var person = {
idNo: "",
firstName: "",
lastName: ""
};
var inputs = document.querySelectorAll("input[type=text]");
for (var i = 0; i < inputs.length; i++) {
idNo = inputs[0].value;
firstName = inputs[1].value;
lastName = inputs[2].value;
text = " " + idNo + " " + firstName + " " + lastName;
}
var li = document.createElement("li");
li.addEventListener("mouseover", mouseOver, false);
//li.addEventListener("click", mouseClick, false);
var node = document.createTextNode(text);
li.appendChild(node);
document.getElementById("list").appendChild(li);
}
function mouseOver() {
this.style.backgroundColor = "red";
}
<form>
ID Number:
<br>
<input type="text" id="idNumber">
<br>First name:
<br>
<input type="text" name="firstName" id="fName">
<br>Last name:
<br>
<input type="text" name="lastName" id="lName">
</form>
<br>
<button type="submit" onclick="myFunction(list)">Submit</button>
<div id="container">
<ul id="list"></ul>
</div>

Why use JS when you can use CSS?
JavaScript:
var li = document.createElement("li");
li.classList.add('my-li-class')
CSS:
.my-li-class:hover {
background-color: red;
}
Anyway if you want to know why your JS doesn't work it's because the li variable is defined outside the mouseOver function scope, do this instead:
function mouseOver() {
this.style.backgroundColor = 'red'
}
Or event this (may not work if li has children):
function mouseOver(evt) {
evt.target.backgroundColor = 'red'
}

Related

How do I get the Onkey Function to copy the value of a input textfield to the other 3 textfields

This is the Java Script I'm using. I can enter in the proceduredate and it copies to proceduredate2 but not 3 and 4--Same with Procedure
function copyTextAreaValue(id, ids) {
// get source element
var sourceElement = document.getElementById(id);
if(sourceElement) {
// copy to destination elements
var destIds = ids.split(',');
for(i=0; i<destIds.length; i++) {
var destEle = document.getElementById(destIds[i]);
if(destEle) {
destEle.value = sourceElement.value;
} else {
console.log('no dest element ' + destIds[i]);
}
}
}
}
Link to JSFiddle with full code
Your question id not clear to me. However, all I understood is you want to copy text from your current text input to other three text input. If that is true, then you can have your solution here. Please, checkout the snippet below.
let el = document.getElementById('field_1');
function copyTextValue() {
let elVal = el.value;
document.getElementById("field_2").value = elVal;
document.getElementById("field_3").value = elVal;
document.getElementById("field_4").value = elVal;
}
copyTextValue();
el.oninput = copyTextValue;
el.onchange = copyTextValue;
Today's Date: <input id="field_1" value=""/><br/>
Procedure Date: <input id="field_2" value=""/> <br/>
Date of Procedure: <input id="field_3" value=""/> <br/>
Surgery Date: <input id="field_4" value=""/> <br/>
function copyTextfieldValue(id, ids) {
// get source element
var sourceElement = document.getElementById(id);
if(sourceElement) {
// copy to destination elements
var destIds = ids.split(',');
for(i=0; i<destIds.length; i++) {
var destEle = document.getElementById(destIds[i]);
if(destEle) {
destEle.value = sourceElement.value;
} else {
//console.log('no dest element ' + destIds[i]);
}
}
}
}
<input id="t1">
<input id="t2">
<input id="t3">
<input id="t4">
<input type="button" value='copy' onclick="copyTextfieldValue('t1','t2,t3,t4');">
Your code seems to work fine. See the snippet.

how to add fields with increased number in name to a form using javascript?

I have a form that looks like this:
<form action="/a1/configurer/1" method="post">
<label>Fill out a revenue (such as "salary")</label>
<input type="text" name="revenu_0[category]">
<label>And the monthly amount</label>
<input type="text" name="revenu_0[amount]">
Add revenus
In this add_field() function I want to add this :
<label>Fill out a revenu</label>
<input type="text" name="revenu_1[category]">
<label>And the monthly amount</label>
<input type="text" name="revenu_1[amount]">
And when clicking the button again, name is "revenu_2" and so on (incrementing).
I have tried this:
function add_field() {
i = 1;
var extra = document.createElement("input");
extra.setAttribute("type","text");
extra.setAttribute("name","revenu_" + i + "[categorie]" );
i = i + 1;
document.getElementsByTagName('body')[0].appendChild(extra);
}
That's only a very small part of the solution and obviously, this doesn't increment.
How do I do this?
You are pretty close. The important piece you're missing is to make sure i is declared outside the add_field function scope. Then, each time you call the function, the previous value of i will be persisted in the outer scope. See below for a working example.
let i = 1;
function add_field() {
const extra = document.createElement("input");
extra.setAttribute("type","text");
extra.setAttribute("name","revenu_" + i + "[categorie]" );
extra.setAttribute("placeholder", "Field " + i);
document.getElementsByTagName('form')[0].appendChild(extra);
i = i + 1;
}
<button onclick="add_field()">Add field</button>
<form></form>
Solution #1
var i = 1;
btn.onclick = () => {
var label = document.createElement('label'),
input = document.createElement('input'),
br = document.createElement('br');
label.innerHTML = 'Label text ';
input.type = 'text';
input.name = 'revenu_' + i + '[category]';
input.placeholder = 'Field #' + i;
myForm.appendChild(label);
myForm.appendChild(input);
myForm.appendChild(br);
i++;
}
<button type="button" id="btn">Add input field</button>
<form id="myForm"></form>
Solution #2
var i = 1;
btn.onclick = () => {
var add = `
<label>Fill out a revenu</label>
<input type="text" name="revenu_${i}[category]">
<label>And the monthly amount</label>
<input type="text" name="revenu_${i}[amount]">
<br>
`;
myForm.insertAdjacentHTML('beforeend', add);
console.log(add);
i++;
}
<button type="button" id="btn">Add input field</button>
<form id="myForm"></form>
Notice that in both cases:
button must have id="btn";
form must have id="myForm".
Obviously, if you change those ids in the HTML code, you need to change them in the JS code as well.

Trying to display object properties stored within an array onto a <ul> element

I've just started learning JS and I'm trying to do some basic projects to cement what I've learned from reading and courses and tutorials and whatnot. I'm trying to make a contact list which takes 4 inputs: first name, last name, email and phone number. I wrote this part already and passed the arguments into an object within an array. What I can't figure out is how to display the contact object. I want to try and print each property into a list item within an unordered list but I'm stuck here, either because I don't know enough about DOM manipulation or just because I'm not looking in the right direction
//this passes the text input as an object to the list array
var contactList = {
list: [],
addNew: function() {
this.list.push({
firstName: document.getElementById('firstname').value,
lastName: document.getElementById('lastname').value,
email: document.getElementById('emailAdd').value,
phoneNumber: document.getElementById('phoneNumber').value
});
},
};
// this runs the addNew() function and clears the input fields afterwards
var handlers = {
addContact: function() {
contactList.addNew();
document.getElementById('firstname').value = '';
document.getElementById('lastname').value = '';
document.getElementById('emailAdd').value = '';
document.getElementById('phoneNumber').value = '';
// view.displayContact();
},
};
//this is where i'm trying to display the contacts array
var view = {
displayContact: function() {
var contacts = document.getElementById('contactul');
for (var i = 0; i < contactList.list.length; i++) {
var li = document.createElement('li');
contacts.appendChild(li);
li.innerHTML += contactList.list[i];
};
},
};
<form>
First name:<br>
<input id="firstname" type="text" name="firstname">
<br> Last name:<br>
<input id="lastname" type="text" name="lastname">
<br> Email Address:<br>
<input id="emailAdd" type="text">
<br> Phone number:<br>
<input id="phoneNumber" type="text">
<br>
</form>
<button onclick='handlers.addContact()'>Submit</button>
<div id='displayContacts'>
<ul id='contactul'>
</ul>
</div>
This is the desired result. I just can't figure out how to write it.
Well, you're close. The problem you have here is that when you go to display your items, you have to get the values for each individual element (first name, last name, etc). You can do that through another loop, or just hard-code each one since there are only 4. Here is an example:
//this passes the text input as an object to the list array
var contactList = {
list: [],
addNew: function() {
this.list.push({
firstName: document.getElementById('firstname').value,
lastName: document.getElementById('lastname').value,
email: document.getElementById('emailAdd').value,
phoneNumber: document.getElementById('phoneNumber').value
});
},
};
// this runs the addNew() function and clears the input fields afterwards
var handlers = {
addContact: function() {
contactList.addNew();
document.getElementById('firstname').value = '';
document.getElementById('lastname').value = '';
document.getElementById('emailAdd').value = '';
document.getElementById('phoneNumber').value = '';
view.displayContact();
},
};
//this is where i'm trying to display the contacts array
var view = {
displayContact: function() {
var contacts = document.getElementById('contactul');
while(contacts.firstChild ){
contacts.removeChild(contacts.firstChild );
}
for (var i = 0; i < contactList.list.length; i++) {
var liForFirstName = document.createElement('li');
contacts.appendChild(liForFirstName);
liForFirstName.innerHTML += "First Name: " + contactList.list[i].firstName;
var liForLastName = document.createElement('li');
contacts.appendChild(liForLastName);
liForLastName.innerHTML += "Last Name: " + contactList.list[i].lastName;
var liForEmail = document.createElement('li');
contacts.appendChild(liForEmail);
liForEmail.innerHTML += "Email: " + contactList.list[i].email;
var liForPhoneNumber = document.createElement('li');
contacts.appendChild(liForPhoneNumber);
liForPhoneNumber.innerHTML += "Phone Number: " + contactList.list[i].phoneNumber;
};
},
};
<form>
First name:<br>
<input id="firstname" type="text" name="firstname">
<br> Last name:<br>
<input id="lastname" type="text" name="lastname">
<br> Email Address:<br>
<input id="emailAdd" type="text">
<br> Phone number:<br>
<input id="phoneNumber" type="text">
<br>
</form>
<button onclick='handlers.addContact()'>Submit</button>
<div id='displayContacts'>
<ul id='contactul'>
</ul>
</div>

Change HTML tag with Javascript

I asking the user to select given emails, and getting them with javascript from a form on click.
If I have an href like
And I have a bunch of checkboxes for every email obtained from the database
Using javascript, how can I add this value into the emails="" tag by clicking the checkbox?
You can listen to change event for each checkbox to keep track of checked emails:
var boxes = document.querySelectorAll('input[name=email]');
var link = document.getElementById('myHref');
var emails = [];
boxes.forEach(box => box.addEventListener('change', function(e) {
var v = e.target.value;
if (e.target.checked === true) {
if (!emails.includes(v)) emails.push(v);
} else {
emails.splice(emails.indexOf(v), 1);
};
link.setAttribute('emails', emails.join(', '));
console.log(link.attributes.emails.value)
}))
<input type="checkbox" value="1#d.com" name="email">
<input type="checkbox" value="2#d.com" name="email">
<input type="checkbox" value="3#d.com" name="email">
Link
You can set a click event on the checkbox.
var arr_el = document.getElementsByClassName('check-boxes');
for(var i = 0; i < arr_el.length; i++){
arr_el[i].addEventListener('click', function(){
var el = document.getElementById('myHref');
var emails = el.getAttribute('emails');
var userSelectedEmail = this.value;
if(this.checked){
el.setAttribute('emails', emails + ';' + userSelectedEmail);
} else {
// debugger;
emails = emails.split(';');
var index = emails.indexOf(userSelectedEmail);
emails.splice(index, 1);
el.setAttribute('emails', emails.join(';'));
}
document.getElementById('emails').innerText = el.getAttribute('emails');
});
}
<html>
<head>
</head>
<body>
<a id="myHref" href="#" emails="test#email.com">Link</a>
<br>
<input class="check-boxes" type="checkbox" value="email2#gmail.com">email2#gmail.com<br>
<input class="check-boxes" type="checkbox" value="email3#gmail.com">email3#gmail.com<br>
<input class="check-boxes" type="checkbox" value="email4#gmail.com">email4#gmail.com<br>
<input class="check-boxes" type="checkbox" value="email5#gmail.com">email5#gmail.com<br>
<p id="emails"></p>
</body>
</html>

implementing insertbefore() in loop

I am trying to show error messages below an array of textboxes that I have selected using Javascript. The error messages are being put by creating a new span element and using the insertBefore() method. The span element is created in the function since I don't want to hard code it into the DOM. The span messages do show but each time I submit the form, they are appended over and over again. I'd like to show the span messages only once and each time the form is submitted, they are shown once only. Below is my code.
HTML
<div class="slideshow">
<form id="form">
<input type="text" name="1" class="textbox" />
<input type="text" name="2" class="textbox" />
<input type="text" name="3" class="textbox" />
<input type="submit" name="submit" value="submit" id="submit" />
</form>
</div>
JAVASCRIPT
<script>
var slideshow = document.querySelector('.slideshow');
// var span = document.createElement('span');
var form = document.querySelector('#form');
var inputs = form.querySelectorAll('.textbox');
form.addEventListener('submit', function(e)
{
e.preventDefault();
for( var i=0; i<inputs.length; i++ )
{
var span = document.createElement('span');
(function(index)
{
span.innerHTML = 'error ' + index;
inputs[index].parentNode.insertBefore(span, inputs[index].nextElementSibling);
})(i);
}
}, false);
</script>
Each time I submit, I'd like the error messages to be shown below the textbox and not appended over and over again. They should be shown just once and I'd like to do this without using jQuery or any sort of library.
I rewerite your example to create available 3 span tags instead of crate them in code. If there are some errors, populate them to span rather than creating/deleting the spans in code.
var slideshow = document.querySelector('.slideshow');
var form = document.querySelector('#form');
var inputs = form.querySelectorAll('.textbox');
form.addEventListener('submit', function (e) {
e.preventDefault();
for (var i = 0; i < inputs.length; i++) {
(function (index) {
document.getElementsByTagName('span')[index]
.innerHTML = 'error ' + index;
})(i);
}
}, false);
<div class="slideshow">
<form id="form">
<input type="text" name="1" class="textbox" /><span></span>
<input type="text" name="2" class="textbox" /><span></span>
<input type="text" name="3" class="textbox" /><span></span>
<input type="submit" name="submit" value="submit" id="submit" />
</form>
</div>
Hope this help.
Just do a check before you insert. Here is one way to do it.
form.addEventListener('submit', function (e) {
e.preventDefault();
for (var i = 0; i < inputs.length; i++) {
var span = document.createElement('span');
(function (index) {
span.innerHTML = 'error ' + index;
if (inputs[index].nextElementSibling.tagName !== 'SPAN')
inputs[index].parentNode.insertBefore(span, inputs[index].nextElementSibling);
})(i);
}
}, false);
You have to wait for page to be load, the you should run JavaScript.
PageLoad Event : window.onload=function(){}
Code :
<script type="text/javascript">
window.onload = function () {
var slideshow = document.querySelector('.slideshow');
var form = document.getElementById('form');
var inputs = document.querySelectorAll('.textbox');
form.addEventListener('submit', function (e) {
e.preventDefault();
for (var i = 0; i < inputs.length; i++) {
var span = document.createElement('span');
(function (index) {
span.innerHTML = 'error ' + index;
inputs[index].parentNode.insertBefore(span, inputs[index].nextElementSibling);
})(i);
}
}, false);
}
</script>
Put your code in window.onload event.

Categories

Resources