I was wondering how someone would send and receive input data to and from a MySQL database when the form that is being submitted can have additional fields added to it (So one order form might have 10 input fields and another might have 30). Here is a snippet to give you an idea of what I am talking about - http://jsfiddle.net/gv0029/M84r7/
I saw an post about using arrays but it was from 4 years ago and am wanting to make sure whatever I do is still using best practices. Any and all help or ideas would be greatly appreciated! Thank you!
HTML:
<fieldset id="fence">
<div name="inputFence" class="inputFence">
<legend><strong>Fence Description</strong>
</legend>
<label>Footage:
<input name="footage_1" class="footage" />
</label>
<label>Fence Height</label>
<select name="fenceHeight_1" class="fenceHeight">
<option value="select">Select Fence Height</option>
<option value="6" id="fH6">6 Ft.</option>
<option value="8" id="fH8">8 Ft.</option>
</select>
<legend><strong>Post Type</strong>
</legend>
<label>Post Quantity:
<input name="postQuantity_1" class="postQuantity" />
</label>
<label>Picket Quantity
<input name="picketQuantity_1" class="picketQuantity" />
</label>
</fieldset>
<div>
<input type="button" id="btnAddFence" value="Add Another Fence" />
<input type="button" id="btnDelFence" value="Remove Fence" />
</div>
</form>
JS
//Dynamic Fence Input Fields
$('#btnAddFence').click(function () {
// create the new element via clone()
var newElem = $('.inputFence:last').clone();
// insert the new element after the last "duplicable" input field
$('.inputFence:last').after(newElem);
// enable the "remove" button
$('#btnDelFence').removeAttr('disabled');
//get the input name and split into array (assuming your clone is always last)
var parts = $('.fenceHeight:last').attr('name').split("_");
//change the second element of the array to be one higher
parts[1]++;
//join back into a string and apply to the new element
$('.fenceHeight:last').attr('name', parts.join("_"));
//do the same for other two inputs
parts = $('.postQuantity:last').attr('name').split("_");
parts[1]++;
$('.postQuantity:last').attr('name', parts.join("_"));
parts = $('.footage:last').attr('name').split("_");
parts[1]++;
$('.footage:last').attr('name', parts.join("_"));
parts = $('.6foc:last').attr('name').split("_");
parts[1]++;
$('.6foc:last').attr('name', parts.join("_"));
parts = $('.railQuantity:last').attr('name').split("_");
parts[1]++;
$('.railQuantity:last').attr('name', parts.join("_"));
});
$('#btnDelFence').click(function () {
//remove the last inputFence
$('.inputFence:last').remove();
// if only one element remains, disable the "remove" button
if ($('.inputFence').length == 1) $('#btnDelFence').attr('disabled', 'disabled');
});
$('#btnDelFence').attr('disabled', 'disabled');
So it sounds like you have an unknown number of fields and you are looking for an easy way to send them to MySql. So I'm assuming you are calling a stored procedure but don't know how to deal with the unknown parameters. I would take the form and either serialize it into JSON or turn all the $_POST values into a XML object. Then you would only need to pass that single object into your MySql stored procedure. Once inside you could use some loops and XML function to do what you have to do. This way it wouldn't matter if your submitting 10 fields or 100 fields, the call to the stored proc would always be the same. I do this with a site and it works pretty good. Not on that PC to where I can get the code right now though. These might help....
To turn the PHP $_POST into XML: http://davidwalsh.name/watch-post-save-php-post-data-xml
Some MySql XML function to use once you're inside the stored proc: http://dev.mysql.com/doc/refman/5.1/en/xml-functions.html
I could help more later when I get on my other PC.. Hope this helps.
UPDATE: Here is how I grab all $_POST data and turn it into a valid XML document...
//Grab all the POST info, turn it into a valid XML object and store it
$postData = null;
if($_SERVER['REQUEST_METHOD'] == 'POST' && count($_POST) > 0) $postData = assocArrayToXML('POST_DATA',$_POST);
//The assocArrayToXML returns the XML object with page breaks, we need a stright non-breaking string
//so that the flexigrid can display the results properly.
$postData = str_replace(chr(13), '', $postData);
$postData = str_replace(chr(10), '', $postData);
And this is the assocArrayToXML function...
function assocArrayToXML($root_element_name,$ar)
{
$xml = new SimpleXMLElement("<?xml version=\"1.0\"?><{$root_element_name}></{$root_element_name}>");
$f = create_function('$f,$c,$a','
foreach($a as $k=>$v) {
if(is_array($v)) {
$ch=$c->addChild(htmlspecialchars($k));
$f($f,$ch,$v);
} else {
$c->addChild($k,htmlspecialchars($v));
}
}');
$f($f,$xml,$ar);
return $xml->asXML();
}
Serialize your form and send. In the server side unserialize it and insert to database
var str = $( "form" ).serialize();
Reference
http://api.jquery.com/serialize/
Related
I'm trying to get data which is selected inside of a multiselect. However, I want to display the selected options inside another field in the form. Therefor I don't want to send the actual form before getting the data and displaying it.
I want to use the value mainly to gather information from a database which gives the user a amount specified for that select option!
I have tried multiple different solutions from different threads but unfortunately they haven't worked!
Select which i want to gather the selected options from:
<div class="col-12">
<label for="misstanke" class="form-label">Lagöverträdelser</label>
<select multiple name="misstanke[]" onkeydown="return event.key != 'Enter';" class="form-select form-select-md">
<?php
include('selects/overtradelser.php');
?>
</select>
</div>
Input field I want to display the data in:
<div class="mb-3">
<label for="straff" class="form-label">Påföljder</label>
<input type="text" onkeydown="return event.key != 'Enter';" class="form-control" name="straff" id="straff">
</div>
Code:
function Straff() {
var select1 = document.getElementById("misstanke");
var selected1 = [];
for (var i = 0; i < select1.length; i++) {
if (select1.options[i].selected) selected1.push(select1.options[i].value);
}
document.getElementById("straff").setAttribute('value', select1);
}
To update the value of an input, assign to its value property, not the attribute.
You should use the join() method to convert the array to a string with a specified delimiter.
document.getElementById("straff").value = selected1.join(',');
I am trying to create a list of names an user could chose from to select a object with multiple hidden values. I work with a PHP backend.
The code I wrote works but I think it is probably not the right way to approach the problem and could be written alot better, but I can't seem to find a better way.
Right now I print a <div> for every object which are clients in my case. Within the div I have four checkboxes that are hidden, which I check and uncheck on the background with a javascript function. The values of those checkboxes is what I need in javascript for an API call after the user choses the client.
I select and deselect the with a javascript function.
foreach($clients as $client) {
echo '<div class="'.$client->name.'-'.$client->id.' client-style" name="'.$client->name.'">
<input type="checkbox" class="'.$client->id.'" name="client_id" value="'.$client->id.'">
<input type="checkbox" class="'.$client->id.'" name="client_fb" value="'.$client->facebook.'">
<input type="checkbox" class="'.$client->id.'" name="client_insta" value="'.$client->instagram.'">
<input type="checkbox" " class="'.$client->id.'" name="client_wb" value="'.$client->website.'"></div>';
}
For every element I create an on click event handler
for (var i = 0; i < clientList.length; i++) {
const {name, id} = clientList[i];
$(`.${name}-${id}`).on('click', function() {
selectClientFromList({name, id});
});
}
I am trying to get a list of clickable "names". When a "name" is clicked, you want to get the "name" but also "id", "facebook", "instagram", "website".
Might be useful to use the <select> tag with multiple values like this but I don't want a dropdown. I need a scrollable list, because I also have use searchbar for this list.
With a lot of clients the html would grow fast. How do I clean my php code and keep the information about a client that the user selected?
Thanks in advance!
A good approach can be to use a hidden input. Give your div a class and then
foreach($clients as $client) {
echo '
<div class="'. $client->name.'-'.$client->id.' client-style" name="'.$client->name.'">
<input type="hidden" class="aclass '.$client->id.'" name="client_id" value="'.$client->id.'">
<input type="hidden" class="aclass '.$client->id.'" name="client_fb" value="'.$client->facebook.'">
<input type="hidden" class="aclass '.$client->id.'" name="client_insta" value="'.$client->instagram.'">
<input type="hidden" class="aclass '.$client->id.'" name="client_wb" value="'.$client->website.'"></div>';
}
And then instead of creating a click handler everytime. One works too.
$(`.aclass`).on('click', function() {
let type = $(this).attr('name'); // client_id or client_fb
let client_id = $(this).attr('class').replace("aclass",""); // $client->id's value is here
let value = $(this).val(); // credentials
});
I try to achieve Total of two input fields and those fields got their value dynamically from database after selecting a dropdown option. The html code and the sql query looks like below:
<select name="getData" ID="getData" onchange="getData()">
<option value="Select">Select Subscription Package</option>
<?php
$sql = "SELECT * FROM package WHERE status = 1";
$result = $connect->query($sql);
while($row = mysqli_fetch_row($result)){
echo '<option data-price="'.$row[4].'" value='.$row[0].'> '.$row[1].' </option>';
}
?>
</select>
<input type="text" id="price1" name="price1"/>
<input type="text" id="price2" name="price2"/>
<input type="text" id="totalAmount" name="totalAmount" onblur="totalCalc()">
Value of price1 & price2 changes when SELECT Option changed. Now I need to get total of these two fields by javascript. The js code is below:
<script>
function totalCalc() {
var A = document.getElementById("price1").value;
var B = document.getElementById("price2").value;
var C = A + B;
document.getElementById("totalAmount").value = C;
}
</script>
I got the total but it needs to click the total amount field. I want the calculation should be done automatically right after the first two fields got their values dynamically.
Any help is appreciated.
You should just set up change event handlers on both inputs that point to your totalCalc function and then, at the end of your getData() function, manually trigger the change event of one of the inputs.
If the code in getData is asynchronous, then the code that manually triggers the change event should be included in the success handler of the operation.
A note about the UI. If the two price fields are being auto-populated and users won't be inputting anything into them manually, disabling the fields is probably appropriate. With regards to the final total, an input there may not make sense at all - you just need to show the result, so a span element would work.
Also, inline HTML event attributes (onclick, onchange, etc.) should not be used. There are many reasons why this 20+ year old technique needs to die the death it deserves, but because so many people don't take the time to really learn JavaScript and modern best-practices, they just copy someone else's code that uses them and go on their merry way.
So, in the code below, I'm showing how to solve this problem using modern, standards-based code that follows best-practices.
// Get references to the DOM elements you'll need to work with
let a = document.getElementById("price1");
let b = document.getElementById("price2");
let total = document.getElementById("totalAmount");
let select = document.getElementById("getData");
let price1 = document.getElementById("price1");
let price2 = document.getElementById("price2");
// Set up event handlers in JavaScript, not HTML
select.addEventListener("change", getData);
price1.addEventListener("change", totalCalc);
price2.addEventListener("change", totalCalc);
function totalCalc() {
total.textContent = +a.value + +b.value;
}
function getData(){
// This is just mean to replicate what SQL does
price1.value = 15;
price2.value = 27;
// Manually trigger the change event for either one of the inputs
// If the existing code in getData is asynchronous, then this code
// should be added to the "success" callback. If not, it can just be
// placed at the end of the function as I'm showing it here.
var event = new Event('change');
price1.dispatchEvent(event);
}
<select name="getData" id="getData">
<option value="Select">Select Subscription Package</option>
<option>Data 1 from SQL</option>
<option>Data 2 from SQL</option>
<option>Data 3 from SQL</option>
</select>
<input type="text" id="price1" name="price1" disabled>
<input type="text" id="price2" name="price2" disabled>
<!-- No need to place the result in an <input> since users won't
be inputted data here. You just need to show it. -->
<span id="totalAmount"></span>
i have a big form with lot of inputs.
Also i have a javascript multidimensional array. It's an array of custom objects, that they are adding and removing as a shopping cart .
The array is defined as a local JS variable.
When i submit the form, i need to pass the array too, and i don't know how to do it.
Here I leave an example, it's illustrative only , as my form and my classes are much more complex .
<SCRIPT LANGUAGE="JavaScript">
var itemList = [];
var CustomClass = function (id, description) {
this.id = id;
this.description = description;
};
function addItem(id, description)
{
var item = new CustomClass( id,description);
itemList.push(item);
}
</script>
<form method="post" action="formSave.php">
<input type="text" name="someInput1">
<input type="text" name="someInput2">
<input type="submit" value="Submit">
</form>
Thank you very much.
If you were set on using a form to submit your data, id make a hidden text input and use JSON.stringify(data) in your js and decode it on server with json_decode server side.
<input id = 'jsValueHolder' style = 'display:none'>
<script>
function loadJSDataBeforeSend(dataToSend){
document.getElementById("jsValueHolder").value = JSON.stringify(dataToSend);
}
loadJSDataBeforeSend(itemList);
</script>
And on server side:
<?php
/* other code */
$jsonDataString = ... // get your data from the input
$dataObject = json_decode($jsonDataString);
$dataKeyValueArray = json_decode($jsonDataString, true);
?>
Note how adding true to the json_decode function returns a key value array rather than a php object.
I am trying to display a MySQL table on a job sheet system form that I am making the drop down list shows the customer details and then once selected the fields should be filled in on the main form.
I know people tend to use AJAX but this is to be used on a tablet tethered to a mobile and want to ask the server as little as possible.
Because I have already got the details from the SQL to display the drop down I thought I could use this. I found the original code at:
http://board.phpbuilder.com/showthread.php?10372137-RESOLVED-How-do-I-populate-multiple-text-boxes-from-a-dropdown-(I-can-populate-1-text-box!)
but I also want to display items that aren't on the dropdown list. Someone said it works but the more I have learned I couldn't see how because the array it was building just didn't seem to be in a JavaScript format.
I have the drop down working and also it fills a JavaScript array using names but I just cannot work out how to use the array to show in the fields.
It seems to be the named indexes used in the array. I can get a test array to display when I use the normal static array but I have commented them out but as soon as I try to use the names on the array I get undefined errors.
<html>
<head>
<script type="text/javascript">
<?php
include_once 'includes/db_connect.php';
$query1 = "SELECT * FROM customer";
$result1 =($mysqli-> query($query1));
// build javascript array building an object
// build javascript array
while($row=mysqli_fetch_array($result1)){
echo 'customer['.$row['customer_id'].'] = new Array(';
echo 'customer['.$row['customer_id'].'][customer_id] = "'.$row['customer_id'].'";';
echo 'customer['.$row['customer_id'].'][post_code] = "'.$row['post_code'].'";';
echo 'customer['.$row['customer_id'].'][company_name] = "'.$row['company_name'].'");';
}
?>
</script>
</head>
<body>
<form name="customerform" form id="customerform">
<p>
<select name="customerselect" id="customerselect" onChange="showname()">
<option value="">Select customer</option>
<?php
$query1 = "SELECT * FROM customer";
$result1 =($mysqli-> query($query1));
// build javascript array
while($row=mysqli_fetch_array($result1)){
echo'<option value="'.$row['customer_id'].'">'.$row['forename'].'">'.$row['surname'].'">'.$row['customer_name'].'</option>';
}
?>
</select>
</p>
<p>
<input type="text" name="cust" value="" id="cust" />
<input type="text" name="cust" value="" id="customerselected" />
<input type="text" name="post_code" value="" id="post_code" />
</p>
<p>update
<input type="button" name="update" id="update" value="update" onClick="showname()">
<p> </p>
<p>
<input name="submit" type="submit" id="submit" value="submit" />
</p>
</form>
</body>
<script>
//var customer = Array();
var customer = Array();
//This below is a test multi dimensional Array which does work. //
//customer['CCS'] = Array[{forename:'Robert', surname:'Grain', company:'HOMS'}];
function showname() {
//this var takes the result of the selected drop down list and shows the correct part of the array.
var customerselected = document.getElementById('customer');
customername = customerselected.value;
// this does work but not from the array just fills the details up
document.customerform.customerselected.value = customername;
// the next part takes the selected dropdown data and calls for the correct place in the array
// document.getElementById("cust").value = customer['CCS'][0];
// document.getElementById("cust").value = customer[CCS]["forename"] ;
// (customer[''][forename]);
document.customerform.post_code.value = customer[customerselect]["post_code"];
}
window.onload=function() {
showname();
}
</script>
</html>
This is the source code from Explorer in the console. from the JavaScript Array.
</body>
</html>customer[118] = new Array(customer[118][customer_id] = "118";customer[118][post_code] = "L37 4RG";customer[118][company_name] = "jc knight");customer[119] = new Array(customer[119][customer_id] = "119";customer[119][post_code] = "DE56 7HG";customer[119][company_name] = "farm Customer giles");customer[122] = new Array(customer[122][customer_id] = "122";customer[122][post_code] = "LE67 8FH";customer[122][company_name] = "a test company");
Also this dropdown list creates:
<select name="customerselect" id="customer" onChange="showname()">
<option value="">Select customer</option>
<option value="118">John">Knight"></option><option value="119">Bill">Giles"></option><option value="122">Robert">Grain"></option> </select>
</p>
Maybe I should move the code to the bottom of the HTML for the JavaScript array although I wasn't sure if this wouldn't be initialised when required because it has ran the HTML first. I'm a little unsure if the order of things were correct.
The error I receive happens as soon as I change the drop downlist and it shows the following:
document.customerform.post_code.value = customer['customerselect'][post_code];
}
X 'post_code' is undefined
I think somewhere I am getting my document.value wrong when showing my array ?
Rather don't hope that a constant will work here.
Instead try the below as a replacement:
// build javascript array
while($row=mysqli_fetch_array($result1)){ ?>
var customer["<?=$row['customer_id']?>"] = [];
customer["<?=$row['customer_id'];?>"]['customer_id'] = "<?=$row['customer_id'];?>";
customer["<?=$row['customer_id'];?>"]['post_code'] = "<?=$row['post_code'];?>";
customer["<?=$row['customer_id'];?>"]['company_name'] = "<?=$row['company_name'];?>";
<? }
Thanks smftre for that. In the end I have opted for the jquery and ajax. and I think it has worked out betted for it originally I was trying to make the code as efficient as possible on bandwidth because the system is to be used but ajax seems to be the standard for a reason and works very well.