Ajax autocomplete extender and get ID of selected item? - asp.net

I am using the autocomplete extender to suggest names when a user types. How to get the select value after the user selects an item? I guess I can use onclientitemselected but I am not familiar on how to write this? I need to populate a textbox based on the selection in the autocompleteextender textbox. Thank you
<asp:TextBox ID="TextBox1" runat="server" Height="27px" Width="570px"></asp:TextBox>
<asp:AutoCompleteExtender ID="AutoCompleteExtender" runat="server"
DelimiterCharacters="" Enabled="True" ServicePath="AutoComplete.asmx"
ServiceMethod="GetCompletionList" TargetControlID="TextBox1"
MinimumPrefixLength="2" UseContextKey="true" ContextKey="StateDropDown"
CompletionListElementID="autocompleteDropDownPanel">
</asp:AutoCompleteExtender>

For this you need to return the list from web service method with ID and Text
Here "lst" is the actual list with data from your data source.
List<string> items = new List<string>(count);
for (int i = 0; i < lst.Count; i++)
{
string str =AjaxControlToolkit.AutoCompleteExtender.CreateAutoCompleteItem(lst[i].Text,Convert.ToString(lst[i].IDValue));
items.Add(str);
}
return items.ToArray();
Then simple javascript
function GetID(source, eventArgs )
{
var HdnKey = eventArgs.get_value();
document.getElementById('<%=hdnID.ClientID %>').value = HdnKey;
}
and dont forget to set the attribute in auto complete extender
OnClientItemSelected="GetID"

The AutoCompleteExtender merely extends the ASP.NET TextBox control, so if you want to know when the text changed, then just raise the TextChanged event on the TextBox control, like this:
Markup:
<asp:TextBox ID="TextBox1" runat="server" Height="27px" Width="570px" OnTextChanged="TextBox1_TextChanged" AutoPostBack="true"></asp:TextBox>
Code-Behind:
protected void TextBox1_TextChanged(object sender, EventArgs e)
{
// Do something here with textbox value
}

Related

asp.net create uzer wizard getting a handle on controls in custom steps

I have added an extra step to my uzerwizard
<asp:TemplatedWizardStep id="stpPayment" runat="server" Title="Payment">
<ContentTemplate>
<asp:DropDownList ID="cmbSubs" runat="server" ClientIDMode="Static"
Width="200px">
<asp:ListItem Value="month">Monthly Subscription</asp:ListItem>
<asp:ListItem Value="year">Annual Subscription</asp:ListItem>
</asp:DropDownList>
i am successfully navigating to the new step
protected void NewUserprofileWizard_NextButtonClick(object sender, WizardNavigationEventArgs e)
{
if (NewUserprofileWizard.ActiveStepIndex == 0)
{
NewUserprofileWizard.ActiveStepIndex = 1;
}
}
but I cant get access to the dropdownlist from my codebehind
note: i can get a handle onto the controls in the 1st (createuser) step.
but any controls in the next step always return a null.
this is the code i am using
DropDownList cmb = (DropDownList)NewUserprofileWizard.WizardSteps[1].FindControl("cmbSubs");
i always return a null.
note that this works just fine
TextBox tmp = (TextBox)NewUserprofileWizard.CreateUserStep.ContentTemplateContainer.FindControl("Email");
userProfile.AccountEmail = tmp.Text;
problem seems unique to custom steps
Thanks for the help
Tried Gregors suggestion. no luck. mine always comes up as null.
if thsi helps any:
my wizard is inside a user control..
the page that uses the user control is inside a master page.....
Here is little sample I have created for you, first aspx code:
<asp:CreateUserWizard ID="CreateUserWizard1" runat="server" OnNextButtonClick="CreateUserWizard1_NextButtonClick">
<WizardSteps>
<asp:WizardStep runat="server" Title="My Custom Step">
<asp:DropDownList ID="cmbSubs" runat="server" ClientIDMode="Static"
Width="200px">
<asp:ListItem Value="month">Monthly Subscription</asp:ListItem>
<asp:ListItem Value="year">Annual Subscription</asp:ListItem>
</asp:DropDownList>
</asp:WizardStep>
<asp:CreateUserWizardStep runat="server" />
<asp:CompleteWizardStep runat="server" />
</WizardSteps>
</asp:CreateUserWizard>
And now the code to find first dropdown:
protected void CreateUserWizard1_NextButtonClick(object sender, WizardNavigationEventArgs e)
{
if (e.CurrentStepIndex == 0)
{
//get instance to dropdown...
string selectedValue = null;
string controlId = null;
foreach (var item in CreateUserWizard1.WizardSteps[0].Controls)
{
DropDownList ddl = item as DropDownList;
if (ddl != null)
{
selectedValue = ddl.SelectedValue;
controlId = ddl.ClientID;
break;
}
}
}
}
Of course you can also find your dropdown like this:
DropDownList cmbSubs = CreateUserWizard1.WizardSteps[0].FindControl("cmbSubs") as DropDownList;
Happy coding!
it appears that today my google foo was doing much better
because i am in a templateswizardstep, i have to cast the wizardstep into the templatedwizardstep.
from here i can now find the control. whooohoo!
TemplatedWizardStep step = (TemplatedWizardStep)NewUserprofileWizard.WizardSteps[1];
cmb = (DropDownList)step.ContentTemplateContainer.FindControl("cmbSubs");
Thanks all for the help

