Proxied filter value for database-backed input field
Background
For the country field, the system detects and defaults to Canada. For the city field, the user types a Canadian city name, populated Facebook-style.
Both the country list and city list are populated using AJAX and JSON, sourced from a remote database using a proxy (queried via PHP).
The country is defaulted to the user's country of origin using MaxMind's GeoIP PHP API.
When the user selects a different country, its two-letter ISO code must be passed as a parameter to the city input so that the query that drives it can search for cities in the selected country.
For example, a user whose IP address is in Canada can choose the United States. When this happens:
- the city field will be erased;
- the city field gains focus; and then
- only U.S. cities are displayed (as the user types).
Problem
The following PHP snippet proxies retrieval of the city list to a remote server:
echo file_get_contents( 'http://server/city.dhtml?q=' .
urlencode( $_GET['q'] ) );
The jQuery tokenInput function does not seem to provide a mechanism to pass additional content. The relevant jQuery snippets follow.
Acquire Countries
The following code gets a country code and a list of countries. It sets the user's country as the default country.
// Where in the world?
$.getJSON( 'geoip.dhtml', function( data ) {
country = data[0].id;
});
// Select from countries that have significant amounts of data.
$.getJSON( 'country.dhtml', function( data ) {
var h = '';
var len = data.length;
for( var i = 0; i < len; i++ ) {
var s = '';
// Make the person's own country the default selection.
if( data[i].id == country ) {
s = '" selected="selected"';
}
h += '<option value="' + data[i].id + s + '">' + data[i].name + '</option>';
}
$('#country').html(h);
});
Acquire Cities
The following code downloads the list of cities. The tokenInput
function automatically passes the q
parameter to the code inside the "local version" of city.dhtml
(the PHP source code snippet is shown above). The q
parameter is the text that the user types for the city.
$('#city').tokenInput( 'city.dhtml', {
hintText: "Type a city name.",
tokenLimit: 1,
classes: {
tokenList: "token-input-list-facebook",
token: "token-input-token-facebook",
tokenDelete: "token-input-delete-token-facebook",
selectedToken: "token-input-selected-token-facebook",
highlightedToken: "token-input-highlighted-token-facebook",
dropdown: "to开发者_JAVA技巧ken-input-dropdown-facebook",
dropdownItem: "token-input-dropdown-item-facebook",
dropdownItem2: "token-input-dropdown-item2-facebook",
selectedDropdownItem: "token-input-selected-dropdown-item-facebook",
inputToken: "token-input-input-token-facebook"
}
});
The city.dhtml
must to filter the cities by country code.
Question
How would you provide the country code to city.dhtml
, without using a cookie?
Ideas
The latest version of the token input supports JSONP, would that be useful?
Thank you!
The problem is that the tokenInput
URL parameter cannot be changed once the input has been set. While perhaps possible to delete the existing tokenInput
and recreate it each time a new country is selected, the solution would be a hack.
The solution is to use a patch for the jQuery TokenInput that allows setting the URL parameter based on the result from a function call.
https://github.com/loopj/jquery-tokeninput/pull/77
Apply the patch and use the following code to change the query dynamically:
function cityURL() {
return 'city.dhtml?c=' + $('#country').val();
}
$('#city').tokenInput( cityURL, { /* ... */ });
And disable caching in jquery.tokeninput.js
(near line 650):
//var cached_results = cache.get(query);
var cached_results = false;
Neat question, +1! What's keeping you from just doing:
$('#city').tokenInput('city.dhtml?c=' + $('#country').val(), { /* ... */ });
You probably need to enclose that within a onChange
event, but it should work.
精彩评论