how to find the selected link button value in the repeater control - asp.net

I have an issue regarding link button, On my website i have got a product for sale page, which has a ryt side bar with filter options
while the left side bar shows the filteration results.
On my ryt sidebar i have used accordion with the repeater control which display the searching criteria from database.
For instance I have 2 searching criteria model and price , under model accordion there are three models, what I want to acheive is
when a user clicks on that specific model , the page should run a query with respect to that click and show bind the results on the
repeater of the left side bar, I know the query to get the results but I dunno how to get the value
of that hyper link button, coz these buttons will be dynamic it can be 3,4 or 10. how will i get the clicked hyperlink value
so that I can run the query depending on the model selected.
Any help or tutorial will highly be appreciated.
AutoSize="None"
FadeTransitions="true"
TransitionDuration="250"
FramesPerSecond="40"
RequireOpenedPane="false"
SuppressHeaderPostbacks="true">
<Panes>
<asp:AccordionPane ID="AccordionPane1" runat="server" >
<Header>
Make
</Header>
<Content>
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<li>
<asp:LinkButton ID="LinkButton2" runat="server" Text='<%# Eval("make") %>'></asp:LinkButton>
</li>
</ItemTemplate>
</asp:Repeater>
</Content>
</asp:AccordionPane>
<asp:AccordionPane ID="AccordionPane2" runat="server" >
<Header>
Price
</Header>
<Content>
</Content>
</asp:AccordionPane>
</Panes>
</asp:Accordion>

Set the CommandArgument of the LinkButton.
Then to access the CommandArgument:
protected void lnkButton_Click(object sender, EventArgs e) {
LinkButton _sender = (LinkButton)sender;
string argument = _sender.CommandArgument;
}

Related

ASP.NET ListView Paging : Invalid viewstate