ASP.Net AJAX UpdatePanel not working with Repeater and RadioButtons

I have a repeater which includes a radio button in each item, and the whole thing sites inside an update panel. When I select a radio button the whole page reloads. Why is it not just updating the update panel. I've reduced this to a pretty simple example to avoid clutter. Code here...
ASPX...
<asp:ScriptManager ID="SM1" runat="server" />
<asp:UpdatePanel ID="up1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Repeater runat="server" ID="history">
<ItemTemplate>
<asp:RadioButton runat="server" ID="radioButton" AutoPostBack="true" GroupName="HistoryGroup" OnCheckedChanged="RadioButton_CheckChanged" /><br />
</ItemTemplate>
</asp:Repeater>
<p><asp:Literal runat="server" ID="output" /></p>
</ContentTemplate>
</asp:UpdatePanel>
Code...
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
List<int> list = new List<int>();
for (int i = 0; i < 20; i++)
list.Add(i);
history.DataSource = list.ToArray();
history.DataBind();
}
}
protected void RadioButton_CheckChanged(Object sender, EventArgs e)
{
output.Text = DateTime.Now.ToString();
}
}
Setting ClientIDMode=Auto on the RadioButton should fix it (it's an infamous .NET bug, http://connect.microsoft.com/VisualStudio/feedback/details/584991/clientidmode-static-in-updatepanel-fails-to-do-async-postback)
please add up1.Update() after output.Text = DateTime.Now.ToString(). Your RadioButton is not the trigger for updatepanel
Turns out the solution was to remove the GroupName from the RadioButton. When I remove this tag it fires asynchronously and just updates the panel. I don't actually need this tag anyway (due to the known bug where GroupName doesn't work on RadioButtons in Repeaters) as I handle the grouping within my click event (i.e. uncheck any other RadioButtons of the same name in other repeater items).

How do I maintain user entered text in a TextBox nested in an UpdatePanel between updates?

