How to associate dynamically added input fields to parent element/id? - javascript

I design a user database system using bootstrap and jquery. The problem is, whenever a button is press, it will append an additional field for user to key in.
let's say the the array name for the first array of the field is ref_title[0]
after the append button is press, another text field will appear with the same attribute but the array value will be ref_title[1].
however on the code itself, it will only show ref_title[]. This is ok, since any new field will keep adding on to the array ref_title[]. Am i right?
next when save changes button is clicked, i will direct the data to js using onclick="newdata('<?php echo $row['drug_id']; ?>')"
'drug_id' is a unique number, for example 1, 2 or 3.
when i inspect the input field for the first box is
<input class="form-control" id="ref_title3" name="ref_title[]" placeholder="Reference Title" type="text">
however on the second box(after the append button is press and additional box appeared)
<input class="form-control" id="ref_title" name="ref_title[]" placeholder="Reference Title" type="text">
Take a look at the id="ref_title". The value 3 is not echo out.
HTML:
<input type="text" class="form-control" id="ref_title<?php echo $row['drug_id'];?>" name="ref_title[]" placeholder="Reference Title">
<button type="button" onclick="newdata('<?php echo $row['drug_id']; ?>')" class="btn btn-primary" data-dismiss="modal">Save changes</button>
JS:
$(document).ready(function() {
var max_fields = 10; //maximum input boxes allowed
var wrapper = $(".input_fields_wrap"); //Fields wrapper
var add_button = $(".add_field_button"); //Add button ID
var x = 1; //initlal text box count
$(add_button).click(function(e){ //on add input button click
e.preventDefault();
if(x < max_fields){ //max input box allowed
x++; //text box increment
$(wrapper).append('<div><input type="text" class="form-control" id="ref_title<?php echo $row['drug_id'];?>" name="ref_title[]" placeholder="Reference Title"/></div>">Remove</div>'); //add input box
}
});
$(wrapper).on("click",".remove_field", function(e){ //user click on remove text
e.preventDefault(); $(this).parent('div').remove(); x--;
})
});
Onlick
function newdata(str){
var ref = $('#ref_title'+str).val(); // !!Only can read the first array
var datas="&ref="+ref;
$.ajax({
type: "POST",
url: "update.php",
data: datas
}).done(function( data ) {
$('#info').html(data);
viewdata();
});
};

