Hide / Replace ASP.NET WebForms Controls - asp.net

I am working on a project that requires that the programmers can add asp:hyperlinks to the pages, but I want to replace those with a custom spun asp:hyperlink which checks before render if the end user has a role or not.
So basically I need a way to tell the asp application that where it renders asp:hyperlink to actually render mycontrols:customhyperlink. Is there a way to make it so that the asp:hyperlink goes to my control library instead of System.Web.UI?

I'm going to assume/suggest that you perform the user-check in the code behind. In that case, you could simply have the two controls right next to each other and only make one visible. For example, in the web-form (aspx):
<asp:Hyperlink ID="Link1" ... />
<asp:CustomHyperlink ID="CustLink1" .../>
Then in the code-behind:
if (user.HasRole) {
CustLink1.Visible = true;
Link1.Visible = false;
}
else {
CustLink1.Visible = false;
Link1.Visible = true;
}

Related

MasterPage with slight modification. Do I need to create a new one?

Working on a ASP.NET webform project. I have a MasterPage which works fine for 99% of my pages. However, on one page where I use a GridView, I need a slighty altered version of this MasterPage. I basically need to remove a few lines off of it:
<%--<div id="pageContentInner">--%>
<asp:ContentPlaceHolder ID="MainContent" runat="server"/>
<%--</div>--%>
Do I need to create a completely separate MasterPage or is there a way to disable that part only for that one page ?
Creating another MasterPage is probably the right way to go. Although you could do something like this:
Change your MasterPage div that needs to be invisible to a Panel.
Add a Property in the MasterPage to toggle visibility of that Panel:
public bool PageContentInnerViewable
{
get
{
return PageContentInner.Visible;
}
set
{
PageContentInner.Visible = value;
}
}
Change the visibility in page code-behind
this.Master.PageContentViewable = false;

ASP.Net FormsAuthentication Rememberme

I am using forms authentication in a web application using the built-in Login capabilities, and it has been working well.
I would like to set DisplayRememberMe.visible to false depending on certain conditions (e.g. which Server, ip address, etc). Of course I can manually add visible="false" to the markup shown here, but that seems like a poor way to go.
<asp:CheckBox ID="RememberMe" runat="server" />
<asp:Label ID="RememberMeLabel" runat="server" AssociatedControlID="RememberMe"
CssClass="inline" >Keep me logged in</asp:Label>
Also, I can't figure out which asp field has the DisplayRememberMe field.
But more importantly, in the code behind file, I have added LoginUser.DisplayRememberMe = False, but it is ignored, and the label and checkbox are still visible. I have tried adding it to various events like Page.Load, Page.Init, Login_User.Init, Login_User.Prerender, but the checkbox and label are still visible after the page loads.
Am I using the proper call? Where should I place it to be effective?
This is my first post on SO, so please excuse any poor etiquette.
You can change visibility of CheckBox and Label by creating event of login control as
OnLoad="LoginUser_OnLoad"
On .cs page
protected void LoginUser_OnLoad(object sender, EventArgs eventArgs)
{
var login = (System.Web.UI.WebControls.Login)sender;
var checkbox = login.FindControl("RememberMe");
checkbox.Visible = false;
var label = login.FindControl("RememberMeLabel");
label.Visible = false;
}
You can also put your visibility conditions in LoginUser_OnLoad method.

How to set focus to a web control in ASP.NET

Question: What is the best way to set focus to a web control in ASP .NET.
I can do it, but it's ugly. I have a web control wrapped in a web control hosted on a web page. So, if you do a view | source on the page the id is something like WrapperControl_Control_TextBox.
I've tried the "tried and true" Javascript methods of grabbing the element and setting it's focus: document.getElementByID( "WrapperControl_Control_TextBox" ).focus(); and it didn't work. I'm not sure why.
I know I could possibly do:
document.getElementById( "<%= TextBox.ClientID %>" ).focus(); too, I think. This won't work because of another totally separate error based on the fact you can't dynamically add controls to a header if there is a "<% %>" in the page. GAH.
In the "bottom-most" control, I've tried setting the focus (TextBox.Focus() in Page_Load) and that doesn't work either.
Anyway, the way that works is by simply taking the ControlsCollection of the Page, grabbing the control I need from that, getting it's collection, grabbing the next lower control and so forth.
I only have to do this seven times. So I have eight foreach loops.
Basically, my code is like this:
///////////////////////////////
// On the page
///////////////////////////////
ControlCollection controls = Controls;
foreach( Control control in controls)
{
if ( string.Equals( control.ID, "FormID", StringComparison.InvariantCultureIgnore ) )
{
ControlCollection nextControls = control.Controls;
foreach( Control nextControl in nextControls )
{
if ( string.Equals( nextControl.ID, "DivICareAboutInTheForm", StringComparison.InvariantCultureIgnor ) )
{
ControlCollection nextNextControls = nextControl.Controls;
//:
//:
//Yes, it's that bad and so forth.
//:
//:
}
}
}
}
You can use jQuery to do a search for IDs that end with your textbox name. This way you wont have to call the UniqueID server-side code. Just make sure not to have multiple controls that end with the same name
<script type="text/javascript">
$(document).ready(function() {
$('[id$=txtBox]').focus();
});
</script>
Or, you can use a Class name for the default text box.
<asp:Textbox ID="txtBox" runat="server" cCssClass="defaultTextbox" />
jquery:
$('.defaultTextbox').focus();
You can get around the "cannot add dynamic controls because a <%= %> block exists on the page" error by changing the block to use databinding syntax: <%# TextBox.ClientID %>, and manually calling Page.DataBind() in Page_Load.
If you really want to use the Page_Load method, then you could always call the SetFocus method on the Page object.
Page.SetFocus(myTextBox);

