how to avoid inline code in .aspx .ascx - asp.net

I have a usercontrol (.ascx) like this:
<% if (HasAccessMediaPlans) { iPortletCounter++; %>
<div class="orange-portlet-box">
<div class="HomeModulePortletTitle">Plans</div>
<p>Create // Edit // Review</p>
</div>
<div style="clear: both;"></div>
<% } %>
where HasAccessMediaPlans is a variable defined in user control's code behind(.ascx.cs) and it's assigned in page load.
protected Boolean HasAccessMediaPlans = false;
protected void Page_Load(object sender, EventArgs e) {
HasAccessMediaPlans = SessionState.CurrentUser.HasModuleAccess(MediaString + " Plans");
}
My question is: how can I avoid inline server code embeded in <% %> at my usercontrol markup(.ascx) ?

You can wrap this piece of code with a server side container control (say <div id="wrapper" runat="server">) and on the server side assign its visibility properties in the wanted manner.
This avoids littering your .aspx/.ascx files with code and keeps code in the code-behind file.

<div class="orange-portlet-box" id="dvBox" runat="server">
<div class="HomeModulePortletTitle">
<a id="aLink">Plans</a>
</div>
<p>Create // Edit // Review</p>
</div>
<div style="clear: both;"></div>
In code behind
Boolean HasAccessMediaPlans = false;
protected void Page_Load(object sender, EventArgs e)
{
HasAccessMediaPlans = SessionState.CurrentUser.HasModuleAccess(MediaString + "Plans");
dvBox.Visible = HasAccessMediaPlans;
aLink.HREF = RootPath + "MediaPlanning/Default.aspx";
}

Related

Custom Panel didn't render well

I'm trying to customize the rendering of an ASP.NET Panel in this way...
[DefaultProperty("ID")]
[ToolboxData("<{0}:NFormPanel runat=server></{0}:NFormPanel>")]
[Description("Aldammam panel.")]
[ParseChildren(false)]
[PersistChildren(true)]
public class NFormPanel : Panel, INamingContainer
{
protected override void RenderContents(HtmlTextWriter output)
{
var sb = new StringBuilder();
sb.AppendLine("<table class=\"con-table\" style=\"width: 100%;\">");
output.Write(sb.ToString());
if (HasControls())
{
this.RenderChildren(output);
}
sb.Clear();
sb.AppendLine("</table>");
output.Write(sb.ToString());
}
}
...but the output renders the panel controls first then renders the table, like this...
<div>
<input name="TextBox1" type="text" id="TextBox1">
<table class="con-table" style="width: 100%;">
</table>
</div>
I would like the child controls inside the table as in the example below...
<div>
<table class="con-table" style="width: 100%;">
<input name="TextBox1" type="text" id="TextBox1">
</table>
</div>
Use the render method instead:
protected override void Render(HtmlTextWriter output)
{
var sb = new StringBuilder();
sb.AppendLine("<table class=\"con-table\" style=\"width: 100%;\">");
output.Write(sb.ToString());
if (HasControls())
{
//Alternatively call base.Render() which renders the panel's DIV
this.RenderChildren(output); //renders inner children only without panel DIV
}
sb.Clear();
sb.AppendLine("</table>");
output.Write(sb.ToString());
}

asp.net Disable master page menu

Im working with asp.net and c#.
I have a master page and many aspx pages that use it.
The master page has a menu defined which is inside an unordered list(html).
I want to be able to disable the menu from the master page, from one of the aspx pages(lets call it page1), when the page1 loads.
<ul class="menu" id="menu" runat ="server">
<li>
Mant
<ul>
<li>Table</li>
</ul>
</li>
</ul>
How can I do that?
Thanks.
If you want to disable list from master page, then you can use this code in master page's Load event.
protected void Page_Load(object sender, EventArgs e)
{
if(ContentPlaceHolder1.Page.GetType().Name=="webform1_aspx")
{
ContentPlaceHolder1.Page.ClientScript.RegisterStartupScript(GetType(), "key", "javascript: document.getElementById('menu').style.visibility = 'hidden';", true);
}
}
If you want to use it in content page's load event then use this
ClientScript.RegisterStartupScript(GetType(), "key", "javascript: document.getElementById('menu').style.visibility = 'hidden';",true);
And menu is like this.
<ul id="listMenu" runat="server">
<li></li>
</ul>
You can access from content page like this :
MasterPagename ms = Master as MasterPagename ;
ms.NavigatorMenu.Items[0].disabled = true;
I think you can use content place holders:
Ex Master Page:
Add:
<asp:contentplaceholder id="Menu" runat="server">
<!-- Menu here -->
</asp:contentplaceholder>
In Content Pages(Page1 in your example) where you dont want to show menu add following tag and remove this from all content pages where you want menu to show:
<asp:Content ID="menuContent1" ContentPlaceHolderID="Menu" Runat="Server">
</asp:Content>
To find menu items in content page and disable it on pageload()
protected void Page_Load(object sender, EventArgs e)
{
Menu mainMenu = (Menu)Page.Master.FindControl("NavigationMenu");
foreach (MenuItem m in mainMenu.Items)
{
m.Enabled = false;
}
}

