AjaxControlToolkit AutoCompleteExtender ... how to fill from linq query? - asp.net

Go easy... I'm a newbie at this.
Ok, I've added the AutoCompleteExtender to my webpage. The user will add search tags to a project, and I want the textbox to autocomplete with tags that already exist in the database.
I don't have a "registry" for tags; only a table with a tagName and a projectID. So, a tagName might be repeated many times in the table. So I just want to return distinct results in my query. (That's easy.)
But how do I tie it to the AutoCompleteExtender? I'm not well versed in WebServices, etc...
I'm using entity framework, fyi...
Here's my autocomplete code on the aspx page:
<asp:TextBox ID="TagNameTextBox" runat="server"></asp:TextBox>
<ajaxToolkit:AutoCompleteExtender ID="TagNameTextBox_AutoCompleteExtender"
runat="server"
ServiceMethod="GetCompletionList"
MinimumPrefixLength="2"
EnableCaching="false"
DelimiterCharacters=""
Enabled="True"
TargetControlID="TagNameTextBox">
</ajaxToolkit:AutoCompleteExtender>
And here's my linq query:
var qrygettags = (from t in db.TagTables
select new { t.TagName }).Distinct().ToString();
I found a few examples of a jquery solution, too, but I don't know how to get my query into that format. Any help or ideas would be greatly appreciated!

Well, I kept hunting around and found this seemingly easy solution, and it works for me.
in the aspx page, in the control, I have
ServiceMethod="GetTagNames"
and in the cs page I added this in the page load:
[System.Web.Services.WebMethod]
public static string[] GetTagNames(string prefixText, int count)
{
mydatabase db = new mydatabase();
return db.TagTables.Where(n => n.TagName.StartsWith(prefixText)).OrderBy(n => n.TagName).Select(n => n.TagName).Distinct().Take(count).ToArray();
}
Hopefully it will help someone else out there!

Related

Auto-complete method does not get called

I'm not sure what is wrong, this is my first time spinning this up. Looking at the ajax examples, all should be working.. but my method does not get called.
I am not making use of a webservice, and want to return my suggestions from a page method.
<asp:TextBox ID="searchBox" runat="server" CssClass="searchTextBox"></asp:TextBox>
<asp:AutoCompleteExtender ID="searchBox_AutoCompleteExtender" runat="server"
DelimiterCharacters="" Enabled="True" ServiceMethod="_get_Suggestions"
TargetControlID="searchBox">
</asp:AutoCompleteExtender>
Page Method:
Private Function _get_Suggestions(prefixText As String, count As Int16) As String()
Dim array() As String = {"doggy", "catty", "fishy"}
Return array
End Function
Also tried:
<WebMethod()> <Script.Services.ScriptMethod()> Public Shared Function _get_Suggestions(prefixText As String, count As Int16) As String()
My Extender AND method, was on my masterpage. After some hints on similar issues, it seems I cant have my page method on the masterpage code behind.
I have to put the page method, in my content page, while the extender itself, can be in my masterpage.
Why? No clue... Maybe someone can elaborate to improve this answer.

__EVENTTARGET Contains Invalid Control ID

Googled variations of the title and everything was related to a null value.
I have an issue where the return value from Page.Request.Params["__EVENTTARGET"] duplicates the unique id of the control.
ctl00$MainContent$ActivityTabset$TabNewActivity$cbxActivityCode$ctl00$MainContent$ActivityTabset$TabNewActivity$cbxActivityCode
cbxActivityCode.UniqueID returns
ctl00$MainContent$ActivityTabset$TabNewActivity$cbxActivityCode
The following is the code that fails in the comparison. It is in the Page_Load event, and is the only code to execute right now if it is a postback.
string controlName = Page.Request.Params["__EVENTTARGET"];
if (cbxActivityCode.UniqueID == controlName)
{
ConfigureActivityUnits();
}
Here is the definition of the control
<obout:ComboBox ID="cbxActivityCode" runat="server"
DataSourceID="ObjectDataSourceDAOActivity"
FilterType="StartsWith" EmptyText="Select..."
AutoPostBack="true"
OnSelectedIndexChanged="cbxActivityCode_SelectedIndexChanged"
AllowCustomText="false" AutoValidate="true" DataValueField="Id"
DataTextField="Description" EnableViewState="true"
OpenOnFocus="true" MenuWidth="425" AllowEdit="False"
Width="300px">
</obout:ComboBox>
I am new to ASP.net and am wondering if it is possible one of the control attributes is causing this behavior?
Is it possibly a bug with the control?
Are there hooks in ASP.net where someone can manipulate a value which will effect Page.Request.Params["__EVENTTARGET"]? (This is a big messy legacy system, and I have no prior developers as a resource.)
If not any of the above, anyone have any ideas as to what could be causing this?

