Removing from a list - javascript

I have an add user and a remove user button. I have functions that take whatever is in a text-input and add or remove it from a select. This is my js code:
var addedUsers = [];
function add(){
var form = document.getElementById('form')
var emailInput = form.elements.typer
let email = emailInput.value
emailInput.value = ""
var select = document.getElementById('users')
var option = document.createElement("option")
option.text = email
emailInput.focus()
if (addedUsers.indexOf(email) == -1){
addedUsers.push(email)
select.add(option)
} else {
alert("This user is already one of your recipients!");
}
}
function rem(){
var form = document.getElementById('form')
var emailInput = form.elements.typer
let email = emailInput.value
emailInput.value = ""
var select = document.getElementById('users')
var options = select.options
emailInput.focus()
if (addedUsers.indexOf(email) != -1){
for (var i = 2; i < options.length; i++){
if(email === options[i].innerHTML){
select.remove(i)
addedUsers.splice(email, 1)
break
}
}
} else {
alert("This user is not already one of your recipients!")
}
}
<form id="form">
<div class="recipients">
<input type="text" class="typer" name="typer">
<br><br>
<button onclick="add()" type="button" class="ar">Add User</button>
<button onclick="rem()" type="button" class="ur">Remove User</button>
<br><br><br>
<select id="users" name="users" class="userlist" size="24">
<option class="listhead">__________*Recipents*__________</option>
<option class="listhead">-------------------------------</option>
</select>
</div>
<div class="content">
<button onclick="mail()" class="send">Send</button>
<br><br>
<textarea type:"content" name="content" class="typec" cols="113" rows="12"></textarea>
</div>
</form>
I noticed that I can add nothing at all and remove nothing at all, until an alert comes up. How can I prevent this? Also, if I hit one of the added options in the select, how do I make it show up in the text-input? Thanks!

I would say that you don't use the good methods to add and remove options to the select.
You should use appendChild to add the option to the select and removeChild to remove an option to the select.
example:
// in the add() function
select.appendChild(option)
// in the rem() function
select.removeChild(options[i])
Documentation:
element.appendChild - Reference Web API | MDN
element.removeChild - Reference Web API | MDN

As Chocolord correctly pointed out, you need to use valid methods, like appendChild and removeChild, respectively, instead of add and remove, respectively.
The reason why your program mistakenly thought the users were correctly added was that you actually added them to the array before the actual DOM operation:
addedUsers.push(email)
select.add(option)
respectively. Make sure you you invert the operation to
select.add(option)
addedUsers.push(email)

Related

How to clone or create a nested DOM node and change all its containing id values according to a current id?

