Friday, July 29, 2011
AJAX autocomplete
Using a nice AJAX auto completable input box is much nicer (for the user) than a combo box with 100 options. If you use jQuery, you may use a quite easy yet powerful plug-in called jquery.autocomplete (original, eh?). Grab it athttp://www.pengoworks.com/workshop/jquery/autocomplete.htm.
Anyway, just to sum it up (you can learn how to use it in detail from the authors web page of course), I use it as follows:
1. First you need to bind the plug-in to the field(s) you want.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <script> $(document).ready(function() { $("#login").autocomplete("<html:rewrite page='/auth/users/autocomplete.action'/>", { delay:10, minChars:3, matchSubset:1, matchContains:1, cacheLength:1, autoFill:true, formatItem:formatItem, formatResult:formatResult }); }); </script> |
The most relevant issues here are:
- The URL from where to get the auto-complete values (in this case a Struts action)
- The function to format the value displayed in the auto-complete list (formatItem)
- The function to format the value loaded into the input field once the user selects an option from the auto-complete list (formatResult)
The page that renders the auto-complete results (in this case autocomplete.action) can end in a JSP that looks something like:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><c:forEach items="${autocompleteList}" var="user">${user.name}|${user.login}</c:forEach>
As you can see it renders one line per item in the list, printing the users name and login separated by a pipe. The autocomplete plugins parses this list, taking each line as a row and each field (delimited by pipes) as a property.
Then we can write the two format functions:
1 2 3 4 5 6 7 | function formatItem(row) { return row[0]; } function formatResult(row){ return row[1]; } |
Which will result in the plug-in showing the users names as auto-complete options, and when one is selected the users login will be loaded into our form input field.
If you want to be a little more fancy, you can add some highlighting to the text part of each auto-complete option that matches what is currently entered into the input field:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | function formatItem(row) { return wrapSubstring(row[0], $("#login").val(), "<span class='autocompleteHighlight'>", "</span>"); } function wrapSubstring(original, substring, prefix, suffix, fromIndex){ var result = original; pos = result.toUpperCase().indexOf(substring.toUpperCase(), fromIndex); if (pos>=0){ result = result.substring(0, pos) + prefix + result.substring(pos, pos+substring.length) + suffix + result.substring(pos+substring.length); fromIndex = pos + suffix.length + prefix.length + substring.length; if (fromIndex<=result.length){ result = wrapSubstring(result, substring, prefix, suffix, fromIndex); } } return result; } |
--
Thank you.
Friday, July 22, 2011
Autocompletion Textbox in MVC Using jQuery
jQuery is awesome. If you haven't started looking at it, I highly recommend that you do. It works wonders in the ASP.NET MVC world. One of the best things about jQuery is the enormous number of plug-ins that are available for adding even more functionality to the library.
The plug-in that I am going to be talking about in this post is jQuery Autocomplete.
So let's make a autocomplete text box in MVC for adding tags (or labels) for a blog post. First, we are going to need to put a text box in one of our views with the name "tags".
1: <div>
2: <%= Html.TextBox("postTags") %>
3: </div>
Now, in the same view (or the master page) we need to add the references for jQuery Autocomplete. The plug-in also comes with a stylesheet for styling the drop-down that will contain the autocomplete options.
1: <link href="/Content/jquery.autocomplete.css" rel="stylesheet" type="text/css" media="screen" />
2: <script type="text/javascript" src="/Scripts/jquery-1.2.6.js"></script>
3: <script type="text/javascript" src="/Scripts/jquery.autocomplete.js"></script>
Next, we need to create a controller action that will return the list of autocomplete values in the JSON format.
1: [HandleError]
2: public class UtilitiesController : Controller
3: {
4: /// <summary>
5: /// This action method looks up the tags.
6: /// </summary>
7: /// <param name="q">The query that contains the user input.</param>
8: /// <param name="limit">The number of tags return.</param>
9: public ActionResult LookupTags(string q, int limit)
10: {
11: // We can get a list of tags from the database, but
12: // for this example, I will populate a list with values.
13: List<string> tags = new List<string>();
14: tags.Add("asp");
15: tags.Add("mvc");
16: tags.Add("microsoft");
17: tags.Add("sql server");
18: tags.Add("jQuery");
19: tags.Add("ajax");
20:
21: // Select the tags that match the query, and get the
22: // number or tags specified by the limit.
23: var retValue = tags
24: .Where(x => x.StartsWith(q))
25: .OrderBy(x => x)
26: .Take(limit)
27: .Select(r => new { Tag = r });
28:
29: // Return the result set as JSON
30: return Json(retValue);
31: }
32: }
Finally, we have to add the jQuery Autocomplete initialization script in the view (or master page) to wire up the plug-in to the text box. Notice in line 4 that we are using a the action method that we created above to get the list of tags.
1: <script type="text/javascript">
2: $(document).ready(function()
3: {
4: $("#postTags").autocomplete('<%=Url.Action("LookupTags", "Utilities") %>',
5: {
6: dataType: 'json',
7: parse: function(data)
8: {
9: var rows = new Array();
10: for (var i = 0; i < data.length; i++)
11: {
12: rows[i] = { data: data[i], value: data[i].Tag, result: data[i].Tag };
13: }
14: return rows;
15: },
16: formatItem: function(row, i, max)
17: {
18: return row.Tag;
19: },
20: width: 300,
21: highlight: false,
22: multiple: true,
23: multipleSeparator: ","
24: });
25: });
26: </script>
The documentation for the plug-in details all of the various options that can be used in the autocomplete function.
Now we have an AJAX enabled autocomplete box using jQuery in ASP.NET MVC.
The power of jQuery never ceases to amaze me. There will likely be plenty more posts to come on the topic of using jQuery in MVC.
--
Thank you.
http://blogs.msdn.com/b/miah/archive/2008/11/13/autocompletion-textbox-in-mvc-using-jquery.aspx
Auto-populating Select Boxes using jQuery & AJAX
The Goal
Allow the user to select a top level category from one select box and to automatically populate the sub-category.
Prerequisites
- Latest copy of jQuery
- A basic understanding of JSON (don't let this put you off - it's really very, very easy)
- A server-side script that can respond to the AJAX request (though I've provided a simple example)
Demo
Our demo will specifically look to build a simple form that allows us to book human resource for a project. The top level category is the resource type, and the sub-category will list the individual's names.
How it works
Once the top level category select is changed, it sends an AJAX request for the sub-categories. The result of which are converted to select options and the sub-category select's elements are replaced.
Unobtrusive JavaScript
First things first: as with any page that is loaded with JavaScript and AJAX functionality, it should work without JavaScript.
To achieve this for our tutorial here's what we need to ensure:
- When the page is loaded, the sub-category is loaded (if the top level has a selected item).
- There is a 'load sub-category' button the user can select to re-load the page. We will hide this button with a <noscript> tag in our demo.
The Code
There are 4 parts to this demo.
- The page's HTML.
- The server-side code to produce the dynamic page (i.e. to pre-load the select boxes when the user first visits).
- The jQuery & JavaScript.
- The JSON response (which will reuse the server-side code).
HTML
<form action="/select_demo.php">
<label for="ctlJob">Job Function:</label>
<select name="id" id="ctlJob">
<option value="1">Managers</option>
<option value="2">Team Leaders</option>
<option value="3">Developers</option>
</select>
<noscript>
<input type="submit" name="action" value="Load Individuals" />
</noscript>
<label for="ctlPerson">Individual:</label>
<select name="person_id" id="ctlPerson">
<option value="1">Mark P</option>
<option value="2">Andy Y</option>
<option value="3">Richard B</option>
</select>
<input type="submit" name="action" value="Book" />
</form>
Server-side
This is just a simple example, but it should be obvious that you can expand this to go off to a database and return an object in a JSON data structure:
<?php
if ($_GET['id'] == 1) {
echo <<<HERE_DOC
[ {optionValue: 0, optionDisplay: 'Mark'}, {optionValue:1, optionDisplay: 'Andy'}, {optionValue:2, optionDisplay: 'Richard'}]
HERE_DOC;
} else if ($_GET['id'] == 2) {
echo <<<HERE_DOC
[{optionValue:10, optionDisplay: 'Remy'}, {optionValue:11, optionDisplay: 'Arif'}, {optionValue:12, optionDisplay: 'JC'}]
HERE_DOC;
} else if ($_GET['id'] == 3) {
echo <<<HERE_DOC
[{optionValue:20, optionDisplay: 'Aidan'}, {optionValue:21, optionDisplay:'Russell'}]
HERE_DOC;
}?>
Note that this is not accessible. To ensure accessibility, the server side will handle the pre-population of the select boxes as the page is loaded. Here is an example (excluding the headers, footers and JavaScript) of theaccessible example.
JSON Response
If I pass the server side id = 2, i.e. /select.php?id=2&ajax=true, the return value is (the ajax=true is an arbitrary flag that I'm using to differentiate between a normal user request and one done via AJAX):
[ {optionValue:10, optionDisplay: 'Remy'},
{optionValue:11, optionDisplay: 'Arif'},
{optionValue:12, optionDisplay: 'JC'}]
The enclosing square brackets denotes an array and each element is separated by a comma.
Within the array are three objects. If you're familiar with PHP or Perl, you can basically treat these as hashes. The objects have keys (in this case two keys, one called 'optionValue' and one called 'optionDisplay'), and values. Note that keys don't need to be wrapped in quotes (though in some cases you will need them sometimes).
There are two ways which we can get the data out of this structure (assuming j is the structure):
alert(j['optionDisplay'])
Or:
alert(j.optionDisplay)
jQuery & AJAX Request
Our JavaScript is going to attach itself after the page is load, and fire an event each time the job function select box is changed.
The event will send the new value of the select box and reload the contents of the person select box.
Note that I'm be a bit naughty here, in that I'm plugging HTML directly in to the DOM.
Each item in the JSON response is looped round and used to build up the new options for the select box. As the response is an array (as mentioned earlier), we can call the .length method on it.
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" charset="utf-8">
$(function(){
$("select#ctlJob").change(function(){
$.getJSON("/select.php",{id: $(this).val(), ajax: 'true'}, function(j){
var options = '';
for (var i = 0; i < j.length; i++) {
options += '<option value="' + j[i].optionValue + '">' + j[i].optionDisplay + '</option>';
}
$("select#ctlPerson").html(options);
})
})
})
</script>
--
Thank you.
http://remysharp.com/2007/01/20/auto-populating-select-boxes-using-jquery-ajax/