I have a ListView control as follows (for posting here I've removed the values from my ItemTemplate):
<asp:ListView ID="ListView1" runat="server" DataSourceID="MyDataSource">
<LayoutTemplate>
<div id="requests" runat="server">
<asp:Panel runat="server" id="itemPlaceholder"></asp:Panel>
</div>
<asp:DataPager runat="server" ID="DataPager" PageSize="3">
<Fields>
<asp:NumericPagerField ButtonCount="10" PreviousPageText="<--" NextPageText="-->" />
</Fields>
</asp:DataPager>
</LayoutTemplate>
<ItemTemplate>
<div ID="itemPlaceholder" class="request" runat="server">
<asp:LinkButton ID="button" runat="server" Text='...' CommandName="..."
CommandArgument='...' OnClick="..."
style="...">
</asp:LinkButton> -
</div>
</ItemTemplate>
</asp:ListView>
This ListView exists as a user control (.ascx), which I've embedded into an ASPX web page.
As I expect, when the web page loads, for a list of 9 items, I get 3 pages of 3 items.
When I click to go to the next page, the page loads the next set of items correctly... but only for a brief second. Then a strange thing happens. The page embeds a copy of itself inside the page 6 times, each one of them underneath one of the fields on the form inside the page.
If I then attempt to go to the next or previous page, an ASP.NET server error appears:
The state information is invalid for this page and might be corrupted.
In the stack trace, it shows the following errors:
FormatException: The input is not a valid Base-64 string as it contains a non-base character, more than two padding characters, or a non-white space character among the padding characters.
ViewStateException: Invalid viewstate.
I was able to replicate this on both my browsers, IE8 and Chrome.
you use listview event OnPagePropertiesChanging
like this
<asp:ListView ID="lvCustomers" runat="server" GroupPlaceholderID="groupPlaceHolder1"
ItemPlaceholderID="itemPlaceHolder1" OnPagePropertiesChanging="OnPagePropertiesChanging">
in aspx.cs
protected void OnPagePropertiesChanging(object sender,PagePropertiesChangingEventArgs e)
{
(lvCustomers.FindControl("DataPager1") as DataPager).SetPageProperties(e.StartRowIndex, e.MaximumRows, false);
this.BindListView();
}
BindListView() is method for binding list view
visit this link for example
i hope it's helpfull

asp.net dropdown tool tip not shown when modal popup is opened

I have a asp.net dropdown control to which tool tip has been added. It works fine on the mouse over. I also have a Modal Popup in that page. When I open and close the Modal Popup the tool tip in the drop are no more shown.
Below is my code.
<div class="col">
<div class="labelname required">
<asp:Label ID="lblsupplier" runat="server" Text="Supplier"></asp:Label>
</div>
<div class="labelvalue">
<asp:DropDownList ID="DdlSupplier" TabIndex="11" runat="server" AutoPostBack="true"
CausesValidation="false" OnSelectedIndexChanged="DdlSupplier_SelectedIndexChanged">
</asp:DropDownList>
<asp:RequiredFieldValidator ID="reqSupplier" runat="server" ControlToValidate="DdlSupplier"
ValidationGroup="SubmitGroupMain" InitialValue="0" ErrorMessage="Please Select Supplier Name"
SetFocusOnError="true" Display="None"></asp:RequiredFieldValidator>
<ajaxToolkit:ValidatorCalloutExtender ID="ValidatorCalloutExtender7" runat="Server"
TargetControlID="reqSupplier" HighlightCssClass="validatorCalloutHighlight">
</ajaxToolkit:ValidatorCalloutExtender>
</div>
<asp:LinkButton runat="server" ID="lnkAddSupplier" CssClass="btnadd" ToolTip="New Supplier"
OnClick="lnkAddSupplier_Click"></asp:LinkButton>
<asp:Button runat="server" ID="popupshowAccount" Style="display: none" />
</div>
</div>
Code behind
foreach (ListItem item in DdlSupplier.Items)
{
item.Attributes.Add("title", item.Text);
}
DdlSupplier.Attributes.Add("onmouseover","this.title=this.options[this.selectedIndex].title");
Clicking on lnkAddSupplier opens up a popup. After closing the popup tool tip is not visible for the dropdown.
Please help on solving this issue.
Attributes won't be saved in Viewstate and that's why they will disappear across postbacks. Similar is the case with Custom Attributes.
That's why we have to use DropDownList Pre Render event to set attributes
protected void DropDownList1_PreRender(object sender, EventArgs e)
{
foreach (ListItem item in DropDownList1.Items)
item.Attributes.Add("title", "Something to test!!!!!!");
}

asp.net ajax like reorder list

I'm trying to create a draggable list to change the order some pictures are displayed in a product page. I wan't to be able to do this in the product edit page (same place where I add the pics and their description). So, when creating I have nothing inserted on the database and since the AJAX toolkit reorderlist only works with a datasource I was specifying the list as the source of the reorderlist and calling the databind method. In the item template of the reorder list I have a textbox to edit the pic description and a img that displays the photo. I can drag the items and the list gets reordered, however when I click save I can't get the updated text on the textbox and the order property on the picture doesn't get updated. I've tried manually getting the items in the reorderlist but they're always null even though the list shows 20 items the DataItem is empty. I've enabled viewstate and didn't help either.
Here's my code:
<ajaxToolkit:ReorderList ID="rdlPhotos" runat="server" SortOrderField="PhotoOrder" AllowReorder="true" PostBackOnReorder="true" ClientIDMode="AutoID" EnableViewState="true" ViewStateMode="Enabled">
<ItemTemplate>
<div>
<%--<eva:PhotoView ID="iPV" runat="server" Photo='<%# Container.DataItem %>' />--%>
<asp:Image ID="imgPhoto" runat="server" ImageUrl='<%# string.Format("http://eva-atelier.net/sparkle{0}", Eval("Path").ToString().Substring(1)) %>' Width="150" Height="150" />
<div class="formGrid">
<label class="formLabel">Title</label>
<asp:TextBox ID="txtTitle" runat="server" Text='<%#Bind("FileTitle") %>' />
<br />
<label class="formLabel">Description</label>
<asp:TextBox ID="txtDescription" runat="server" Text='<%#Bind("FileDescription") %>' />
<br />
</div>
<p>
<asp:Button ID="btnRemove" runat="server" Text="Remover" />
</p>
</div>
</ItemTemplate>
<ReorderTemplate>
<asp:Panel ID="pnlReorder" runat="server" />
</ReorderTemplate>
<DragHandleTemplate>
<div style="width:20px;height:20px;background-color:Red"></div>
</DragHandleTemplate>
</ajaxToolkit:ReorderList>
And below the C# code:
private void AddPhotosView()
{
if (_currentProduct.Photos != null && _currentProduct.Photos.Count > 0)
{
rdlPhotos.DataSource = _currentProduct.Photos;
rdlPhotos.DataBind();
}
}
I'm new to Asp.net I come from a large WPF background, sorry if I'm making basic question :)
Thanks
For updating order of ReorderList items add your handler for it's OnItemReorder event. In this case your handler may looks like this:
protected void ReorderHandler(object sender, ReorderListItemReorderEventArgs e)
{
var movedPhoto = _currentProduct.Photos[e.OldIndex];
_currentProduct.Photos.RemoveAt(e.OldIndex);
_currentProduct.Photos.Insert(e.NewIndex, movedPhoto);
_currentProduct.Photos.Save();
}
For updating FileTitle and FileDescription of single Photo it is easy to use OnUpdateCommand event of ReorderList and a button with attribute CommandName="Update" for each Photo.
And for updating all Photos at once just iterate through rdlPhotos.Items in next manner:
protected void SaveAllHandler(object sender, EventArgs e)
{
foreach (var riItem in rdlPhotos.Items)
{
var id = ((HiddenField)riItem.FindControl("itemID")).Value;
var title = ((TextBox)riItem.FindControl("txtTitle")).Text;
var description = ((TextBox)riItem.FindControl("txtDescription")).Text;
UpdatePhoto(id, title, description);
}
}
Remember that rdlPhotos.Items here are in initial order. And for identifying which Photo should be updated add hidden field with Photo.ID-value to ReorderList's ItemTemplate like this:
<asp:HiddenField runat="server" ID="itemID" Value='<%# Eval("ID") %>' />