Jquery datepicker with entity framework

<form id="Form1" runat="server">
**<input type="text" id="DateInput" />**
<asp:Repeater ID="DataViewer" runat="server">
<ItemTemplate>
<div style='border: 1px; width: 600px; overflow-x: auto; overflow-y: hidden;'>
<div style='float: left;'>
<%# Eval("DriverName") %> </div>
</div>
</ItemTemplate>
</asp:Repeater>
this is my function:
protected void Page_Load(object sender, EventArgs e)
{
OrderDataRepository rep = new OrderDataRepository();
var results = rep.GetAllOrderData().Where(x => x.POD_DATE == ????????????????).
GroupBy(o => o.User).
Select(g =>
new
{
DriverId = g.Key.Id,
DriverName = g.Key.Name,
OrderCount = g.Count(),
OrderCountWhereNameIsNotNull =
g.Count(o => o.RECEIVE_NAME != null)
}).ToList();
DataViewer.DataSource = results;
DataViewer.DataBind();
}
at the moment i get all the results from the table,
i want to add Datepicker for jQuery http://keith-wood.name/datepick.html
<script src="Scripts/jquery.js" type="text/javascript"></script>
when user will pick a day it needs to load all the results for the day that the user picked
please show me how it should be done using jquery with entity framework
You'll need a function in your repository some thing like:
Function SelectOrdersByDate(date as string) as ienumerable(of Order)
Using yourcontext as new context
Dim query = yourcontext.Orders.Where(function(o) o.OrderDate = date).ToList
return query
End Using
End Function
Then call this function via ajax/jquery

ASP.NET Decimal.Parse()

