Limiting dropdown options based on userID - javascript
I am asking this question because I'm unsure of the best way to solve my problem.
Problem:
I have a pre-populated drop down list of 1,000 or so numbers. I need to limit which numbers appear in the drop down based on which user is using the drop down.
Solution I thought of:
Hide all numbers with jQuery
Use jQuery / AJAX to call a database, passing a userID
DB returns a list of values based on the userID
Show options in drop down that have same values as numbers returned from the DB
Lets say this is my HTML:
<select>
<option>Please Select..</option>
<option value="101"> CC 101 </option>
<option value="102"> CC 102 </option>
<option value="103"> CC 103 </option>
<option value="104"> CC 104 </option>
<option value="105"> CC 105 </option>
<option value="106"> CC 106 </option>
</select>
And this is my DB table:
=======================
| User1 | 101 |
| User2 | 101 |
| User2 | 102 |
| User2 | 103 |
| User3 | 103 |
=======================
I need to figure out, for example, how to pass user2 and then return 101,102,103.
I only know basic js/jQuery, and I am not very experienced with DBs, so I am welcome to any suggestions that can help me accomplish my end goal.
EDIT/NOTE: As dumb as this sounds.... Security is not a huge deal here. This will be used on an internal company website, where if a user felt the need to hack around and select a different number, it really wouldn't matter that much. I also don't foresee any of the employees of the company having the desire/need/want to select a different option than they are allowed.
Also, the list must be pre-populated then numbers hidden. Its the way the platform I am using is set up, so I have to use show/hide, or something similar.
I would go only with steps 2-3 of your approach; however, I would not store the numbers in the way you showed. A better approach would be to store them in a table called user_value -or something like that-:
user_id | value
---------+-------
user1 | 101
user1 | 102
user2 | 101
Just because you can then easily add/remove/update values in the future as opposed to having to parse the comma-delimited value.
I would avoid using jQuery to simply "hide" things because Javascript can be disabled by the user and he may end up submitting whatever value he wants (visible or invisible) - Never trust user input.
In conclusion do this:
Use jQuery / AJAX to call a database, passing a userID
DB returns a list of values based on the userID
populate the dropdownlist with the values returned from the database.
Validate the form on the server side to make sure that the value submitted is present in the user_value table.
If that's the example Database Table and an example of a Select element. Then I think the best method would be to not write anything on your own and just let the Database choose what to share and where to share.
Here we go with the coding. I will try to explain what I am writing and how I am writing; since you're a newbie :-)
HTML code for you
The HTML code for your job, would be simple as this
<select name="someName">
<!-- No options please! -->
</select>
Getting the UserId
Now, once the user has logged in. Try to get the UserId by any one of the following method.
jQuery
To use jQuery you will need to be using the Server's generated value, because jQuery cannot interfere the Server Requests and code. So, you can create a simple hidden input and give it the value of the current logged in user. Here is the example
<input type="hidden" id="userId" value="#WebSecurity.CurrentUserId" />
Now, using jQuery you can get the value for this input. Here would be the code for that
var userId = $('#userId').val();
ASP.NET
To use ASP.NET, you don't do anything. All you do is you use the Built-in method of the ASP.NET as
WebSecurity.CurrentUserId;
and it would give you an integer value. Which would be the userId of the currently logged in user.
Usage of WebSecurity
The WebSecurity as the following link states, is a Class of data. Which can be used in your application, to lessen down the code and to help you get the User's properties at a better rate.
This class is used as a value for the variable, or as a parameter. This method would return a particular user's property. For example, you can get User's UserId, his UserName, his CreateDate, or you can use WebSecurity to Login a user, or Log him out.
Here would be an example of using WebSecurity. Just the way you create a variable in jQuery and get its value. You use this method and get the value.
jQuery Method
var userId = $('someElement').val();
/* get the value of some element as userId */
WebSecurity.CurrentUserId Method
var userId = WebSecurity.CurrentUserId;
Then you can use it inside the Database query,
db.Query("SELECT * FROM UserProfile WHERE UserId =#0", userId);
or, write it inside the document
Response.Write(userId);
Or do what ever you want to do. You can learn the syntax of the Class and other stuff in the links of MSDN. :-)
http://msdn.microsoft.com/en-us/library/webmatrix.webdata.websecurity(v=vs.111).aspx
Sending the Ajax request
Now send the Ajax request. If you know, then wonderfull! If not, then here is the example of the Ajax request to be sent
$.ajax({
url: 'page_url',
data: 'userId=' + userId, // userId that you got from input
success: function (data) { // note the data parameter
/* write in the select statement */
$('select').html(data); // usage of data parameter
}
});
Once it is done. It would update the Select element's options. But wait, what would it add to it?
It you, who control it too. You edit the server-side code to the following.
Getting the Data from Database.
If you're a newbie to the Databases and ASP.NET you need to first learn a bit.
http://www.asp.net/web-pages/tutorials/data/5-working-with-data
Ok, you can learn that a bit later too. I will still explain all my code to you. :-)
So, for Database you first need to create a Connection to the database and then you can search its tables and other content. Here is the code
var db = Database.Open("databaseName"); // Open a connection
var userId = Request.QueryString["userId"]; // get userid from ?userId=int
var selectQuery = "SELECT * FROM table_name WHERE UserId =#0"; // Query
var results = db.Query(selectQuery, userId); // Get data in a variable
After getting all these values, all that you need to do is to create a Response, to be sent to the client.
I hope, you're using Web Pages technology. Good! You're one step safer than others here.
Just press Page Down and move down to the last few lines and create a new Div element
<div>
<!--empty div element -->
</div>
Now, write an if else statement in it and create a Response which would be added to the select element.
P.S Other method (Actual method) of giving out a Response, is using the Actuall HttpResponse class and then giving the values to it. Like this
Response.Write("Hello World!");
If you write the above line, it would add this string to your select statement (although illegal) but that would make you understand its usage.
http://msdn.microsoft.com/en-us/library/system.web.httpresponse.aspx
I'm still a little confused about your constraints, but based on your comment:
The list will be pre-populated client-side (from a server I can't access/modify) THEN the AJAX call to a different DB (simple, two columns) THEN return values to original AJAX call, where THEN JS hides the values not returned (or shows the returned values, if they are initially hidden.)
Why not create a "unifying" service (on a server) so that you only make one AJAX call (from the client)?
http://MySite/MyService.aspx/GetOptionsForUser(101)
This service would make calls to both databases an return a list of the allowable option for the given user ID. This lets the server do most of the heavy lifting and greatly reduces the amount of jQuery on the client.
More Info:
The URL is what jQuery uses to make the AJAX call.
The simplest thing to do is:
Create a webpage called http://mySite/MyService.aspx
Add a public method called GetOptionsForUser() that accepts an integer and returns a list of numbers. This is the "unifying" logic that queries both databases. Make the method AJAX-callable by adding the WebMethod attribute.
In the existing web page where you want to populate your dropdowns, you make an AJAX call to http://MySite/MyService.aspx/GetOptionsForUser and pass the User ID as the AJAX parameter.
i think a good way to do it would be using JSON for all users.
prepare a json array for users with options and render it based on users to populate options.
eg.
var user1 = '["101","102","103"]';
This is an Example that shows how jquery ajax and php works to gather:
for example when a button clicked a ajax send an order to server side language (php), and php proccess that order and shows a suitable response:
$("#button").click(function(){
$.ajax({
type:"POST",
url:"ajax/alertMe.php",
data:({alert:"yes"}),
// The alert ^^ is the name of $_POST variable in php
success:function(data){
//this data can be some javascript and HTML codes or a text and ...
evel(data);
}
});
})
and here is php code with name alertMe.php:
<?php
if(isset($_POST['alert']) && $_POST['alert']!=""){
if($_POST['alert']=="yes"){
echo 'alert("the condition says I should alert!");';
}else{
echo '$(this).fadeOut();';
}
}
?>
Since you are saying that - You have pre-populated entries I would have gone with this approach -
First save all the items in a JS array at page load-
var alloptions = $("select").find("option").get();
Then for each user ID after getting the list of items, show and hide them as following -
//getting the id of the user and passing to AJAX call
$.ajax({
url: '',
dataType: 'json',
type: 'GET',
success:function(data){
// other codes
var userItemList = []; //list of items for this user [102,103, etc]
$("select").empty();
$("select").append(alloptions[0]) //the first one since it is the null one
for(var i = 0; i < userItemList.length; i++){
for(var j = 0; j < alloptions.length; j++){
if (parseInt($(alloptions[j]).val()) == userItemList[i]){
$("select").append(alloptions[j]);
}
}
}
}
});
If you only need to populate once at the first page loads this is the best option by me
Example:
HTML:
<select id="auto-populated">
<?php
//Next three lines you need if you dont have the user_id stored before in your code
require('db.php');
session_start();
$user_id = $_SESSION['user_id'];
//Selecting only the needed options to put here
$sql = "SELECT dropdown_value, dropdown_option FROM tbl_dropdown WHERE dropdown_number='your-filter-kriteria-here'";
$result = mysql_query($sql, $db) or die(mysql_error().': '.$sql);
//After you got the filtered results from database, print them in the <select>
echo "<option value=' '>Please select one...</option>";
while ($item = mysql_fetch_assoc($result)) {
echo "<option value='".$item['dropdown_value']."'>".$item['dropdown_option']."</option>";
}
?>
</select>
EDIT: I see that you need for asp.net so try converting this
Straightforward problem. I will try to answer in your own way you thought of.
0. Your existing HTML code
Choose your Value:
<select id="dropDown">
<option>Please Select..</option>
<option value="101"> CC 101 </option>
<option value="102"> CC 102 </option>
<option value="103"> CC 103 </option>
<option value="104"> CC 104 </option>
<option value="105"> CC 105 </option>
<option value="106"> CC 106 </option>
</select>
1. Hide all numbers with jQuery
<script>
$("#dropDown").html("<option>Please Select..</option>");
</script>
2. Use jQuery / AJAX to call a database, passing a userID &
3. DB returns a list of values based on the userID
<script>
$(function()
{
var userId = 1; <!-- Read & store the userId here -->
$.ajax({
type: 'POST',
url: 'server.php', <!--server.pl, server.js, server.asp, server.py whatever-->
dataType: "json",
data: {'userId': userId},
success: function (returnData) //Returns "[101, 102, 103]"
{
4. Show options in drops down that have same values as numbers returned from the DB
for (var i=0; i<returnData.length; i++)
{
$("#dropDown").append("<option value='"+returnData[i]+"'> CC "+returnData[i]+" </option>");
}
}
});
});
</script>
Related
Ajax passing php variable to javascript function as an argument
I have three tables in my database: Person (id, name, last_name), System (id, name), PersonInSystem(id, person_id, system_id). The last one is used to link a person with a system. I use <select> to display every person from my DB like this echo '<option value="'.$queryResult["id"].'">'.$queryResult["name"].' '.$queryResult["last_name].'</option>'; I use Ajax to get the id and to send a query SELECT * FROM Person WHERE id = ID_FROM_SELECT. Then, I display the data like this (I can't copy the code, so I have to rewrite it from head, I will use pseudo PHP + HTML), and the main purpose of it is to edit a chosen person: <form> Name: <input type="text" value="'.$nameFromDB.'" name="name"> Last name: <input type="text" value="'.$lastNameFromDB.'" name="lastname"> System: while () { // if one person is assigned to many systems, I will display them all in separate selects <select><option value="'.$systemAssignedToPerson.'">'.$systemAssignedToPerson.'</option> while () { // display every system except for the one listed above } </select><img src="drop.gif" onclick="deleteSystem(document.getElementById(\"system\").value)"><input type="hidden" id="system" value="'.$systemAssignedToPerson.'"> } <input type-"submit" value="Edit" name="editPerson"> </form> Now if I want to unassign a person from given system, I would like to click the drop.gif image and trigger deleteSystem(value) function, which will send query DELETE FROM PersonInSystem WHERE system_id = SYSTEM_ID_SENT and person_id = PERSON_ID_SENT, but I can't pass the value and I don't have really idea how to do it (I'm new with Ajax). I can store person's id in a session variable, but I don't know how to send system id, and also I don't want to sent the data to another page. Also I would like to refresh the page with changed system assignment (the same person should be displayed).
I think you need native javascript function call to the server function deleteSystem(value){ var deleteflag=confirm("Are you sure to delete?!!"); if(deleteflag){ //setup your request to the server window.location='delete.php?SYSTEM_ID_SENT='+value } } In your delete.php file you can get the SYSTEM_ID_SENT in this way $id=$_GET['SYSTEM_ID_SENT']; $personid=$_SESSION['your session variable name']; // run your delete query $delqry=mysql_query(""); if($delqry){ //redirect to the page you want header('location:yourpage.php'); }
Change the code as below. It should work <img src="drop.gif" onclick="deleteSystem('<?php echo $systemAssignedToPerson;?>')">
Your deleteSystem JavaScript function needs to send the following kind of request to the server: (Example: Handler file for unassign) "unassign.php?systemId=459&personId=300" (Example: Generic handler file) "handler.php?systemId=459&personId=300&action=unassign" In unassign.php: $systemId = $_GET["systemID"]; $personId = $_GET["personID"]; /* Your SQL stuff here - statement something like DELETE FROM PersonInSystem WHERE person_id = "$personId" AND system_id = "$systemId" */ Improvements: * Use a javascript library like Prototype (oldschool, lightweight) or jQuery (more heavy) for handling the Ajax stuff * Use $_POST and post variables instead of $_GET * Use a library for properly quoting your SQL * Care about html special characters and proper input validation/filtering
jQuery Autofill textbox with information from another autofill
I am having an issue with jQuery autocomplete. Basically I have a search bar, and when you type in what you're looking for the jQuery code I have calls a php script which does a MySQL query and returns everything I need and fills in the text boxes accordingly. What I then want to do is take the value I receive from that autocomplete, and use it in another autocomplete to fill in more data. The tricky part is that the data I need to get with the 2nd query is located in a different table than the first query, which share a relationship. My question is do I need a completely separate function to do this, or can I simply put both queries in the 1 php script and have the information from the first query be used for my 2nd query. Any help is appreciated thanks! Here is the jQuery function: $(function() { /* $('#abbrev').val(""); */ $("#q16_location16").autocomplete({ source: "location_query.php", minLength: 1, select: function(event, ui) { $('#q16_location161').val(ui.item.LocationID); $('#SystemName').val(ui.item.SystemName); $('#SiteAddress1').val(ui.item.SiteAddress1); $('#SiteAddress2').val(ui.item.SiteAddress2); $('#SiteCPP').val(ui.item.SiteCPP); $('#Contact').val(ui.item.Contact); $('#SiteLocationHours').val(ui.item.SiteLocationHours); } }); }); and the php script: /* If connection to database, run sql statement. */ if ($conn) { $fetch = mysql_query(" SELECT Location.LocationID, Location.SystemName, Location.SiteAddress1, Location.SiteAddress2, CONCAT_WS(' ', Location.SiteCity, Location.SiteProvince, Location.SitePostalCode) AS SiteCPP, CONCAT_WS(' ', Location.ContactName, Location.ContactPhone, Location.ContactEmail) AS Contact, Location.SiteLocationHours, CONCAT_WS(' ', SystemName, SiteNameLocation, SiteAddress1, SiteCity, SiteProvince, SitePostalCode) as expr2 FROM Location WHERE Location.SystemName like '%".mysql_real_escape_string($_GET['term'])."%' OR Location.SiteNameLocation like '%".mysql_real_escape_string($_GET['term'])."%' OR Location.SiteAddress1 like '%".mysql_real_escape_string($_GET['term'])."%' OR Location.SiteCity like '%".mysql_real_escape_string($_GET['term'])."%' OR Location.SiteProvince like '%".mysql_real_escape_string($_GET['term'])."%' OR Location.SitePostalCode like '%".mysql_real_escape_string($_GET['term'])."% ' LIMIT 0,15"); /* Retrieve and store in array the results of the query.*/ while ($row = mysql_fetch_array($fetch, MYSQL_ASSOC)) { $row_array['LocationID'] = $row['LocationID']; $row_array['value'] = $row['expr2']; $row_array['SystemName'] = $row['SystemName']; $row_array['SiteAddress1'] = $row['SiteAddress1']; $row_array['SiteAddress2'] = $row['SiteAddress2']; $row_array['SiteCPP'] = $row['SiteCPP']; $row_array['Contact'] = $row['Contact']; $row_array['SiteLocationHours'] = $row['SiteLocationHours']; array_push($return_arr,$row_array); } } /* Free connection resources. */ mysql_close($conn); /* Toss back results as json encoded array. */ echo json_encode($return_arr, $return_arr2); So when the user types in "New York" they can can select that option. In my example New York has an ID of 5. I also have a query that selects different streets in new york but this is in a separate table. in my streets table however, there is a "LocationID" column that for every street in new york will have a value of 5. So I want to take that ID of 5 when a user enters in new york and generate all the streets from a different table which also have that ID. I have tried multiple things in terms of creating a new function but I am just unsure of how I would pass that ID to the function. Thanks
You can use one PHP script for this. Here's about what I'd think the basic structure will look like: Pass two values to "location_query.php". The first value would be the name of the table that you want to query. The second value could be the selection result from the auto-complete text box. Create a prepared statement in "location_query.php" from the two values that were passed to "location_query.php". Perform your query. JSON encode the result (just like you did before). I'd also like to point out a security concern with your code. You should be using Mysqli and prepared statements instead of PHP's MySQL and mysql_real_escape_string. mysql_real_escape_string has been shown to have security deficiencies that can lead to security breaches and PHP's MySQL class has been deprecated. Mysqli and Prepared statements are much safer, and, in my opinion, provide for cleaner code since it allows for the separation of the SQL and the parameters. Hope this helps! EDIT: I think I understand what you're trying to do now, but I think there's a better way to go about doing it. Instead of assigning the id value to a hidden field and trying to have jquery detect every time that field is changed, I would just do the following: For your first text box's select method: select:function(event, ui) { $.get("location_query.php", { searchterm:$(ui).val() }, yourFunction); } Here's an example implementation of "queryFinished": function queryFinished(data, textStatus, jqXHR) { var mJSON = $.parseJSON(data); /* mJSON is the parsed JSON data returned from your "location_query.php" script.*/ //TODO the rest of your code } Here's what's going on: We define a custom function to be called when the first text box has a new item selected. This functions only purpose is to call a GET on "location_query.php". Then, we pass the value of the selected field from the first text box via our GET call. We then create a function to be called when GET returns. Finally, we parse the encoded JSON that is returned by "location_query.php". After that, you can perform whatever tasks you need with the parsed JSON (mJSON in our example). Taking this approach keeps us from having to worry about "listening" for a value change in our hidden ID field and makes everything nice and clean.
How do I pull rows from mysql with Javascript onchange
I have a website where info of registered member from various countries and states are collected. On my search form, I have 3 fields; Country, State and Sex. I listed all the countries of the world in my search (as a dropdown), but the state field is empty. Want I want is that once a visitor select a country, i want only the states of that country which registered members have are in my database to be pulled into the state field, instead of all the state of that country. Eg 3 members from USA are from New York, New Jersey and Georgia. On selecting USA in the country dropdown, only these 3 state should appear under the state instead of the 50 states in america.
You would need to do a script, for example, in php(or any server side language), that does the query, it would look like: $countryId = $_POST['countryId']; $sql = "SELECT fields FROM states WHERE countryId = $countryId"; $result = .... etc; returning an json object for example to the main page. And from the main page you should do a Ajax request to the php page, getting the json object returned depending on your option selected and populating the next field. You could have a look at jQuery framework as at least I, find easier than using raw javascript.
You could pull the the states of the registered members from your database using php or any server-side language you are using. Then you can use AJAX to get the states as an xml or a JSON object. You can the use the members of the object to populate the dropdown. Example sql query string to get states of registered users: Select state From user_details WHERE country = 'USA'. This should return the states (probably in an array); Example PHP code that will be retrieved by an AJAX call: $reply = {states: [NJ, NY, AZ]}. Example JS code to parse the above reply: var reply = JSON.parse(serverReply); var states = reply.states; . I hope this helps
Too much JSON crashes browser :(
I have an ajax country/city selector. When I select United States the browser crashes. Doh! I have a dropdown list of countries. When I select a country a jQuery ajax call is run which gets a JSON response of cities belonging to that country. I should have seen it coming when I had to increase my allowed memory during execution. Here's the JSON response from selecting the UK. {"5947":"Aberdeen","12838":"Aberystwyth","15707":"Aldershot","18575":"Alsagers Bank","18682":"Altrincham","4863":"Andover","41802":"AOL","6471":"Armagh","18945":"Ascot","4864":"Ashby-de-la-Zouch","4865":"Ashford","5948":"Aviemore","12985":"Aylesbury","12281":"Ballymena","14446":"Banbury","12445":"Bangor","13631":"Barking","4866":"Barnet","17004":"Barnsley","16423":"Barrow-in-Furness","16254":"Basildon","12402":"Basingstoke","5826":"Bath","13289":"Beddgelert","15082":"Bedford","4868":"Belfast","4869":"Belper","13874":"Benfleet","5827":"Benson","15514":"Berkhamsted","4870":"Berwick Upon Tweed","12948":"Betws-y-Coed","18776":"Bexley","14530":"Bicester","4871":"Billericay","18436":"Birkenhead","4872":"Birmingham","14592":"Blackburn","14686":"Blackpool","12526":"Bolton","12480":"Bournemouth","13062":"Bracknell","18772":"Bradford","4873":"Braemar","4874":"Brecon","4875":"Brentwood","18820":"Brighton","14260":"Bristol","4876":"Broomfield","42004":"Burgess Hill","14654":"Burnley","4877":"Burton Upon Tren","13812":"Bury","15835":"Bury St Edmunds","16500":"Camberley","4878":"Cambridge","4879":"Canterbury","5957":"Cardiff","14443":"Carlisle","14065":"Carrickfergus","42384":"Chalgrove","5832":"Chatham","13641":"Chelmsford","4880":"Cheltenham","4881":"Chester","42879":"Chesterfield","12160":"Chichester","41768":"Chorley","14056":"Church Stretton","5949":"Cladich","4884":"Colchester","16204":"Congleton","17534":"Coniston","42888":"Corsham","4885":"Coventry","13575":"Crawley","15410":"Crewe","13913":"Croydon","4886":"Cumbernauld","13711":"Dartford","4887":"Dartmouth","5833":"Derby","17468":"Derry","4889":"Doncaster","13696":"Dorchester","15377":"Dorking","5834":"Dover","16659":"Dudley","41867":"Dumbarton","18091":"Dumfries","4890":"Dunbar","14217":"Dunblane","4891":"Dundee","14067":"Dunfermline","4892":"Durham","16058":"East Molesey","17521":"East Preston","12501":"Eastbourne","12374":"Eastrea","4893":"Edinburgh","18992":"Elgin","41763":"Ellesmere","12883":"Ely","16825":"Enfield","14510":"Epsom","5835":"Exeter","4894":"Falkirk","5836":"Falmouth","42388":"Faringdon","42034":"Farmington","14604":"Farnham","42347":"Feltham","12829":"Fleet","4895":"Forres","42315":"Frosterley","5950":"Glasgow","4896":"Glastonbury","12562":"Gloucester","15956":"Gosport","4898":"Grangemouth","12626":"Gravesend","16057":"Grays","4899":"Great Wilbraham","4900":"Greenock","12752":"Grimsby","11747":"Guildford","14506":"Guilford","11938":"Halifax","5010":"Hamilton","15553":"Harlow","41733":"Harpenden","14713":"Harrow","4902":"Hartlepool","18952":"Haslemere","13977":"Hastings","14917":"Hatfield","12529":"Haverfordwest","4903":"Haverhill","4904":"Hawarden","5951":"Hawick","11776":"Hemel Hempstead","15302":"Hereford","14999":"Hertford","41893":"Heston","16056":"Hexham","13019":"High Wycombe","13643":"Hoddesdon","5958":"Holyhead","12420":"Hornchurch","14160":"Horsham","12108":"Huddersfield","5837":"Hull End","13296":"Huntingdon","14801":"Hyde","17707":"Ilford","41721":"Inverkeithing","4905":"Inverness","5838":"Ipswich","4906":"Keighley","4907":"Kelso","18628":"Kendal","17805":"Kenilworth","4908":"Kennet","4909":"Kettering","18578":"Kidsgrove","18984":"Kilmarnock","4910":"Kingston Upon Hull","5952":"Kirkwall","18257":"Lakenheath","15425":"Lampeter","13182":"Lancaster","4911":"Laughton","13488":"Leamington","18824":"Leeds","13135":"Leek","17849":"Leicester","17716":"Leigh","12836":"Lerwick","13387":"Letchworth","4912":"Lewes","41767":"Leyland","13546":"Lichfield","5840":"Lincoln","19039":"Little Chalfont","16778":"Liverpool","13442":"Llandrindod Well","5953":"Loch Ness","12008":"London","15035":"Loughborough","15518":"Loughgall","15011":"Louth","18492":"Lowestoft","14023":"Luton","4913":"Machynlleth","12416":"Maidenhead","12230":"Maidstone","14722":"Manchester","4914":"Mansfield","4915":"Margate","4916":"Marlborough","17889":"Marlow","18870":"Melborne","16170":"Melton Mowbray","4917":"Merton","5844":"Middlesbrough","5959":"Milford","15181":"Millom","12315":"Milton Keynes","12089":"Mold","18816":"Montrose","5954":"Motherwell","18574":"Nantwich","4918":"Newark","17097":"Newbury","5845":"Newcastle","4919":"Newcastle Upon Tyne","19040":"Newport","41682":"Newquay","13629":"Northallerton","4922":"Northampton","18577":"Northwich","42209":"northwold","15080":"Norwich","5847":"Nottingham","4923":"Oban","11975":"Oldham","6474":"Omagh","17161":"Oxford","15422":"Oxshott","18627":"Penrith","4925":"Penzance","16404":"Perth","5848":"Peterborough","4926":"Plains","4927":"Plymouth","15551":"Pontypridd","14208":"Poole","4928":"Portsmouth","17642":"Portstewart","41766":"Preston","5011":"Prestwick","18579":"Radway Green","42069":"Ramsgate","11775":"Reading","14706":"Redditch","16276":"Ringwood","15522":"Ripon","14673":"Rochester","15968":"Romford","41857":"Rugby","15289":"Runcorn","17520":"Rustington","14052":"Saint Albans","16462":"Salford","4931":"Salisbury","42295":"Sandwich","17690":"Sandy","4932":"Scarborough","13975":"Seaford","12003":"Shaftesbury","18891":"Sheffield","5850":"Shrewsbury","13178":"Slough","14708":"Solihull","4935":"Southampton","4936":"Southborough","14524":"Southend-on-Sea","13970":"Southport","42260":"St Albans","5955":"St Andrews","15841":"St Asaph","18576":"St Helens","16114":"St Ives","12717":"Stafford","41746":"Staines","14051":"Stanmore","16656":"Stansted","42032":"Stevenage","5012":"Stirling","11801":"Stockport","14198":"Stockton-on-Tees","4937":"Stoke On Trent","42386":"Stranraer","4938":"Stratford-Upon-Avon","4939":"Stroud","18615":"Sudbury","11860":"Sunderland","16393":"Sutton","5960":"Swansea","12853":"Swindon","4941":"Taunton","5851":"Teeside","13973":"Telford","4943":"Truro","17702":"Virginia Water","5852":"Waddington","12059":"Wakefield","4945":"Wallingford","4947":"Wareham","5853":"Warrington","4948":"Warwick","4949":"Watford","12009":"Wellingborough","12528":"Wellington","13366":"Wells","12530":"Welwyn Garden City","16785":"Weston Under Lizard","16334":"Wetherby","18171":"Weymouth","4950":"Whitby","13308":"Whitehaven","42387":"Whitehead","5956":"Wick","17581":"Wilmslow","5854":"Wimbledon","12524":"Wimborne Minster","12551":"Winchester","15946":"Windsor","18573":"Winsford","4952":"Wisbech","4953":"Wisborough Green","12982":"Woking","18769":"Wokingham","13287":"Wolverhampton","17904":"Woodford","18086":"Woolavington","11783":"Worcester","12128":"Worthing","5961":"Wrexham","13630":"Yarm","17015":"Yeovil","11824":"York"} Here is my Javascipt: $('#current-country').change(function(){ //any select change on the dropdown with id country trigger this code $('.select-current-city').show(); $("#current-cities > option").remove(); //first of all clear select items var country_id = $('#current-country').val(); // here we are taking country id of the selected one. $.ajax({ type: "POST", url: "<?php echo base_url()?>map/get_cities/"+country_id, //here we are calling our user controller and get_cities method with the country_id success: function(cities) //we're calling the response json array 'cities' { $.each(cities,function(id,city) //here we're doing a foeach loop round each city with id as the key and city as the value { var opt = $('<option />'); // here we're creating a new select option with for each city opt.val(id); opt.text(city); $('#current-cities').append(opt); //here we will append these new select options to a dropdown with the id 'cities' }); } }); }); Has anyone any suggestions on how I can process this much data in the browser? I'm using PHP (Codeigniter), MySQL and jQuery.
I would recommend creating an array of your new option nodes, and then appending them en masse. Doing them one at a time may be what's killing you. var newOptions = []; $.each(cities,function(id,city) { var opt = $('<option />', { "val": id, "text": city }); newOptions.push(opt[0]); //need to push actual dom node - thanks RightSaidFred }); $('#current-cities').append(newOptions); Or should this be clearing previous options in the dropdown? If so: $('#current-cities').html(newOptions);
First double check you are not making the same AJAX request more than once. A quick and easy solution would be to split your AJAX requests in more than one. Start by dividing it into two, and if that still isn't enough, divide them by 3 or more. You can then check which JSON size is the right one for you, and use that one. Or you can have your php determine how much requests are needed based on the number of total cities. For really large lists, I had to split the requests into 100 items each. The first request I would get the first piece of list along with a bit of data indicating how much requests I had to make to obtain the full list, append the new nodes, then I would make the remaining requests, until I got the full list.
I don't see how that would crash for you. Here I am doing the worst possible thing and it is blazing fast: http://jsfiddle.net/HZnYQ/ Each time you select something, I remove all elements one by one and then append them one by one, and it's still instant. Actually my CPU doesn't even make a note of it.
Django Dynamic Drop-down List from Database
I wanted to develop a Django app and one of the functionalities I'd like to have is dynamic drop-down lists...specifically for vehicle makes and models...selecting a specific make will update the models list with only the models that fall under that make....I know this is possible in javascript or jQuery (this would be my best choice if anyone has an answer) but I don't know how to go about it. Also, I'd want the make, model, year and series to be common then the other attributes like color, transmission etc to be variables so that one needs only enter the make, model, year, and series only for a new vehicle. Any ideas would be highly appreciated.
The 3 things you mention being common, make, model, year, would be the 3 input values. When given to the server, an object containing the details would be returned to the calling page. That page would parse the object details (using JavaScript), and update the UI to display them to the user. From the Django side, there needs to be the facilities to take the 3 inputs, and return the output. From the client-side, there needs to be the facilities to pass the 3 inputs to the server, and then appropriately parse the server's response. There is a REST api framework for Django that makes it rather easy to add the "api" mentioned above -- Piston. Using Piston, you'd simply need to make a URL for that resource, and then add a handler to process it. (you'll still need to skim the Piston documentation, but this should give you an idea of what it looks like) urls.py: vehicle_details = Resource(handler=VehicleDetails) url(r'^vehicle/(?<make>.*)/(?<model>.*)/(?<year\d{2,4}/(?P<emitter_format>[a-z]{1,4}), vehicle_details, name='vehicle_details'), handler.py: class VehicleDetails(BaseHandler): methods_allowed = ('GET',) model = Vehicles #whatever your Django vehicle model is def read(self, request, *args, **kwargs): # code to query the DB and select the options # self.model.objects.filter()... # Build a custom object or something to return return custom_object This simply sets up the url www.yoursite.com/vehicle/[make]/[model]/[year]/json to return a custom data object in JSON for jquery to parse. On the client side, you could use jquery to setup an event (bind) so that when all 3 drop downs have a value selected, it will execute a $.get() to the api URL. When it gets this result back, it passes it into the Jquery JSON parser, and gives the custom object, as a javascript object. That object could then be used to populate more drop down menus. (Big warning, I just wrote the following off the top of my head, so it's not meant to be copy and pasted. It's just for the general idea.) <script type="text/javascript"> // On document load $(function() { $('#dropdown_make').bind('change', checkForValues()); $('#dropdown_model').bind('change', checkForValues()); $('#dropdown_year').bind('change', checkForValues()); }); function checkForValues() { if ($('#dropdown_make').val() && $('#dropdown_model').val() && $('#dropdown_year').val()) updateOptions(); } function updateOptions() { url = '/vehicle/'; url += $('#dropdown_make').val() + '/'; url += $('#dropdown_model').val() + '/'; url += $('#dropdown_year').val() + '/'; url += 'json/'; $.get(url, function(){ // Custom data object will be returned here }) } </script>
This is uncanny: Dynamic Filtered Drop-Down Choice Fields With Django His question: "Here is the situation: I have a database with car makes and models. When a user selects a make, I want to update the models drop-down with only the models associated with that make. ... Therefore I want to use Ajax to populate the data." You're not the same guy? :)