List item can't be added using javascript - javascript

I checked all the code and there is nothing wrong with it. When I check the "vegetables" radio button, write something in the text field and hit add, it doesn't add the element.
function add() {
var item;
item = document.getElementById("item").value;
if (document.getElementById("1").checked) {
var li = document.createElement(li);
text = document.createTextNode(item);
li.appendChild(text);
document.getElementById("1v").appendChild(li);
}
}
<section>
<h1>Welcome to your shopping List!</h1>
<h2>Type in the item, choose its type, and hit add !!</h2>
<div id="blue">
<form action="">
<label for="task">I need :</label><br>
<input type="text" placeholder="Example : Apples" id="item" name="item"><br>
<br>
<label for="type">which is :</label><br>
<div class="">
<input type="radio" id="1" name="type" value="Vegetables">
<label for="">Vegetables</label><br>
</div>
<br>
<button id="add" onclick="add()">Add !</button>
</section>
</form>
</div>
<br>
<footer id="white">
<div>
<table border="bold">
<th>Vegetables</th>
<tbody>
<tr>
<td>
<ol id="1v"></ol>
</td>
</tr>
</tbody>
</table>
</div>
</footer>

You have several problems:
You are using a form, so when you click the button, the form
submits and you leave the page. In your case, you aren't really going to submit data anywhere, so you really don't even need the form element or to specify name attributes for your fields.
You don't have li in quotes, so you aren't actually creating an
<li> element. Without quotes, the system thinks li is a variable, but since you don't have a variable called that, a new Global variable is created with a value of undefined, so your code executes as: document.createElement("undefined"), which does actually create: <undefined></undefined>, but since that isn't an actual HTML element, nothing is rendered for it, except the text you placed inside it (but no numbering):
var li;
let el = document.createElement(li);
console.log(el);
You are using label incorrectly. A <label> element correlates to a form-field element (i.e. input, select, textarea) as a way to have a "caption" for that element. To use it, you should set its for attribute to the id of the form-field its associated with or you can not use for and just nest the form-field its associated with inside of the label. label is not just for text you want to display.
Your HTML is not nested properly and you are missing elements.
Tables should really not be used for anything but displaying tabular
data. They should not be used for layout. Since you are creating new
ordered list items for each item added, you should not use a table.
But, even when you do, you can't just have th. th must be inside
of tr, which would then be inside of thead.
A footer element is meant to provide "the fine print" content at the end of a section. Producing your list isn't that kind of content and shouldn't be in a footer.
Here's all of that put toghether:
// Get your DOM references just once
const item = document.getElementById("item");
const list = document.getElementById("1v");
const veg = document.getElementById("type");
// Don't use inline HTML event attributes to set up events.
// Do your event binding in JavaScript, not HTML.
document.getElementById("add").addEventListener("click", add);
function add() {
if (veg.checked) {
var li = document.createElement("li"); // <-- Need quotes around the element name
li.textContent = item.value;
list.appendChild(li);
}
}
table,th,td { border:1px solid black; }
<section>
<h1>Welcome to your shopping List!</h1>
<h2>Type in the item, choose its type, and hit add !!</h2>
<div id="blue">
I need : <input type="text" placeholder="Example : Apples" id="item"><br>
<br>
which is : <input type="checkbox" id="type" value="Vegetables"> Vegetables
<div><button id="add">Add !</button></div>
</div>
</section>
<br>
<footer id="white">
<div>
Vegetables
<ol id="1v"></ol>
</div>
</footer>

2 quick fixes to your code (personally, I would rewrite the whole thing):
add type="button" to the button. It will prevent the button from defaulting to a submit.
Syntax error in var li = document.createElement(li);. the li should be in quotes:
var li = document.createElement('li');

Related

Remove option item from dataset