I have an ASP.Net UpdatePanel that updates on a timer. Within the UpdatePanel and nested in a GridView, I have a TextBox that the user enters a value in with a submit button. Everything works fine, except if the user does not submit the value before the timed interval, the text is removed from the TextBox.
Is there a way to persist the user entry into the TextBox between updates? Is there a better way of doing this?
All suggestions welcome.
Respectfully,
Ray K. Ragan
Code Postscript:
aspx:
<script type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_beginRequest(beginRequest);
function beginRequest() {
prm._scrollPosition = null;
}
</script>
<asp:Timer ID="Timer1" runat="server" Interval="900" OnTick="Timer1_Tick"></asp:Timer>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
</Triggers>
<ContentTemplate>
<asp:DataList RepeatColumns="5" RepeatDirection="Horizontal" ID="dlMine" runat="server" OnItemCommand="Item_Command">
<ItemTemplate>
<div style="border:1px solid black;margin:3px;height:300px;text-align:center;padding:5px;">
<div style="width:150px;">
<asp:Label ID="lblTitle" runat="server" Text='<%# left(DataBinder.Eval(Container.DataItem,"title").ToString(), 75) %>'></asp:Label>
</div>
<asp:Label ID="Label1" runat="server" Text='<%# (DateTime)DataBinder.Eval(Container.DataItem,"end_date") %>'></asp:Label>
<br />
<asp:Label ID="Label2" runat="server" Text='<%# String.Format("{0:C}",DataBinder.Eval(Container.DataItem,"current_value")) %>'></asp:Label>
<br />
<asp:TextBox ID="txtNewValue" runat="server"></asp:TextBox>
<asp:Button Visible='<%# (isInThePast((DateTime)DataBinder.Eval(Container.DataItem,"end_date"))) ? false : true %>' CssClass="bid_button" runat="server" CommandArgument='<%# Eval("ID") %>' CommandName="Revalue" ID="btnBid" Text="Submit New Valuation" />
</div>
</ItemTemplate>
</asp:DataList>
</ContentTemplate>
</asp:UpdatePanel>
Codebehind:
protected void Page_Load(object sender, EventArgs e)
{
Timer1.Tick += new EventHandler<EventArgs>(Timer1_Tick);
if (!IsPostBack)
{
dataBindList();
}
}
protected void dataBindList()
{
if (Request.QueryString["GroupID"] != null)//Are they coming here with a URL var? If so, build content object
{
List<Item> itemList = ItemManager.getItemsByGroupID(Request.QueryString["GroupID"].ToString());
dlMine.DataSource = itemList.Take(15);
dlMine.DataBind();
}
}
protected void Timer1_Tick(object sender, EventArgs e)
{
dataBindList();
UpdatePanel1.Update();
}
protected void Item_Command(Object sender, DataListCommandEventArgs e)
{
if (e.CommandName == "Revalue")
{
Person p = (Person)Session["Person"];
foreach (DataListItem item in dlMine.Items)
{
string textBoxText = ((TextBox)item.FindControl("txtNewValue")).Text;
Utilities.writeLog("txtNewValue: " + textBoxText, 1);
}
dataBindList();
UpdatePanel1.Update();
}
}
You're rebinding the DataList every time the Timer ticks. All changes in the ItemTemplates of the DataList will be lost on postback.
Why not use Javascript to "pause" the timer whenver one of the textboxes gains focus. This will prevent the Timer from firing and let users finish entering text. Once they leave the textbox of "onblur" then you can restart the timer.
Update
The following will take a bit of effort to make it happen but you can do something like:
When the Timer posts back, before rebinding, iterate over the DataList while searching for textboxes with text in them. Something like:
foreach (DataListItem item in dlMine.Items)
{
//find the textbox control and check for text
}
At this point, you'll know which rows need there textboxes repopulated. Store this information in a hashtable.
In the DataList ItemDataBound event, check each rowID against the hashtable to see if its corresponding textbox exists. If so, repopulate the textbox in the DataList row.
Are you initializing the TextBbox value in your code-behind, perhaps in Page_Load or another page method?
TextBox1.Text = "";
If so, that code is executing on every timer event. You can prevent that like this:
if (! IsPostback) {
TextBox1.Text = "";
}
The first request that hits an ASP.NET page is usually an HTTP GET request, while ASP.NET buttons and update panel events issue HTTP POST requests. So the code above will clear TextBox1 the first time you access the page, but leave the value alone when receiving requests from itself. (If you really are setting the text box's value to its default - empty - you could just remove the initialization code.)

How do I find the Client ID of control within an ASP.NET GridView?

I have a asp:GridView which contains a asp:TextBox within a TemplateField. I would like to obtain it's ID for use in javascript. Something like this:
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="textDateSent" runat="server" />
<input type="button" value='Today'
onclick="setToday('<%# textDateSent.ClientID %>');" />
</ItemTemplate>
</asp:TemplateField>
But when I compile, I get an error:
The name 'textDateSent' does not exist in the current context
Anybody know how to get the client ID of this TextBox?
Try this:
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="textDateSent" runat="server">
</asp:TextBox>
<input type="button" value='Today' onclick="setToday('<%# ((GridViewRow)Container).FindControl("textDateSent").ClientID %>');" />
</ItemTemplate>
</asp:TemplateField>
Maybe you don't want to do it where you need the ClientID. Check out this post here where the controls in a row are referenced in a generic way.
Change <%# textDateSent.ClientID %> to <%= textDateSent.ClientID %>.
Argh, you may need to use the OnDataBinding event of the grid view. Then put a literal control in your javascript. Then you can get the clientID of the text box and feed that into your literal control.
protected void GridViewName_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//Create an instance of the datarow
DataRowView rowData = (DataRowView)e.Row.DataItem;
//locate your text box
//locate your literal control
//insert the clientID of the textbox into the literal control
}
}
Look here for a great detailed tutorial on working within this context.
You can get client id like this:
protected void Gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string strClientID = ((TextBox)e.Row.FindControl("txtName")).ClientID;
}
}
This will give unique client ID for each textbox in all rows.
I just do this...
var tbl = document.getElementById('<%=GridView.ClientID%>');
var checkBox = tbl.rows[i].cells[11].getElementsByTagName("input")[0].id;
the cell should always be the same and it gets rendered into an input. You may have to change the number at the end if you have more then one input in that cell. This will give you the new clientid/id of the input object (checkbox or whatever)
This is what I did. In the aspx page I just passed the entire object to the javascript function, so I didn't even meed to client id. In my case the object was a drop down list in the EditItemTemplate of the GridView. I added an html onchange(this) event in the aspx code.
<asp:DropDownList ID="custReqRegionsDDL" runat="server" onchange='custReqRegionsDDLOnChange(this)'>
</asp:DropDownList>
here is my javascript
function custReqRegionsDDLOnChange(myDDL)
{
alert('selected text=' + myDDL.options[myDDL.selectedIndex].text);
}