lazy loading asp.net Ajax Control Toolkit accordion

I am using the asp.net Ajax Control Toolkit accordion (http://www.asp.net/ajaxlibrary/act_Accordion.ashx) and each accordion pane contains quite a lof information.
All that info is generated in the page but it is not shown because the toolkit gives the non active panes a
(style="display:none;)
But because the info is in the page, it becomes a very heavy page to load.
I am looking for a way to load the panes on-demand: so only if the user clicks the pane an ajax request is send and the pane is loaded and expanded.
Can this be done with this control or should i choose a different accordion? Any help or suggestions appreciated.
update
Currently the Accordion is created with two, nested, repeaters. The first repeater loops over the categories and creates a panel for each category. The second repeater repeates inside each panel takes the content for one category and creates the content of the panel.
Pleun
I don't have the points to comment and ask you questions. Sorry. :(
My questions are in regard to how you plan to create and populate the Accordion.
Will you create panes by hand using markup in the IDE or will you bind the Accordion to a DataSource that will dynamically create the panes you need?
Will you have 3 separate DataSources or a different combination of the following:
1.) DataSource to initialize the number of panels and populate only the panel's Header information.
2.) DataSource to populate the Static Content of all panels on first load.
3.) DataSource to populate the Lazy-Loaded Content of a single panel the user clicks to expand.
With your answers I hope to update this answer with a real one. Thanks.
Update: This is achievable with the Ajax Control Toolkit's Accordion.
I have some very basic code below as proof of concept. It could be smoother, but I'll leave it up to you to add a "Loading" image using the UpdatingProgress control if you find it necessary.
The Accordion in the Aspx markup:
(Notice the UpdatePanels - you can replace them with callbacks if you want, I just wanted to keep the answer simple)
<asp:Accordion ID="acc_Accordion" runat="server" RequireOpenedPane="false"
SelectedIndex="-1" onitemcommand="acc_Accordion_ItemCommand" >
<HeaderTemplate>
<asp:UpdatePanel ID="up_UpdateHeader" runat="server">
<ContentTemplate>
<%--When using "Eval" inside strings for Asp.net controls,
you MUST wrap them in apostrophes ('),
otherwise with (") you will get parser errors!--%>
<asp:LinkButton ID="btn_Header" runat="server"
Text='<%# Eval("HeaderText") %>'
CommandName="UpdatePane" CommandArgument='<%# Eval("ItemID") %>'
Font-Underline="false" ForeColor="Black"
style="width:100%; height:100%; cursor:pointer;"/>
<%--Use Cursor:Pointer to keep a consistent
interface after disabling the button.--%>
</ContentTemplate>
</asp:UpdatePanel>
</HeaderTemplate>
<ContentTemplate>
<asp:UpdatePanel ID="up_UpdateContent" runat="server"
UpdateMode="Conditional">
<ContentTemplate>
<%# Eval("ContentText")%>
<asp:Label ID="lbl_Content" runat="server"
Text="<%# DateTime.Now.ToLongTimeString() %>"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
</ContentTemplate>
</asp:Accordion>
The Page_Load() - Prep our "dummy" data:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack == false)
{
DataTable dt = new DataTable();
dt.Columns.Add("ItemID");
dt.Columns.Add("HeaderText");
dt.Columns.Add("ContentText");
dt.Rows.Add(new object[] { 123456, "Header 1", "Content A." });
dt.Rows.Add(new object[] { 654321, "Header 2", "Content B." });
acc_Accordion.DataSource = new System.Data.DataTableReader(dt);
acc_Accordion.DataBind();
}
}
The ItemCommand() - This captures button-clicks inside the Accordion:
protected void acc_Accordion_ItemCommand(object sender, CommandEventArgs e)
{
if (e.CommandName == "UpdatePane")
{
AjaxControlToolkit.AccordionContentPanel acp
= (e as AjaxControlToolkit.AccordionCommandEventArgs).Container;
UpdatePanel upHeader
= acc_Accordion.Panes[acp.DisplayIndex].HeaderContainer
.Controls.OfType<Control>()
.Single(c => c is UpdatePanel) as UpdatePanel;
LinkButton btn
= upHeader.ContentTemplateContainer
.Controls.OfType<Control>()
.Single(b => b is LinkButton) as LinkButton;
UpdatePanel upContent
= acc_Accordion.Panes[acp.DisplayIndex].ContentContainer
.Controls.OfType<Control>()
.Single(c => c is UpdatePanel) as UpdatePanel;
Label lbl
= upContent.ContentTemplateContainer
.Controls.OfType<Control>()
.Single(c => c is Label) as Label;
lbl.Text = " ID: " + e.CommandArgument
+ " and Time: " + DateTime.Now.ToLongTimeString();
//You can use the ID from e.CommandArgument to query the database
// for data to update your Repeaters with.
btn.Enabled = false;//Disabling the button for our Header
// will prevent Asyncronous Postbacks to update the content again.
//Only disable this if you don't need to update the content
// when the user clicks to view the pane again.
upContent.Update();//Set UpdateMode="Conditional".
}
}
I know this looks like a lot, but it's only a few lines of code (before wrapping and commenting).
Tip 4 in 6 Tips for Working with the ASP.NET AJAX Accordion Control explains how to determine when the selected index has changed. From the JavaScript event handler you can do whatever you want to update the content of the newly-selected accordion pane (call a web service, use an update panel, etc.)
Combining this with another article explaining how to use an update panel to refesh content when a tab page is selected for a simple demo:
<ajaxToolKit:Accordion ID="accSample" runat="server"
RequireOpenedPane="false" SelectedIndex="-1">
<Panes>
<ajaxToolKit:AccordionPane runat="server">
<Header>Sample</Header>
<Content>
<asp:Button ID="btnSample" runat="server" OnClick="OnShowSample" Style="display: none" />
<script type="text/javascript">
Sys.Application.add_load(function (sender, args) {
if (!args.get_isPartialLoad()) {
var accSample = $find('<%= accSample.ClientID %>_AccordionExtender');
accSample.add_selectedIndexChanged(function (sender, eventArgs) {
$get('<%= btnSample.ClientID %>').click();
});
}
});
</script>
<asp:UpdatePanel ID="upSample" runat="server">
<ContentTemplate>
<asp:DataGrid ID="dgSample" runat="server" Visible="false"/>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnSample" />
</Triggers>
</asp:UpdatePanel>
</Content>
</ajaxToolKit:AccordionPane>
</Panes>
</ajaxToolKit:Accordion>
then in code-behind
protected void OnShowSample(object sender, EventArgs e)
{
dgSample.DataSource = new string[] { "test" };
dgSample.DataBind();
dgSample.Visible = true;
}
Take a look at the ASPxNavBar control (a part of the free ASPxperience Suite) from DevExpress. If the ASPxNavBar’s EnableCallBacks property is set to true, contents of collapsed groups are not represented on the client side. When a group is expanded for the first time, its content is retrieved from the server and then cached on the client. The next time the group is expanded, its content is taken from the client and no callback to the server is performed.
Review the ASPxNavBar - Callbacks (AJAX) Online Demo for more information.
All I can suggest to you is add linkButtons to your headers and panels to your panes:
<Panes>
<asp:AccordionPane ID="First" runat="server">
<Header>
<asp:LinkButton CommandName="ASD2" ID="LinkButton2" runat="server">LinkButton</asp:LinkButton>
</Header>
<Content>
<asp:Panel ID="Panel2" runat="server" Visible="true">
First
</asp:Panel>
</Content>
</asp:AccordionPane>
<asp:AccordionPane ID="Second" runat="server">
<Header>
<asp:LinkButton CommandName="ASD" ID="LinkButton1" runat="server">LinkButton</asp:LinkButton>
</Header>
<Content>
<asp:Panel ID="Panel1" runat="server" Visible="false">
Second
</asp:Panel>
</Content>
</asp:AccordionPane>
</Panes>
and in the Accordion1_ItemCommand set the Visible property of corresponding panel.
protected void Accordion1_ItemCommand(object sender, CommandEventArgs e)