SubSonic 2.2 and ASP.NET gridview

I'm trying to show a custom column in my gridview which displays a content type based on a couple of boolean fields in my database. Everything works fine but it's causing a lot of overhead the way I do it now.. like this:
<ItemTemplate>
<asp:Label ID="lblType" runat="server" Text='<%# GetType((int)DataBinder.Eval(Container.DataItem))%>' />
</ItemTemplate>
This calls a function GetType which queries the database based on the ArticleID. Of course this happens for every item in the gridview. Now I would like to know if it's possible to send the current (subsonic) collection item to this function instead? Because the item is already available but I don't know how to put this in my itemtemplate.
My current item is DAL.Article which contains everything I need.
I hope I made myself clear a little !Thanks for your time.
Kind regards,
Mark
Subsonic generated classes are partial and thus extendable.
Let's say you have a DAL object called Person. You can create a new file Person.cs (in a different folder of course).
namespace Your.Dal.Namespace {
public partial class Person
{
public string DisplayName
{
get
{
return String.Format("{0}, {1}", this.LastName, this.FirstName);
}
}
}
}
Now you can access the DisplayName property of your class:
PersonCollection col = new PersonCollection().Load();
foreach(Person p in col)
Console.WriteLine(p.DisplayName);
I use this technique for binding Subsonic Collections to a Windows.Forms DataGridView a lot.
But it should work for asp.net, too.

set calendar extender format

Does anyone know if there is a way of specifying the Format of a calendar extender with a dynamic value from the aspx?
I tried this but it doesnt seem to set the format at all. Does anyone see anything wrong with it:
<asp:TextBox ID="tbStartDate" runat="server" />
<act:CalendarExtender ID="clndrStartDate" PopupPosition="Right" runat="server"
Format='<%# DefaultDateFormat %>' TargetControlID="tbStartDate"></act:CalendarExtender>
and i have the DefaultDateFormat getter in a base page of the code beheind like this:
public static string DefaultDateFormat
{
get { return "dd/MM/yyyy"; }
}
Any help would be appretiated.
Thank you
Call DataBind Method on calendar extender instance.
clndrStartDate.DataBind();
This solution worked for me.
Don't you mean to say Format="<% =DefaultDateFormat%>" and you may not want DefaultDateFormat to be a static property.
You appear to be missing "" and = in your example. But I could be wrong.

Forcing TargetControl Textbox to use a value in the AutocompleteExtender