Use data in repeater when Checkbox is check in ASP.net

I have a repeater for showing my data . this repeater showing 2 field that one of feild is checkBox Control and other is a lable.
NOW , how can I understand text of lable when the checkBox is Checked?
I want to see text of lable in evry row that the CheckBoxes is checksd.
how do I do?
I use LINQtoSQL for get and set data from database
On postback, you need to loop through every row of your repeater, and grab out the checkbox control. Then you can access it's .Checked and .Text properties. If it's .Checked, then add it to a list or array. I can elaborate if needed..
Page...
<asp:CheckBox ID="chkBoxID" runat="server" OnCommand="doSomething_Checked" CommandArgument="<%# Some Binding Information%>"
CommandName="NameForArgument">
</asp:CheckBox>
Code Behind...
protected void doSomething_Checked(object sender, CommandEventArgs e) {
CheckBox ctrl = (CheckBox)sender;
RepeaterItem rpItem = ctrl.NamingContainer as RepeaterItem;
if (rpItem != null) {
CheckBox chkBox = (LinkButton)rpItem.FindControl("chkBoxID");
chkBox.DoSomethingHere...
}
}
<asp:Repeater ID="rptX" runat="server">
<ItemTemplate>
<asp:Label ID="lblX" runat="server" Visible='<%# Eval("IsChecked") %>' />
<asp:CheckBox ID="chkX" runat="server" Checked='<%# Eval("IsChecked") %>' />
</ItemTemplate>
</asp:Repeater>
And code behind when you assign your data
rptX.DataSource = SomeIEnumerableFromLinq; // which has a bool field called IsChecked
rptX.DataBind();

Resources