Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I have this:
<form>
Input name: <input type="text"/><br/>
Input last name: <input type="text"/><br/>
Your age: <input type="number"/><br/>
Your points: <input type="number"/><br/>
Overral: <input type="number"/><br/>
<button type="submit">Submit</button><br>`
What I want to do, so, as you can so i have button sumbit, and I want when i click it to make numbered list of my form. Something like this:
Mark
Williams
....
Try this, it takes all inputs and appends into a list
$(document).ready(function(){
$('button').click(function(e){
e.preventDefault();
$('#a').append('<ol><li>'+$("#name").val()+'</li><li>'+$("#last").val()+'</li><li>'+$("#age").val()+'</li><li>'+$("#points").val()+'</li><li>'+$("#over").val()+'</li></ol>')
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
Input name: <input type="text" id="name"/><br/>
Input last name: <input type="text" id="last"/><br/>
Your age: <input type="number" id="age"/><br/>
Your points: <input type="number" id="points"/><br/>
Overral: <input type="number" id="over"/><br/>
<button type="submit">Submit</button><br></form>
<div id="a"></div>
At the risk of overly complicated and wordy to newcomers (particularly when compared to 5 lines of jQuery) - here's a plain JavaScript approach with a bit of explanation as to what's going on at every step.
Adding people to the list:
<!--
1 ) Add an ID so we can identify the form
-->
<form id="person-add">
Input name: <input type="text"/><br/>
Input last name: <input type="text"/><br/>
Your age: <input type="number"/><br/>
Your points: <input type="number"/><br/>
Overral: <input type="number"/><br/>
<!-- 2 ) Add an onclick event to run a JavaScript function.-->
<button onclick="addPerson(event);">Submit</button><br>
</form>
<!-- 3 ) Add the list we'll add people to. This has an ID as well.-->
<ol id="person-list">
</ol>
<!-- 4 ) Then the JavaScript function that activates when the button is pressed. -->
<script type="text/javascript">
// It accepts a parameter, 'event' - this is passed from the onclick event.
function addPerson(event){
// By default, clicking a button in a form submits the form to the server.
// Since we're using JavaScript to create the list, we'll prevent that from happening.
event.preventDefault();
// Using querySelectorAll, we get all the input fields within '#person-add'
var person_fields = document.querySelectorAll('#person-add input');
// Here we get the #person-list element we'll be adding the person to.
var person_list = document.getElementById('person-list');
// Create a list item for the person, but don't put it in the list yet.
var person = document.createElement('li');
// Loop through the fields and add their value list item.
for( var field = 0; field < person_fields.length; field++ ) {
// Add the value of the field to the person list item.
person.innerText += person_fields[field].value;
// If the next item isn't the end of the list, we'll add a space.
if( field + 1 !== person_fields.length ){
person.innerText += ' ';
}
}
// Lastly, add the person to the person_list.
person_list.appendChild(person);
}
</script>
Sorting the list by high score:
If you wanted to extend upon this, one thing to do would be to add field names to the input fields, so you could build an array of people and then list them in order of who has the most points.
I'm not going to tell you exactly how to implement this - but here's a few hints to get you started:
Setting field names
<input type="number" name="points"/>
Creating a list of people
// Create an empty list.
var people = [];
Creating an object to respresent a person
// Create an empty object.
var person = {};
Adding values to an object
// Add a property matching the field name with the field value.
person[ person_fields[field].getAttribute('name') ] = person_fields[field].value;
Adding an object to a list
// Add the person to the list of people.
people.push( person );
Draw the list in order of highest points to lowest
Check out Mozilla docs for a breakdown of JavaScript for array sorting.
function updateList(){
// Here we get the #person-list element we'll be adding the person to.
var person_list = document.getElementById('person-list');
// Empty the person_list as we're redrawing it in order.
person_list.innerHTML = '';
// Sort the people list by highest points.
people.sort( function( person1, person2 ) {
return person2.points - person1.points;
} );
// Loop through the fields and add their value list item.
for( var position in people ) {
// Create a list item for the person, but don't put it in the list yet.
var list_item = document.createElement('li');
// Get the person.
var person = people[position];
// Add the value of the field to the person list item.
list_item.innerText += person.firstname + ' ' + person.lastname;
list_item.innerText += ' ( ' + person.points + ' points )';
// Add the list item to the person_list.
person_list.appendChild(list_item);
}
}
Hope this helps!
Related
This question already has answers here:
Stop input from clearing on innerHTML insert
(4 answers)
Closed 8 months ago.
Hi Folks I'm new to JS World.
I am trying to add A <div> dynamically to my HTML with the help of JavaScript.
var counter = 0;
function add_more_animals() {
counter+=1;
html = `<div id="animal${counter}">
<input type="text" name="animalName${counter}">
<input type="text" name="animalType${counter}">
</div>`;
var form = document.getElementById("animals");
form.innerHTML+=html;
}
<div id="animals">
<div id="animal0">
<input type="text" name="animalName0">
<input type="text" name="animalType0">
</div>
</div>
<button type="button" onclick="add_more_animals()">Add animals (+)</button>
The issue I'm facing:
While I populate the fields of animalName0 and animalType0 on UI. After I click on add button so as to insert more animals data, new div is created as per JS logic written in file. But my earlier inputs to animalName0 & animalType0 becomes empty & I have to insert data there all over again.
Can you please help here?
The problem stems from the line form.innerHTML+=html which is shorthand for form.innerHTML = form.innerHTML + html. When it gets the form.innerHTML it is grabbing the HTML only; The text typed into the inputs are not a part of this HTML. When the innerHTML gets set, think form.innerHTML = form.innerHTML + html, brand new HTML elements are created based off of the HTML only, and any state, including typed in text, is lost. Any event listeners will also be lost in this process.
The proper way of adding a new element while leaving adjacent elements in place is to create the new element with document.createElement, and add it with a function like .appendChild, like so
var counter = 0
function add_more_animals() {
counter+=1;
// Create an empty element
const newEl = document.createElement('div')
newEl.id = `catalogue${counter}`
// Add the first input
const nameInput = document.createElement('input')
nameInput.name = `animalName${counter}`
newEl.appendChild(nameInput)
// Now the second one
const typeInput = document.createElement('input')
typeInput.name = `animalType${counter}`
newEl.appendChild(typeInput)
// And finally attach everything to the animals form
document.getElementById("animals").appendChild(newEl)
}
<div id="animals">
<div id="animal0">
<input type="text" name="animalName0">
<input type="text" name="animalType0">
</div>
</div>
<button type="button" onclick="add_more_animals()">Add animals (+)</button>
As you can imagine, this can become verbose if you have a large amount of HTML to add. To make this process easier they came out with template tags which you may prefer using. Use them either like this or like this.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I need to be able to search in an array of objects.
I have a HTML-for:
<form action="#" id="filters">
<label for="search">Search</label>
<input type="search" name="search" id="search"/>
</form>
<div id="searchresult"></div>
I have no idea how to begin, can someone help me?
Thanks in advance!
There are more than one ways to achieve what you are trying to do.
One way would be to attach an input event to the input field so that whenever there's a change in the input field value, you can get the input field value and then use filter method to filter the meals array based on the value of the input field. Finally, you can display the filtered results in the searchresult div.
const meals = [
{
id: 1,
title: 'Strawberry Salad with Poppy Seed Dressing',
img: 'Strawberry-Salad-with-Poppy-Seed-Dressing.jpg',
book: 1
},
{
id: 2,
title: 'Cashew Turkey Salad Sandwiches',
img: 'turkey-sandwich.jpg',
book: 2
}
];
const searchField = document.querySelector('#search');
const searchResultsContainer = document.querySelector('#searchresult');
searchField.addEventListener('input', (e) => {
// if input field is empty, clear the search results
if(e.target.value === '') {
searchResultsContainer.innerHTML = '';
return;
}
// filter the meals array
const searchResults = meals.filter(meal => {
return meal.title.toLowerCase().includes(e.target.value.toLowerCase());
});
// before displaying the search results, clear the search results div
searchResultsContainer.innerHTML = '';
// display the titles of the meal objects that include the text entered in input field
searchResults.forEach((element, index) => {
const p = document.createElement('p');
p.textContent = (index + 1) + '. ' + element.title;
searchResultsContainer.appendChild(p);
});
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<form action="#" id="filters">
<label for="search">Search</label>
<input type="search" name="search" id="search"/>
</form>
<div id="searchresult"></div>
</body>
</html>
Without revealing complete code and say, here you are, I will try to navigate you so you can come up with your own solution instead. follow roughly these steps:
listen to your search input = When you type on keyboard you want to
update search results. You can listen for onkeypress,
onkeydown or simple input change
other events inside the input
when key is pressed you need to check the new value inside input = You can do that by checking it's value property.
lastly, you want to get only objects from the list conforming to the
search value = there are sleek JS functions to filter out items in an
array or you can do it in standard for loop
Hope that gives you some idea about what to do. This might be a source of inspiration for you
Try using
array.filter(function(currentValue, index, arr), thisValue)
This question already has answers here:
How can I remove a specific item from an array in JavaScript?
(142 answers)
Closed 5 years ago.
The websites purpose is to store and order book titles, I need to make it so that the user can delete books they have entered into the array. I'm pretty new at Javascript but have a little bit of Java and C# experience.
Little bit stuck on this one. Was doing some reading about removing elements from the array within the code with splice and delete. But when i create a function for it, it removes everything in the array and not just the text box input string.
For the purposes of my assessment it needs to be done without using a third party library.
I'm aware that this is probably not the best way to go about storing data since it clears upon refresh or closing the page.
HTML:
<!DOCTYPE html>
<html>
<body>
<h1> Prototype Book Storage and Display </h1>
<form id = "formWrapper">
Search<br>
<input id="myTextBox" type="text" name="search">
<br>
<input onClick="submitData()" type="button" value="Submit Book">
<input onClick="printBooks()" type="button" value="Find Book">
<input onClick="deleteData()" type="button" value = "Delete Book">
<p id = "booktitle"></p>
</form>
</body>
</html>
Javascript:
var myFormData = []; //declare an array
var value1;
//Prints My Books to a list
function printBooks() {
clearBook();
alert(myFormData);
document.getElementById('booktitle').innerHTML = myFormData;
}
//Submits input to array
function submitData()
{
value1 = document.getElementById("myTextBox").value;
myFormData.push(value1);
alert(myFormData);
clearField();
}
//Deletes data from the array
function deleteData()
{
deleteValue = document.getElementById("myTextBox").value;
myFormData.splice(deleteValue);
alert(deleteValue + " " + "Deleting your book");
}
//clears textbox field
function clearField()
{
var txt2 = document.getElementById("myTextBox");
txt2.value = "";
}
//Refreshes book object model
function clearBook()
{
var txt3 = document.getElementById("booktitle");
txt3.value="";
}
The problem is in
myFormData.splice(deleteValue);
splice() expects a starting index, you are passing a string value. See How do I remove a particular element from an array in JavaScript? on how to use it.
In your case it would be
// get the index of the value in the array or -1 if it does not exist
var index = myFormData.indexOf(deleteValue);
// only try removing it, if it exists in the array
if (index !== -1) {
myFormData.splice(index, 1);
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I better make a list in order to explain the steps that I would like to do:
Get the name of the last element of the html-input (has been generated via PHP)
The basic setting looks like this:
<input type='text'name='E_8' value= '123' />
<input type='text'name='E_9' value= '456' />
<input type='text'name='E_10' value= '789' />
<input type='submit' name='submit' value='Update'/>
Pass it over to a JS function
Append some additional fields (use part of the name as an id for new fields
The JS-script works fine and I am able to add fields. Also the content of the fields is being processed by the PHP script and written in a db.
Short: how do I get the last value, no matter how many fields there are?
edit: I had forgotten that there is a submit button that would appear as the last element as well ... sorry for that
There are a number of approaches, but given all other answers rely on the jQuery library (which adds an unnecessary overhead), I'll focus on showing some plain JavaScript approaches (works on recents browsers above IE8+).
var allTextInputs = document.querySelectorAll('input[type="text"]'),
lastInput = allTextInputs[allTextInputs.length - 1],
lastInputName = lastInput.name;
var allInputsTxt = document.querySelectorAll('input[type="text"]');
var lastInput = allInputsTxt[allInputsTxt.length - 1];
var lastInputName = lastInput.name;
var lastInputValue = lastInput.value;
alert('last input name : ' + lastInputName + '; last input value : ' + lastInputValue);
<input type='text'name='E_8' value= '123' />
<input type='text'name='E_9' value= '456' />
<input type='text'name='E_10' value= '789' />
<input type='submit' name='submit' value='Update'/>
If what you want is the value and not the name attribute, do this after using the same approach as above to get the name of the last <input type="text"/>:
var lastInputValue = lastInput.value;
These approaches will give the value of the last <input /> of the type="text" in the document at the point at which the code is run; to find the value of a last <input /> that's dynamically added to the document, you'll need to re-run a working approach following that element's insertion.
jQuery...
var lastInputName = $('input[type="text"]:last').attr('name');
The following jQuery code should do the trick.
var lastValue = $("input[type=text]:last").val();
Also with jQuery:
var $inputs = $("input[type=text]");
var lastValue = $inputs[$inputs.length - 1].value;
Use CSS3 selectors in combination with sizzle (jquery) to target last element
var name = $('input[name^=E_]:last')[0].name
the last value in PHP or JavaScript?
in PHP the fields are normally passed as an array, so you can get the last value using
end($array)
Even better if you name your filed like this
<input type='text'name='E[8]' value= '123' />
<input type='text'name='E[9]' value= '456' />
<input type='text'name='E[10]' value= '789' />
in JS you need to get the fields into an array and get the last.... you need something like this
var myFields = document.forms["myform"].getElementsByTagName('input'),
var lastValue = myFields[(myFields.length-1)].value;
By wrapping your code a parent element, let's says with an attribute id="inputs", here is a vanilla DOM (no jQuery) solution :
// start by finding the last-most element
var lastInput = document.getElementById('inputs').lastElementChild;
// search backward to the last 'text' element
while (lastInput && lastInput.type !== 'text') {
lastInput = lastInput.previousElementSibling;
}
// and get its value
var lastValue = lastInput ? lastInput.value : null;
The interesting part of this solution is that is create no array, so you save some JavaScript memory.
It should be ok with Firefox, Chrome and IE 9.
I am using ASP.Net MVC along with Jquery to create a page which contains a contact details section which will allow the user to enter different contact details:
<div id='ContactDetails'>
<div class='ContactDetailsEntry'>
<select id="venue_ContactLink_ContactDatas[0]_Type" name="venue.ContactLink.ContactDatas[0].Type">
<option>Email</option>
<option>Phone</option>
<option>Fax</option>
</select>
<input id="venue_ContactLink_ContactDatas[0]_Data" name="venue.ContactLink.ContactDatas[0].Data" type="text" value="" />
</div>
</div>
<p>
<input type="submit" name="SubmitButton" value="AddContact" id='addContact' />
</p>
Pressing the button is supposed to add a templated version of the ContactDetailsEntry classed div to the page. However I also need to ensure that the index of each id is incremented.
I have managed to do this with the following function which is triggered on the click of the button:
function addContactDetails() {
var len = $('#ContactDetails').length;
var content = "<div class='ContactDetailsEntry'>";
content += "<select id='venue_ContactLink_ContactDatas[" + len + "]_Type' name='venue.ContactLink.ContactDatas[" + len + "].Type'><option>Email</option>";
content += "<option>Phone</option>";
content += "<option>Fax</option>";
content += "</select>";
content += "<input id='venue_ContactLink_ContactDatas[" + len + "]_Data' name='venue.ContactLink.ContactDatas[" + len + "].Data' type='text' value='' />";
content += "</div>";
$('#ContactDetails').append(content);
}
This works fine, however if I change the html, I need to change it in two places.
I have considered using clone() to do this but have three problems:
EDIT: I have found answers to questions as shown below:
(is a general problem which I cannot find an answer to) how do I create a selector for the ids which include angled brackets, since jquery uses these for a attribute selector.
EDIT: Answer use \ to escape the brackets i.e. $('#id\\[0\\]')
how do I change the ids within the tree.
EDIT: I have created a function as follows:
function updateAttributes(clone, count) {
var f = clone.find('*').andSelf();
f.each(function (i) {
var s = $(this).attr("id");
if (s != null && s != "") {
s = s.replace(/([^\[]+)\[0\]/, "$1[" + count + "]");
$(this).attr("id", s);
}
});
This appears to work when called with the cloned set and the count of existing versions of that set. It is not ideal as I need to perform the same for name and for attributes. I shall continue to work on this and add an answer when I have one. I'd appreciate any further comments on how I might improve this to be generic for all tags and attributes which asp.net MVC might create.
how do I clone from a template i.e. not from an active fieldset which has data already entered, or return fields to their default values on the cloned set.
You could just name the input field the same for all entries, make the select an input combo and give that a consistent name, so revising your code:
<div id='ContactDetails'>
<div class='ContactDetailsEntry'>
<select id="venue_ContactLink_ContactDatas_Type" name="venue_ContactLink_ContactDatas_Type"><option>Email</option>
<option>Phone</option>
<option>Fax</option>
</select>
<input id="venue_ContactLink_ContactDatas_Data" name="venue_ContactLink_ContactDatas_Data" type="text" value="" />
</div>
</div>
<p>
<input type="submit" name="SubmitButton" value="AddContact" id='addContact'/>
</p>
I'd probably use the Javascript to create the first entry on page ready and then there's only 1 place to revise the HTML.
When you submit, you get two arrays name "venue_ContactLink_ContactDatas_Type" and "venue_ContactLink_ContactDatas_Data" with matching indicies for the contact pairs, i.e.
venue_ContactLink_ContactDatas_Type[0], venue_ContactLink_ContactDatas_Data[0]
venue_ContactLink_ContactDatas_Type[1], venue_ContactLink_ContactDatas_Data[1]
...
venue_ContactLink_ContactDatas_Type[*n*], venue_ContactLink_ContactDatas_Data[*n*]
Hope that's clear.
So, I have a solution which works in my case, but would need some adjustment if other element types are included, or if other attributes are set by with an index included.
I'll answer my questions in turn:
To select an element which includes square brackets in it's attributes escape the square brackets using double back slashes as follows: var clone = $("#contactFields\[0\]").clone();
& 3. Changing the ids in the tree I have implemented with the following function, where clone is the variable clone (in 1) and count is the count of cloned statements.
function updateAttributes(clone, count) {
var attribute = ['id', 'for', 'name'];
var f = clone.find('*').andSelf();
f.each(function(i){
var tag = $(this);
$.each(attribute, function(i, val){
var s = tag.attr(val);
if (s!=null&& s!="")
{
s = s.replace(/([^\[]+)\[0\]/, "$1["+count+"]");
tag.attr(val, s);
}
});
if ($(this)[0].nodeName == 'SELECT')
{ $(this).val(0);}
else
{
$(this).val("");
}
});
}
This may not be the most efficient way or the best, but it does work in my cases I have used it in. The attributes array could be extended if required, and further elements would need to be included in the defaulting action at the end, e.g. for checkboxes.