I need to display some numbers, strings from a class named Student, but i can't figure it out how i can change the id from children element. I have to use JavaScript.
what i tried to do:
class Student{
static count = 0;
constructor(nume, prenume, data_nasterii, foaie_matricola){
this.IdClasa = ++Student.count;
//definirea atributelor
this.nume = nume;
this.prenume = prenume;
this.data_nasterii = data_nasterii;
this.foaie_matricola = foaie_matricola;
}
afiseazaVarsta(){
}
afiseazaNotele(){
}
calculeazaMedia(){
}
adaugaNota(nota_noua){
}
}
var Stud = [new Student("Name", "Name1", "2000.01.01", "0123123"),
new Student("Green", "Blue", "2022/12.12", "321321")];
function afisareStudenti(){
let i = 0; let bol = false;
for(let x=1; x<=Student.count; x++) {
console.log(document.getElementById("AfisareStudenti"+x)==null);
if(document.getElementById("AfisareStudenti"+x)==null)
{
i = x;
bol = true;
break;
} else {
bol = false;
}
}
if((i<=Student.count)&&(bol==true)){
for(i; i<=Student.count; i++) {
console.log("i="+i);
var div = document.querySelector('#AfisareStudenti1');
var divClone = div.cloneNode(true);
console.log(divClone);
divClone.id = 'AfisareStudenti'+(i);
div.after(divClone);
var NumeStud = document.getElementById("NumeStudent"+(i-1));
var PrenumeStud = document.getElementById("PrenumeStudent"+(i-1));
var dataNastStud = document.getElementById("intData"+(i-1));
var FoaiaMatStud = document.getElementById("FoaiaMatStud"+(i-1));
NumeStud.id = "NumeStudent"+(i);
PrenumeStud.id = "PrenumeStud"+(i);
dataNastStud.id = "intData"+(i);
FoaiaMatStud.id = "FoaiaMatStud"+(i);
}
}
}
and this is the html file(the div that i want to clone):
<!--AFISARE-->
<div id="AfisareStudenti1">
<h2> Afisare Student 1</h2>
<label>Ce student doriti sa modificati? </label>
<form>
<label>Nume:</label><br>
<input type="text" id="NumeStudent1"><br>
<label>Prenume:</label><br>
<input type="text" id="PrenumeStudent1"><br>
<label>Data Nasterii:</label><br>
<input type="date" id="intData1"><br>
<label>Foaie matricola:</label><br>
<input type="text" id="FoaiaMatStud1"><br><br>
<input class="butoane" type="submit" value="Afisare"
onclick="afisareMeniuAfisStudenti()">
</form>
</div>
the class is saved in a dynamic array (could be n object of the class) so i have to make somehow to display the information dynamic. My version changes the id from all elements with the same id (every incrementation of i, the idnumber from id is incremented also). I tried to create that div with document.createElement but is impossible(at least for me) xD . I started coding in javascript 2 days ago, so please take it slow on me :(
I think i found the problem, but it doesn't solve it. (i need to put (i-1) when calling for getting the ids). (Newbie mistake)
Having commented ...
"I have the feeling that if provided with the broader picture the audience could be of much more help since the OP could be provided back with leaner/cleaner and better maintainable approaches."
... I nevertheless hereby lately provide a template-based approach which, besides supporting the OP's id based querying of student-items, is also easier to read and to maintain.
The code provided within the example-code's main function does not just implement the usage of the template-based node-creation via template literals and DOMParser.parseFromString but also prevents the default behavior of each student-form's submit-button by making use of event-delegation.
function createStudentElement(studentId) {
const markup =
`<div class="student-item" id="AfisareStudenti${ studentId }">
<h2> Afisare Student ${ studentId }</h2>
<label>Ce student doriti sa modificati? </label>
<form>
<label>Nume:</label><br>
<input type="text" id="NumeStudent${ studentId }"><br>
<label>Prenume:</label><br>
<input type="text" id="PrenumeStudent${ studentId }"><br>
<label>Data Nasterii:</label><br>
<input type="date" id="intData${ studentId }"><br>
<label>Foaie matricola:</label><br>
<input type="text" id="FoaiaMatStud${ studentId }"><br><br>
<input
class="butoane" type="submit" value="Afisare"
onclick="afisareMeniuAfisStudenti(${ studentId })"
>
</form>
</div>`;
const doc = (new DOMParser).parseFromString(markup, 'text/html');
return doc.body.removeChild(doc.body.firstElementChild);
}
// the button click handler.
function afisareMeniuAfisStudenti(studentId) {
console.log({ studentId })
}
function main() {
const itemsRoot = document.querySelector('.student-items');
// - prevent any form-submit by making use of event-delegation.
itemsRoot.addEventListener('submit', evt => evt.preventDefault());
// - just for demonstration purpose ...
// ... create student-items from a list of student IDs.
[1, 2, 3, 4, 5].forEach(studentId =>
itemsRoot.appendChild(
createStudentElement(studentId)
)
);
}
main();
.as-console-wrapper { left: auto!important; width: 50%; min-height: 100%; }
<div class="student-items"></div>
Tom's answer above is what you want for the element id problem that you asked about.
For your code in particular, you are going to have a couple other problems:
Because the final input is type="submit", its going to reload the page by default when it is clicked. The name of the "onclick" function also needs to match the function you defined (afisareStudenti).
You have:
<input class="butoane" type="submit" value="Afisare" onclick="afisareMeniuAfisStudenti()">
Change this to:
<input class="butoane" type="submit" value="Afisare" onclick="afisareStudenti(event)">
Now, when you click that button, it will call the afisareStudenti function and pass in the "event". So if you change:
function afisareStudenti(){
let i = 0; let bol = false;
to:
function afisareStudenti(event){
event.preventDefault()
let i = 0; let bol = false;
This will correctly call your function, and prevent the "default" action of that submit button from reloading the page.
To change the id attribute of children elements, you could use Element.querySelector() on divClone.
Because if you use Document.querySelector() or Document.getElementById() you will get the first element that matches your selector (i.e.children of div#AfisareStudenti1).
let i = 2;
var div = document.querySelector('#AfisareStudenti1');
var divClone = div.cloneNode(true);
divClone.id = 'AfisareStudenti'+(i);
divClone.querySelector("h2").innerText = "Afisare Student " + i;
var NumeStud = divClone.querySelector("#NumeStudent1");
var PrenumeStud = divClone.querySelector("#PrenumeStudent1");
var dataNastStud = divClone.querySelector("#intData1");
var FoaiaMatStud = divClone.querySelector("#FoaiaMatStud1");
NumeStud.id = "NumeStudent"+(i);
PrenumeStud.id = "PrenumeStud"+(i);
dataNastStud.id = "intData"+(i);
FoaiaMatStud.id = "FoaiaMatStud"+(i);
div.after(divClone);
<div id="AfisareStudenti1">
<h2> Afisare Student 1</h2>
<label>Ce student doriti sa modificati? </label>
<form>
<label>Nume:</label><br>
<input type="text" id="NumeStudent1" /><br>
<label>Prenume:</label><br>
<input type="text" id="PrenumeStudent1" /><br>
<label>Data Nasterii:</label><br>
<input type="date" id="intData1" /><br>
<label>Foaie matricola:</label><br>
<input type="text" id="FoaiaMatStud1" /><br><br>
<input class="butoane" type="submit" value="Afisare" onclick="afisareMeniuAfisStudenti()" />
</form>
</div>

How do I change the class of a forms parent if they enter it wrong?

I'm using a at the moment in order to add a search feature to my site. I want them to enter a number that starts with 765611 and then has 11 numbers after that; if they type in a correct number, it will run the below script:
var a = document.getElementById('search');
a.addEventListener('submit',function(e) {
e.preventDefault();
var b = document.getElementById('searchbar').value;
window.location.href = 'thecopperkings.co.uk'+b;
});
If they enter a wrong number (i.e. one that does not start with 765611 and have 11 numbers proceeding it) the background of the div will flash red for two seconds (I assume the way this would be done is by adding a temporary class value which has a red background) with a transition as well, and the above code wouldn't run.
I'm pretty terrible (and new) to JS but looking at other peoples code and my basic knowledge, I assume it would have to be something along the lines of this:
var search = document.getElementByID('search');
a.addEventListener('submit',function(e) {
if document.getElementByID('searchbar').value = "765611[0-9]{11}$" {
e.preventDefault();
var b = document.getElementById('searchbar').value;
window.location.href = 'thecopperkings.co.uk'+b;
}
else {
**SET THE FORM'S CLASS TO "RED"?**
}
What is the best and most efficient way of doing this?
var a = document.getElementById('search');
a.addEventListener('submit',function(e) {
e.preventDefault();
var b = document.getElementById('searchbar').value;
window.location.href = 'thecopperkings.co.uk'+b;
});
<div>
<form class="search" id="search" method="get" action="html/player.html">
<input type="text" placeholder="What is your SteamID?" id="searchbar" name="id" maxlength="17">
<input type="submit" value="Search">
</form>
</div>
Please find the below answer.
working example can be found here jsFiddle
Add class red as .red { background-color:red !important;}
var a = document.getElementById('search');
function appendClass(elementId, classToAppend){
var oldClass = document.getElementById(elementId).getAttribute("class");
if (oldClass.indexOf(classToAppend) == -1)
{
document.getElementById(elementId).setAttribute("class", oldClass+ " "+classToAppend);
}
}
function removeClass(elementId, classToRemove){
var oldClass = document.getElementById(elementId).getAttribute("class");
if (oldClass.indexOf(classToRemove) !== -1)
{ document.getElementById(elementId).setAttribute("class",oldClass.replace(classToRemove,''));
}
}
a.addEventListener('submit',function(e) {
e.preventDefault();
var b = document.getElementById('searchbar').value;
//regular expression to match your criteria and test the sample value
if(/^765611[0-9]{11}$/.test(b)) {
alert('success -> '+ b );
window.location.href = 'thecopperkings.co.uk'+b;
} else {
//append the class red for searchid which is in form element
appendClass('search','red');
//remove the red class after 2sec(2000milliseconds)
window.setTimeout(function(){removeClass('search','red');},2000);
}
});
<div>
<form class="search" id="search" method="get" action="html/player.html">
<input type="text" placeholder="What is your SteamID?" id="searchbar" name="id" maxlength="17">
<input type="submit" value="Search">
</form>
</div>
var patt = new RegExp("765611[0-9]{11}$");
var searchbar = document.getElementByID('searchbar');
var searchForm = document.getElementByID('search');
if( patt.test(searchbar.value) ){
searchForm.classlist.remove('error');
// do your magic
} else{
searchForm.classlist.add('error');
// And maybe an alert or notice for the user
}
Also, check out the html5 input attribute pattern=""

check if selected option and checkbox is checked

I have some problems here with javascript.
I want someone to choose an option and a checked box, and if both are checked then other checkboxes should not be able to click.
I had tried to give the function 2 parameters (one is for the option and one for the checkbox).
function bs(id /*,chbxvalue */ )
{
var selectElement = document.getElementById(id);
var selectValue = selectElement.options[selectElement.selectedIndex].value;
//var select2Element = document.getElementById(chbxvalue);
//var selectCHBXval = select2Element.options[select2Element.selectedIndex].value;
if((selectValue == "banana" ) /*&& (document.getElementById("apple").checked == true )*/ )
{
document.getElementById("juice").checked = true;
}
else if(selectValue == "Salad")
{}
}
The thing in the comments doesn't work.
<div id="flavor"><br />
<select id="bss" name="beh" onChange="bs('bss')">
<option value="banana" >banana</option>
<option value="pinapple" >pinapple</option>
</select>
</div>
<div id="divcontainer" class="cont" style="display:block;">
<input type="checkbox" name="app" id="apple" value="appl" />Apples <br />
<input type="checkbox" name="juices" id="juice" value="fj" />Fruitjuice <br />
</div>
I've changed the names here. Has anybody an idea? Sorry, I am not so good with javascript... .
Sounds like you'd like to use simply
document.getElementById("...").disabled=true;
Or if you'd like to disable more checkboxes at once, assign them a class, and use
elements = document.getElementsByClassName("my_class");
for(var i = 0; i < elements.length; ++i)
{elements[i].disabled = "true"; }
I'm not exactly sure if this is what you're after, but it seems like you want some kind of conditional logic. I made a fiddle to illustrate it: https://jsfiddle.net/75uLereo/
var radios = document.myform.type,
select = document.myform.flavor;
for(var i = 0; i < radios.length; i++){
radios[i].addEventListener('change', checkValues);
}
select.addEventListener('change', checkValues);
function checkValues(){
var select = document.myform.flavor,
selectedValue = select.options[select.selectedIndex].value,
radioValue = document.querySelector('input[name = "type"]:checked').value;
if(radioValue !== "undefined"){
switch(selectedValue){
case 'none':
case 'banana':
case 'strawberry':
alert("This is "+selectedValue+" and "+radioValue+". Do some conditional logic with the values!");
break;
default:
break;
}
}
}
This binds a function to change events on the radio buttons and the select and then uses a switch on the different values to do whatever you want it to do.
Updated:
I made another example, with checkboxes and the bool value from the checkboxes if they are selected
https://jsfiddle.net/75uLereo/2/

When "check-all" box checked, check others

I have a form located on my html page with a bunch of checkboxes as options. One of the options is "check-all" and I want all the other check boxes to be checked, if unchecked, as soon as the "check-all" box is checked. My code looks something like this:
<form method = "post" class = "notification-options">
<input type = "checkbox" name = "notification-option" id = "all-post" onClick = "javascript:checkALL(this
);"> All Posts <br/>
<input type = "checkbox" name = "notification-option" id = "others-post"> Other's Posts <br/>
<input type = "checkbox" name = "notification-option" id = "client-post"> Cilent's Post <br/>
<input type = "checkbox" name = "notification-option" id = "assign-post"> Task Assigned </form>
java script:
<script type = "text/javascript">
var $check-all = document.getElementbyId("all-post");
function checkALL($check-all){
if ($check-all.checked == true){
document.getElementByName("notification-option").checked = true;
}
}
</script>
nothing happens when I run my code
Here are some guidelines.
type attribute is not needed and can be omitted.
JS variable names can't contain hyphens, a typo in
getElementById()
You're using a global variable name as an argument, in the same time
you're passing this from online handler. The passed argument shadows the
global within the function.
if (checkAll.checked) does the job
Typo in getElementsByName(), gEBN() returns an HTMLCollection,
which is an array-like object. You've to iterate through the
collection, and set checked to every element separately.
Fixed code:
<script>
var checkAll = document.getElementById("all-post");
function checkALL(){
var n, checkboxes;
if (checkAll.checked){
checkboxes = document.getElementsByName("notification-option");
for (n = 0; n < checkboxes.length; n++) {
checkboxes[n].checked = true;
}
}
}
</script>
You can also omit the javascript: pseudo-protocol and the argument from online handler.
You can do it like this using jQuery:
$("#all-post").change(function(){
$('input:checkbox').not(this).prop('checked', this.checked);
});
Here is a JSfiddle
if all post check box is checked it will set check=true of others-post and client-post check boxes
$("input[id$=all-post]").click(function (e) {
if ($("input[id$=all-post]").is(':checked')) {
$("input[id$=others-post]").prop('checked', true);
$("input[id$=client-post]").prop('checked', true);
}
});
Check to see if any of the checkboxes are not checked first.
If so, then loop through them and check any that aren't.
Else, loop through them and uncheck any that are checked
I have an example at http://jsbin.com/witotibe/1/edit?html,output
http://jsfiddle.net/AX3Uj/
<form method="post" id="notification-options">
<input type="checkbox" name="notification-option" id="all-post"> All Posts<br>
<input type="checkbox" name="notification-option" id="others-post"> Other's Posts<br>
<input type="checkbox" name="notification-option" id="client-post"> Cilent's Post<br>
<input type="checkbox" name="notification-option" id="assign-post"> Task Assigned
</form>
function checkAll(ev) {
checkboxes = document.getElementById('notification-options').querySelectorAll("input[type='checkbox']");
if (ev.target.checked === true) {
for (var i = 0; i < checkboxes.length; ++i) {
checkboxes[i].checked = true;
}
} else {
for (var i = 0; i < checkboxes.length; ++i) {
checkboxes[i].checked = false;
}
}
}

why are names not being added to the list?

I found this fiddle and I am trying to get it to work...I can not figure out why the names are not being added to the list, for some reason Add button is acting like a submit button and I can not tell why...It should add all the numbers to a list so when I click submit, then it should send the numbers in an array..
JavaScript:
function bindName() {
var inputNames = document.getElementById("names").getElementsByTagName("inputNames");
for (i = 0; i < inputNames.length; i++) {
inputNames[i].onkeydown = function() {
if (this.value == "") {
setTimeout(deletename(this), 1000);
}
}
}
}
document.getElementById("addName").onclick = function() {
var num1 = document.getElementById("name");
var myRegEx = /^[0-9]{10}$/;
var myRegEx = /^[0-9]{10}$/;
var itemsToTest = num1.value;
if (myRegEx.test(itemsToTest)) {
var form1 = document.getElementById("names");
var nameOfnames = form1.getElementsByTagName("inputNames").length;
var newGuy1 = document.createElement("inputNames");
newGuy1.setAttribute("id", nameOfnames);
newGuy1.setAttribute("type", "text");
newGuy1.setAttribute("value", num1.value);
form1.appendChild(newGuy1);
num1.value = "";
bindName();
}
else {
alert('error');
}
};
HTML:
<h1>Enter Name</h1>
<div id="mainName">
<h2>name</h2>
<label for="name">Add Names: </label>
<input id="name" type="text">
<button id="addName">Add</button>
<form>
<div id="names">
</div>
<input METHOD="POST" action="text.php" type="submit" value="Submit">
</form>
</div>
I've seen
document.createElement("inputNames");
Shouldn't be
document.createElement("input");
?
Because this /^[0-9]{10}$/; will accept only 10 numbers and only that, try entering 1234567890 and you will see no error.
I'm not sure why your "name" field is restricted to 10 digit numbers, but I've got the thing to work.
http://jsfiddle.net/y8Uju/4/
I think the problem was that you were trying to create an element with the tag name inputNames, but that's not a valid tag. Instead I changed it to create inputs, and set the class to inputNames.

Categories