Showing posts with label sql. Show all posts
Showing posts with label sql. Show all posts

Wednesday, March 28, 2012

Dynamic Creation of CollapsablePanels

I'd like to know how to create a CollapsablePanel in code-behind. My goal is to fetch records from a SQL 05 DB, and create a panel for each record/row in the dataset. I don't know how many rows I'll have, if any, and this means I need to do it on the back end, not in the XHTML code.

Hi,

I made the following sample according to your requirements, please try it:

<%@. Page Language="C#" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><script runat="server"> protected void Page_Load(object sender, EventArgs e) { int numberOfRecordsToBeShown = 10; // this value can be determined by the number of rows in database for (int i = 0; i < numberOfRecordsToBeShown; i++) { Panel pnl = new Panel(); Label lblContent = new Label(); LinkButton lbHeader = new LinkButton(); PlaceHolder1.Controls.Add(lbHeader); PlaceHolder1.Controls.Add(pnl); pnl.Controls.Add(lblContent); lbHeader.ID = "Header" + i.ToString(); lbHeader.Text = "Header" + i.ToString(); pnl.ID = "Row" + i.ToString(); lblContent.Text = "Content to be shown"; AjaxControlToolkit.CollapsiblePanelExtender cpe = new AjaxControlToolkit.CollapsiblePanelExtender(); cpe.ID = "Extender" + i.ToString(); cpe.SuppressPostBack = true; cpe.CollapseControlID = lbHeader.ID; cpe.ExpandControlID = lbHeader.ID; cpe.TargetControlID = pnl.ID; PlaceHolder1.Controls.Add(cpe); } }</script><html xmlns="http://www.w3.org/1999/xhtml" ><head runat="server"> <title>Untitled Page</title></head><body> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> </div> <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder> </form></body></html>
Hope this helps.

I gave it a go, but all I get is 10 lines of 'Content to be shown' on my screen. No collapsing/expanding... nothing, really, except 10 lines of text.


ok, with a few slight alterations, I wound up with this:

protected void Page_Load(object sender, EventArgs e) {
SpewOutCollapses();
}

public void SpewOutCollapses() {
int numberOfRecordsToBeShown = 5; // this value can be determined by the number of rows in database
for (int i = 0; i < numberOfRecordsToBeShown; i++) {
AjaxControlToolkit.CollapsiblePanelExtender cpe = new AjaxControlToolkit.CollapsiblePanelExtender();
StringBuilder sBuild = new StringBuilder();

Panel pnlContainer = new Panel();
Panel pnlHeaderGoal1Update = new Panel();
Label lblContent = new Label();
LinkButton lbHeader = new LinkButton();
PlaceHolder1.Controls.Add(lbHeader);
PlaceHolder1.Controls.Add(pnlContainer);
pnlContainer.Controls.Add(pnlHeaderGoal1Update);
pnlHeaderGoal1Update.Controls.Add(lblContent);

pnlContainer.ID = "pnlContainer" + i.ToString();
pnlContainer.Style.Add("background", "#DFDFDF");

lbHeader.ID = "Header" + i.ToString();
sBuild.Append(" <table class=\"clsOneHundredPercentWide clsBGGreyA clsCursorPointer txtWhiteBold\" style=\"height: 25px;\">");
sBuild.Append(" <tr>");
sBuild.Append(" <td class=\"clsTwoByFivePadding cls25pxHigh clsBold clsLeftAlign\" style=\"width: 15%\">ID " + i.ToString() + "</td>");
sBuild.Append(" <td class=\"clsTwoByFivePadding cls25pxHigh clsLeftAlign\" style=\"width: 85%\">(Show Details...)</td>");
sBuild.Append(" </tr>");
sBuild.Append(" </table>");
lbHeader.Text = sBuild.ToString();

pnlHeaderGoal1Update.ID = "pnlHeaderGoal1Update" + i.ToString();

lblContent.Text = "<div class=\"clsTwoByFivePadding clsLeftAlign\" style=\"padding-right: 10px;\">";
lblContent.Text += " <p>Quisque felis lacus, sodales in, commodo ut, pellentesque sed, orci. Pellentesque congue nisi sed enim. Quisque congue sodales sapien. Suspendisse et lorem ut erat dignissim vestibulum. In hac habitasse platea dictumst. Sed nisl neque, convallis eu, sagittis dignissim, molestie eu, odio. Fusce quam orci, vehicula sollicitudin, tincidunt sed, lobortis dignissim, lectus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed interdum tincidunt mi. Vivamus blandit molestie lectus. Praesent sem lacus, tincidunt nec, placerat ac, feugiat non, tortor. Donec eu pede in neque viverra iaculis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Integer interdum augue quis risus. Pellentesque malesuada elit et eros. In ipsum. Pellentesque eget diam. Aenean quis lorem. Cras et dolor at urna pharetra nonummy. Sed posuere, risus eget suscipit lacinia, ipsum nulla adipiscing sapien, vitae aliquet lacus arcu blandit neque.</p>";
lblContent.Text += "</div>";

cpe.ID = "Extender" + i.ToString();
cpe.SuppressPostBack = true;
cpe.CollapseControlID = lbHeader.ID;
cpe.ExpandControlID = lbHeader.ID;
cpe.TargetControlID = pnlHeaderGoal1Update.ID;
PlaceHolder1.Controls.Add(cpe);
}
}

It works great, but that brings me to part 2 of my question: Is there a way to generate SUB collapsers in this... to in effect nest collapsing panels in collapsing panels. I can hard-code that, but I would love to generate it. What I want is, inside the existing panel generation, to generate a single collapsablePanel (so that each collapser has one nested collapser inside). Think that's possible?


Ok, let's forget the nesting for the moment, and think instead about something else: can you explain, possibly, why the panels start fully expanded?


Morydyn:

Ok, let's forget the nesting for the moment, and think instead about something else: can you explain, possibly, why the panels start fully expanded?

By default, the initial state is expanded. You can change it to collapsed explicitly.

cpe.ID = "Extender" + i.ToString();
cpe.Collapsed = true;
cpe.SuppressPostBack = true;

Dynamic CollapsiblePanel

I am surely a novice, but was wondering if it is possible to dynamically build a page of collapsible panels based on the values in a SQL table. The code size would be greatly reduced if it can be done.Just another forum that noone uses!

I'll be honest, this is a very vague question. And it seems as though you are fishing for free code. We aren't here to code projects for you. If you are looking for pointers, I'll gladly provide this.

The approach I would take is to use either a SqlDataSource or ObjectDataSource to retrieve the data. I like working with objects, so it tends to take more code up front to get the data from SQL and turn it into objects in my object model. But once done, I then use the ObjectDataSource to get the data ready for binding.

Then you can use any number of databound controls. One example might be the Repeater control. This is a very free form control that will let you provide any HTML per object (or row) returned from the datasource. In the ItemTemplate, you just define the CollapsiblePanelExtender as you would in any databound control.

If you get stuck, please post here with the code that is blocking you and I'll do what I can to help.


Got it working. The problem was with the page sub-class.

Dynamic Collapsible Panels - Flicker and slow load

Hello,

I have a User Control that dynamically creates several collapsible panels depending on records read from sql db. The panels are created okay, but the page loads slow and flickers several times. It partially loads, displays first panel very quickly and goes blank until all other panels are created and data is loaded. It looks awfull!!

Is there a way to improve the UI?, so the page shows all panels when loaded. It would be good also showing a "wait for a moment" message when creating many panels. What is the best way to do it?

Thank you,

Carlos Lozano

Any one?

Any comments would be helpfull. Thank you.Carlos


I can't help with your issues, but could you show me how you create dynamic panels based on SQL data? Once I get it working, I will discuss with others around here to determine if there is a solution.


Mine works without the flickering. I don't use a code behind in the control that buildds it.


Try to set in web.config <compilation debug="false">

It will improve some performance.


Below is the main code that creates the panel.

Notes:

1) CustomPanel is a customization of Panel class.