Am trying to achieve the following:
The user can select a resource name from a datalist.
The selected resource name will be created in another div.
At the same time, the resource name should be removed from the original datalist. Just to prevent from having the user selecting the same resource name again.
I used the following HTML Code:
<div class="container-client">
<form action="#">
<div class="user-details">
<div class="input-box">
<span class="details">Collaborateurs<small>*</small></span>
<input type="text" placeholder="Selectionner un collaborateur" list="resource-list" required autocomplete="off" id="candidate">
<datalist id="customer-list">
<option value="Alex">Menuisier</option>
<option value="Peter">Charpentier</option>
<option value="Alain">Ingénieur béton</option>
<option value="Adam">Placo</option>
</datalist>
</div>
<div class="button-plus">
<input type="button" value="+" onClick="addResource();">
</div>
</div>
</form>
<hr>
<form action="index.html">
<div class="user-details">
<div class="input-box">
<span class="details">Mon équipe:</span>
</div>
<div class="new-box" id="dynamic-list">
</div>
<div class="new-box">
<div class="button">
<input type="submit" value="✔">
</div>
</div>
</div>
</form>
</div>
Here below the JS code I tried to use; adding the resource name to the div works completely fine, however the removal of the resource name doesn't work.
function addResource()
{
var new_team_member = document.getElementById ('dynamic-list');
var generic_list = document.getElementById ('resource-list');
var candidate = document.getElementById("candidate");
if (candidate.value =='')
{
alert('No data selected');
}
else
{
var div = document.createElement("div");
div.setAttribute('class','input-box');
var input = document.createElement("input");
input.setAttribute('type','text');
input.setAttribute('placeholder',candidate.value);
input.setAttribute('disabled','disabled');
div.appendChild(input);
new_team_member.appendChild(div);
generic_list.removeChild(candidate);
document.getElementById('candidate').value = '';
}
}
The error message I got is about "add-resources.js:20 Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node." indicating thatt the following JS line is causing the problem: generic_list.removeChild(candidate);
Can you please help recommending a solution. Thanks in advance.
First of all, in the code, you provided the resource-list and customer-list look like they should be the same thing. In the input tag, the customer-list is used, and in the datalist, the resource-list is used. I've guessed that both of these should be resource-list, to link them correctly.
It looks like you are trying to get the datalist item that you clicked. In the code, as it is right now, you are removing the <input> tag as your candidate variable. If you would remove this, the whole input field would be gone, and the error is caused by this input field not being a child of the generic_list variable.
Now to solve this issue, you can use the document.querySelector() function to get the datalist item that was selected. The following change to your code would have the desired effect:
function addResource()
{
var new_team_member = document.getElementById ('dynamic-list');
var generic_list = document.getElementById ('resource-list');
var candidate = document.getElementById("candidate");
if (candidate.value =='')
{
alert('No data selected');
}
else
{
var div = document.createElement("div");
div.setAttribute('class','input-box');
var input = document.createElement("input");
input.setAttribute('type','text');
input.setAttribute('placeholder',candidate.value);
input.setAttribute('disabled','disabled');
div.appendChild(input);
new_team_member.appendChild(div);
// Get datalist item with selected candidate
datalist_item = document.querySelector('#resource-list option[value="'+CSS.escape(candidate.value)+'"]');
// Remove item from list
generic_list.removeChild(datalist_item);
document.getElementById('candidate').value = '';
}
}
This query selector allow you to use CSS like syntax to select elements. In the string '#resource-list option[value="'+CSS.escape(candidate.value)+'"]' it first finds the resource list, and then takes the option tag that has the candidate name as its value.
For security, I also use the CSS.escape() function that makes sure any name with special characters gets correctly escaped in this string.

How to solve ERROR TypeError: Cannot read property 'Checked' of undefined this error

