well I'm pretty new in Javascript and I would like to improve the following code
that I made to order the buttons based on the search,I don't know that else should I add to make it work so this is what I've done until now, every comment or suggestion will be welcome
Thanks a lot!
//Variables
let valorBusqueda = document.querySelector('#valor');
let opcBusqueda = document.querySelector('.opc-busqueda');
//Event Listener
valorBusqueda.addEventListener('keyup', keyUpCampo);
//Funciones
function keyUpCampo() {
//Muestra el menu de sugerencias
opcBusqueda.style = "display: flex; flex-direction:column; width:165px";
sendToPage();
}
var sendToPage = function () {
//Get the input value by finding the element by its ID
let busqueda = document.getElementById('valor').value;
//Check if the value is in the array
var sugerencias = ['marvel','maravilloso', 'futbol','goku ssj','falafel','robocop', 'rick','ricardo', 'morty', 'x-men', 'starwars', 'goku', 'bulma', 'vegeta', 'simpsons', 'homer', 'cartoon'];
var coincidencias =[]
for (indice in sugerencias) {
let lSug = sugerencias[indice].charAt();
if (lSug.includes(busqueda.charAt())) {
coincidencias.push(sugerencias[indice]);
opcBusqueda.innerHTML = `<input type="button" value=${coincidencias[0]} >
<input type="button" value=${coincidencias[1]} >
<input type="button" value=${coincidencias[2]} >
`
}
}
}
<body>
<div class="busqueda">
<div class="inputs">
<input id="valor" type="text" placeholder=" Busca hashgtags, temas, busca lo que quieras..">
</div>
</div>
<div class="opc-busqueda" style="display: none;">
</div>
</body>
Related
I have created a form which can be dynamically changed using the buttons included. These buttons allow for more input fields to be added/removed. The issue is that the input fields created are not posting any data/ Values in those fields not being added to the $POST array on the submit of the form.
The main functions below resposible for adding and removing rows is RemoveRows() and addRows()
What should happen is that on submit all values in the form should be "posted" then I can access all of those fields via $_POST["nameOfField"].
The way I have currently approached this is to create an input fields with the relevant id's and names then append that field to where the "hard coded" fields exists.
From my initial debugging none of the fields that have been added via javascript are in $Post which I have checked via var_dump($_REQUEST);
I have also seen that the nodes that are added are not elements of the form tag even though the nodes are added between the opening and closing tag. This can be seen in the doBeforeSubmit() Function where we can see all elements that are children of the and this never changes as rows are added/removed.
function showPlatforms() {
let nacellesOptions = ["Option1", "option2", "Option3"];
let milOptions = ["Option1", "option2", "Option3"]
let highOptions = ["Option1", "option2", "Option3"]
let entry = document.getElementById("vs")
let platfom = document.getElementById("platform")
if (platform.hasChildNodes()) {
var lastChild = platfom.lastElementChild
while (lastChild) {
platfom.removeChild(lastChild)
lastChild = platform.lastElementChild
}
}
if (entry.value == "Nacelles") {
for (var i = 0; i < 2; i++) {
var option = document.createElement("option");
option.value = nacellesOptions[i]
option.innerHTML = nacellesOptions[i]
platform.appendChild(option)
}
} else if (entry.value == "Military") {
for (var i = 0; i < 2; i++) {
var option = document.createElement("option");
option.value = milOptions[i]
option.innerHTML = milOptions[i]
platform.appendChild(option)
}
} else {
for (var i = 0; i < 2; i++) {
var option = document.createElement("option");
option.value = highOptions[i]
option.innerHTML = highOptions[i]
platform.appendChild(option)
}
}
}
function formOptions() {
let entry = document.getElementById("type")
if (entry.value == "Engineering MAM") {
document.getElementById("WBS").disabled = false
document.getElementById("Desc").disabled = false
document.getElementById("ProName").disabled = false
} else {
document.getElementById("WBS").disabled = true
document.getElementById("Desc").disabled = true
document.getElementById("ProName").disabled = true
}
}
function formoptions2() {
let entry2 = document.getElementById("organisation")
if (entry2.value == "Aftermarket") {
document.getElementById("COT").disabled = false
document.getElementById("COC").disabled = false
} else {
document.getElementById("COT").disabled = true
document.getElementById("COC").disabled = true
}
}
count = document.getElementById("partNum").childElementCount
function addRows() {
rowNames = ["partNum", "partDesc", "leadTime", "quantity", "dateReq", "unitCost", "unitExtention", "unitSaleValue", "estSalesValue"]
rowNames.forEach(addRow, count)
count = document.getElementById("partNum").childElementCount
//doBeforeSubmit()
}
function doBeforeSubmit() {
var es = document.getElementById("form").elements;
var l = es.length;
var msgs = [];
for (var idx = 0; idx < l; idx++) {
var e = es[idx];
msgs.push('name=' + e.name + ', type=' + e.type + ', value=' + e.value);
}
alert(msgs.join('\n'));
return false;
}
function addRow(id) {
let col = document.getElementById(id)
var box = document.createElement("INPUT")
box.setAttribute("type", "text")
box.setAttribute("id", id + count)
box.setAttribute("name", id + count)
box.setAttribute("class", "form-control")
col.appendChild(box)
}
function RemoveRows() {
rowNames = ["partNum", "partDesc", "leadTime", "quantity", "dateReq", "unitCost", "unitExtention", "unitSaleValue", "estSalesValue"]
rowNames.forEach(removeBoxes)
count = document.getElementById("partNum").childElementCount
}
function removeBoxes(item) {
let box = document.getElementById(item)
let last = box.lastChild
box.removeChild(last)
}
function checkData() {
// if all stuff is correct do this:
document.getElementById("submit").disabled = false
// else dont activate the submit button.
}
<form method="post" id="form" action="SubmitMAM.php">
<div class="row" id="productRow" style="width:95%; margin:auto">
<div id="partNo" class="col-2">
<h3>Part Number:</h3>
</div>
<div class="col-2">
<h3>Part Description:</h3>
</div>
<div class="col-1">
<h3>Lead Time:</h3>
</div>
<div class="col-1">
<h3>Quantity:</h3>
</div>
<div class="col-1">
<h3>Date Required:</h3>
</div>
<div class="col-1">
<h3>Unit Cost:</h3>
</div>
<div class="col-2">
<h3>Unit Cost Extension:</h3>
</div>
<div class="col-1">
<h3>Unit Sale Value:</h3>
</div>
<div class="col-1">
<h3>Est Sales Value:</h3>
</div>
</div>
<div class="row" id="productRow" style="width:95%; margin:auto">
<div id="partNum" class="col-2">
<input type="text" id="partNum0" class="form-control" name="partNum0">
</div>
<div id="partDesc" class="col-2">
<input type="text" id="partDesc0" class="form-control" name="partDesc0">
</div>
<div id="leadTime" class="col-1">
<input type="text" id="leadTime0" class="form-control" name="leadTime0">
</div>
<div id="quantity" class="col-1">
<input type="text" id="quanitity0" class="form-control" name="quantity0">
</div>
<div id="dateReq" class="col-1">
<input type="text" id="dateReq0" class="form-control" name="dateReq0">
</div>
<div id="unitCost" class="col-1">
<input type="text" id="unitCost0" class="form-control" name="unitCost0">
</div>
<div id="unitExtention" class="col-2">
<input type="text" id="unitExtention0" class="form-control" name="unitExtention0">
</div>
<div id="unitSaleValue" class="col-1">
<input type="text" id="unitSaleValue0" class="form-control" name="unitSaleValue0">
</div>
<div id="estSalesValue" class="col-1">
<input type="text" id="estSalesValue0" class="form-control" name="estSalesValue0">
</div>
<button onclick="addRows()" class="btn btn-primary" type="button">Add a Product</button>
<button onclick="RemoveRows()" class="btn btn-primary" type="button">Remove Row</button>
<button onclick="checkData()" class="btn btn-primary" type="button">Check Data</button>
<br>
<button type="submit" name="submit" id="submit" class="btn btn-primary" disabled>Submit</button>
</form>
PHP:
<?php
var_dump($_REQUEST)
?>
UPDATE:
The code has been changed to use a php array by adding square brackets into the name which produces the following html:
<input type="text" id="partNum0" class="form-control" name="partNum[]">
<input type="text" id="partNum1" name="partNum[]" class="form-control">
<input type="text" id="partNum2" name="partNum[]" class="form-control">
You just need to use the name property of the input and add [] at the end, as GrumpyCrouton said. PHP parse it as an array, and you can access it as:
$partNum = $_POST["partNum"];
FIXED: It turns out the above code did not have any issues with the logic or the way it should work, in the source code in visual studio the indentation of some of the Divs was off causing the browser to have issues in rendering the form correctly hence why the added boxes were not included in the form and their values not POSTED.
As a heads up to anyone with maybe a similar issue, it pays to have your code neat.
I have a dynamic form section which I need the name attribute to be dynamic as well.
the number should always get +1 each time the user create a new section !
name="training**1**[institut]"
This is crucial to have a proper SQL insert ... otherwise the array won't have a classical database logics !
JSFIDDLE here
Any idea ? thanks a lot from France !
<form method="post" action="">
<!-- INFO SECTION -->
<div id="infos">
<h2>Infos personnelles</h2>
<input placeholder="Prénom">
<input placeholder="Nom">
</div>
<!-- TRAINING SECTION -->
<div id="training">
<h2>Formation</h2>
<!-- Template -->
<div id="new-training" style="display:none">
<div>
</br>
<p></p>
<input id="mytext" type="text" name="training[1][institut]" placeholder="Diplôme" value="">
<input name="training[1][institut]" placeholder="Institut">
</div>
</div>
</div>
<p id="addnew">
+ Ajouter une formation
</p>
<p>
<br>
<input type="submit" value="Sauvergarder" name="submit">
</p>
</form>
<script> // 1st : Enregistrer / supprimer une formation
var ct = 1;
function addTraining()
{
ct++;
var div1 = document.createElement('div');
div1.id = ct;
// link to delete extended form elements
var delLink = 'Supprimer cette formation';
div1.innerHTML = document.getElementById('new-training').innerHTML + delLink;
document.getElementById('training').appendChild(div1);
}
function removeTraining(eleId)
{
d = document;
var ele = d.getElementById(eleId);
var parentEle = d.getElementById('training');
parentEle.removeChild(ele);
}
The best solution (my opinion) is to use a simple templating engine
https://jsfiddle.net/nget5dq2/1/
Addition to your HTML:
<template id="new_el_template" hidden>
<div id="row-{cid}">
<input id="mytext-{cid}" type="text" name="training[{cid}][institut]" placeholder="Diplôme" value="">
<input name="training[{cid}][institut]" placeholder="Institut">
</div>
Supprimer cette formation
</template>
JS
var ct = 1;
function addTraining() {
ct++;
let div = document.createElement('div');
div.innerHTML = document.getElementById('new_el_template').innerHTML.replace(/\{cid\}/gi, ct);
document.getElementById('training').appendChild(div);
}
function removeTraining(eleId) {
document.getElementById('row-' + eleId).parentNode.remove();
}
And yes, you can go ahead and generate the initial element directly from the template.
write the name attribute this way you should get all the data from the form when u post it.
<input id="mytext" type="text" name="training[diploma][]" placeholder="Diplôme" value="">
<input name="training[institut][]" placeholder="Institut">
Here is a working example with comments added throughout..
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>
<form method="post" action="">
<!-- INFO SECTION -->
<div id="infos">
<h2>Infos personnelles</h2>
<input placeholder="Prénom">
<input placeholder="Nom">
</div>
<!-- TRAINING SECTION -->
<div id="training">
<h2>Formation</h2>
<!-- Template -->
<div id="new-training" >
<div>
</br>
<p></p>
<input id="mytext" type="text" name="training[1][institut]" placeholder="Diplôme" value="">
<input name="training[1][institut]" placeholder="Institut">
</div>
</div>
</div>
<p id="addnew">
<a style="color: blue" onclick="addTraining()">+ Ajouter une formation</a>
</p>
<p>
<br>
<input type="submit" value="Sauvergarder" name="submit">
</p>
</form>
</body>
<script>
const addTraining = () => {
//Get parent container to place new input into
const parent = document.getElementById('training');
//Create DIV to wrap around input elements
let div = document.createElement('div')
//Create new input with a unique name attribute
let newInput1 = document.createElement('input');
let newInput2 = document.createElement('input');
//You can get an array of all existing elements and add 1 to create a unique name for each
let num = parent.querySelectorAll('div').length + 1,
newName = 'training['+ num +'][institut]';
//Set name attribute
newInput1.setAttribute('name', newName);
newInput2.setAttribute('name', newName);
//Set other attributes you alreadt had
newInput1.setAttribute('placeholder', 'Diplôme');
newInput2.setAttribute('placeholder', 'Institut');
newInput1.setAttribute('id', 'myText');
newInput1.setAttribute('type', 'text');
//Append elements
parent.appendChild(div);
div.appendChild(newInput1);
div.appendChild(newInput2)
}
</script>
</html>
I have a div being cloned and I would like the button remove to remove the selected div. It's only removing the html div that is used to clone the field.
See my code below:
JS
// Clones Schedule Field
function cloneField(){
const newFieldContainer = document.querySelector(".schedule-item").cloneNode(true)
console.log(newFieldContainer)
let fields = newFieldContainer.querySelectorAll('input')
fields.forEach(function(field){
field.value = ""
})
document.querySelector("#schedule-items").appendChild(newFieldContainer)
}
// Adds new field
function addButton(){
let button = document.querySelector("#add-time")
const selected = document.getElementById('select').selected
let scheduleItems = document.querySelector('#schedule-items')
let inputs = scheduleItems.querySelectorAll('input')
if(selected == true || [...inputs].some(input=>input.value === "")){
alert('Tem o dia ou a hora faltando nos Horários Disponíveis.')
button.removeEventListener('click',cloneField)
}else{
button.addEventListener('click',cloneField)
}
}
// Removed field added if needed
let buttonRemove = document.querySelector('.remove-schedule-item')
buttonRemove.addEventListener('click',removeField)
function removeField(){
let scheduleItem = document.querySelector('.schedule-item')
scheduleItem.parentNode.removeChild(scheduleItem);
console.log('hey')
}
HTML
<fieldset id="schedule-items">
<legend>Horários disponíveis
<button type="button" id="add-time" onclick="addButton()">+Novo horário</button>
</legend>
<div class="schedule-item">
<div class="select-block">
<label for="weekday">Dia da semana</label>
<select name="weekday[]" required="true">
<option id="select" value="select" selected>Selecione uma opção</option>
{%for weekday in weekdays %}
<option value="{{loop.index0}}">{{weekday}}</option>
{%endfor%}
</select>
</div>
<div class="input-block">
<label for="time_from">Das</label>
<input type="time" name="time_from[]" required>
</div>
<div class="input-block">
<label for="time_to">Ate</label>
<input type="time" name="time_to[]" required>
</div>
<div class="remove-schedule-item">
<button>remove</button>
</div>
</div>
</fieldset>
</form>
Thanks in advance
when you try to remove the item
function removeField(){
let scheduleItem = document.querySelector('.schedule-item')
scheduleItem.parentNode.removeChild(scheduleItem);
console.log('hey')
}
you are always selecting the first .schedule-item and then delete the first item
edit:
when you clone you element you need to add event listener to the new element
function cloneField(){
const newFieldContainer = document.querySelector(".schedule-item").cloneNode(true);
let fields = newFieldContainer.querySelectorAll('input')
fields.forEach(function(field){
field.value = ""
});
document.querySelector("#schedule-items").appendChild(newFieldContainer);
const removeBtn = newFieldContainer.querySelector('.remove-schedule-item');
if(removeBtn){
removeBtn.addEventListener('click',function(){
newFieldContainer.remove();
});
}
}
I am creating a website that has a list of user inputs, however at a certain stage I want users to see a summarized page of all their inputs. If the input was not chosen it should not show as part of the summary (as in the script example below).
Here is my problem: there will be multiple user inputs and to write a JS script to achieve what I had done in an example script below will be lots of work and unfeasible. Is there a way the two JS scripts for the individual ID's can be combined into one as in the script below?
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div>
<label>For the first test</label>
<input type="text" placeholder="Enter Number" name="clientinfo" id="test1" required>
</div>
<div>
<label>For the second test</label>
<input type="text" placeholder="Enter Number" name="clientinfo" id="test2" required>
</div>
<button id="myBtn">Test</button>
<div style="color:blue;">
<p id="result1"></p>
</div>
<div style="color:red">
<p id="result2"></p>
</div>
<script>
function getUserName() {
var test1 = document.getElementById('test1').value;
var result1 = document.getElementById('result1');
if (test1.length > 0) {
result1.textContent = 'Test1: ' + test1;
} else {
null;
}
}
var myBtn = document.getElementById('myBtn');
myBtn.addEventListener('click', getUserName, false);
</script>
<script>
function getUserName() {
var test2 = document.getElementById('test2').value;
var result2 = document.getElementById('result2');
if (test2.length > 0) {
result2.textContent = 'Test2: ' + test2;
} else {
null;
}
}
var myBtn = document.getElementById('myBtn');
myBtn.addEventListener('click', getUserName, false);
</script>
</body>
</html>
P.s. I would also like to know if a user were to press the test button with an input, remove the input and press the test button again, that the first input would be removed?
You can get all inputs and loop throw the result and create an dom element which will contain the value of the input
and each created element will be added to lets say a result element
See code snippet
function getUserName() {
var inputList = document.getElementsByTagName("INPUT");
var res = document.getElementById("result");
res.innerHTML = "";
var indx = 1;
for (i = 0; i < inputList.length; i++) {
if (inputList[i].value != "") {
var ele = document.createElement("p");
ele.innerHTML ="test " + indx + " : " + inputList[i].value
res.appendChild(ele);
indx++;
}
}
}
var myBtn = document.getElementById('myBtn');
myBtn.addEventListener('click', getUserName, false);
<div>
<label>For the first test</label>
<input type="text" placeholder="Enter Number" name="clientinfo" id="test1" required>
</div>
<div>
<label>For the second test</label>
<input type="text" placeholder="Enter Number" name="clientinfo" id="test2" required>
</div>
<button id="myBtn">Test</button>
<div id="result">
</div>
I have a html form, where user need to enter the name and address of their office. The number of offices are dynamic.
I want to add an Add More button, so that users can enter the details of any number of offices.
My question is, how can I create an array of inputs where new elements can be added and removed using JavaScript. Currently, I'm doing it using js clone method, but I want an array, so that input data can easily be validated and stored to database using Laravel.
What I'm currently doing..
This is my HTML form where users have to enter the address of their clinic or office. I've taken a hidden input field and increasing the value of that field whenever a new clinic is added, so that I can use loop for storing data.
<div class="inputs">
<label><strong>Address</strong></label>
<input type="text" class="hidden" value="1" id="clinicCount" />
<div id="addresscontainer">
<div id="address">
<div class="row" style="margin-top:15px">
<div class="col-md-6">
<label><strong>Clinic 1</strong></label>
</div>
<div class="col-md-6">
<button id="deleteclinic" type="button" class="close deleteclinic"
onclick="removeClinic(this)">×</button>
</div>
</div>
<textarea name="address1" placeholder="Enter Clinic Address" class="form-control"></textarea>
<label class="text-muted" style="margin-top:10px">Coordinates (Click on map to get coordinates)</label>
<div class="row">
<div class="col-md-6">
<input class="form-control" id="latitude" type="text" name="latitude1" placeholder="Latitude" />
</div>
<div class="col-md-6">
<input class="form-control" id="longitude" type="text" name="longitude1" placeholder="Longitude" />
</div>
</div>
</div>
</div>
</div>
<div class="text-right">
<button class="btn btn-success" id="addclinic">Add More</button>
</div>
And my js code..
function numberClinic(){
//alert('test');
var i=0;
$('#addresscontainer > #address').each(function () {
i++;
$(this).find("strong").html("Clinic " + i);
$(this).find("textarea").attr('name','name'+i);
$(this).find("#latitude").attr('name','latitude'+i);
$(this).find("#longitude").attr('name','longitude'+i);
});
}
$("#addclinic").click(function(e){
e.preventDefault();
$("#addresscontainer").append($("#address").clone());
numberClinic();
$("#addresscontainer").find("div#address:last").find("input[name=latitude]").val('');
$("#addresscontainer").find("div#address:last").find("input[name=longitude]").val('');
$("#clinicCount").val(parseInt($("#clinicCount").val())+1);
});
function removeClinic(address){
if($("#clinicCount").val()>1){
$(address).parent('div').parent('div').parent('div').remove();
$("#clinicCount").val(parseInt($("#clinicCount").val())-1);
}
numberClinic();
}
This way, I think I can store the data to the database but can't validate the data. I'm using the laravel framework.
One way you could do this is by using the position of the input in the parent as the index in the array, then saving the value in the array every time each input is changed. Then you can just add and remove inputs.
Sample code:
var offices = document.getElementById('offices');
var output = document.getElementById('output');
var data = [];
var i = 0;
document.getElementById('add').addEventListener('click', function() {
var input = document.createElement('input');
input.setAttribute('type', 'text');
input.setAttribute('placeholder', 'Office');
var button = document.createElement('button');
var index = i++;
input.addEventListener('keyup', function() {
for (var i = 0; i < offices.children.length; i++) {
var child = offices.children[i];
if (child === input) {
break;
}
}
// i is now the index in the array
data[i] = input.value;
renderText();
});
offices.appendChild(input);
});
document.getElementById('remove').addEventListener('click', function() {
var children = offices.children;
if (children.length === data.length) {
data = data.splice(0, data.length - 1);
}
offices.removeChild(children[children.length - 1]);
renderText();
});
function renderText() {
output.innerHTML = data.join(', ');
}
JSFiddle: https://jsfiddle.net/94sns39b/2/