2) sNewEndingID is a counter to identify each panel and its controls.

3) TableUtil.AddTableRow function basically adds the <tr><td>controls here</td></tr> to the panel to organize the panel presentation.

4) oOptions.getOptionData("Inspection") Pulls data from SQL DB to populate some of the control options (ie. DropdownList, etc).

-- Code --

public void createInspectorPanel(ref CustomPanel oParentPanel, string sNewEndingID)
{
OptionsObject oOptions = new OptionsObject();
//oParentPanel.Visible = false;

AjaxControlToolkit.CollapsiblePanelExtender oExPanel = new AjaxControlToolkit.CollapsiblePanelExtender();
CustomPanel oPanel = new CustomPanel();
oPanel.ID = "InspectorItem" + sNewEndingID;
if (oParentPanel.Controls.IndexOf(oPanel) == -1)
{
oExPanel.ID = "InspectorPanelExtender" + sNewEndingID;
oExPanel.TargetControlID = "InspectorPanel" + sNewEndingID;
oExPanel.ExpandControlID = "InspectorPanelHeader" + sNewEndingID;
oExPanel.CollapseControlID = "InspectorPanelHeader" + sNewEndingID;
oExPanel.Collapsed = true;
oExPanel.TextLabelID = "lblInspectorControlText" + sNewEndingID;
oExPanel.CollapsedText = sNewEndingID + ") - Click to view details ";
oExPanel.ExpandedText = sNewEndingID + ") - Click to hide details ";
oExPanel.SuppressPostBack = false;
oPanel.Controls.Add(oExPanel);

CustomPanel oPanelHeader = new CustomPanel();
oPanelHeader.ID = "InspectorPanelHeader" + sNewEndingID;
oPanelHeader.CssClass = "collapsePanelHeader";
//oPanelHeader.Width = 300;
oPanelHeader.Width = Unit.Percentage(98);

Label oCounterLabel = new Label();
oCounterLabel.ID = "lblInspectorCounter" + sNewEndingID;
oPanelHeader.Controls.Add(oCounterLabel);

Label oControlLabel = new Label();
oControlLabel.ID = "lblInspectorControlText" + sNewEndingID;
oControlLabel.CssClass = "BTextClass";
oPanelHeader.Controls.Add(oControlLabel);
oPanel.Controls.Add(oPanelHeader);

CustomPanel oDetailPanel = new CustomPanel();
oDetailPanel.ID = "InspectorPanel" + sNewEndingID;
oDetailPanel.Height = 50;
//oDetailPanel.Width = 350;
oDetailPanel.Width = Unit.Percentage(98);

HtmlTable oTable = new HtmlTable();
TableUtil.AddTableRow(ref oTable, 1, "InspectorName", "Name: ", 1, sNewEndingID);
TableUtil.AddTableRow(ref oTable, 2, "CompanyName", "Company: ", 1, sNewEndingID);
DropDownList MPICertLevel = new DropDownList();
TableUtil.AddTableRow(ref oTable, ref MPICertLevel, ";1;2;3", "MPICertLevel", "MPI Cert. Level: ", sNewEndingID);
DropDownList LPCertLevel = new DropDownList();
TableUtil.AddTableRow(ref oTable, ref LPCertLevel, ";1;2;3", "LPCertLevel", "LP Cert. Level: ", sNewEndingID);
DropDownList EMICertLevel = new DropDownList();
TableUtil.AddTableRow(ref oTable, ref EMICertLevel, ";1;2;3", "EMICertLevel", "EMI Cert. Level: ", sNewEndingID);
DropDownList UTCertLevel = new DropDownList();
TableUtil.AddTableRow(ref oTable, ref UTCertLevel, ";1;2;3", "UTCertLevel", "UT Cert. Level: ", sNewEndingID);
//DropDownList Inspection = new DropDownList();
ListBox Inspection = new ListBox();
Inspection.DataTextField = "Description";
Inspection.DataValueField = "Id";
Inspection.DataSource = oOptions.getOptionData("Inspection");
Inspection.Rows = 6;
Inspection.SelectionMode = ListSelectionMode.Multiple;
Inspection.DataBind();
TableUtil.AddTableRow(ref oTable, ref Inspection, "Inspection", "Inspections Done: ", sNewEndingID);
DropDownList TxtPerformance = new DropDownList();
TxtPerformance.DataTextField = "Description";
TxtPerformance.DataValueField = "Id";
TxtPerformance.DataSource = oOptions.getOptionData("InspPerformance");
TxtPerformance.DataBind();
TableUtil.AddTableRow(ref oTable, ref TxtPerformance, "Performance", "Performance: ", sNewEndingID);
TableUtil.AddTableRow(ref oTable, 9, "InspDiscrepancies", "Discrepancies: ", 2, sNewEndingID, 40);

oDetailPanel.Controls.Add(oTable);
oPanel.Controls.Add(oDetailPanel);
oParentPanel.Controls.Add(oPanel);
//oParentPanel.Visible = true;
}
}


