The AutoCompleteExtender that came with the Ajax Control Toolkit is great for linear data, but what happens when you want to customize its output, e.g say you want to display the multiple values in a table form?
This is definately possible since at the end of the day, the UI is rendered using Javascript, however you will need to do some tweaking.
WebService
In order to return multiple values, your webservice needs to return an object[] array, or more specifically, a Pair<> array, this is because the client side javascript reading the webservice functions such that if a pair is returned, it will set the whole pair object as the “value” for the item.
[WebMethod]
public object[] GetCompletionList(string prefixText, int count)
{
//demo code
if (count == 0)
{
count = 10;
}
if (prefixText.Equals(“xyz”))
{
return new string[0];
}
Random random = new Random();
var items = new List
>(count);
var jss = new System.Web.Script.Serialization.JavaScriptSerializer();
for (int i = 0; i < count; i++)
{
char c1 = (char)random.Next(65, 90);
char c2 = (char)random.Next(97, 122);
char c3 = (char)random.Next(97, 122);
int id = i;
int age = random.Next(18, 70);
var item = new Pair(id.ToString(), new object[]{prefixText + c1 + c2 +c3, age});
items.Add(item);
}
return items.ToArray();
}
Now that the webservice is returning the data, lets move on to the client side javascripts. What we need to do is to “override” the onClientItemSelected and onClientShowing javascripts
The below example assumes a HTML table display format.
function OnClientItemSelected(behaviour, args) {
var element = behaviour.get_element();
var control = element.control;
//args._value is the pair object which is returned
if (control && control.set_text)
control.set_text(args._value.First);
else
element.value = args._value.First;
}
function OnClientShowing(behaviour, e) {
var ResultsDiv = behaviour.get_completionList();
for (var i = 0; i < ResultsDiv.childNodes.length; i++) {
var item = ResultsDiv.childNodes[i];
//since the pair object stores the values to display in the second variable, lets get it out to do our own processing
var vals = item._value.Second;
//remove all child nodes
while (item.childNodes.length > 0)
item.removeChild(item.firstChild);
//create the table
var tbl = document.createElement(“table”);
tbl.setAttribute(“width”, “100%”);
tbl.setAttribute(“border”, “1″);
tbl.setAttribute(“style”, “border: solid 1px black;border-collapse: collapse;”);
tbl._value = item._value;
var tbody = document.createElement(“tbody”);
var tr = document.createElement(“tr”);
tr.setAttribute(“valign”, “top”);
tr._value = item._value;
for (var j = 0; j < vals.length; j++) {
CreateTableCell(tr, vals[j], item._value);
}
tbody.appendChild(tr);
tbl.appendChild(tbody);
item.appendChild(tbl);
}
}
function CreateTableCell(tr, str, value, width) {
td = document.createElement(“td”);
//this is a very important step, if you forget to set the td._value, when onClientSelected triggers, args._value will be null
td._value = value;
td.setAttribute(“width”, width);
td.innerHTML = str;
tr.appendChild(td);
}
This is definately possible since at the end of the day, the UI is rendered using Javascript, however you will need to do some tweaking.
WebService
In order to return multiple values, your webservice needs to return an object[] array, or more specifically, a Pair<> array, this is because the client side javascript reading the webservice functions such that if a pair is returned, it will set the whole pair object as the “value” for the item.
[WebMethod]
public object[] GetCompletionList(string prefixText, int count)
{
//demo code
if (count == 0)
{
count = 10;
}
if (prefixText.Equals(“xyz”))
{
return new string[0];
}
Random random = new Random();
var items = new List
>(count);
var jss = new System.Web.Script.Serialization.JavaScriptSerializer();
for (int i = 0; i < count; i++)
{
char c1 = (char)random.Next(65, 90);
char c2 = (char)random.Next(97, 122);
char c3 = (char)random.Next(97, 122);
int id = i;
int age = random.Next(18, 70);
var item = new Pair(id.ToString(), new object[]{prefixText + c1 + c2 +c3, age});
items.Add(item);
}
return items.ToArray();
}
Now that the webservice is returning the data, lets move on to the client side javascripts. What we need to do is to “override” the onClientItemSelected and onClientShowing javascripts
The below example assumes a HTML table display format.
function OnClientItemSelected(behaviour, args) {
var element = behaviour.get_element();
var control = element.control;
//args._value is the pair object which is returned
if (control && control.set_text)
control.set_text(args._value.First);
else
element.value = args._value.First;
}
function OnClientShowing(behaviour, e) {
var ResultsDiv = behaviour.get_completionList();
for (var i = 0; i < ResultsDiv.childNodes.length; i++) {
var item = ResultsDiv.childNodes[i];
//since the pair object stores the values to display in the second variable, lets get it out to do our own processing
var vals = item._value.Second;
//remove all child nodes
while (item.childNodes.length > 0)
item.removeChild(item.firstChild);
//create the table
var tbl = document.createElement(“table”);
tbl.setAttribute(“width”, “100%”);
tbl.setAttribute(“border”, “1″);
tbl.setAttribute(“style”, “border: solid 1px black;border-collapse: collapse;”);
tbl._value = item._value;
var tbody = document.createElement(“tbody”);
var tr = document.createElement(“tr”);
tr.setAttribute(“valign”, “top”);
tr._value = item._value;
for (var j = 0; j < vals.length; j++) {
CreateTableCell(tr, vals[j], item._value);
}
tbody.appendChild(tr);
tbl.appendChild(tbody);
item.appendChild(tbl);
}
}
function CreateTableCell(tr, str, value, width) {
td = document.createElement(“td”);
//this is a very important step, if you forget to set the td._value, when onClientSelected triggers, args._value will be null
td._value = value;
td.setAttribute(“width”, width);
td.innerHTML = str;
tr.appendChild(td);
}
No comments:
Post a Comment