Okay I have some code for a website I am building. I have a listbox that is databound to an SqlDataSource. When selected, it is supposed to generate an SQL query that updates\filters a different listbox elsswhere in the page. I have tried testing it just to get it to change the text of a Label and that isn't even working. Here is some of my code:
<asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server">
<%--register triggers for Partial postback --%>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="showbutton" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="viewapps" EventName="Click" />
</Triggers>
<ContentTemplate>
<%--- the controls in their rows and columns --%>
<%--column 1 --%>
<asp:Label runat="server" ID="TESTER">Text</asp:Label>
<asp:Panel runat="server" CssClass="column1">
<asp:Panel ID="Panel1" runat="server" CssClass="row1">
<%-- Make Panel --%>
<span style="padding:8px; position:relative;">
<asp:Label ID="label1" runat="server" Text="Make" Font-Size="Large" ></asp:Label>
<asp:Listbox ID="MakeList" runat="server" Width="166px" SelectionMode ="Multiple" DataSourceID="MakeSource" DataTextField="MakeName" AutoPostBack="true" DataValueField="MakeID" OnSelectedIndexChanged="UpdateModels">
</asp:Listbox>
</span>
<asp:SqlDataSource ID="MakeSource" runat="server" ConnectionString="<%$ ConnectionStrings:VCDBConnectionString %>" ></asp:SqlDataSource>
</asp:Panel>
Now in my C# Codebehind I have this:
public void UpdateModels(object sender, EventArgs e)
{
//build a string for a SQL query for the Models
string newQuery = "SELECT M.[ModelID], M.[ModelName] FROM Model M INNER JOIN BaseVehicle BV ON BV.ModelID = M.ModelID Where BV.MakeID= '";
string test = "";
foreach (ListItem li in MakeList.Items)
{
//add each piece of the selected text to the string
if (li.Selected)
{
test += li.Value;
test += "' AND BV.MakeID= '";
}
int cleanup = test.LastIndexOf("' AND BV.MakeID= '");
test.Remove(cleanup-19,cleanup);
//ScriptManager.RegisterStartupScript(this, GetType(), "ServerControlScript", "alert('" + test + "');", true);
TESTER.Text = test;
}
But still tester is not being updated. Even though AutoPostBack=true, even though the whole thing is wrapped in an update panel. =( I need some help figuring this one out.
I would also appreciate any other advice.
I would be glad to provide any additional information you may need, just let me know in the comments.
String.remove does not work the way I was thinking it did. This was causing a runtime exception that did not show up until I did debugging, which is why TESTER's text wasn't getting updated.
I was able to fix my problem a different way.
Instead of building the string immediately and trying tricky string operations, instead I just put each string into a list and then removed the last item of the last at the end.
Then once I had the perfected list, then I added it to the string.
In code it looks like this:
List<string> queryBuilder = new List<string>();
//add the seleted items to items in the list
foreach (ListItem li in MakeList.Items)
{
if (li.Selected)
{
queryBuilder.Add(li.Value);
queryBuilder.Add("' OR BV.MakeID = '");
//build the list of selected makes for later use
selectedMakes.Add(li.Value);
}
}
try
{
//remove the last ' AND BV.MakeID= '
queryBuilder.RemoveAt(queryBuilder.Count-1);
//add back the ' and the orderby
queryBuilder.Add("'");
queryBuilder.Add(" ORDER BY [ModelName]");
//build the string
foreach(string s in queryBuilder){
newQuery+= s;
}
//debug for visibilty
TESTER.Text =newQuery;
Related
I have an ajax tabcontainer in an updatepanel with all tabpages set visible until you want to add a tabpanel based on the dropdownlist selected value
CODE:
<cc1:TabContainer ID="tabControlParameters" runat="server" CssClass="ajax__tab_xp"
ScrollBars="Both" ActiveTabIndex="15" UseVerticalStripPlacement="True">
<%--EnvironmentTab --%>
<cc1:TabPanel ID="pnlEnvironment" HeaderText="Environment" runat="server" Visible="false">
<ContentTemplate>
//somecontent
</ContentTemplate>
</cc1:TabPanel>
<cc1:TabPanel ID="pnlDatabase" HeaderText="Environment" runat="server" Visible="false">
<ContentTemplate>
//somecontent
</ContentTemplate>
</cc1:TabPanel>
<cc1:TabPanel ID="pnlFirstError" HeaderText="Environment" runat="server" Visible="false">
<ContentTemplate>
//somecontent
</ContentTemplate>
</cc1:TabPanel>
With a button add which is inside the Updatepanel and has a correct async trigger assigned to it.
From C# codebehind I've made a loop to check if the dropdownlist selectedvalue = panel_headertext if so make it visible
CODE:
protected void btnAddParameters_Click(object sender, EventArgs e)
{
String Parameter = ddlParameterTypes.SelectedValue.ToString();
AjaxControlToolkit.TabContainer container = (AjaxControlToolkit.TabContainer)tabControlParameters;
foreach (object obj in container.Controls)
{
if (obj is AjaxControlToolkit.TabPanel)
{
AjaxControlToolkit.TabPanel tabPanel = (AjaxControlToolkit.TabPanel)obj;
if (tabPanel.HeaderText == ddlParameterTypes.SelectedValue)
{
tabPanel.Visible = true;
tabPanel = tabControlParameters.ActiveTab;
container.ActiveTab = tabPanel;
}
}
}
}
Now this works perfectly if the updatepanel trigger is set to fullPostback but it's set to async postback then it only works on the first click even though the event is fired every time I'm clicking on the button. Am I missing something obvious here?
Petar
You have the same value in HeaderText for each of your TabPanels. I think it'll work if you correct the HeaderText attributes.
Im using a repeater to display some products in an online shop for a school project. This is how the front end looks with the repeater
<asp:Repeater ID="Repeater1" runat="server" OnItemCommand="rptList_ItemCommand">
<ItemTemplate>
<span style="float:left; padding:25px;" class="backgrnd">
<asp:ImageButton ID="imgProd" runat="server" style="width:150px; height:150px;" ImageUrl='<%# DataBinder.Eval(Container.DataItem, "productImg")%>' CommandArgument='<%# DataBinder.Eval(Container.DataItem, "productID")%>' CommandName="ViewIndividProd"/><br />
<p style="clear:left;">
<asp:Label ID="lbName" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "productName")%>' /><br />
<asp:Label ID="lbUnitPrice" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "unitPrice")%>'/><br />
<asp:Label ID="lbRatings" runat="server" Text=''>Ratings</asp:Label><br />
<asp:LinkButton ID="linkCart" runat="server" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "productID")%>' CommandName="AddToCart">Add to Cart</asp:LinkButton>
</p>
</span>
</ItemTemplate>
</asp:Repeater>
As you can see I've added on the OnItemCommand in the Repeater tag so that this is invoked whenever one of the buttons(image/link) is fired. That works perfectly fine for both commandname AddToCart and ViewIndividProd. However, i want to store the the productid of a specific item that was invoked by the particular button. In my case now, it only stores ONE productid in the arraylist at a time and 'forgets' the productid that was stored previously when another linkbutton is clicked.
Question How do i make it such that everytime a linkbutton in the repeater is fired, it remembers the productid pertaining to the linkbutton that was fired and save these ids into the arraylist?
This is how the back end looks
ArrayList cart = new ArrayList();
protected void rptList_ItemCommand(object sender, RepeaterCommandEventArgs e) {
if (e.CommandName == "ViewIndividProd") {
Session["productID"] = e.CommandArgument.ToString();
Response.Redirect("IndividProduct.aspx");
}
if (e.CommandName == "AddToCart") {
string prodid = e.CommandArgument.ToString();
cart.Add(prodid);
Session["ShoppingCart"] = cart;
Response.Redirect("IndividCat.aspx");
}
msg.Text = "Shopping cart: " + String.Join(",", cart.ToArray());
}
Your feedback would be much appreciated.
You need to understand the Asp.net Page life cycle.
A new instance of your Page object is created on every request.
Values from your input are populated into it.
Your array list is getting recreated every time.
If you want the values to persist, you will have to store your arraylist in the ViewState or the Session
Refer: How to: Save Values in View State
void Page_Load(object sender, EventArgs e)
{
if (ViewState["arrayListInViewState"] != null)
{
PageArrayList = (ArrayList)ViewState["arrayListInViewState"];
}
else
{
// ArrayList isn't in view state, so we need to create it from scratch.
PageArrayList = CreateArray();
}
// Code that uses PageArrayList.
}
We can store comma separated or JSON value in either Session or hidden variable (If you are on the same page and opening new page in different tab then we can use hidden variable also). So every time an button has been click we can append the product id.
I have a GridView and a column in GridView which has a linkButton that opens a modalpopupextender on click. I am able to bind data in popextender panel but now i want to retrieve data from that panel.
I am getting data from each GridRow like:
foreach (GridViewRow row in MyGridView.Rows)
{
Label Date = (Label)row.Cells[0].FindControl("DateId");
string date = Date.Text;
//Code to get linkButton(asp:ModalpopUpextender) and data from
//asp:panel of ModalpopUpextender
}
I have searched around for answers but wasn't able to find a solution to my problem.
Thanks in advance.
Assuming you are having a setup like this
<ajaxToolKit:ModalPopupExtender
ID="mdlPopup" runat="server" TargetControlID="btnShowPopup" PopupControlID="pnlPopup"
CancelControlID="btnClose" BackgroundCssClass="modalBackground" />
<asp:Panel ID="pnlPopup" runat="server" Width="500px" style="display:none">
<asp:UpdatePanel ID="updPnlCustomerDetail" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Label ID="lblCustomerDetail" runat="server" Text="Customer Detail" Width="95%" />
</ContentTemplate>
</asp:UpdatePanel>
You might try finding your panel first and then drill down to the required control.I would suggest putting this code in the row editing event
gridViewTest_RowEditing(object sender, GridViewEditEventArgs e)
{
gridViewTest.EditIndex=e.NewEditIndex;
Panel myPanel = (Panel)gridViewTest.Rows(gridViewTest.EditIndex).FindControl("pnlPopup");
Label myLabel = (Label)myPanel.Findcontrol("lblCustomerDetail");
}
//then do stuff with the label.
Thanks Abide for the useful post...finally i found the solution...
Panel.FindControl("ControlId");
does not work fine because somtimes panel is not added to the page.
we can use this code.It works fine.
foreach( Control cntrl in Panel.Controls )
{
if(cntrl.ID == "RequiredConteolId")
{
//your application code goes here...
}
}
I have 2 update panel in one update panel i have a datalist and in other update panel I have a textbox with tinymce editor.
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:DataList ID="dlst1" runat="server" RepeatDirection="Horizontal" CellSpacing="5" CellPadding="7"
DataKeyField="Id" CaptionAlign="Left" OnItemCommand="dls1_ItemCommand"
OnItemDataBound="dlst1_ItemDataBound">
<ItemTemplate>
<asp:ImageButton ID="btnImg" OnClientClick="javascript:void(0);"
runat="server" ImageUrl='<%#"~/Controls/Images.ashx?FileName=" +DataBinder.Eval(Container.DataItem, "FilePath") %>'
CommandName="Select" OnCommand="Select_Command"
CommandArgument='<%# Eval("Id").ToString() ' />
</ItemTemplate>
</asp:DataList>
</ContentTemplate>
<asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Always">
<ContentTemplate>
<asp:TextBox ID="TextBox1" CssClass="tinyEditor" ClientIDMode="Static" runat="server" TextMode="MultiLine"></asp:TextBox>
</ContentTemplate>
</asp:UpdatePanel>
for making tinymce worked I am using
ScriptManager.RegisterClientScriptBlock(UpdatePanel2, this.GetType(), "init", "tinyMCE.execCommand('mceAddControl', false, '" + TextBox1.ClientID + "');", true);
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function () {
TinyMCEEditor();
});
$(function () {
TinyMCEEditor();
});
my TinyMCE Editor
function TinyMCEEditor() {
tinyMCE.init({
mode: "textareas",
theme: "advanced"
});
}
on page load.
I am giving the text for every image, for the previous image I am storing the textbox value in a view state, suppose I have 3 images for image 1 i have given the text abcd and selected image2, so image 1 text will store in the viewstate.
on Select_Command:
if (ViewState["txbtext"] != null)
txbtext= (Hashtable)ViewState["txbtext"];
int index1 = previouslySelectedIndex;
if (index1 != -1)
{
ImageButton imgbtn= (dlst1.Items[index1].FindControl("btnImg") as ImageButton);
if (imgbtn!= null)
{
string[] ImgStr = imgbtn.CommandArgument.ToString().Split(';');
Int32 selectedId = Convert.ToInt32(Str[0]);
if (txbtext!= null && txbtext.ContainsKey(selectedId))
txbtext[selectedId] = textbox.Text;
else
txbtext.Add(selectedId, textbox.Text);
}
}
ViewState["txbtext"] = txbtext (//this is the hashtable);
}
when I was not using update panel it was working fine, but as I am using update panel I am not able to store the textbox value in viewstate,
Please someone tell me how can I fix this issue, if possible give some exp. code.
Some one plz help me
I had the same problem with it and I decided to use another editor. Have a look at CKEditor for ASP.NET http://www.ckeditor.com/download
I have added
onchange_callback: function(ed) { ed.save(); }
for my TInyMCE Editor its working now...
In my UserControl, Im trying to update a updatepanel that is inside a repeater like this:
HTML-Markup
<asp:UpdatePanel ID="updDocumentQuickView" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Repeater ID="repFolders" runat="server" OnItemDataBound="repFolders_OnItemDataBound" OnItemCommand="repFolders_OnItemCommand">
<ItemTemplate>
<asp:LinkButton ID="lnkFolder" runat="server"></asp:LinkButton>
<asp:UpdatePanel ID="updFiles" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Repeater ID="repFiles" runat="server" OnItemDataBound="repFiles_OnItemDataBound">
<ItemTemplate>
<%# Container.DataItem %>
</ItemTemplate>
</asp:Repeater>
</ContentTemplate>
</asp:UpdatePanel>
</ItemTemplate>
</asp:Repeater>
</ContentTemplate>
</asp:UpdatePanel>
C#-code
protected void repFolders_OnItemCommand(object sender, CommandEventArgs e)
{
int intRow = -1;
ScriptManager myScriptManager = (ScriptManager)Page.Master.FindControl("myScriptManager");
Match myMatch = Regex.Match(myScriptManager.AsyncPostBackSourceElementID, "repFolders.ctl([0-9]*).lnkFolder");
if (myMatch != null)
intRow = Convert.ToInt32(myMatch.Groups[1].Value);
if (intRow > -1)
{
RepeaterItem myItem = repFolders.Items[intRow];
Repeater repFiles = (Repeater)myItem.FindControl("repFiles");
UpdatePanel updFiles = (UpdatePanel)myItem.FindControl("updFiles");
string[] arr1 = new string[] {
"array item 1",
"array item 2",
"array item 3",
"array item 4",
"array item 5" };
repFiles.DataSource = arr1;
repFiles.DataBind();
updFiles.Update();
}
}
The end result I get is that updDocumentQuickView is the UpdatePanel that gets updated, and not updFiles. If i wrap an UpdatePanel around lnkFolder, then that UpdatePanel gets updated, with the same C# code. Ive checked what kind of data that are sent back with fiddler, and the wrong UpdatePanel is sent. Im getting the correct RepeaterItem, and both repFiles and updFiles are found. What do I miss to get the right UpdatePanel to get updated?
UPDATE
Hawxby solution solved the problem with updDocumentQuickView getting updated, thanks for that. But im still having problems with updFiles sending nothing back. Some further testing, with putting literals inside updFiles and working, tells me that theres something with repFiles that isnt returned. repFiles does have data that is bounded.
FINAL SOLUTION
repFiles.Visible were set to false in repFolders_OnItemDataBound, no wonder it didnt show.
It's likely because you have to explicitly set the async bindings
<asp:UpdatePanel ID="updDocumentQuickView" ChildrenAsTriggers="false">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="repFolders" EventName="repFolders_OnItemCommand" />
</Triggers>
</asp:UpdatePanel>