Did you set your Content Panel's height to 0px. I'm not sure if I'm reading this correctly but I seeoDetailPanel.Height = 50;Maybe try setting that to 0 and see if that helps with the flickering.

Saturday, March 24, 2012

DropDownLists in 2 separate updatepanels only work once, then dont.

Hey, i have 2 dropdownlists, both databound to my sql server, the first one simply selects anything from the "catagories" database. Autopostback is enabled. The next one is a select to the subcatagories database, with an inner join to catagories on the catagory_id column..

The idea here was to make an ajax enabled cascading databound dropdownlist, and it DOES work... but only once. i tried making the trigger the indexChanged event of the 1st dropdown list, but i have the same results. If i change catagories more than once, i will not get a subcatagory change..

Any ideas?

So not sure why DropDownList1 is in an UpdatePanel, but DropDownList2 is the issue here eh and is in a panel, and has a dependant control, being the first drop down list.

So the second one, add a Trigger like this;

<asp:AsyncPostbackTriggerControlID="DropDownList1"EventName="SelectedIndexChanged"/>

Is that any help? Post a snippet of your page here.

Cheers,

Steve


You should use the Cascading Dropdown of Ajax Control Toolkit, it is specially developed for this purpose. Checkout the live demo of it:
http://www.asp.net/AJAX/Control-Toolkit/Live/CascadingDropDown/CascadingDropDown.aspx