Hi i need to remove multiple files uploaded from an array based on user selection in javascript or angular.........
I have tried with below code
First we have a files that are uploaded in an array and is displayed in checkboxes as shown below in code
<div *ngFor="let image of uploadedImages" style="margin-left:10%" >
<label class="container" style="font-size:14px">
{{image.name}} ModifiedDate: {{image.lastModifiedDate}}
<input type="checkbox" style="float:left" value="{{image.name}}" id="lifecheck"
[name]="image.name">
<span class="checkmark"></span> <br><br>
</label>
</div>
<div style="padding-left:34px;padding-bottom:3px;">
<button *ngIf="imagefilename.length" class="btn btn-danger" style="width:200px;padding-left:30px" (click)="dropzone.reset();resetimage(image.Checked)">
Reset Selected files
</button>
</div>
The user will click on the checkboxes that are to be removed and the click on the button displayed and
it calls a function as displayed below
resetimage(imageName:any) {
for(var index = 0; index<this.uploadedImages.length;index++){
if(document.getElementByName("lifecheck")[i].checked==true){
this.uploadedImages.splice(index,1);
}
}
}
So in this function ,only first file in an array is getting removed where the user has selected multiple files to remove
So please help me if there is any solution
Expected result :
to remove multiple files uploaded from an array based on user selection in javascript or angular
Actual result :
Getting error
In your typescript document.getElementByName("lifecheck") cannot find the element in the dom hence you getting the error. In your dom you are creating dynamic input elements with id ='lifecheck'. This is already the wrong way of assigning ids, since dom ids must be unique.
So to fix this you can change your view to assign dynamic unique ids to your input elements:
<div *ngFor="let image of uploadedImages;let i=index" style="margin-left:10%" >
<label class="container" style="font-size:14px">
{{image.name}} ModifiedDate: {{image.lastModifiedDate}}
<input type="checkbox" style="float:left" value="{{image.name}}" id="lifecheck_{{i}}"
[name]="image.name">
<span class="checkmark"></span> <br><br>
</label>
</div>
<div style="padding-left:34px;padding-bottom:3px;">
<button *ngIf="imagefilename.length" class="btn btn-danger" style="width:200px;padding-left:30px" (click)="dropzone.reset();resetimage(image.Checked,i)">
Reset Selected files
</button>
So you are creating input elements with id= "lifecheck_1" etc. Then you can pass this id to your typescript function and find the element:
resetimage(imageName:any,id:number) {
for(var index = 0; index<this.uploadedImages.length;index++){
if(document.getElementById("lifecheck_" + id).checked==true){
this.uploadedImages.splice(index,1);
}
}
}
NOTE: this should be the way to fix your error;

How to use checked input values used for math as part of cloned div elements