I have problem in webpage , Visual Studio claims that problem is with this line decimal newAmount = PLNamount * Decimal.Parse(item.Value);. The solution is crushed when I choose the Current (web page is simple current converter) .
this is listing of CurrencyConverter.aspx.cs
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
public partial class CurrencyConverter : System.Web.UI.Page
{
protected void Page_Load(Object sender, EventArgs e)
{
if (this.IsPostBack == false)
{
// The HtmlSelect control accepts text or ListItem objects.
Currency.Items.Add(new ListItem("Euros", "0.25"));
Currency.Items.Add(new ListItem("US Dollar", "0.32"));
Currency.Items.Add(new ListItem("British Pound", "0.205"));
}
}
protected void Convert_ServerClick(object sender, EventArgs e)
{
decimal PLNamount;
bool success = Decimal.TryParse(PLN.Value,out PLNamount);
if (success)
{
PLNamount = Decimal.Parse(PLN.Value);
ListItem item = Currency.Items[Currency.SelectedIndex];
decimal newAmount = PLNamount * Decimal.Parse(item.Value); //prollematic line
Result.InnerText = PLNamount.ToString() + " Polish PLN = ";
Result.InnerText += newAmount.ToString() + " " + item.Text;
}
else Result.InnerText = "Invalid content";
}
}
This is listing of CurrencyConverter.aspx
<%# Page Language="C#" AutoEventWireup="true"
CodeFile="CurrencyConverter.aspx.cs" Inherits="CurrencyConverter" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Currency Converter</title>
</head>
<body>
Simple Currency Converter in ASP.NET web forms <br />
<form id="Form1" runat="server">
<div>
Convert:
<input type="text" ID="PLN" runat="server" />
Polish PLN to Euros.
<select ID="Currency" runat="server" />
<br /><br />
<input type="submit" value="OK" ID="Convert" runat="server"
OnServerClick="Convert_ServerClick" />
<br /><br />
<div style="font-weight: bold" ID="Result" runat="server"></div>
</div>
</form>
</body>
</html>
This Code is changed listing from apress "Pro ASP.NET 3.5 in C# 2008, Second Edition" (original version) from chapter 5. Link to source code apress.com/book/downloadfile/3803 . I have exactly the same problem in the same line
Original source code from the book
aspx
<%# Page Language="C#" AutoEventWireup="true"
CodeFile="CurrencyConverter.aspx.cs" Inherits="CurrencyConverter" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Currency Converter</title>
</head>
<body>
<form ID="Form1" method="post" runat="server">
<div style="border-right: thin ridge; padding-right: 20px; border-top: thin ridge;
padding-left: 20px; padding-bottom: 20px; border-left: thin ridge; width: 531px;
padding-top: 20px; border-bottom: thin ridge; font-family: Verdana; background-color: #FFFFE8">
Convert:
<input type="text" ID="US" runat="server" style="width: 102px" /> U.S. dollars to
<select ID="Currency" runat="server" />
<br /><br />
<input type="submit" value="OK" ID="Convert" runat="server" OnServerClick="Convert_ServerClick" />
<input type="submit" value="Show Graph" ID="ShowGraph" runat="server" OnServerClick="ShowGraph_ServerClick" />
<br /><br />
<img ID="Graph" alt="Currency Graph" scr="" runat="server" />
<br /><br />
<div style="font-weight: bold" ID="Result" runat="server"></div>
</div>
</form>
</body>
</html>
aspx.cs
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
public partial class CurrencyConverter : System.Web.UI.Page
{
protected void Page_Load(Object sender, EventArgs e)
{
if (this.IsPostBack == false)
{
// The HtmlSelect control accepts text or ListItem objects.
Currency.Items.Add(new ListItem("Euros", "0.85"));
Currency.Items.Add(new ListItem("Japanese Yen", "110.33"));
Currency.Items.Add(new ListItem("Canadian Dollars", "1.2"));
}
Graph.Visible = false;
}
protected void Convert_ServerClick(object sender, EventArgs e)
{
decimal amount;
bool success = Decimal.TryParse(US.Value, out amount);
if (success)
{
// Retrieve the selected ListItem object by its index number.
ListItem item = Currency.Items[Currency.SelectedIndex];
decimal newAmount = amount * Decimal.Parse(item.Value);
Result.InnerText = amount.ToString() + " U.S. dollars = ";
Result.InnerText += newAmount.ToString() + " " + item.Text;
}
else
{
Result.InnerText = "The number you typed in was not in the correct format. ";
Result.InnerText += "Use only numbers.";
}
}
protected void ShowGraph_ServerClick(object sender, EventArgs e)
{
Graph.Src = "Pic" + Currency.SelectedIndex.ToString() + ".png";
Graph.Visible = true;
}
}
Problem solved
This is link to print screen with this error. http://img210.imageshack.us/f/currencyerror.png/
I think the answer is localisation based. I suspect you are parsing "0.25" as a decimal in your a culture style which uses commas as decimal separators. What you need to do is to specify what style the numbers are in so that it interprets them correctly. One way to do this is:
decimal newAmount = PLNamount * Decimal.Parse(item.Value, CultureInfo.InvariantCulture.NumberFormat)
Hopefully people will comment if there is a nicer way of doing it.
Hope that helps. I've not confirmed that this is definitely your problem but if I try to parse the number as pl-PL (just guessing you are polish from the page) then it fails for me on that line you quoted so I reckon I'm on the right lines. :)
Edit to add: The other option is to change your dropdown to have values like "0,25" which should parse correctly. However, I personally would prefer to use the CultureInfo option.
Interestingly when I enter numbers into the box on the page it seems to recognise "0.9" and "0,9" as the same thing. Not sure why it works there but I guess its related to tryParse and Parse workign subtly differently.
You don't need to do both:
bool success = Decimal.TryParse(PLN.Value,out PLNamount);
if (success)
{
PLNamount = Decimal.Parse(PLN.Value);
If the TryParse succeeded then PLNamount will contain the correct value. Check the MSDN documentation for TryParse.
Also:
ListItem item = Currency.Items[Currency.SelectedIndex];
decimal newAmount = PLNamount * Decimal.Parse(item.Value); //prollematic line
if the value in item isn't a string representing a number Parse will throw an exception. For safety you should use TryParse on this value as well (if it's not already a numeric type of course).
you should delete the following line
PLNamount = Decimal.Parse(PLN.Value);
if(success) ... then PLNamount are already parsed, it is an out parameter...
Parse throws an exception if the value being parsed isn't a decimal. TryParse is safer in that respect; it returns a bool if it is a decimal, and returns the value through an output parameter, but you should check that TryParse returns true.
if (decimal.TryParse("12", out decValue)) { .. }
Using TryParse for the item check, where the error occurs, too may help...
The problem is't solved .
item.Value is string in 100% //debuger confirms that.
I don't know what I have to do.
the answer is this, assuming it's a value from a DropDown that always contains percentages.
decimal ItemValue = Decimal.Parse(Item.Value.Substring(0, Item.Value.IndexOf('%')));
It strips the % from the string and then converts the remainder to a decimal.
If you look at your debug, item.value = "US Dollar". This is a string value, you've probably want the "Text" property.