Not exactly an answer to your question, but a suggestion on what you could do.
Prerequisite: test.php
<pre><?php var_export($_POST); ?></pre>
When you give input controls a name containing [...] php will treat the data as if it were arrays. E.g.
<!DOCTYPE html>
<html>
<head>
<title>...</title>
<meta charset="utf-8" />
</head>
<body>
<form method="post" action="test.php">
<input type="hidden" name="foo[a]" value="a" />
<input type="hidden" name="foo[b]" value="b" />
<input type="hidden" name="foo[bar][]" value="bar1" />
<input type="hidden" name="foo[bar][]" value="bar2" />
<input type="hidden" name="foo[bar][]" value="bar3" />
<div>
<input type="submit" />
</div>
</form>
</body>
</html>
the ouput of test.php will be
<pre>array (
'foo' =>
array (
'a' => 'a',
'b' => 'b',
'bar' =>
array (
0 => 'bar1',
1 => 'bar2',
2 => 'bar3',
),
),
)</pre>
i.e. the names
name="foo[a]"
name="foo[b]"
name="foo[bar][]"
name="foo[bar][]"
name="foo[bar][]"
caused php to build the _POST array like
$_POST = array();
$_POST['foo']['a'] = 'a';
$_POST['foo']['b'] = 'b';
// $_POST['foo'][bar] = array()
$_POST['foo']['bar'][] = 'bar1';
$_POST['foo']['bar'][] = 'bar2';
$_POST['foo']['bar'][] = 'bar3';
Now I suggest that you build the names for the input controls like this:
[drugs][145][add][]
telling hte php script that it is supposed to work on drug items, which one (145), that it should add something plus the [] so you can add an (virtually) arbitrary amount of items.
So a POST body like
drugs[145][add][]=drug145.1&drugs[145][add][]=drug145.2&drugs[22][add][]=drug22.1
(yeah, yeah, the encoding is off....)
would lead to
_POST==$_POST = array(
'drugs' = >array(
'145' => array(
'add' => array(
'drug145.1',
'drug145.2'
),
'22' => array(
'add' => 'drug22.1'
)
)
);
telling your php script to add/append the two descriptions drug145.1 and drug145.2 to the item 145 and drug22.1 to the item 22.
And here's an example how you can do this with html/javascript/jquery
<!DOCTYPE html>
<html>
<head>
<title>...</title>
<meta charset="utf-8" />
<style type="text/css">
.adddrugdesc {
margin-left: 1em;
cursor: pointer;
background-color: Cornsilk;
border: 1px solid silver;
}
</style>
</head>
<body>
<form method="post" action="test.php">
<div class="druglist">
<!-- note the drugid as an data-* attribute, see e.g. https://developer.mozilla.org/en/docs/Web/Guide/HTML/Using_data_attributes
Your php script is supposed to output this id when serving the html document
-->
<fieldset><legend data-drugid="3">Drug A</legend></fieldset>
<fieldset><legend data-drugid="7">Drug B</legend></fieldset>
<fieldset><legend data-drugid="145">Drug C</legend></fieldset>
<fieldset><legend data-drugid="22">Drug D</legend></fieldset>
</div>
<input type="submit" />
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script>
$(document).ready(function() {
var dl = $(".druglist");
// add some kind of edit/add button to each fieldset/legend
dl.find("fieldset legend").each(function(x) {
$(this).append('<span class="adddrugdesc">add description</span>');
});
// add an event handler for all edit/add buttons
dl.on('click', '.adddrugdesc', function(e) {
var me = $(this); // this will be the span element the usr clicked on
var legend = me.parent('legend'); // this will be the legend element in which the span is located
var fset = legend.parent('fieldset'); // same as with legend
var drugid = legend.data()['drugid']; // access the data-* attribute of the element via data() and pick the element "drugid"
var newinput = $('<input type="text" />');
newinput.attr("name", "drugs["+drugid+"][add][]");
fset.append(newinput);
});
});
</script>
</body>
</html>
(It's a bit verbose to keep it "understandable". And ...it's only an example. Some things might be a bit prettier, more robust et al)

Related

Dynamically updating Selectize fields using Javascript/JQuery

I have a form that contains a number of fields including some selects that are using the Selectize jquery plugin. Part of what the form does involves taking the input from a modal window, which is then added dynamically to the relevant 'selectized' select field.
I am currently doing this as follows:
//Initialise Selectize on the required fields
var $select = $('.selectize').selectize(...do some stuff in here...);
//Fetch the selectize instances
var select0 = $select[0].selectize;
var select1 = $select[1].selectize;
...etc, one for each select...
//This is where I get the text entered in the modal and update
//the relevant select field.
function processText(){
//Get the name of the field we need to update
var thisFormElement = $('#sourceFormElementName').val();
//Get the text to update the above field with
var thisText = $('#inputQuickTextOriginalText').val();
//Figure out which select field to update. Messy.
if(thisFormElement == "select0"){
//'select#' is the reference back to the selectize instances we declared earlier
select0.addOption({value:thisText, text:thisText});
select0.addItem(thisText);
}
else if(thisFormElement == "select1"){
select1.addOption({value:thisText, text:thisText});
select1.addItem(thisText);
}
...more statements...
}
Presumably one way to clean this up would be to reference the selectize instance using the thisFormElement value (or similar). Then there would be no need to the if statement and new fields can be added without altering this part of the code. E.g. something like:
//Assume thisFormElement = select0, for example
var thisFormElement = $('#sourceFormElementName').val();
thisFormElement.addOption({value:thisText, text:thisText});
thisFormElement.addItem(thisText);
I understand that the above won't work, but is there some way to achieve something similar (or a completely different way entirely)?
Below is an approach to enabling users to input an option in one field and add that option to a corresponding selectize field. For those just looking for basic functionality enabling users to add new options to a selectize field, check out the Tagging demo from the selectize documentation.
const params = {
options: [],
placeholder: 'Select...',
valueField: 'value',
labelField: 'text',
searchField: ['text'],
create: false
};
// init selectize inputs and add to 'selects' array
const selects = [];
selects.push($('#select1').selectize(params));
selects.push($('#select2').selectize(params));
$('#add button').click(() => {
$('#add input').each((index, elem) => {
if (elem.value) {
const id = $(elem).data('select-id');
for (const select of selects) {
// find corresponding selectize field and add option
if (id === select[0].id) {
const value = Object.keys(select[0].selectize.options).length + 1;
const text = elem.value;
select[0].selectize.addOption({value: value, text: text});
select[0].selectize.addItem(value);
break;
}
}
elem.value = '';
}
});
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Selectize</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.6/css/selectize.default.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.6/js/standalone/selectize.js"></script>
</head>
<body>
<div id="add">
<div>
<input name="add1" type="text" value="" placeholder="Add option to 1st select..." data-select-id="select1" />
</div>
<div>
<input name="add2" type="text" value="" placeholder="Add option to 2nd select..." data-select-id="select2" />
</div>
<div>
<button>Add</button>
</div>
</div>
<br>
<form id="select" action="" method="POST">
<input class="myselect" id="select1" name="select1" type="text" />
<input class="myselect" id="select2" name="select2" type="text" />
</form>
</body>
</html>

Submiting Javascript variable to PHP via HTML Form

I have these below codes which give user option to reserve a seat according to their choice. These 3 mentioned below are difficulties that I am facing I need help.
To send the total value of a variable named total from Javascript to PHP
To send the total number of selected seats which are being hold by a variable called results from Javascript to PHP
How to make a Reserve Now button inactive if a user did not select any seat from checkbox.
These below are my codes.
index.php
<!DOCTYPE html>
<html lang="en">
<head>
<title>Seat(s)</title>
</head>
<body>
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
if (isset($_POST['submit'])) { //Seat Reserve
require 'action_page.php';
}
elseif (isset($_POST[''])) { //Cancel
require 'mypage.php';
}
}
//
$parameter = "this is a php variable";
echo "var myval = foo(" . parameter . ");";
?>
?>
<h2>Please choose a seat to book</h2>
<form action="index.php" method="post">
<input type="checkbox" name="vehicle" id="A1" value="100">$100<br>
<input type="checkbox" name="vehicle" id="A2" value="65"> $65<br>
<input type="checkbox" name="vehicle" id="A3" value="55"> $55<br>
<input type="checkbox" name="vehicle" id="A4" value="50"> $50<br>
<p id="demo">
Selected Seat(s)
<br>
<span id="selected-seats"></span> <!-- container for selected seats -->
<br>
Total: <span id="total-container"></span> USD
<button type="submit" class="btn btn-primary" name="submit">Reserve Now</button>
</p>
</form>
<script>
const selections = {};
const inputElems = document.getElementsByTagName("input");
const totalElem = document.getElementById("total-container");
const seatsElem = document.getElementById("selected-seats");
for (let i = 0; i < inputElems.length; i++) {
if (inputElems[i].type === "checkbox") {
inputElems[i].addEventListener("click", displayCheck);
}
}
function displayCheck(e) {
if (e.target.checked) {
selections[e.target.id] = {
id: e.target.id,
value: e.target.value
};
}
else {
delete selections[e.target.id];
}
const result = [];
let total = 0;
for (const key in selections) {
result.push(selections[key].id);
total += parseInt(selections[key].value);
}
totalElem.innerText = total;
seatsElem.innerHTML = result.join(",");
//window.alert(result); //Hold Number of Seats Selected.
//window.alert(total); //Hold Total Cost of Selected Seats.
}
var myval = foo("this is a php variable"); // I tried to take this value and output it but it didn't work out.
$.ajax({
type: 'POST',
url: 'action_page.php',
data: {'variable': total},
});
</script>
</body>
</html>
action_page.php
<html>
<head>
<title>Seats Feedback</title>
</head>
<body>
<?php
echo "<br>";
$myval = $_POST['variable'];
print_r($myval);
?>
Looking forward to hear from you guys.
When you're not doing AJAX, posting data to a PHP script the old fashioned way is a matter of:
setting the action attribute on a <form> element to point to the destination PHP script URL
ensuring your form's <input> elements contain all of the data you want to post
adding a submit button to the form
For step 1, currently, your form says to send the post request to itself. This is totally fine (you can use a <?php block ?> like you're doing to determine whether to show a success confirmation or a blank form depending on the contents of $_POST, but I'm guessing your intention is to ultimately send the data over to action_page.php. I made that the action target and removed all of the PHP from your index.
As for step 2, your total isn't currently in an <input> element and won't be posted. I created an invisible total element for this purpose: <input type="hidden" name="total" id="hidden-total" value="0"> and added a couple lines to the script to retrieve this element and set its value whenever your total is recalculated. You could combine the two total elements and style one to look and be non-editable (exercise for the reader).
Another problem relating to step 2 is that you have four different elements with the name vehicle. Only one of these name/value pairs will be posted, so I updated these elements to use unique names so they'll all be sent.
Step 3, making sure you have a submit button, you've already done successfully.
To verify it's working, you can var_dump($_POST) on the receiving PHP script to see the results of the post request or retrieve a specific value by name with e.g. $_POST['total']. At this point, your PHP script can go ahead and parse/validate/sanitize the post data, render proper response output, do a redirect, and/or do whatever else needs to be done, such as writing to a database.
Here's the full code:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Seat(s)</title>
</head>
<body>
<h2>Please choose a seat to book</h2>
<form action="action_page.php" method="post">
<input type="checkbox" name="vehicle-a1" id="A1" value="100">$100<br>
<input type="checkbox" name="vehicle-a2" id="A2" value="65"> $65<br>
<input type="checkbox" name="vehicle-a3" id="A3" value="55"> $55<br>
<input type="checkbox" name="vehicle-a4" id="A4" value="50"> $50<br>
<input type="hidden" name="total" id="hidden-total" value="0">
<p id="demo">
Selected Seat(s)
<br>
<span id="selected-seats"></span> <!-- container for selected seats -->
<br>
Total: <span id="total-container"></span> USD
<button type="submit" class="btn btn-primary" name="submit">Reserve Now</button>
</p>
</form>
<script>
const selections = {};
const inputElems = document.getElementsByTagName("input");
const totalElem = document.getElementById("total-container");
const hiddenTotalElem = document.getElementById("hidden-total");
const seatsElem = document.getElementById("selected-seats");
for (let i = 0; i < inputElems.length; i++) {
if (inputElems[i].type === "checkbox") {
inputElems[i].addEventListener("click", displayCheck);
}
}
function displayCheck(e) {
if (e.target.checked) {
selections[e.target.id] = {
id: e.target.id,
value: e.target.value
};
}
else {
delete selections[e.target.id];
}
const result = [];
let total = 0;
for (const key in selections) {
result.push(selections[key].id);
total += parseInt(selections[key].value);
}
totalElem.innerText = total;
hiddenTotalElem.value = total;
seatsElem.innerHTML = result.join(",");
}
</script>
</body>
</html>
action_page.php
<!DCOTYPE html>
<html lang="en">
<head>
<title>Seats Feedback</title>
</head>
<body>
<?php
echo "<pre style='font-size: 1.5em;'>"; // format debug post dump
var_dump($_POST);
?>
</body>
</html>
Sample output
array(5) {
["vehicle-a1"]=>
string(3) "100"
["vehicle-a3"]=>
string(2) "55"
["vehicle-a4"]=>
string(2) "50"
["total"]=>
string(3) "205"
["submit"]=>
string(0) ""
}
As before, this isn't an industrial strength example and there is plenty of room for improvement, but hopefully it does communicate the basic idea.

jquery - copy value of input from one form to another (form and input named the same)

I would like to copy the value from an input in one form to the value of an input(with the same name) of the next form down. The forms and inputs are named the same. All it needs to do is copy the value of the title input to the title input one form down.
<form>
<input name="file" value="1.xml">
<input name="title" id="title" value="Smith">
<input type="submit" id="copy-down" value="copy">
</form>
<form>
<input name="file" value="2.xml">
<input name="title" id="title" value="Anderson">
<input type="submit" id="copy-down" value="copy">
</form>
etc...
In this case when the top "copy" button is clicked I would like jquery to overwrite Anderson with Smith.
$('#title').attr('value'));
Gives me Smith but I'm not sure what to do with that value once I have it.
Change HTML to this:
<form>
<input name="file" value="1.xml">
<input name="title" id="title1" value="Smith">
<input type="submit" id="copy-down1" value="copy">
</form>
<form>
<input name="file" value="2.xml">
<input name="title" id="title2" value="Anderson">
<input type="submit" id="copy-down2" value="copy">
</form>
Javascript:
function copyHandler() {
var copyVal = document.getElementById("title1").value;
var replaceInput = document.getElementById("title2");
replaceInput.value = copyVal;
}
document.getElementById("copy-down1").onclick = function(){
copyHandler();
return false;
}
Some notes:
This is so straightforward in vanilla javascript that I didn't add the jQuery code.
You should never assign multiple elements to the same ID, class or name can be used for that purpose.
The return false; portion of the onclick function is necessary so that the form doesn't reload when you click your submit button.
Let me know if you have any questions.
you can try
$(document).ready(function(){
$('form').on('submit', function(e){
e.preventDefault();
var GetNameAttr = $(this).find('input:nth-child(2)').attr('name');
var GetTitleValue = $(this).find('input:nth-child(2)').val();
var NextFormNameAttr = $(this).next('form').find('input:nth-child(2)').attr('name');
if(NextFormNameAttr == GetNameAttr){
$(this).next('form').find('input:nth-child(2)').val(GetTitleValue );
}
});
});
Note: this code will change the second input value in next form with
the second input value of form you click if the name is same .. you
can do the same thing with the first input by using :nth-child(1)
Demo here
if your forms dynamically generated use
$('body').on('submit','form', function(e){
instead of
$('form').on('submit', function(e){
for simple use I create a function for that
function changeNextValue(el , i){
var GetNameAttr1 = el.find('input:nth-child('+ i +')').attr('name');
var GetTitleValue1 = el.find('input:nth-child('+ i +')').val();
var NextFormNameAttr1 = el.next('form').find('input:nth-child('+ i +')').attr('name');
if(NextFormNameAttr1 == GetNameAttr1){
el.next('form').find('input:nth-child('+ i +')').val(GetTitleValue1);
}
}
use it like this
changeNextValue($(this) , nth-child of input 1 or 2);
// for first input
changeNextValue($(this) , 1);
// for second input
changeNextValue($(this) , 2);
Working Demo

Dynamic text field can't take the value jquery php

I'm trying to add/remove items dynamically but I can't take the values of all the elements of the array.
Basically I have this form
<form action="" method="post">
<div class="input_fields_wrap">
<div>
<label> <span>Team name </span>
<input type="text" class="input-field" name="teams[]"> </label>
</div>
</div>
<span id="num_teams"></span> <label><span> </span>
<input type="submit" value="Add Team" class="add_field_button" name="add_field_button">
<input type="submit" name="next" value="Next" />
</label>
</form>
It just shows an input box where I'd have to insert the team name and two buttons ; one to go to the next page, and the other one to add a new text field using jquery.
Here it is the jquery script
<script type="text/javascript">
$(document).ready(function() {
var wrapper = $(".input_fields_wrap"); //Fields wrapper
var add_button = $(".add_field_button"); //Add button ID
var x = 1; //initlal text box count
$(add_button).click(function(e){ //on add input button click
e.preventDefault();
var max_fields = $('#n_teams').val(); //maximum input boxes allowed
if(x < max_fields){ //max input box allowed
x++; //text box increment
$(wrapper).append('<div><label><span>Team Name </span><input type="text" class="input-field" name="teams[]"> Delete</label></div>'); // add input box
$("#num_teams").html('Number of Teams: '+x);
}
});
$(wrapper).on("click",".remove_field", function(e){ //user click on remove text
e.preventDefault(); $(this).parent('label').remove(); x--;
$("#num_teams").html('Number of Teams: '+x);
})
});
</script>
The script above works perfectly: it adds and removes textfields.
The problem that I have now is that I can't take the values of the array 'teams[]' .
in a
if(isset($_POST['next']))
even if I try to take the values manually like
echo $_POST["teams"][0]; and
echo $_POST["teams"][1]; ect...
It just takes the first value (i.e. the one I don't add using jquery). It doesn't 'see' the jquery text fields added.
Of course my final aim is to insert 'teams[]' in a mysql table, but for now I noticed that I can't either take the values.
Where am I wrong ?
EDIT - SOLVED
It was a very stupid error I made in the html code. Actually there was a <div> before of the <form> that caused all the troubles. After a very accurate analysis , trying every single piece of code alone, I finally got that I just had to move the <form> above two <div> to make the code work.
I do apologize to everyone, silly me!
Instead of using name="teams[]" use name="teams" and on server side use:
$_POST['teams']
which should give you the comma separated list.
var wrapper = $(".input_fields_wrap").first();

Getting rid of Value attribute of a textBox when using clone method in jQuery

I'm having a problem with this form I'm working on. Whenever I add, or refresh the page, the values are still there. I believe this is because the clone method copies the value attribute from the textBox. Is there any way I can get rid of them when I add another textBox?
<html>
<head>
<title>JQuery Example</title>
<script type="text/javascript" src="jquery-1.4.js"></script>
<script type="text/javascript">
function removeTextBox()
{
var childCount = $('p').size() //keep track of paragraph childnodes
//this is because there should always be 2 p be tags the user shouldn't remove the first one
if(childCount != 2)
{
var $textBox = $('#textBox')
$textBox.detach()
}
}
function addTextBox()
{
var $textBox = $('#textBox')
var $clonedTextBox = $textBox.clone()
//document.getElementById('textBox').setAttribute('value', "")
$textBox.after($clonedTextBox)
}
</script>
</head>
<body>
<form id =
method="POST"
action="http://cs.harding.edu/gfoust/cgi-bin/show">
<p id= "textBox">
Email:
<input type = "text" name="email" />
<input type ="button" value ="X" onclick = "removeTextBox()"/>
</p>
<p>
Add another email
</p>
<input type="submit" value="submit"/>
</form>
</body>
</html>
The Following addition should work:
var $clonedTextBox = $textBox.clone();
$($clonedTextBox).val('');

Categories