I have written a script that clones a certain div as required by the user. Within the div there are three checkbox input options and each option as a numeric value. I want the script to allow the user to select a checkbox and then the value will be reflected in another input space and each value that are added will be separated by a comma.
The tricky part is that it should be done for each clone, and that each checkbox has the same class name to which the script should be written. I realize that using unique id's would be better, but I would like it that a for loop could do it for any number of checkboxes under the specific class.
Here is the html script:
<style>
.hidden {
display: none;
}
</style>
<body>
<h2>Test</h2>
<button id="add">Add</button>
<div class="test hidden">
<div class="user_input1">
<label>Input1</label>
<input class="input1" type="text" required>
<label>Input2</label>
<input type="text" name="value2" required>
<div class="user_input2">
<table>
<thead>
<tr>
<th>Pick Option</th>
</tr>
</thead>
<tbody>
<tr id="append">
<td><input class="test" type="checkbox" name="test" value="1">Test1</td>
<td><input class="test" type="checkbox" name="test" value="2">Test2</td>
<td><input class="test" type="checkbox" name="test" value="3">Test3</td>
</tr>
</tbody>
</table>
<input type="text" id="insert" name="check">
<button class="hidden" id="testbtn">Calc</button>
</div>
</div>
</div>
<form action="server/server.php" method="POST">
<div class="paste">
</div>
<button type="submit" name="insert_res">Submit</button>
</form>
</body>
And my attempt for the jQuery:
$(document).ready(function() {
var variable = 0
$("#add").click(function() {
var element = $(".test.hidden").clone(true);
element.removeClass("hidden").appendTo(".paste:last");
});
});
$(document).ready(function(event) {
$(".test").keyup(function(){
if ($(".test").is(":checked")) {
var test = $(".test").val();
};
$("#insert").val(test);
});
$("#testbtn").click(function() {
$(".test").keyup();
});
});
I think a for loop should be used for each checkbox element and this to specify each individual clone, but I have no idea where or how to do this. Please help!
I am assuming you already know how to get a reference to the dom element you need in order to append, as well as how to create elements and append them.
You are right in that you can loop over your dataset and produce dom elements with unique id's so you can later refer to them when transferring new values into your input.
...forEach((obj, index) => {
(produce tr dom element here)
(produce three inputs, give all unique-identifier)
oneOfThreeInputs.setAttribute('unique-identifier', index); // can set to whatever you want, really
(proceed to creating your inputs and appending them to the tr dom element)
targetInputDomElementChild.setAttribute('id', `unique-input-${index}`); // same here, doesn't have to be class
});
Observe that I am using template strings to concat the index number value to the rest of the strings. From then on, you can either reference the index to refer to the correct input or tr using jquery in your keyUp event handler:
function keyUpEventHandler($event) {
const index = $(this).attr('unique-identifier');
const targetInput = $(`#unique-input-${index}`)
// do stuff with targetInput
}
I have created a fiddle to show you the route you can take using the above information:
http://jsfiddle.net/zApv4/48/
Notice that when you click an checkbox, in the console you will see the variable number that designates that set of checkboxes. You can use that specific number to get the input you need to add to and concat the values.
Of course, you still need to validate whether it is being checked or unchecked to you can remove from the input.

Simple Javascript front-end message board design

I am working on a personal blog website project, and I wanted to implement a simple message board on my index page. Due to the projected site traffic (relatively low) I decided on only using a front-end implementation without linking to a database with the following js and html code:
<section class="message-board">
<div class="title">
<h2>
Leave a message
</h2>
</div>
<textarea class="message" type="text"></textarea><br/>
<input value="submit" type="button" class="submit-btn">
<div class="display-area">
Existing comment:
</div>
</section>
and then the js,
<script>
window.onload=function() {
var displayArea = document.getElementsByClassName("display-area");
var btn = document.getElementsByClassName("submit-btn");
btn.onclick = function() {
var comment = document.getElementsByClassName("message").value;
displayArea.appendChild(comment);
};
}
</script>
My intention was to make my display-area contain whatever was put in textarea via .appendChild when submit is clicked. Sadly, it isn't working as intended-nothing actually happens. I am thinking about potential errors in my js code, but just couldn't figure out anything that would resolve the problem.
Any assistance will be greatly appreciated!!!
getElementsByClassName() returns a collection of elements (note the s in Elements). If you have only one element that matches the class name, you have this element in the first index of the array-like collection.
var displayArea = document.getElementsByClassName("display-area")[0];
var btn = document.getElementsByClassName("submit-btn")[0];
You can also use querySelector(), that uses CSS selectors (like jQuery) and returns a single element:
var displayArea = document.querySelector(".display-area");
In order to append a text node (your variable comment stores a string), use append() instead of appendChild():
displayArea.append(comment);
Two ways this can be done are by calling the JavaScript function on click, or by calling it on form submission.
1) call function onclick:
Wrap your form within a form tag, and call your JavaScript function based on the element Ids.
Note the showInput function is being called onclick when the button is clicked.
function showInput() {
console.log('showInput called...')
var userInput = document.getElementById("userInput").value;
var display = document.getElementById("display");
display.innerHTML = userInput;
}
<section class="message-board">
<div class="title">
<h2>
Leave a message
</h2>
</div>
<form>
<textarea class="message" type="text" id="userInput"></textarea><br/>
</form>
<input type="submit" onclick="showInput();">
<div class="display-area">
Existing comment:
</div>
<p><span id="display"></span></p>
</section>
Here's a jsfiddle, with the same code as above: http://jsfiddle.net/ethanryan/94kvj0sc/
Note the JavaScript in the jsfiddle is being called at the bottom of the Head section of the HTML.
2) call function on form submit:
You can also do this by calling the JavaScript function on the submission of the form, instead of on the click of the button. However, since this form uses a textarea, hitting return will add a line break to the text, and not submit the form, so the button still needs to be clicked for the function to be called.
function showInput() {
console.log('showInput called...')
event.preventDefault()
var userInput = document.getElementById("userInput").value;
var display = document.getElementById("display");
display.innerHTML = userInput;
}
<section class="message-board">
<div class="title">
<h2>
Leave a message
</h2>
</div>
<form onsubmit="showInput()">
<textarea class="message" type="text" id="userInput"></textarea><br/>
<input type="submit" value="Submit">
</form>
<div class="display-area">
Existing comment:
</div>
<p><span id="display"></span></p>
</section>
Note the event.preventDefault() in the form, since the default behavior of forms is to submit data to a backend database.
jsfiddle: http://jsfiddle.net/ethanryan/qpufd469/
3. appending instead of replacing text
Finally, my examples above used innerHTML to replace the userInput text. If you want to append instead of replace the text, you can use insertAdjacentHTML to add the text to the end, and then append a linebreak to it. Finally, you can reset the form.
function showInput() {
console.log('showInput called...')
event.preventDefault()
var userInput = document.getElementById("userInput").value;
var display = document.getElementById("display");
var theForm = document.getElementById("theForm");
var linebreak = document.createElement("br");
display.insertAdjacentHTML('beforeend', userInput);
display.appendChild(linebreak);
theForm.reset();
}
<section class="message-board">
<div class="title">
<h2>
Leave a message
</h2>
</div>
<form onsubmit="showInput()" id="theForm">
<textarea class="message" type="text" id="userInput"></textarea><br/>
<input type="submit" value="Submit">
</form>
<div class="display-area">
Existing comment:
</div>
<p><span id="display"></span></p>
</section>
jsfiddle: http://jsfiddle.net/ethanryan/x4hq0Lzp/

