Custom AutoCompleteExtender with multiple word suggestions |
Visite: 23400 |
sabato 14 ottobre 2006 |
By default, the AutoCompleteExtender
shows results from the entire value of one text box. With my implementation, it is possible to search more than one word inside a text box divided by comma (or another character). Every time a comma is written, the list of suggestions appears for the new word.
At the moment,
AutoCompleteExtender doesn’t support the style for the popup list. We’ll implement these properties during the modifications for multiple suggestions.
Inherit the AutoCompleteProperties
The first step is to create C# classes for the new control
CustomAutoCompleteExtender. We want to declare
a class called
CustomAutoCompleteProperties
that inherits from
AutoCompleteProperties
and adds the support for the “multiple word suggestions” and CSS styles properties.
For “multiple word suggestions”, we need one property:
SeparatorChar. With this property, we are
able to divide word-to-word and open the suggestions’ list for the new word written.
namespace CustomAtlas.Controls
{
public class CustomAutoCompleteProperties : AutoCompleteProperties
{
public string SeparatorChar
{
get
{
object obj = base.ViewState["SeparatorChar"];
if (obj != null) return (string)obj;
else return ",";
}
set
{
base.ViewState["SeparatorChar"] = value;
base.OnChanged(EventArgs.Empty);
}
}
public string CssList
{
get
{
object obj = base.ViewState["CssList"];
if (obj != null) return (string)obj;
else return String.Empty;
}
set
{
base.ViewState["CssList"] = value;
base.OnChanged(EventArgs.Empty);
}
}
public string CssItem
{
get
{
object obj = base.ViewState["CssItem"];
if (obj != null) return (string)obj;
else return String.Empty;
}
set
{
base.ViewState["CssItem"] = value;
base.OnChanged(EventArgs.Empty);
}
}
public string CssHoverItem
{
get
{
object obj = base.ViewState["CssHoverItem"];
if (obj != null) return (string)obj;
else return String.Empty;
}
set
{
base.ViewState["CssHoverItem"] = value;
base.OnChanged(EventArgs.Empty);
}
}
}
}
The
CssList,
CssItem, and
CssHoverItem are necessary to build the control’s style.
CssList
provides to draw the list’s box, and
CssItem and
CssHoverItem
draw every item in the list.
Inherit the AutoCompleteExtender
First step done, we continue with the Extender. In this case, we inherit from the
AutoCompleteExtender
class and add new properties to the control:
namespace CustomAtlas.Controls
{
public class CustomAutoCompleteExtender : AutoCompleteExtender
{
protected override void RenderScript(
Microsoft.Web.Script.ScriptTextWriter writer, Control targetControl)
{
// get our CustomAutoCompleteProperties
CustomAutoCompleteProperties cacp =
(CustomAutoCompleteProperties)
base.GetTargetProperties(targetControl);
if ((cacp != null) && cacp.Enabled)
{
// check if the ServicePath is set
string _ServicePath = cacp.ServicePath;
if (_ServicePath == String.Empty)
{
_ServicePath = this.ServicePath;
}
if (_ServicePath == String.Empty)
{
throw new InvalidOperationException("The ServicePath " +
"must be set for AutoCompleteBehavior");
}
// check if the ServiceMethod is set
string _ServiceMethod = cacp.ServiceMethod;
if (_ServiceMethod == String.Empty)
{
_ServiceMethod = this.ServiceMethod;
}
if (_ServiceMethod == String.Empty)
{
throw new InvalidOperationException("The ServiceMethod " +
"must be set for AutoCompleteBehavior");
}
// search for the completion list control if an ID was supplied
Control c = null;
string drp = this.DropDownPanelID;
if (drp != String.Empty)
{
c = this.NamingContainer.FindControl(drp);
if (c == null)
{
throw new InvalidOperationException("The specified " +
"DropDownPanelID is not a valid ID");
}
}
// write the Atlas markup on page
writer.WriteStartElement("autoComplete");
writer.WriteAttributeString("serviceURL",
base.ResolveClientUrl(_ServicePath));
writer.WriteAttributeString("serviceMethod", _ServiceMethod);
if (c != null)
writer.WriteAttributeString("completionList", c.ClientID);
writer.WriteAttributeString("minimumPrefixLength",
cacp.MinimumPrefixLength.ToString());
writer.WriteAttributeString("separatorChar",
cacp.SeparatorChar);
writer.WriteAttributeString("cssList", cacp.CssList);
writer.WriteAttributeString("cssItem", cacp.CssItem);
writer.WriteAttributeString("cssHoverItem",
cacp.CssHoverItem);
writer.WriteEndElement();
}
}
}
}
Implementing the custom AutoCompleteBehavior
Now that the control is ready, we have only to manage the client-side code to send the right value to the Web Service (the comma-separated word) and to apply our custom CSS style.
Searching for the
AutoCompleteBehavior class in the
Atlas.js file, we can copy it and register our custom class.
First, we have to add the four properties created in the Extender class. Now, we are able to use the properties’ values of the control placed in the .aspx page container.
Searching inside the code, there is a function
_onTimerTick used to show the list after a time delay. In this function, we’ll intercept the value to send to the Web Service and change it as we want:
var text = this.control.element.value;
if ( text.lastIndexOf(_separatorChar) > -1 )
{
// found separator char in the text, choosing the right word
var pos = text.lastIndexOf(_separatorChar);
pos++;
text = text.substring(pos, (text.length));
text = text.trim();
}
Now, when the user types a value in the text box, the
AutoCompleteBehavior verifies the presence of the separator char. If present, the text sent to the Web Service is the last word found and not the entire value of the text box.
Like a standard, I use to save .js code into
scriptLibrary folder.
Let’s try it
The situation:
AutoCompleteBehavior.js saved into the
scriptLibrary
folder,
CustomAutoCompleteProperties.cs and
CustomAutoCompleteExtender.cs
saved into the
App_Code folder... we are ready to try it.
Create a new .aspx file, and add a reference to the
CustomAutoCompleteExtender class, and place the controls in the page:
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register Namespace="CustomAtlas.Controls" TagPrefix="customAtlas" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>CustomAutoCompleteExtender</title>
<link href="StyleSheet.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form id="form1" runat="server">
<atlas:ScriptManager ID="scriptManager" runat="server">
<Scripts>
<atlas:ScriptReference ScriptName="Custom" />
<atlas:ScriptReference
Path="scriptLibrary/CustomAutoCompleteBehavior.js" />
</Scripts>
</atlas:ScriptManager>
<div>
<asp:TextBox ID="txtSuggestions"
runat="server"></asp:TextBox>
<customAtlas:CustomAutoCompleteExtender
ID="CustomAutoCompleteExtender1" runat="server">
<customAtlas:CustomAutoCompleteProperties
TargetControlID="txtSuggestions"
ServicePath="WebServiceDemo.asmx"
ServiceMethod="GetSuggestions"
MinimumPrefixLength="1"
SeparatorChar=","
CssList="autoCompleteList"
CssItem="autoCompleteItem"
CssHoverItem="autoCompleteHoverItem"
Enabled="true" />
</customAtlas:CustomAutoCompleteExtender>
</div>
</form>
</body>
</html>
Call a demo Web Service (returns the same value written 10 times), digit one word, then comma (comma is the default char), and starting with a new word, a list with suggestions for a new item is shown.
Hope this will be helpful.
Click here to download the ZIP file about this article
|
Hi,
I tried your extender and I really liked it, but now when beta version of ajax is out it's not working especially it's not recognizing
RenderScript(Microsoft.Web.Script.ScriptTextWriter writer, Control targetControl) cause there is no more ScriptTextWriter in ajax and I can't find any info how to transform it to work again, any help will be very appreciated.
Best regards.
|
| Scritto da dimus - mercoledì 1 novembre 2006 alle ore 16.45 |
Hi dimus, please try this new version without custom CSS support but with the same functionally of the old CustomAutoCompleteExtender.
Take a look also to the NoMinimumPrefix property (boolean value) to call the Webservice when the Textbox has focus and show possible suggestions.
Download the CustomAutoCompleteExtender for ASP.NET AJAX 1.0
|
| Scritto da ZofM - mercoledì 1 novembre 2006 alle ore 17.57 |
|
Hi, thanks a lot for reply. Your script is great. BTW NoMinimumPrefix property is nice but it has a bug when you trying to select something every time timer is ticking it's loosing your selection. but apart that script is very good.
Best regards and many thanks.
|
| Scritto da dimus - venerdì 3 novembre 2006 alle ore 11.48 |
Hi Gianni
Another Ajax release - Beta 2 & another problem. When trying to use your extender on updated ajax core - beta 2 founding js error:
"Sys.ScriptLoadFailedException: The script '../script/CustomAutoCompleteBehavior.js' could not be loaded or does not contain the Sys.Application.notifyScriptLoaded() callback."
I've searched ajax.asp.net forum & found that with new release they introduced changes to load of file based scripts: 'http://ajax.asp.net/files/AspNet_AJAX_CTP_to_Beta_Whitepaper.aspx#link24.
I tried to fix the script but with no luck as I really a novice in a whole ajax thing at the moment specially in extenders.
So if could point me how can I fix it I would be really appreciating it.
Best regards.
|
| Scritto da dimus - giovedì 23 novembre 2006 alle ore 17.54 |
Hi Dmitrij, to fix that problem with CustomAutoCompleteBehavior.js file try this out..
First modify the first lines of the file with this piece of text:
Then add to the end of the file this line:
Let me now if it will resolve your problems ;)
|
| Scritto da ZofM - venerdì 24 novembre 2006 alle ore 11.39 |
|
Working like a dream, thanks a lot!!!
|
| Scritto da dimus - venerdì 24 novembre 2006 alle ore 12.30 |
Hi!
I am absulutely new in ajax.net, but I am using the AutoCompleteExtender with Atlas, and it works fine.
Now, I tried to run the CustomAutoCompleteExtenderAjax, I modified the lines as Zofm has written, but it doesn't work.
While debugging,the IE gives the message:
Microsoft JScript runtime error: Object doesn't support this property or method
Then in VS this line is higlighted:
var e = Function._validateParams(arguments, [{name: 'path', type: String}]);
Have you any idea, what is the problem?
Many thanks!
|
| Scritto da tanacs - martedì 28 novembre 2006 alle ore 10.58 |
|
Hi! Thank you for the good script but I have the same problem while selecting a suggested word. Everytime the timer is ticking it’s loosing the selection. I modified the js file but it doesn’t work.
Please let me known if you could help me.
Many thanks in advance!
|
| Scritto da sven - venerdì 1 dicembre 2006 alle ore 11.06 |
I updated the .ZIP file with a new version.
I fixed the "loosing selection" and now it's functionally inside an UpdatePanel.
Try to download again the file at this location: http://www.zofm.net/download/CustomAutoCompleteExtender.zip
Inform me about the new version.
Bye ;)
|
| Scritto da ZofM - venerdì 1 dicembre 2006 alle ore 15.13 |
|
It seems to be broken in an update panel getting an error to do with the timer, also what happened to teh css modifications in the newest version they don't exist and the example differs majorly from your code.. ?
|
| Scritto da infintevs - sabato 2 dicembre 2006 alle ore 18.17 |
Yes, sorry but this Beta version of AJAX is changing every month so I had to update the version of my example continuously. Now, the last version, is only functionally with the new AJAX 1.0 Beta 2 package.
For the problem with Timer ensure you have added in your ScriptManager a reference to the Microsoft.Web.Preview library:
Bye, Gianni.
|
| Scritto da ZofM - lunedì 4 dicembre 2006 alle ore 10.11 |
|
I'm confused as to why your behavior class reincludes all the base methods, like Sys$Preview$UI$AutoCompleteBehavior$get_completionInterval, etc. Could you enlighten me? Thanks!
|
| Scritto da Max Metral - venerdì 15 dicembre 2006 alle ore 22.15 |
Hi Gianni,
new release new incompatibility issues, spent couple of long hours to migrate code to new ajax 1.0 RC but with no luck. If you'll have some time to rewrite a source code would be very appreciating it.
Best regards.
|
| Scritto da dimus - lunedì 18 dicembre 2006 alle ore 16.07 |
Hi Gianni,
new release new incompatibility issues, spent couple of long hours to migrate code to new ajax 1.0 RC but with no luck. If you'll have some time to rewrite a source code would be very appreciating it.
Best regards.
|
| Scritto da dimus - lunedì 18 dicembre 2006 alle ore 16.15 |
Forgot to add the error I'm getting is:
'Sys.Net._WebMethod' is null or not an object
|
| Scritto da dimus - lunedì 18 dicembre 2006 alle ore 16.17 |
Hi everyone,
Just found a solution how to fix code for ajax 1.0 RC.
1.Change:
to:
Next modify the CustomAutoCompleteBehavior.js file. Replace:
with this:
of course apart this you have to follow migration guide to make all the necessary changes from beta 2 to 1.0 RC: Converting Applications from ASP.NET AJAX Beta 2 to ASP.NET AJAX RC(also available in Word format and inPDF format)
|
| Scritto da dimus - mercoledì 20 dicembre 2006 alle ore 11.37 |
|
I've been trying to adapt your control to use the release version of AJAX controls and the Ajax Control Toolkit. I went through quite a bit to get it to run but now javascript doesn't error but it doesn't work either. Any chance, that you will re-release to work with the released 1/29 released version of Microsoft Ajax v1.0
|
| Scritto da malsmith - martedì 30 gennaio 2007 alle ore 7.51 |
|
Hi,
just wanted to say thanks for this excellent extension.
Now, I've also upgraded to the RTM release, and the control is not working anymore. So if there is any chance of releasing an updated version I would be very grateful :)
-- dag
|
| Scritto da Dag - martedì 30 gennaio 2007 alle ore 17.53 |
|
After some trial and error I have this working on the 1/27 Microsoft Ajax Version 1.0 (Final Release). There were lots of changes due to the move of AutoCompleteExtender to AjaxToolkit assembly (which is now required to use this control. However, the December CTP is no longer needed. So only Release code is needed to use this control.
You can download the changed files from http://www.treehousesystems.com/CustomAutoComplete_MSFTAJAXRelease1.0.zip
|
| Scritto da malsmith - martedì 30 gennaio 2007 alle ore 18.03 |
Hi,
First of all thanks a lot for the excellent extension.
I am trying to pass another parameter while calling the web service method. I've done the following :
1. added a property on the class CustomAutoCompleteExtender.
2. added it to the list in CustomAjax.UI.AutoCompleteBehavior.descriptor and
CustomAjax.UI.AutoCompleteBehavior.prototype.
3. provided getter and setter methods in CustomAutoCompleteBehavior.js.
4. added it while calling the webservice in the _onTimerTick method.
But, I get an error "Microsoft JScript runtime error: Sys.InvalidOperationException: 'newParam' is not a property or an existing field." . Am I missing something? Please help me with this.
Thanking you in anitcipation.
|
| Scritto da Sarith Sutha - giovedì 1 marzo 2007 alle ore 18.51 |
|
Hi,
Please ignore my previous post, the javascript file was cached. It started working after I cleared the browser cahce.
I've one more question. How can I add this AutoCompleteExtender dynamically onto a webform?
Thanks.
|
| Scritto da Sarith Sutha - giovedì 1 marzo 2007 alle ore 19.32 |
|
Thanks ZofM..
|
| Scritto da infinitevs - martedì 6 marzo 2007 alle ore 16.07 |
|
When will a AJAX & PHP based version of the cool script be out?
|
| Scritto da Ashwin Date - mercoledì 2 maggio 2007 alle ore 14.05 |
|
This is great. I was able to get this working in a few minutes. This has been a great help for me.
I did add a function when you leave the textbox to remove that last comma. If there is a better way to do this please let me know!
function removelastcomma(elem) { //will remove the last comma in a text box
if (elem.value.charAt(elem.value.length-1) == ',')
{ elem.value = elem.value.substring(0,elem.value.length-1);}
}
|
| Scritto da Louis De Grazia - venerdì 31 agosto 2007 alle ore 20.08 |
|
can I get this code in php language
|
| Scritto da naveen - giovedì 30 aprile 2009 alle ore 14.25 |
Scrivi nuovo commento