It says AsyncPostbackTrigger was a unknown element... Here's my code:

Catagory:<BR /><asp:DropDownList id="DropDownList1" runat="server" DataValueField="Catagory_ID" DataTextField="Catagory" DataSourceID="SqlDataSource2" AutoPostBack="True"></asp:DropDownList><asp:UpdatePanel id="UpdatePanel1" runat="server" >
<contenttemplate>
SubCatagory:<BR /><asp:DropDownList id="ddlSubCat" runat="server" DataValueField="SubCatagory_ID" DataTextField="SubCatagory" DataSourceID="ddlsubCatagory"></asp:DropDownList>

<asp:SqlDataSource id="SqlDataSource2" runat="server" SelectCommand="SELECT [Catagory], [Catagory_ID] FROM [db_Catagories]" ConnectionString="<%$ ConnectionStrings:floofieConnectionString %>"></asp:SqlDataSource><BR /><asp:SqlDataSource id="ddlsubCatagory" runat="server" SelectCommand="SELECT db_SubCatagories.SubCatagory, db_SubCatagories.SubCatagory_ID FROM db_Catagories INNER JOIN db_SubCatagories ON db_Catagories.Catagory_ID = db_SubCatagories.Catagory_ID WHERE (db_Catagories.Catagory_ID = @.catid)" ConnectionString="<%$ ConnectionStrings:floofieConnectionString %>"><SelectParameters>

<asp:ControlParameter PropertyName="SelectedValue" Name="catid" ControlID="DropDownList1"></asp:ControlParameter>
</SelectParameters>
</asp:SqlDataSource>
</contenttemplate>


KaziManzurRashid:

You should use the Cascading Dropdown of Ajax Control Toolkit, it is specially developed for this purpose. Checkout the live demo of it:
http://www.asp.net/AJAX/Control-Toolkit/Live/CascadingDropDown/CascadingDropDown.aspx

That looks really nice, is there any way of getting the web service code for vb.net?


Can you post the complete markup of UpdatePanel. If any of your dropdown is outsite the update panel set its AutoPostback=true and create AsyncPostbackTrigger in Update Panel which points to that dropdownlist.


KaziManzurRashid:

Can you post the complete markup of UpdatePanel. If any of your dropdown is outsite the update panel set its AutoPostback=true and create AsyncPostbackTrigger in Update Panel which points to that dropdownlist.

Sorry bout that, thought i had it all.

Catagory:<BR /><asp:DropDownList id="DropDownList1" runat="server" DataValueField="Catagory_ID" DataTextField="Catagory" DataSourceID="SqlDataSource2" AutoPostBack="True"></asp:DropDownList><asp:UpdatePanel id="UpdatePanel1" runat="server"> <contenttemplate>SubCatagory:<BR /><asp:DropDownList id="ddlSubCat" runat="server" DataValueField="SubCatagory_ID" DataTextField="SubCatagory" DataSourceID="ddlsubCatagory"></asp:DropDownList> <BR /><asp:SqlDataSource id="SqlDataSource2" runat="server" SelectCommand="SELECT [Catagory], [Catagory_ID] FROM [db_Catagories]" ConnectionString="<%$ ConnectionStrings:floofieConnectionString%>"></asp:SqlDataSource><BR /><asp:SqlDataSource id="ddlsubCatagory" runat="server" SelectCommand="SELECT db_SubCatagories.SubCatagory, db_SubCatagories.SubCatagory_ID FROM db_Catagories INNER JOIN db_SubCatagories ON db_Catagories.Catagory_ID = db_SubCatagories.Catagory_ID WHERE (db_Catagories.Catagory_ID = @.catid)" ConnectionString="<%$ ConnectionStrings:floofieConnectionString%>"><SelectParameters><asp:ControlParameter PropertyName="SelectedValue" Name="catid" ControlID="DropDownList1"></asp:ControlParameter></SelectParameters></asp:SqlDataSource></contenttemplate> <triggers><asp:AsyncPostBackTrigger ControlID="DropDownList1" EventName="SelectedIndexChanged"></asp:AsyncPostBackTrigger></triggers> </asp:UpdatePanel>

I acctually fixed it... the problem was, there was 3 other updatepanels, and they all need to be set to conditional.

I cant beleive i didnt see that in the first place.