I'm all afternoon trying to run my code, but I'm doing something wrong. I will explain what I need to do.
I need to make when the user selects his city in a select box the neighborhoods corresponding to that city needs to be inserted into another select box. For this, I am using the following logic:
I have two tables in my database, one called cities and other called neighborhoods. The struct of the table cities is:
city_id (PRIMARY_KEY)
city_name
The struct of the table neighborhoods is:
neighborhood_id (PRIMARY_KEY)
city_id (To know what city the neighborhood belongs.)
neighborhood_name
Now in the register page I have this code to populate the user_city_id select box:
<label>City <span style='color: red'>*</span><br/>
<select id='user_city_id' name='user_city_id'>
<option value=''>-- Select a city --</option>
<?php
$sql = "SELECT * FROM cities ORDER BY city_id";
foreach($connection->query($sql) as $city)
{
echo "<option value='{$city['city_id']}'>{$city['city_name']}</option>";
}
?>
</select></label>
Ok, this code part insert the cities in select box with their ID in values and names. All right here.
Below I have the neighborhood select box with:
<label>Neighborhood <span style='color: red'>*</span><br/>
<select id='user_neighborhood_id' name='user_neighborhood_id'>
<option value=''>-- Select a neighborhood --</option>
</select></label>
Now is the hard part, the AJAX. I'm trying using jQuery and JSON to parse the data with the following code:
$(function(){
$('#user_city_id').change(function()
{
if($(this).val())
{
$.getJSON('neighborhood.ajax.php?search=', {city_id: $(this).val(), ajax: 'true'}, function(j)
{
var options = '<option value=""></option>';
for (var i = 0; i < j.length; i++)
{
options += '<option value="' + j[i].neighborhood_id + '">' + j[i].neighborhood_name + '</option>';
}
});
}
else
{
$('#user_neighborhood_id').html('<option value="">-- Select a neighborhood --</option>');
}
});});
The file to process the data is neighborhood.ajax.php. In this file I have:
require_once("db-connect.php");
$city_id = $_GET['user_city_id'];
$neighborhoods = array();
$sql = "SELECT * FROM neighborhoods WHERE city_id = {$city_id} ORDER BY neighborhood_name";
$stmt = $connection->prepare($sql);
$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
extract($row);
$neighborhoods[] = array
(
'neighborhood_id' => $neighborhood_id,
'neighborhood_name' => $neighborhood_name
);
}
echo(json_encode($neighborhoods));
...but simply nothing happens! Of course I'm doing something wrong, but so far I could not solve by myself. I'm trying and nothing.
I had never worked with AJAX. What is missing here?
You need to tell the browser that the data being sent from the server is JSON.
Add this line at the top of neighborhood.ajax.php
header('Content-Type: application/json');
I've found the solution today by myself.
It was a terribly simple solution that I could not see yesterday due to fatigue. I just noticed that I did not send the statement to insert HTML in select box, the options var data. I just inserted it with $('#user_neighborhood_id').html(options).show();. Here are the solution:
$(function(){
$('#user_city_id').change(function()
{
if($(this).val())
{
$.getJSON('neighborhood.ajax.php?search=', {city_id: $(this).val(), ajax: 'true'}, function(j)
{
var options = '<option value=""></option>';
for (var i = 0; i < j.length; i++)
{
options += '<option value="' + j[i].neighborhood_id + '">' + j[i].neighborhood_name + '</option>';
}
$('#user_neighborhood_id').html(options).show();
});
}
else
{
$('#user_neighborhood_id').html('<option value="">-- Select a neighborhood --</option>');
}
});});
Related
I'm working on a complex project for a car dealership where I have to create database search based on multiple criteria. The cars in the database are divided into 3 types - let's call them A, B and C. Let's say that the value of A=1, B=2, C=3. The url would look something like index.php?type_id=1 . The working search code so far is as follows.
In index.php :
<script type="text/javascript">
$(document).ready(function(){
$('#car').on('change',function(){
var carID = $(this).val();
if(carID){
$.ajax({
type:'POST',
url:'ajaxData.php',
data:'marque_id='+carID,
success:function(html){
$('#model').removeAttr("disabled");
$('#model').html(html);
}
});
}else{
$('#model').attr("disabled");
$('#energy').attr("disabled");
}
});
});
</script>
$type_id = $_GET['type_id];
$query = $db->query("SELECT DISTINCT marque_name,a.marque_id FROM vehicule_marque as a INNER JOIN vehicule as b WHERE b.type_id = '$type_id' AND a.marque_id = b.marque_id order by marque_name");
$rowCount = $query->num_rows;
<div>Select car</div>
<select name="car" id="car" required >
<option value="">Select Car</option>
<?php
if($rowCount > 0){
while($row = $query->fetch_assoc()){
echo '<option value="'.$row['marque_id'].'">'.$row['marque_name'].'</option>';
}
}else{
echo '<option value="">Car not available</option>';
}
?>
</select>
<div>Select car model</div>
<select name="model" id="model" disabled>
<option value=""><!--Select car first--></option>
</select>
In ajaxData.php :
if(isset($_POST["marque_id"]) && !empty($_POST["marque_id"])) {
//Get all state data
$query = $db->query("SELECT DISTINCT a.modele_id, modele_name, a.marque_id FROM vehicule_modele as a INNER JOIN vehicule as b WHERE a.marque_id = ".$_POST['marque_id']." AND b.type_id = '$type_id' AND b.marque_id = a.marque_id AND b.modele_id = a.modele_id ORDER BY modele_name ");
//Count total number of rows
$rowCount = $query->num_rows;
//Display model list
if($rowCount > 0){
echo '<option value="">Select model</option>';
while($row = $query->fetch_assoc()){
echo '<option value="'.$row['modele_id'].'">'.$row['modele_name'].'</option>';
}
}else{
echo '<option value="">Model not available</option>';
}
}
The problem is with taking the type_id value and using it in ajaxData.php query in order to show the model once the customer selected a car brand. In index.php, I GET the value from the url successfully (I tried echoing it and it worked), but then I can't get it to work in the other query - it keeps on showing only "Model not available" option. I tried putting inside the script the $type_id into a new variable, but this didn't work either. I'm not sure what I'm missing. If I remove the type_id condition, everything works perfectly. If anyone has any idea how to fix this, I would appreciate it.
First of all, you need to understand that request to url index.php?type_id=1 and request to url ajaxData.php are different requests and know nothing about each other.
So, if you try to access $_GET['type_id'] in ajaxData.php you will obviously receive nothing, because $_GET is empty in ajaxData.php. If you send request to ajaxData.php?type_id=42 you will get 42 as $_GET['type_id'].
So, you if you want to use some $_GET or $_POST data in ajaxData.php you must send this data explicitly.
It can be either:
url:'ajaxData.php?type_id=' + yourValue,
// access it with $_GET['type_id']
or
data:'marque_id='+carID+'&type_id='+yourValue,
// access it with $_POST['type_id']
I have a couple of SELECT boxes that are pulling from the database, how can I get the option that is selected in SELECT box 1 to filter the SQL in the SELECT box 2?
EG SELECT 1 - Make (Audi, BMW) SELECT 2 - Model (A1,A3, 1 Series, 3 Series)
I want to show that if I pick Audi from SELECT 1 that it will use Audi to fill the WHERE clause in my SQL to filter for the SELECT 2
<label>Manufacturer</label>
<select class="select2_category form-control" data-placeholder="Choose a Category" tabindex="1" id="make" name="make" >
<option value=""></option>
<?php $sqlmake = odbc_exec($cnn, "SELECT DISTINCT Manufacturer FROM lkup.alldata ORDER BY Manufacturer ");
while($manurs = odbc_fetch_array($sqlmake)) {
echo '<option value="'. $manurs['Manufacturer'] .'">'. $manurs['Manufacturer'] .'</option>';
}
?>
</select>
From the above I've been working on this below, which returns no errors but also when you click on the SELECT returns no values in the SELECT.
Where have I gone astray?
My SELECT
<select class="select2_category form-control" data-placeholder="Choose a Category" tabindex="1" id="model" name="model">
<option value=""></option>
</select>
<script>
$(function() {
$('.make').change(function() {
var select = $('.model').empty();
$.get('assets/configs/script.php', {model: $(this).val()}, function(result) {
$.each(result, function(i, item) {
$('<option value="' + item.value + '">' + item.name + '</option>').
appendTo(select);
});
});
});
});
</script>
The script.php
<?php
session_start();
date_default_timezone_set("Europe/London");
error_reporting(0);
include 'config.php'; //my db settings
if (isset($_GET['model'])) {
$model = addslashes($_GET['model']);
$sqlmodel = odbc_exec($cnn, "SELECT DISTINCT ModelName FROM lkup.MyTable WHERE ModelName IS NOT NULL AND Make = $model ORDER BY ModelName ");
$modelrs = array();
while ($row = $sqlmodel->fetch_assoc()) {
$modelrs[] = array(
'ModelName' => $modelrs['ModelName']
);
}
echo json_encode($modelrs);
}?>
If you are familiar with javascript or jQuery you could run another php echo statement to create the other select options with all the possibilities, and then with jQuery hide or show the appropriate options.
$('select[name=first_select]').on('change', function(){
var make = $(this).val();
$.each($('select[name=second_select] option'), function(){
if($(this).prop('class') != make){
$(this).hide();
}
}
});
After a lot of problems with this I found this link that worked a treat. I think my main problem is that I'm using PHP & MS SQL Server, which makes life difficult.
This I found as my solution
I'm fairly new to PHP and MySQL, have a little experience with jQuery and almost no experience with JSON, just to give you some background. I am trying to implement cascading dropdowns in my form.
I have two tables:
|city|
|city_id INT| - PK
|city VARCHAR (45)|
|state_state_id INT | - FK
|state|
|state_id INT| - PK
|state VARCHAR (25)|
Here's my form:
State:<br />
<select name="state" id="stateName">
<?php foreach($rows as $row): ?>
<option value="<?php echo htmlentities($row['state'],ENT_QUOTES,'UTF-8');?>"><?php echo htmlentities($row['state'],ENT_QUOTES,'UTF-8');?>
</option>
<?php endforeach; ?>
</select>
<br /><br />
City:<br />
<select name="city" id="cityName"></select>
<input type="submit" name="work_order_submit" id="" value="Add Work Order" />
I populate the State dropdown with this query:
$query = "SELECT * FROM state WHERE 1 ORDER BY state";
try{
$stmt = $db->prepare($query);
$stmt->execute();
}catch(PDOException $ex){
//On production remove getMessage.
die("Failed to run query: " . $ex->getMessage());
}
$rows = $stmt->fetchAll();
Here's the jQuery I've created to run the JSON and populate the City dropdown with the cascaded values from the state dropdown when a state is selected:
<script>
function populateCityName(){
$.getJSON('state-names.php', {stateName:$('#stateName').val()},
function(data){
var select = $('#cityName');
var options = select.prop('options');
$('option', select).remove();
$.each(data, function(index, array){
options[options.length] = new Option(array['city']);
});
});
}
$(document).ready(function(){
populateCityName();
$('#stateName').on('change', function(){
populateCityName();
});
});
</script>
And here's the code in the state-names.php file (I connect to the database before this code):
$rows = array();
if(isset($_GET['stateName'])){
$query = "SELECT city FROM city INNER JOIN state ON city.state_state_id = state.state_id WHERE state = :state ORDER BY city";
$query_params = array(":state" => $_GET['stateName']);
try{
$stmt = $pdo->prepare($query);
$stmt->execute($query_params);
}catch(PDOException $ex){
//On production remove .getMessage.
die("Failed to run query: " . $ex->getMessage());
}
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
echo json_encode($rows);
Nothing happens when I select the state in the form. I don't even get an error. I've tested the SQL and it runs fine and retrieves the values that I want, but for some reason that I can't figure out, the values aren't being cascaded into the City dropdown.
Any help is very much appreciated.
EDIT: As I'm doing more debugging and realizing a few things, this is what I've found so far. The JSON comes in like this:
[{"city":"Salt Lake City"},{"city":"Toole"},{"city":"Provo"},{"city":"St. George"}]
I now know the JSON is working correctly. When I changed the dropdown selection in the state dropdown to a state that I know had entries for the cities, the city dropdown showed blank 'option' fields for the number of entries that there actually were. So, using the answer below and MANY different tutorials on cascading dropdowns and chained dropdowns, I finally figured it out. I've submitted an answer with the working code.
Can you try:
$.each(data, function(index, array){
// new Option(text [, value, defaultSelected, selected]);
select.add(new Option(array['city'], index), null);
});
??
All of the code above worked except the jQuery function. Well, the jQuery worked for what I told it to do, not for what I really wanted the code TO DO... Big difference.
Here's the working jQuery that populates the city dropdown based on a selection made in the state dropdown:
<script>
function populateCityName(){
$.getJSON('state-names.php', {stateName: $('#stateName').val()},
function(data){
var html = '<option value="';
var htmlEnd = '</option>';
var options = '';
var select = $('#cityName');
$('option', select).remove();
$.each(data, function(index, array){
options += html + array['city'] + '">' + array['city'] + htmlEnd;
});
$('#cityName').append(options);
});
}
$(document).ready(function(){
populateCityName();
$('#stateName').on('change', function(){
populateCityName();
});
});
</script>
Before, the code would find the number of entries and the select box would show this number, but the selections were blank. With this code, the number of entries is found, but the values for those entries also show. Hope this helps someone else later.
I have a form with 2 selection boxes, both of these boxes draw their options from my database through php.
The first one shows a list of books ordered by their ISBN like this:
<ISBN> - <Book name>
Now the second selection box will list all the editions that exist for the book selected in the previous selection (based on ISBN) and show each one of them with just the number of the edition.
What I do in this form is insert a specific copy of the selected book with the specific edition with its serial number in the database.
What I try to do is with the onChange to retrieve the ISBN selected from the first select and use it to show the options of the second selection.
I use the function dropdown() to display the book select and the dropdownEdition() for the edition select:
function dropdown($intIdField, $strNameField, $strTableName, $strOrderField,
$strNameOrdinal, $strMethod="asc") {
echo "<select name=\"$strNameOrdinal\">\n";
echo "<option value=\"NULL\">Select Value</option>\n";
$strQuery = "select $intIdField, $strNameField
from $strTableName
order by $strOrderField $strMethod";
$rsrcResult = mysql_query($strQuery);
while($arrayRow = mysql_fetch_assoc($rsrcResult)) {
$strA = $arrayRow["$intIdField"];
$strB = $arrayRow["$intIdField"] . " - " . $arrayRow["$strNameField"];
echo "<option value=\"$strA\">$strB</option>\n";
}
echo "</select>";
}
function dropdownEdition($intId1Field, $intId2Field, $strTableName, $strOrderField,
$strNameOrdinal, $strMethod="asc") {
echo "<select name=\"$strNameOrdinal\">\n";
echo "<option value=\"NULL\">Select Value</option>\n";
$strQuery = "SELECT $intId1Field, $intId2Field
FROM $strTableName
ORDER BY $strOrderField $strMethod";
$rsrcResult = mysql_query($strQuery);
while($arrayRow = mysql_fetch_assoc($rsrcResult)) {
$strA = $arrayRow["$intId1Field"];
echo "<option value=\"$strA\">$strA</option>\n";
}
echo "</select>";
}
What I basically want to do is pass the ISBN selected previously with the onChange, in the variable $intId2Field of the dropdownEdition().
The problem with that is I have searched for tutorials but I can't understand anything because I have never worked with jQuery or Javascript or AJAX and I am a very novice web programmer. That is the reason for I am asking for some help here.
Here are how the 2 functions are called:
<?php dropdown("book_ISBN", "book_title", "book", "book_ISBN", "book"); ?>
<?php dropdownEdition("edition_no", "???????", "edition", "edition_no", "edition"); ?>`
The ???? are the book_ISBN because I don't know how to pass it in.
Here are how the tables are connected:
References -
It sounds like you've already figured this out, but you will need to make an asynchronous request to the server, passing the ISBN to a PHP script which will execute your mySQL query.
Your PHP script would return the mysql results, possibly as a JSON object which could then be parsed using JS and formatted as HTML.
Here is some code I chucked together to demonstrate.
HTML:
<select name="isbn-select" id="isbn-select">
<option value="">Select an ISBN</option>
<option value="isbn1">isbn1</option>
<option value="isbn2">isbn2</option>
<option value="isbn3">isbn3</option>
</select>
JS:
$('#isbn-select').on('change', function() {
isbn = $('#isbn-select').val();
$.getJSON('get_editions.php',
{
isbn: isbn
},
function(data) {
var editions = [];
$.each(data, function(index, val) {
editions.push('<option value="' + val + '">' + val + '</option>');
});
$('<select/>', {
'id': 'editions-select',
'name': 'editions-select',
html: editions.join('')
}).appendTo('body');
});
});
PHP:
<?php
// Code to select editions from your database goes here....
// Your isbn can be accessed as $_GET['isbn']
$editions_arr = array('editon1', 'edition2', 'edition3');
echo json_encode($editions_arr);
?>
I have used jQuery's getJSON method to fetch a JSON object from get_editions.php. The results are then formatted as a select and appended to the HTML document. To keep things simple I am not doing any error checking or validation.
I hope this helps get you on the right track!
EDIT:
If you wish to return formatted HTML instead of a JSON object, here's how you can do that.
JS:
$('#isbn-select').on('change', function() {
isbn = $('#isbn-select').val();
$.get('get_editions.php',
{
isbn: isbn
},
function(data) {
$('body').append(data);
});
});
PHP:
<?php
// Code to select editions from your database goes here....
// Your isbn can be accessed as $_GET['isbn']
$editions_html = '<select id="editions-select" name="editions-select">';
$editions_html .= '<option value="edition1">edition1</option>';
$editions_html .= '<option value="edition2">edition2</option>';
$editions_html .= '<option value="edition3">edition3</option>';
$editions_html .= '</select>';
echo $editions_html;
?>
You can read up on jQuery's AJAX functions here: http://api.jquery.com/category/ajax/
I have 2 tables, Provinces and Districts. I would like to populate a select field with options as District names based on which Province is chosen in another select. The Districts table has a ProvinceID field to reference which Province it belongs to. I know this is doable, I just can't figure it out. I also want to create and update the new Districts select without refreshing the page.
UPDATE: I'm writing it in PHP and MySQL, using jQuery as sparingly as possible.
In order to do it without AJAX, prepopulate a Javascript dataset... warning, if you have a lot of data this could be slow, but if it's a manageable list length, you could save some overhead from multiple AJAX requests loading the same data over and over.
var provinces = {};
provinces['province_a_id'] = [
{ name:'District A', id:'district_a_id' },
{ name:'District B', id:'district_b_id' }
];
provinces['province_b_id'] = [
{ name:'District C', id:'district_c_id' },
{ name:'District D', id:'district_d_id' }
];
function getDistricts( referenced_select ) {
var selected_province = $(referenced_select).val();
var district_select = $('#districts');
district_select.empty();
if ( provinces[selected_province] ) {
$.each( provinces[selected_province], function(i,v) {
district_select.append( $('<option value="' + v['id'] + '">').text( v['name'] ) );
} );
}
}
$(document).ready( function() {
$('#provinces').bind( 'change', function() {
getDistricts(this);
} );
} );
-- HTML
<select id="provinces" name="provinces">
<option value="province_a_id">Province A</option>
<option value="province_b_id">Province B</option>
</select>
<select id="districts" name="districts">
</select>
Make a php script and call it dp.php ( dp, short for data_provider, use any name you like). In dp.php
// get province id passed in via `post` or `get`
$pid = $_REQUEST['pid'];
// get the districts in that province
$query = "SELECT `district_id`, `district` FROM `districts` WHERE province_id` ='$pid'";
// link to your database
$link = mysqli_connect(HOST, USER, PASS, DBNAME);
// execute your query
$result = mysqli_query($link, $query);
// parse the options
while($row = mysqli_fetch_assoc($result)) {
$options .= '<option value="' . row['district_id'] . '">' . $row['district'] . "</option>\n";
}
// send options
echo $options
With the following markup in your page:
<select id="province" name="province">
<option value="ny">New York</option>
...
</select>
<select id="district" name="district">
</select>
Include the following jQuery:
// whenever a different province is selected
$('#province').change(function() {
// remove all options in district select
$('#district').html('');
// find the new province selected
var my_province = $('#province').val();
// get new options from server and put them in your district select
$('#district').get('path/to/dp.php?pid=' + my_province);
)};
You didn't state what server side technology you are using (if any). Here's an example in ASP.net - it should point you in the right direction:
http://www.mikesdotnetting.com/Article/97/Cascading-DropDownLists-with-jQuery-and-ASP.NET
I actually figured this out on my own using jQuery and post. On the primary select, I added onchange="getDistricts()" and used this for that function:
function getDistricts()
{
var province_id = $("#provinces").val();
$.post("handler.php",
{
"mode" : "get_districts",
"pid" : province_id
},
function(data)
{
$("#districts").html(data);
}, "text");
}
And then in handler.php, I have a case that catches the mode, and runs the following code:
<query on districts table>
while($row = $sql->fetchrow($result);
{
$id = $row['id'];
$name = $row['name'];
$html .= "<option value='$id' id='$id'>$name</option>";
}
echo $html;
I'm not a fan of this solution, and would really like something better, but it does what I need it to do for the moment. I hope this can help someone else out.