jquery mobile listview count items after filter

I need some help. I am trying to display the number of visible listview items after filter has been applied, either by a button click or by applying a text filter. The button clicks simply put text into the text filter and so it's all the same trigger point hopefully.
Html is pretty much like this...
<div>
<form class="ui-filterable">
<input id="myFilter" data-type="search" placeholder="Text Filter...">
</form>
<div data-role="fieldcontain">
<input type="button" data-inline="true" value="More Info Provided" id="more-info-provided-filter" />
<input type="button" data-inline="true" value="In Progress" id="in-progress-filter" />
</div>
<p id="listInfo"></p>
<ol data-role="listview" id="myList" data-filter="true" data-input="#myFilter"></ol>
</div>
And my javascript for each button click is just like this...
$(document).on('click', '#in-progress-filter', function(){
$('input[data-type="search"]').val('in progress');
$('input[data-type="search"]').trigger("keyup");
var volListItemsDisplayed;
volListItemsDisplayed = $("#myList li:visible").length;
document.getElementById("listInfo").innerHTML = "Number of items (filter on): " + volListItemsDisplayed;
});
The javascript fires before the filter is applied. Is there a way that I can attach my function to the filter, like an onchange type of event? You can assume the listview is populated with records containing either of the text strings being applied by the buttons.
Thanks
With JQM you can do it following way:
$(document).on("pagecreate", "#search-page-id", function(e) {
$("#my-list" ).on("filterablefilter", function(e, data) {
var result = $(this).children("li").not(".ui-screen-hidden").length;
console.log("FILTERED ITEMS: ",result);
});
});
If inside your listview you have also list dividers, you may narrow down the filter by excluding them:
var result = $(this).children("li").not("[data-role=list-divider]").not(".ui-screen-hidden").length;

Categories