This application searches an Indian location/PIN-code database while the user types. It demonstrates a larger remote Autocomplete source, selection by record ID, loading full details, and an optional state filter.
Demo: search a city/location and show details →
<input type="text" id="t1" class="form-control">
<button type="button" id="img1" class="btn btn-secondary">
Reset
</button>
<div id="d2"></div>

$( "#t1" ).autocomplete({
delay: 400,
minLength: 2,
source: function ( request, response ) {
$.getJSON(
"indexck.php",
{ term: request.term }
)
.done( response )
.fail( function () {
response( [] );
} );
}
});
select: function ( event, ui ) {
event.preventDefault();
this.value = ui.item.label;
$( "#d2" ).load(
"indexck-dtl.php",
{ id: ui.item.value }
);
return false;
}

This uses jQuery load() to request the selected record details.
$( function () {
const $input = $( "#t1" );
$input.trigger( "focus" );
$input.autocomplete({
delay: 400,
minLength: 2,
source: function ( request, response ) {
$.getJSON(
"indexck.php",
{ term: request.term }
)
.done( response )
.fail( function () {
response( [] );
} );
},
select: function ( event, ui ) {
event.preventDefault();
this.value = ui.item.label;
$( "#d2" ).load(
"indexck-dtl.php",
{ id: ui.item.value }
);
return false;
}
});
$( "#img1" ).on( "click", function () {
$input.val( "" ).trigger( "focus" );
$( "#d2" ).empty();
});
});

Demo: search city/location within a selected state →
Send both the text term and selected state to the backend:
source: function ( request, response ) {
$.getJSON(
"indexck.php",
{
term: request.term,
statename: $( "#statename" ).val()
}
)
.done( response )
.fail( function () {
response( [] );
} );
}
When the state changes, trigger another Autocomplete search:
$( "#statename" ).on( "change", function () {
$( "#t1" ).autocomplete( "search" );
});
The original script combines WHERE conditions, LIKE matching and CONCAT() to produce labels such as Office Name, State. That search purpose is retained, but use prepared placeholders for every typed keyword and state value.
$term = trim($_GET['term'] ?? '');
$state = trim($_GET['statename'] ?? '');
$words = preg_split(
'/\s+/',
$term,
-1,
PREG_SPLIT_NO_EMPTY
);
$conditions = [];
$params = [];
foreach ($words as $index => $word) {
$placeholder = ':term' . $index;
$conditions[] = "officename LIKE $placeholder";
$params[$placeholder] = '%' . $word . '%';
}
$where = '(' . implode(' OR ', $conditions) . ')';
if ($state !== '') {
$where .= ' AND statename = :state';
$params[':state'] = $state;
}
$sql = "
SELECT
CONCAT(officename, ', ', statename) AS label,
id AS value
FROM pincode_india
WHERE $where
ORDER BY officename
LIMIT 30
";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
echo json_encode(
$stmt->fetchAll(PDO::FETCH_ASSOC)
);
The earlier version used each() while building keyword conditions. That function was removed from modern PHP; foreach is the current pattern.
The detail endpoint receives the selected record ID and should use a prepared statement.
$id = filter_input(
INPUT_GET,
'id',
FILTER_VALIDATE_INT
);
$stmt = $connection->prepare(
'SELECT *
FROM pincode_india
WHERE id = ?'
);
$stmt->bind_param( 'i', $id );
$stmt->execute();
Escape values before placing database text into HTML. The original tutorial links remain useful: fetch_array(), JSON output, and SELECT queries.
| File | Purpose |
|---|---|
config.php | Database connection settings. |
index.php | Main location-search page. |
index-state.php | Search page with an additional state filter. |
indexck.php | Returns matching label/value suggestions. |
indexck-dtl.php | Returns details for the selected record ID. |
sql_dump.txt | Sample database/table data. |
templates/head.php, templates/bottom.php | Project page shell/assets. |
Download the existing Autocomplete Search ZIP
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.