Add client side javascript code and ASP.Net validation on a asp.net button

I wanted to write javascript code on "OnClientClick" of the asp.net button and also I want the asp.net validation to be run for that button. but when i mix these both validation is not working. please help me out. Below is my code
ASPX
<asp:Button ID="btnAddToFeatureOffers" runat="server" Text="Add to Feature Offers"
OnClick="btnAddToFeatureOffers_Click" ValidationGroup="vgAddOffer" OnClientClick="add();" />
javascript
function add() {
var selectedOrder = $('#ctl00_MainContent_ddlFeaturedHostingType option:selected')[0].index;
var offer = $('#<%=txtOrder.ClientID%>').val();
var a = $("<a>").attr("href", "#").addClass("offer").text("X");
$("<div>").text(offer).append(a).appendTo($('#resultTable #resultRow td')[selectedOrder - 1]);
}
Try giving a return false or return true inside the function add based on your validation result.
Also no need to write selector like this
$('#resultTable #resultRow td')
Simply write
$('#resultRow td')

ASP.Net - repeating input boxes on the client side using Repeater

I have the following requirement for creating a user profile in my application:
User should be able to enter multiple phone numbers/email addresses in his profile.
The screen looks somewhat like this:
- By default, on page load a single textbox for phone and email are shown.
- User can click a "+" button to add additional numbers/addresses.
- On clicking the "+" button we need to add another textbox just below the first one. User can add as many numbers/addresses as he wants. On submit, the server should collect all numbers/emails and save it in DB.
I tried using the Repeater control to do this. On page_load I bind the repeater to a "new arraylist" object of size 1. So, this renders fine - user sees a single textbox with no value in it.
When he clicks the "+" button, I ideally want to use javascript to create more textboxes with similar mark-up as the first.
My questions are these:
Can I render the new textboxes anyway using js? I notice that the HTML rendered by the repeater control is somewhat complex (names/ids) etc. and it might not be possible to correctly create those controls on client-side.
If there is a way to do #1, will the server understand that these additional inputs are items in the repeater control? Say, I want to get all the phone numbers that the user entered by iterating over Repeater.DataItems.
Conceptually, is my approach correct or is it wrong to use the Repeater for this? Would you suggest any other approach that might handle this requirement?
Coming from a Struts/JSP background, I am still struggling to get a grip on the .NET way of doing things - so any help would be appreciated.
The repeater control may be a bit of overkill for what you're trying to accomplish. It is mainly meant as a databound control for presenting rows of data.
What you can do is to dynamically create the boxes as part of the Page_Load event (C#):
TestInput.aspx :
<form id="form1" runat="server">
<asp:HiddenField ID="hdnAddInput" runat="server" />
<asp:Button ID="btnPlus" OnClientClick="setAdd()" Text="Plus" runat="server" />
<asp:PlaceHolder ID="phInputs" runat="server" />
</form>
<script type="text/javascript">
function setAdd() {
var add = document.getElementById('<%=hdnAddInput.ClientID%>');
add.value = '1';
return true;
}
</script>
TestInput.aspx.cs:
protected void Page_Load(object sender, EventArgs e)
{
if (ViewState["inputs"] == null)
ViewState["inputs"] = 1;
if (hdnAddInput.Value == "1")
{
ViewState["inputs"] = int.Parse(ViewState["inputs"].ToString()) + 1;
hdnAddInput.Value = "";
}
for (int loop = 0; loop < int.Parse(ViewState["inputs"].ToString()); loop++)
phInputs.Controls.Add(new TextBox() { ID = "phone" + loop });
}
I ended up using a PlaceHolder to dynamically add the text boxes and a HiddenField to flag when another TextBox needed to be added. Since the IDs were matching, it maintains the ViewState of the controls during each postback.
Welcome to the hairball that is dynamically-added controls in ASP.NET. It's not pretty but it can be done.
You cannot add new fields dynamically using javascript because the new field would have no representation in the server-side controls collection of the page.
Given that the requirements are that there is no limit to the number of addresses a user can add to the page, your only option is to do "traditional" dynamic ASP.NET controls. This means that you must handle the adding of the control server-side by new-ing a new object to represent the control:
private ArrayList _dynamicControls = new ArrayList();
public void Page_Init()
{
foreach (string c in _dynamicControls)
{
TextBox txtDynamicBox = new TextBox();
txtDynamicBox.ID = c;
Controls.Add(txtDynamicBox);
}
}
public void AddNewTextBox()
{
TextBox txtNewBox = new TextBox();
txtNewBox.ID = [uniqueID] // Give the textbox a unique name
Controls.Add(txtNewBox);
_dynamicControls.Add([uniqueID]);
}
You can see here that the object that backs each dynamically-added field has to be added back to the Controls collection of the Page on each postback. If you don't do this, data POSTed back from the field has nowhere to go.
If you want to user the repeater, I think the easiest way is to put the repeater in a ASP.Net AJAX update panel, add the extra textbox on the sever side.
There are definitely other way to implement this without using repeater, and it maybe much easier to add the textbox using js.
No, but you can create input elements similar to what TextBox controls would render.
No. ASP.NET protects itself from phony data posted to the server. You can't make the server code think that it created a TextBox earlier by just adding data that it would return.
The approach is wrong. You are trying to go a middle way that doesn't work. You have to go all the way in either direction. Either you make a postback and add the TextBox on the server side, or you do it completely on the client side and use the Request.Form collection to receive the data on the server side.

Resources