I'm sure I'm going to have to write supporting javascript code to do this. I have an autocomplete extender set up that selects values from a database table, when a selection is made, i would like it to set the ID of the value selected to a hidden control. I can do that by handling a value change on the text box and making a select call to the database, Select idCompany from Companies Where CompanyName = "the text box value";
The most important thing is to constrain the values of the text box that is the targetcontrol for the autocomplete extender to ONLY use values from the autocomplete drop down. Is this possible with that control, is there examples somewhere? is there a better control to use (within the ajax control toolkit or standard .net framework - not a third party control)?
I'm going to be trying to work out some javascript, but I'll be checking back to this question to see if anyone has some useful links. I've been googling this last night for quite a while.
Update: I did not get an answer or any useful links, I've posted an almost acceptable user control that does what I want, with a few workable issues.
No one was able to give me an answer. This has been an ongoing saga. It started when I was trying to find a solution not using drop down lists for large amounts of data. I have run into issues with this so many times in previous projects. This seems to be workable code. Now I need to know how to supply a AutoPostBack Property, and allow for some events, such as SelectedValueChanged. And due to the javascript, it will conflict with another control, if I have more than one of them on the same page. Well, that's some of the known issues I'm looking at with the code, but it's a start and definately better than looking at a hung browser for 3 or 4 minutes while the drop down is loading 30k list items.
This code is assuming there is an asmx file with the script methods GetCompanyListBySearchString and GetCompanyIDByCompanyName.
ASPX FILE
<%# Control Language="C#" AutoEventWireup="true" CodeFile="SelectCompany.ascx.cs" Inherits="Controls_SelectCompany" %>
<%# Register TagPrefix="ajaxToolkit" Namespace="AjaxControlToolkit" Assembly="AjaxControlToolkit" %>
<script language="javascript" type="text/javascript">
var txtCompanyIDHiddenField = '<%= fldCompanyID.ClientID %>';
var txtCompanyIDTextBox = '<%= txtCompany.ClientID %>';
function getCompanyID() {
if (document.getElementById(txtCompanyIDTextBox).value != "")
CompanyService.GetCompanyIDByCompanyName(document.getElementById(txtCompanyIDTextBox).value, onCompanyIDSuccess, onCompanyIDFail);
}
function onCompanyIDSuccess(sender, e) {
if (sender == -1)
document.getElementById(txtCompanyIDTextBox).value = "";
document.getElementById(txtCompanyIDHiddenField).value = sender;
}
function onCompanyIDFail(sender, e) {
document.getElementById(txtCompanyIDTextBox).value = "";
document.getElementById(txtCompanyIDHiddenField).value = "-1";
}
function onCompanySelected() {
document.getElementById(txtCompanyIDTextBox).blur();
}
</script>
<asp:TextBox ID="txtCompany" runat="server" onblur='getCompanyID()'
/><ajaxToolkit:AutoCompleteExtender runat="server" ID="aceCompany" CompletionInterval="1000" CompletionSetCount="10"
MinimumPrefixLength="2" ServicePath="~/Company/CompanyService.asmx" ServiceMethod="GetCompanyListBySearchString"
OnClientItemSelected="onCompanySelected" TargetControlID="txtCompany" />
<asp:HiddenField ID="fldCompanyID" runat="server" Value="0" />
CODE BEHIND
[System.ComponentModel.DefaultProperty("Text")]
[ValidationProperty("Text")]
public partial class ApplicationControls_SelectCompany : System.Web.UI.UserControl
{
public string Text
{
get { return txtCompany.Text; }
set
{
txtCompany.Text = value;
//this should probably be read only and set the value based off of ID to
// make certain this is a valid Company
}
}
public int CompanyID
{
get
{
int ret = -1; Int32.TryParse(fldCompanyID.Value, out ret); return ret;
}
set
{
fldCompanyID.Value = value.ToString();
//Todo: should set code to set the Text based on the ID to keep things straight
}
}
}
Thanks for your post here. It is useful, however, it is assuming that everyone knows the setup to get the webservice called by a javascript function.
Sorry to be soo newbie, but I couldn't get the webservice called from client-side.
I read this documentation: http://msdn.microsoft.com/en-us/magazine/cc163499.aspx
Furthermore, I found an interesting post that explains how to create/get a name value pair which is pretty much what you are expecting as far as I understood:
http://blogs.msdn.com/phaniraj/archive/2007/06/19/how-to-use-a-key-value-pair-in-your-autocompleteextender.aspx
Sorry if I misunderstood you, but I am just trying to guide other people that pass through the same situation.
Thanks a lot.
You can check the value of the selection by trapping on ClientItemSelected event and ensure that it is not blank.

Resources