ASP.NET: User control with access to the controls that it wraps

I have a bunch of occurrences of this kind of boilerplate code in my ASP.NET project.
<div class="inputfield">
<div class="tl">
<span class="tr"><!-- --></span>
<span class="ll"><!-- --></span>
<div class="lr">
<div class="cntnt">
<asp:TextBox .../>
</div>
</div>
</div>
</div>
As you may have guessed, everything in that snippet is pure boilerplate except for the innermost text field.
What is the best way to avoid such boilerplate in ASP.NET? In e.g. Django I would make a custom tag for it, as such:
{% boiler %}
<input ... />
{% endboiler %}
I was thinking that maybe I can create a user control, but all the tutorials on ASP.NET user controls that I've found are very simplistic and "self-closing", i.e. they are not aware of the contents of the tag. I need something along the lines of:
<Hello:MyControl>
<asp:TextBox .../>
</Hello>
So my question is the following: what's the best way to avoid the boilerplate?
You can use an ITemplate property. Thus, you can inject different content in different situations.
[PersistChildren(false), ParseChildren(true, "ContentTemplate")]
public partial class WebUserControl1 : System.Web.UI.UserControl
{
[System.ComponentModel.Browsable(false), System.Web.UI.PersistenceMode(PersistenceMode.InnerProperty)]
public ITemplate ContentTemplate { get; set; }
protected override void CreateChildControls()
{
if (this.ContentTemplate != null)
this.ContentTemplate.InstantiateIn(this);
base.CreateChildControls();
}
}
Put the asp:TextBox in your user control, along with the other html tags. Provide properties on your user control that match the properties of the text box, so that you would do something like this:
<Hello:MyControl ID="myControl" runat="server" Width="300px" MaxLength="30" />
and then the width and maxlength properties would just get transferred to the internal textbox.
You could also provide access to the textbox from the usercontrol and set all the properties in the code behind.
Create a class like this:
[PersistChildren(false), ParseChildren(true, "ContentTemplate")]
public class CustomContent:WebControl
{
[System.ComponentModel.Browsable(false), System.Web.UI.PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public ITemplate ContentTemplate { get; set; }
private PlaceHolder m_placeHolder;
protected override void CreateChildControls()
{
m_placeHolder = new PlaceHolder();
if (this.ContentTemplate != null)
this.ContentTemplate.InstantiateIn(m_placeHolder);
Controls.Add(m_placeHolder);
}
protected override void RenderContents(HtmlTextWriter writer)
{
writer.Write(#"<div class=""inputfield"">
<div class=""tl"">
<span class=""tr""><!-- --></span>
<span class=""ll""><!-- --></span>
<div class=""lr"">
<div class=""cntnt"">
");
base.RenderContents(writer);
writer.Write(#" </div>
</div>
</div>
</div>
");
}
}
This class isn't a "User Control" it's a "Server Control". You can do the same thing with a user control but you'll have issues with the designer. This will work in the designer.
And you can put markup like this in your ASPX:
<uc1:CustomContent runat="server" ID="content">
<asp:textbox runat="server"></asp:textbox>
</uc1:CustomContent>
don't forget the Register page declaration at the top of the aspx
<%# Register tagprefix="uc1" Assembly="Assembly where CustomContent is" Namespace="namespace where CustomContent is" %>
You can put whatever you want inside the uc1:CustomContent tags and it will render that boilerplate html around it. If you are curious about how ITemplate works, there are plenty of articles on msdn, etc.

Resources