I learned quite a bit from what you posted and ran with a few ideas to change this around a bit. I'm sticking with the simple example that you suggested as a learning tool before I try to apply it to my actual database code. The first thing is that I'm not sure if I clearly explained the intent of the form. I have multiple sets of two selects. The first select is the field to query by, and the second is the value. Then I want the user to click a button to add an additional set of two selects, and so on. Then when the form is finally submitted, if the user added three sets of selects, it would be able to return a table of transactions for a particular item by a customer in a single month. I made those changes to the example that you gave back to me as such:
query.html:
<!DOCTYPE html>
<html>
<head>
<title>Page reloads</title>
<meta charset="utf-8">
<style>
form {
width: 20em;
}
.hide {
display: none;
}
</style>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
jQuery(document).ready(function ($) {
$('#add-query-element').on('click', function(evt) {
var numFields = $(this.form).find('input[id="numFields"]').prop('value');
var newFieldId = Number(numFields)+1;
$('#numFields').val(newFieldId);
$f = $(this.form);
var opts = {
url : $f.attr('action'),
method : $f.attr('method'),
data : $f.serialize()+'&cmd=add_field'
}
$.ajax(opts).done(function(data, textStatus, jQueryXHRObject) {
var groupSelect = '<select name="group['+newFieldId+']" id="group['+newFieldId+']" class="group">';
var subGroupSelect = '</select><select name="subgroup['+newFieldId+']" id="subgroup['+newFieldId+']" class="subgroup"></select>';
data = groupSelect + data + subGroupSelect;
$('<div>',
{
id: 'input['+newFieldId+']',
html: data
}).appendTo('#inputs');
$('#group['+newFieldId+']').html(data);
});
});
$('#submit-query').on('click', function(evt) {
$f = $(this.form);
var opts = {
url : $f.attr('action'),
method : $f.attr('method'),
data : $f.serialize()+'&cmd=submit_query'
}
$.ajax(opts).done(function(data, textStatus, jQueryXHRObject) {
$('#show-query').html(data);
});
});
$('.group').change(function() {
alert('changed');
var groupId = $(this).val();
var groupFieldId = $(this).attr('id');
$f = $(this.form);
var opts = {
url : $f.attr('action'),
method : $f.attr('method'),
data : 'group='+groupId+'&cmd=on_change'
}
$.ajax(opts).done(function(data, textStatus, jQueryXHRObject) {
$f.find('select[name="sub'+groupFieldId+'"]').html(data).parent();
});
});
});
</script>
</head>
<body>
<div>
<form action="form_send.php" method="GET">
<fieldset>
<legend>Type & Value</legend>
<div id='inputs'>
<input type="text" name="numFields" id="numFields" value=1 /><br />
<div id='input[1]'>
<select name="group[1]" id="group[1]" class="group">
<option value="0">Please choose…</option>
<option value="1">Customer</option>
<option value="2">Month</option>
<option value="3">Item</option>
</select>
<select name="subgroup[1]" id="subgroup[1]" class="subgroup"></select>
</div>
</div>
</fieldset>
<div id="buttons">
<button id="add-query-element" type="button">Add A Qualifier</button>
<button id="submit-query" type="button">Submit the Query</button>
</div>
<div id="show-query"></div>
</form>
</div>
</body>
</html>
And then form_send.php:
<?php
header ('content-type: text/html; charset=utf-8');
/* The good thing about the previous separation of code from presentation
* is that we can reuse it with little modification. Imagine if this had all been in the middle of
* the actual html code.
*/
function get_query_fields()
{
$rows = array(array('value' => 1, 'text' => 'Customer'),
array('value' => 2, 'text' => 'Month'),
array('value' => 3, 'text' => 'Item'),);
$options = array('<option value="0">Please select</option>');
foreach ($rows as $row)
{
$options[] = sprintf('<option value="%d">%s</option>',
(int) $row['value'] /* always escape data as needed */,
htmlspecialchars($row['text']) /* depending on what type it should be */
);
}
return implode('', $options);
}
function sub_group_select($group)
{
if (empty($group))
return '';
/* I've just removed the logic needed to retrieve the data, and assume
that it's returned as an array of rows with fields "value" and "text" */
if ($group == 1)
$rows = get_customer_data();
if ($group == 2)
$rows = get_months();
if ($group == 3)
$rows = get_items();
$options = array('<option value="0">Please select…</option>');
foreach ($rows as $row)
{
$options[] = sprintf('<option value="%d">%s</option>',
(int) $row['value'] /* always escape data as needed */,
htmlspecialchars($row['text']) /* depending on what type it should be */
);
}
return implode('', $options);
}
/* generate dummy data instead of db calls */
function get_customer_data()
{
return array(
array('value' => 1, 'text' => 'John'),
array('value' => 2, 'text' => 'Sue'),
array('value' => 3, 'text' => 'Ellen'),
);
}
/* i realize that this is probably something other than actual months */
function get_months()
{
return array(
array('value' => 1, 'text' => 'January'),
array('value' => 2, 'text' => 'February'),
array('value' => 3, 'text' => 'March'),
);
}
/* i realize that this is probably something other than actual months */
function get_items()
{
return array(
array('value' => 1, 'text' => 'Mimes'),
array('value' => 2, 'text' => 'Hair Extensions'),
array('value' => 3, 'text' => 'Milli Vanilli CDs'),
);
}
function submit_query($group)
{
$sql = "select stuff from MySQL: ".implode(', ',$group);
return ($sql);
}
if (empty($_GET['group']))
echo 'nothing sent';
else
if($_GET['cmd'] == 'add_field')
{
echo get_query_fields();
}elseif($_GET['cmd'] == 'submit_query')
{
echo submit_query($_GET['group']);
}elseif($_GET['cmd'] == 'on_change')
{
echo sub_group_select($_GET['group']);
}else{
echo sub_group_select($_GET['group']);
}
exit
?>
I'm still fumbling through a lot of this and learning along the way, but I'm hitting a wall at one particular point. When I click Add A Qualifier, I get a new set of two selects, so that's great, but then when I change the value in group[2], nothing happens. I don't get the alert that I added in to the $('.group').change(function(). Does .change() not recognize that I added a new field to the form with that class?
Also - I'm not sure if I didn't come across properly, or if I just haven't had the ah ha moment yet with this, but how will I be able to pass into query.html the different parameters like query.html?group[1]=1&subgroup[1]=2&group[2]=2&subgroup[2]=1 (Customer = John and Month = January)? Will I just have to write some checking of the url parameters to see if they're there? But then how do I add the proper number of sets of selects.... I'm not sure I 'get' that yet, but I'm willing to keep at it.
Thanks again for the great help!