I am currently dynamically generating ASP elements on a website. The site displays items for a specific motorcycle based on the make/model/year.
Issue 1: I have all of the items displaying correctly, on the page, but I cannot figure out how to get my CSS styling to apply to the dynamically generated items.
Heres what I have, it querys the items into a datatable first:
try
{
int tempflag = 0;
foreach (DataRow tempRow in dt.Rows)
{
string tempCategory = tempRow[4].ToString();
string tempPartUrl = tempRow[5].ToString();
string tempImageUrl = tempRow[6].ToString();
string tempPartBrand = tempRow[7].ToString();
string tempPartName = tempRow[8].ToString();
string tempPrice = tempRow[9].ToString();
string tempStoreName = tempRow[10].ToString();
//panel to hold an item
Panel pnlItem = new Panel();
pnlItem.ID = "id_pnItem_" + tempflag;
pnlItem.CssClass = "itemDiv";
divSearchResultsBody.Controls.Add(pnlItem);
//image
Image tpImg = new Image();
tpImg.ID = "id_tpImg_" + tempflag;
tpImg.ImageUrl = tempImageUrl;
pnlItem.Controls.Add(tpImg);
Label lblBR = new Label();
lblBR.ID = "frt" + tempflag;
lblBR.Text = "<br />";
pnlItem.Controls.Add(lblBR);
//brand
Label lblBrand = new Label();
lblBrand.ID = "id_lblBrand_" + tempflag;
lblBrand.Text = tempPartBrand;
pnlItem.Controls.Add(lblBrand);
//name
Label lblName = new Label();
lblName.ID = "id_lblName_" + tempflag;
lblName.Text = tempPartName;
pnlItem.Controls.Add(lblName);
//price
Label lblPrice = new Label();
lblPrice.ID = "id_lblPrice_" + tempflag;
lblPrice.Text = tempPrice;
pnlItem.Controls.Add(lblPrice);
//url
HyperLink hyp = new HyperLink();
hyp.ID = "id_link_" + tempflag;
hyp.NavigateUrl = tempPartUrl;
hyp.Text = "View Part";
pnlItem.Controls.Add(hyp);
tempflag++;
}
}
catch (Exception ex)
{
handleTheError(ex);
}
I'm not sure how to access my css sheet from the .aspx.cs. so all the elements are just smashed together one after another each in a panel.
Issue 2: I am also generating checkboxes based on the item's category's so I can create a filter. I grab distinct categories with a query and fill them into a datatable. I have all the checkboxes but I have no idea how to go about generating an event for them because they are dynamic, and I've only used events that are hard coded. The code is similar:
foreach (DataRow tempRow in dt2.Rows)
{
string tempCategory = tempRow[0].ToString();
CheckBox cbCategory = new CheckBox();
cbCategory.ID = "id_cbCategory_" + tempflag2;
cbCategory.Text = tempCategory;
divFilterCategory.Controls.Add(cbCategory);
tempflag2++;
}
Issue 3: There are two divs that are next to each other, one for filter results that are generated, and another for the item results that are generated. As I mentioned they both generate properly at the moment, but for some reason when the items generate it shoots the second div halfway down the page. Pics:Before searching, After searching, Filters halfway down the page
Heres what the initial design looks like
<div runat="server" id="divSearch" class="divCenterItems">
<table class="searchTable">
<tr style="width: 100%">
<td style="width: 29%">
<div runat="server" id="divSearchFiltersHeader" class="divSearchHeaders">
<asp:Label runat="server" ID="lblFilterResults" Text="Filter Results" CssClass="headerLabels"></asp:Label>
</div>
<div runat="server" id="divSearchFiltersBody">
<div runat="server" id="divFilterCategory"></div>
<div runat="server" id="divFilterBrand"></div>
<div runat="server" id="divFilterPrice"></div>
</div>
</td>
<td style="width: 69%">
<div runat="server" id="divSearchResultsHeader" class="divSearchHeaders">
<asp:Label runat="server" ID="lblSearchTitle" Text="Search Results Title" CssClass="headerLabels"></asp:Label>
</div>
<div runat="server" id="divSearchResultsBody">
<div runat="server" id="divItemsMSS"></div>
<div runat="server" id="divItemsRMATVMC"></div>
<div runat="server" id="divItemsDK"></div>
</div>
</td>
</tr>
</table>
</div>
Styles:
.divCenterItems
{
border: 1px solid black;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.searchTable
{
width: 100%;
padding-left: 5px;
padding-right: 5px;
}
.divSearchHeaders
{
border: 1px solid black;
background-image: url('../Resources/header.png');
background-repeat: no-repeat;
background-size: 100% 100%;
height: 30px;
}
.headerLabels
{
color: white;
font-size: 16px;
line-height: 2em;
padding-left: 10px;
}
Im not sure if any of these styles would be causing the filter div to act like this, but I've been playing around with them with no success. Any tips for tricks for these types of situations would be greatly appreciated, I'm new to dynamically generating elements. Cheers!
Issue 1:
Consider Using the Literal Web Control and putting html elements inside of the text with your desired classes.
var ltl = new Literal();
ltl.ID = "id_ltlName_" + tempFlag;
ltl.Text = $"<div class='class1'>{tempRow[1]}></div><div>{tempRow[2]}";
pnlItem.Controls.Add(ltl);
You could also create an ascx user control, and load instances of that dynamically if you want more functionality inside of the panel.
Issue 2
To add events to a dynamically created control, use the += operator to add a handler to be called when the event is fired. For Example, to handle the CheckChanged event for a checkbox. Remember that with dynamic controls, these event handlers have to be registered on every postback.
var checkbox1 = new CheckBox();
checkbox1.CheckedChanged += ClickedCheckBox;
private void ClickedCheckBox(object sender, EventArgs e)
{
var checkbox1 = sender as CheckBox;
}
Issue 3
You have 2 tds next to each other. Try vertical-align:top on both of them
<div runat="server" id="divSearch" class="divCenterItems">
<table class="searchTable">
<tr style="width: 100%">
<td style="vertical-align:top;width: 29%;">
</td>
<td style="vertical-align:top;width: 69%">
</td>
</tr>
</table>
</div>
Related
What I'd like to do is have something similar to what SO does on the main page:
So, what I did was add this code:
C# Code-Behind:
protected void LoadInterests()
{
//Fill Interests based on table values
string strSQL2 = "SELECT UM.MatchValue, DD.DDLValue FROM tmpUsermatch UM ";
strSQL2 = strSQL2 + "INNER JOIN (SELECT StoredValue, DDLValue FROM tmpDropdowns WHERE ddlName = 'ddlInterests') DD ";
strSQL2 = strSQL2 + "ON UM.MatchValue = DD.StoredValue ";
strSQL2 = strSQL2 + "WHERE MatchField = 'MatchInterests' AND UserID = '" + lblUserID.Text + "'";
using (var con = new SqlConnection(strCon1))
using (var adapter2 = new SqlDataAdapter(strSQL2, con))
{
DataTable dt2 = new DataTable();
adapter2.Fill(dt2);
foreach (DataRow row in dt2.Rows)
{
Label dynamicLabel = new Label();
dynamicLabel.ID = "lbl" + row["DDLValue"].ToString();
dynamicLabel.Text = row["DDLValue"].ToString();
dynamicLabel.CssClass = "lbl.interests";
div1.Controls.Add(dynamicLabel);
}
}
}
asp.net:
<div>
<asp:Panel ID="Panel1" runat="server" Height="100px" ScrollBars="Vertical" Style="float: left; margin-left: 1px; background-color:#f5f5f5" Width="807px" BorderColor="LightSteelBlue" BorderStyle="Solid" BorderWidth="1px">
<div id="div1" runat="server" class="clear" style="width:820px; border-width:1px; margin-left:20px"></div>
</asp:Panel>
</div>
CSS:
lbl.interests
{
background-color: #465c71;
/* background-color: white; */
border: 1px #4e667d solid;
color: white;
display: block;
line-height: 1.35em;
padding: 4px 20px;
text-decoration: none;
white-space: nowrap;
}
The end result is still this:
when I want it to look like this:
Any ideas on where I'm going wrong?
Change the line
dynamicLabel.CssClass = "lbl.interests";
to
dynamicLabel.CssClass = "lbl interests";
AND change CSS selector to
.lbl.interests
Remember . is used for selecting class name only in CSS, it will not be present in HTML, also if you specify just name in css like lbl you are referring to a TAG in HTML which is invalid tag according to HTML and also does match with the code.
My suggestion would be first write plain HTML and CSS and confirm your layout is working as expected, then generate the HTML with C#/ASP.Net
Refer the below link for help on CSS Selectors
W3Schools - CSS Selectors
I am having a problem with how to display a link in Sitecore. Currently I have three fields that I use: Name, Title and Link. All three of these fields are within a div tag, so...
<div class="container">
<div class="name"><sc:FieldRenderer ID="ColumnName" FieldName="Name" runat="server" /></div>
<div class="title"><sc:FieldRenderer ID="ColumnTitle" FieldName="Title" runat="server" /></div>
<div class="link"><sc:FieldRenderer ID="ColumnLink" FieldName="Link" runat="server" /></div>
</div>
For regular view, the link tag is being displayed as just text (that is written in Sitecore) but when it switches to mobile view, the container becomes the link with the Name and Title as the only thing showing and taking away what is in the Link field. My problem is how do I make the container the same link as the one that displays as text in desktop view? Is there a way have the text not be displayed and put an overlay container ontop of everything but just have the background as transparency to make the container go to the same link? For the backend, I just used a Listview that contained everything to make the fields show:
protected void Page_Load(object sender, EventArgs e)
{
Item item = this.DataSourceItem;
lvContains.DataSource = ((MultilistField)item.Fields["Columns"]).GetItems();
lvContains.DataBind();
}
protected void lvContains_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
Item item = (Item)e.Item.DataItem;
((FieldRenderer)e.Item.FindControl("ColumnName")).Item = item;
((FieldRenderer)e.Item.FindControl("ColumnTitle")).Item = item;
((FieldRenderer)e.Item.FindControl("ColumnLink")).Item = item;
}
}
Assuming you are using a responsive design, for the mobile/tablet breakpoints you can add some additional CSS properties to make the link the full height/width of the parent container and hide the text:
.container { border: solid 1px red; position: relative; }
.name { border: solid 1px blue; }
.title { border: solid 1px green; }
.link a {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
font-size: 0;
color: transparent;
}
<div class="container">
<div class="name">Item Name</div>
<div class="title">Item Title</div>
<div class="link">Item Link</div>
</div>
If you are not using a responsive design, and using device detection, then you can add an additional CSS class to the link and modify the css to match:
.link a.mobile {
...
}
And add the CSS Class in code behind:
((FieldRenderer)e.Item.FindControl("ColumnLink")).CssClass = "mobile";
<div class="controls">
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<h1>Create a new event
<asp:TextBox ID="EventName_TB" runat="server" CssClass="control-label"></asp:TextBox>
starting on
<asp:TextBox ID="StartDate_TB" runat="server" Style="color: #727272 !important; font-size: 24px; font-weight: 100;" CssClass="span2 input-xlarge datepicker" placeholder="mm/dd/yy"></asp:TextBox>
for
<asp:DropDownList ID="EventDuration_DDL" runat="server" Style="color: #727272 !important; font-size: 24px; font-weight: 100;" CssClass="span1" AutoPostBack="true">
<asp:ListItem>1</asp:ListItem>
<asp:ListItem>2</asp:ListItem>
<asp:ListItem>3</asp:ListItem>
<asp:ListItem>4</asp:ListItem>
<asp:ListItem>5</asp:ListItem>
<asp:ListItem>6</asp:ListItem>
<asp:ListItem>7</asp:ListItem>
</asp:DropDownList>
days. </h1>
</ContentTemplate>
</asp:UpdatePanel>
</div>
This is my C# code
private void EventDuration()
{
Labeldiv.Controls.Clear();
DateTime dt = DateTime.Parse(StartDate_TB.Text);
int Duration = Int32.Parse(EventDuration_DDL.SelectedItem.ToString());
UpdatePanel up = new UpdatePanel();
up.ID = "UpdatePanel8";
up.UpdateMode = UpdatePanelUpdateMode.Conditional;
for (int id = 0; id < Duration; id++)
{
Label NewLabel = new Label();
NewLabel.ID = "Label" + id;
var eventDate = dt.AddDays(id);
NewLabel.Text = eventDate.ToLongDateString();
CheckBox newcheck = new CheckBox();
newcheck.ID = "CheckBox" + id;
newcheck.AutoPostBack = true;
newcheck.CheckedChanged += new EventHandler(newcheck_CheckedChanged);
up.ContentTemplateContainer.Controls.Add(NewLabel);
this.Labeldiv.Controls.Add(NewLabel);
up.ContentTemplateContainer.Controls.Add(newcheck);
this.Labeldiv.Controls.Add(new LiteralControl("<br/>"));
}
this.Labeldiv.Controls.Add(up);
}
actually it gives the labels & checkboxes according to my condition before I create the Update Panel dynamically...
It gives only one Label & one checkbox. Is this correct way to create Update Panel dynamically?
Create an UpdatePanel instance then create your "child" controls and add them to the Controls collection of the ContentTemplateContainer property of the UpdatePanel. Finally add the UpdatePanel to the Form and you're done. You'll need a on your page.
Check thisLink : Link that shows a simple example.
It could be that you are adding controls at the wrong page event.
Try to use Init or PreInit event.
I have some problems with css that I need help with.
I have the following code:
<div class="UpperClass"></div>
<div class="LowerClass"></div>
Wit the following simple CSS:
.UpperClass{
background-color: red;
width: 50px;
height: 50px;
}
.MiddleClass{
background-color: green;
width: 50px;
height: 50px;
}
.LowerClass{
background-color: blue;
width: 50px;
height: 50px;
}
Now, in code behind I am dynamically adding the middle class div:
int count = 1; //Could be anything
foreach (var item in count)
{
Label placeholder = new Label();
StringBuilder sbExample = new StringBuilder();
sbExample.append("<div class='MiddleClass'></div>");
HtmlString text = new HtmlString(sbExample.ToString());
placeholder.Text = text.ToString();
this.Controls.Add(placeholder);
}
Now, all 3 divs are showing on the page, but the div with the middleclass is behind the upperclass, what I want is the upperclass to come first, then all middleclass divs and below that the lowerclass div, all nicely sorted below each other. How do I do that?
Thanks in advance.
EDIT:
Also, if I want a wrapper around it, how can I place it like this:
<div class="wrapper">
<div class="UpperClass">
</div>
//Middle class here
<div class="LowerClass">
</div>
</div>
On the front end have this:
<div class="UpperClass"></div>
<%= PopulateMiddleClass() %>
<div class="LowerClass"></div>
and on the backend
String PopulateMiddleClass()
{
String ret = "";
//loop through and populate string
return ret;
}
Or
<div class="UpperClass"></div>
<asp:PlaceHolder ID="MyPlaceHolder" runat="server"></asp:PlaceHolder>
<div class="LowerClass"></div>
Then on the backend
Page_Load(object sender, EventArgs e)
{
Literal literal = new Literal();
literal.Text = "<div class='MiddleClass'></div>";
MyPlaceHolder.Controls.Add(literal); // you could loop through and keep adding controls or you could compile them all into the one literal.
}
Hopefully this gets you on your way.
You can create one div with attribute runat="server" and use it as shown below :
Design Page:
<div class="wrapper">
<div class="UpperClass">
</div>
<div runat="server" id="divMiddle">
</div>
<div class="LowerClass"></div>
</div>
Code Behind :
int count = 1; //Could be anything
for (int i = 0; i < count; i++ )
{
Label placeholder = new Label();
StringBuilder sbExample = new StringBuilder();
sbExample.Append("<div class='MiddleClass'></div>");
HtmlString text = new HtmlString(sbExample.ToString());
placeholder.Text = text.ToString();
this.divMiddle.Controls.Add(placeholder);
}
i have written one javascript function to retrieve the position of a button and assigned it to asp:updateprogress but i want to apply the button's position to div element in the code or a label control within the updateprogress not to update progress.
<asp:UpdateProgress ID="UpdateProgress2"
runat="server"
AssociatedUpdatePanelID="SendMailUpdatePanel"
DisplayAfter="0">
<ProgressTemplate>
<div id="blur" style="top: 0px; left: 0px; width: 99%; height: 5000px; position: absolute;background-color: white; z-index: 999; filter: alpha(opacity=50); opacity: 0.5;-moz-opacity: 0.85; padding-top: 25%; padding-left: 30%;" />
<div id="progress" style="text-align: center; width: 444px; border: 1px solid black;padding: 10px; background-color: #eee; z-index: 998; filter: alpha(opacity=500);-moz-opacity: 1.00;">
<b>Mail is being Sent! Please Wait...</b>
<br />
<asp:Image ID="LoadImage"
runat="server"
ImageUrl="~/Images/spinner.gif" />
<br />
</div>
</ProgressTemplate>
</asp:UpdateProgress>
My javascript function is:
function getPosition(btnSendResume, progress)
{
var btnSendRe = document.getElementById(btnSendResume);
var divp = document.getElementById(progress);
divp.style.display="block";
divp.style.left=btnSendRe.offsetLeft;
divp.style.top=btnSendRe.offsetTop + btnSendRe.offsetHeight - 40;
}
I have written following under button click:
btnSendResume.Attributes.Add("onclick", "getPosition('" + btnSendResume.ClientID + "','" + UpdateProgress2.FindControl(progress).ClientID + "');");
But it is giving error that progress doesn't exist under the current context.
Your <div id="progress" is a normal HTML element, not a server-side control.
You should just write document.getElementById("progress").
You can do this by Jquery.
A simple offset() will return left and top position of a control.
function getPosition(btnSendResume, progress)
{
var btnSendReOffset = $('#btnSendResume').offset();
var btnSendRe = $('#btnSendResume');
var divp = document.getElementById(progress);
divp.style.display="block";
divp.style.left=btnSendReOffset.left;
divp.style.top=btnSendReOffset.top+ btnSendRe.height() - 40;
}
You can add a click event to your button on window load and trigger your function.