AJAX TabContainer containing user controls

Wondering if someone here can help.
I have an AJAX tabcontainer which has a number of tabs and each tab contains a user control. When I add a new item from one of the tabs, it is not reflected in the user control in another tab unless a postback occurs. (e.g. the first tab has a listview where I add a new record and the second has a simple form which contains a drop-down which I expect to contain value added from first tab).
How can I make the tabcontainer to refresh its tabs from a usercontrol?
Any help will be most appreciated.
Thanks,
Ali
You could fire an event from your first user control so that the page can handle this event and tell the other usercontrol to databind
Here is a example
<act:TabContainer ID="TabContainer2" runat="server" CssClass="EmployeeProfile" ActiveTabIndex="0">
<act:TabPanel ID="TabPanel1" runat="server" HeaderText="Datos Generales">
<ContentTemplate>
<br />
<uc1:EmployeeGeneralDetails ID="EmployeeGeneralDetails2" runat="server" OnUpdated="EmployeeGeneralDetails2_OnUpdated" />
</ContentTemplate>
</act:TabPanel>
<act:TabPanel ID="TabPanel2" runat="server" HeaderText="Referenias Personales">
<ContentTemplate>
<uc3:EmployeeResumeView ID="EmployeeResumeView2" runat="server" />
</ContentTemplate>
</act:TabPanel>
</act:TabPanel>
protected void EmployeeGeneralDetails2_OnUpdated(object o, EventArgs e)
{
EmployeeResumeView2.DataBind();
}

Resources