I have 4 server side ListBox controls. All of them have their Enabled property set to false, yet when rendered they are definitely enabled. They are all multiple select. These have no data binding or any code behind touching them. Below is the markup for all of them (save the ID). I am running v4 of the .NET Framework with IIS6.
<asp:ListBox runat="server" ID="lstProduct" Enabled="false" SelectionMode="Multiple" Rows="6"></asp:ListBox>
Here is the markup that is generated by the runtime:
<select size="6" name="ctl00$ctl00$MainContent$MainContent$lstProduct" multiple="multiple" id="MainContent_MainContent_lstProduct" class="aspNetDisabled">
I found a solution. In the <system.web> section of web.config, you must add <pages controlRenderingCompatibilityVersion="3.5">.
With Asp.net 4.0, any control that does not take specific user input (textbox or password), will not be rendered with a disabled="disabled" attribute when Control.Enabled = false is set.
Try this:
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
this.lstProduct.Attributes.Add("disabled", "");
}
}
To remove it you can just remove the disabled tag like this:
this.lstProduct.Attributes.Remove("disabled");
Write the following line in the .cs file
ListBox.Attributes.Add("disabled", "true");
A better solution is to inherit from the ListBox class and then override the SupportsDisabledAttribute property. Detailed information can be found in MSDN library
e.g.
public class MyListBox : ListBox
{
public override bool SupportsDisabledAttribute { get { return true; } }
}
This should be considered a bug in the .Net Framework.
http://www.asp.net/whitepapers/aspnet4/breaking-changes#0.1__Toc256770141 says:
Controls that are not designed for user input (for example, the Label control) no longer render the disabled="disabled" attribute if their Enabled property is set to false (or if they inherit this setting from a container control).
Also see rationale for the change (rendering valid html) at http://msdn.microsoft.com/en-us/library/system.web.ui.control.renderingcompatibility.aspx.
But a list box is designed for user input and the disbled attribute is supported in html, so it ought to render disabled="disabled".
You can use a little jquery as a bandaid until this is properly fixed. If you put this somewhere that's run for all pages it will fix it for all disabled listboxes on all pages:
$(document).ready(function () {
$("select.aspNetDisabled").attr('disabled', 'disabled');
});
You may wish to instead disable the options within the select box, as this will allow scrolling.
//Listbox cannot be disabled directly, instead the inners should be disabled instead.
foreach(ListItem item in lbCategory.Items)
{
item.Attributes.Add("disabled", "disabled");
if (item.Selected)
{
//cannot reliably style with [disabled='disabled'][selected='selected'] or :checked:selected etc, so need a class
item.Attributes.Add("class", "disabledSelected");
}
}
I then use the following CSS, so the user can still see preselected items.
/* Slightly lighter colour than the normal #3399FF because you cannot change the foreground color in IE, so means that it isn't contrasted enough */
select option.disabledSelected { background-color: #97cbff !important}
Unfortunately from my initial investigations it's a bit of a pain to style disabled input elements in a nice cross browser way. I've setteled with using a class for my purposes, however this article regarding styling disabled form elements might help.
You may also notice that in IE, click events will still be triggered, which seemed to deselect the options but only in some combinations of trying to use [disabled='disabled'][selected='selected'] or :checked:selected etc.
I had the same problem but with CheckBoxList.
Setting its Enabled property to false didn't disable it. The panel it was inside of would also not have an effect on it when Enabled = false.
The solution was to use a foreach loop over the items in the CheckBoxList.
foreach (var item in checkBoxList.Items.Cast<ListItem>())
{
item.Enabled = false;
}
Related
How would you guys conditionally disable checkboxes in an asp treeview?
For instance, if an application user does not have a certain permission, disable that permission entry checkbox in a permissions treeview.
Here's what i'm looking for, this is the equivaqlent in a winform app (the checkboxes are disabled where the text is grayed out):
I saw other solutions where the click event on the checkboxes is intercepted and ignored. I would prefer a solution where the checkboxes are simply set to disabled.
I'm looking for a C# solution but will be happy with a C#/Javascript solution.
Thanks!
Ok, found a fairly clean solution to this:
in code-behind:
TreeNode newNode = new TreeNode(permission.ToString());
newNode.SelectAction = TreeNodeSelectAction.None; // no Link
if (shouldDisableCheckbox)
{
// Set a class so disabled nodes can be formatted thru CSS
// and be identifiable as disabled in Javascript.
newNode.Text = "<span class=disabledTreeviewNode>" + newNode.Text +"</span>";
}
nodes.Add (newNode);
in Javascript, scan all treeview nodes for those that have that className and disable the checkboxes associated to them:
// Called via a startup script created in Code Behind.
// Disables all treeview checkboxes that have a text with a class=disabledTreeviewNode.
// treeviewID is the ClientID of the treeView
function DisableCheckBoxes(treeviewID)
{
TREEVIEW_ID = treeviewID;
var treeView = document.getElementById(TREEVIEW_ID);
if (treeView)
{
var childCheckBoxes = treeView.getElementsByTagName("input");
for (var i = 0; i < childCheckBoxes.length; i++)
{
var textSpan = GetCheckBoxTextSpan(childCheckBoxes[i]);
if (textSpan.firstChild)
if (textSpan.firstChild.className == "disabledTreeviewNode")
childCheckBoxes[i].disabled = true;
}
}
}
function GetCheckBoxTextSpan(checkBox)
{
// Set label text to node name
var parentDiv = checkBox.parentNode;
var nodeSpan = parentDiv.getElementsByTagName("span");
return nodeSpan[0];
}
Sadly, I don't have enough reputation to be able to comment directly on zukanta's answer which is a bit of a pain, but I had to make a modification in the javascript to make this work:
if (textSpan.firstChild)
if (textSpan.className == "disabledTreeviewNode")
childCheckBoxes[i].disabled = true;
i.e. replace textSpan.firstChild.ClassName with textSpan.ClassName
Also worth pointing out that the JavaScript will error out unless all of your tree nodes in the treeview that you are addressing have a
<span></span>
in them. You get a null reference at
if (textSpan.firstChild)
and no subsequent nodes are processed.
I got around this point by adding a span with class=enabledTreeviewNode to all tree nodes that I didn't want disabled.
You could also handle the exception in the JavaScript, I guess.
Hope this helps someone who stumbles across this (otherwise excellent) solution later on.
You could use security trimming to not show items that the user doesn't have access to. I don't know of any way to have the items displayed but not active. Disabling checkboxes on the client side only could create a security hole.
Walkthrough: Filtering Site-Map Nodes Based on Security Roles
ASP.NET Site-Map Security Trimming
The OP was looking for conditional disable but I just want to use the TreeView to display historical audit data, logs of when items were switched on.
All the checkboxes on my page should be disabled. It took me some time to find this elegant jQuery solution. I hope it helps anyone with a similar issue.
Add the code below to your script section. As all input boxes will be disabled, there's no need to make any changes at all to your codebehind.
<script type="text/javascript">
$(document).ready(function () {
$("input:checkbox").each(function () {
$(this).prop('disabled', true);
});
});
</script>
I a have a web form with few textboxes,dropdowns and finally towards the end of the page is 4 custom ajax editors. So on page load the focus is always inside the last editor and no way it comes to the first text box or top of page.On each page load the cursor goes inside the last editor control.How to bring the focus inside the first text box?
Below are the few methods i tried
1.<body onload="document.body.scrollTop = 0;">
2. void Page_Init(object sender, EventArgs e)
{
SetFocus(txtReqtitle);
}
for the above while loading the page i could see the focus goes to the desired text box and then it comes to the last custom control.
3. if(!Page.ClientScript.IsStartupScriptRegistered("scrFocus"))
{
string strScript="var txtBox=document.getElementById('" + txtReqtitle.ClientID.ToString() +"');txtBox.focus();";
ClientScript.RegisterStartupScript(this.GetType(),"scrFocus", strScript,true);
}
4.
function setFocus() {
document.getElementById("txtReqtitle").focus();
}
5. ScriptManager.GetCurrent(this.Page).SetFocus(txtReqtitle);
Any ideas? Thanks..
Seems focus property is not working in load event because of ajax editors
Please add txtReqtitle.Focus() in Page Prerendercomplete() event and let me know whether it works
found the solution which worked for me .would like to share it .. its simple ..just make the autofocus=false for the control.
using jquery
$(document).ready(function(){
$('#<%= txtReqtitle.ClientID %>').focus();
});
I have created simple controls that are based on dot net controls . For example there is a simple GridView control that is based on dot net GridView control , I just set some setting in my control to use it in my .aspx pages , for example I set the Width of GridView in the constructor method :
// constructor of my custom class
public GridView(): base()
{
this.Width = new Unit(100, UnitType.Percentage);
}
and also I've added some custom properties :
public int SelectedID
{
get
{
if (ViewState["SelectedID" + this.ID] == null)
ViewState["SelectedID" + this.ID] = "-1";
return Convert.ToInt32(ViewState["SelectedID" + this.ID]);
}
set
{
ViewState["SelectedID" + this.ID] = value;
}
}
The *Problem* : when I use Tools>Generate Local Resource in VS2010
the aspx markup before I use this tool is like this :
<RPC:GridView ID="grdData" runat="server" onrowcommand="grdData_RowCommand">
but this tool adds any public property or any setting to my aspx markup , like this :
<RPC:GridView ID="grdData" runat="server" onrowcommand="grdData_RowCommand"
meta:resourcekey="grdDataResource1" SelectedID="-1" Width="100%">
I don't like VS2010 add my settings (like width) and my custom properties (like SelectedID) to aspx markup , this prevent me having the ability of changing my custom control code and reflect changes in all aspx pages that include this control , for example if
I change the width of my control to 50% , it doesn't reflect to any pages
Please tell me what should I do to fix my problem
Thank you very much for your feedbacks
This is a slightly complicated topic to address in one answer here to be honest! There are more than one approaches you can take to resolve this problem. It all depends on the kind of properties your control has and if it is a templated control or not. As a quick fix try decorating your public properties with the following attribute
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
or if you don't want the user to be able to set the public property at all via HTML markup then use
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
another attribute declaration which will be helpful with
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
is
PersistenceMode(PersistenceMode.Attribute)
I've found doing any initialisation in the ctor causes major headaches for local resource generation (even corruption). Use the DefaultValue attribute on properties and/or use OnLoad if possible. (As a side note use CSS rather than explicitly setting control width).
The Scenario: I have an asp.net website where I show a div popup on page load for taking a few user details. When a user inputs the details, or closes the popup, I set up a flag cookie so that the popup is not displayed again for the user. The div is in the MasterPage so that it is displayed no matter on which page a user lands first time. The div contains an UpdatePanel which has all the controls required for taking the details. This whole functionality is working fine.
The Problem: Now this div popup is not showing(by setting display:none) on subsequent postbacks(which I want), but the html markup is still loading with the page unnecessarily adding to the page size. What I would idealy want to do is: Check if flag cookie is set. If no, show the popup, else remove the popup's markup from the page.
Now since the div is not a server control, I cannot possibly remove it and the all the controls inside it. So, I thought of removing the UpdatePanel from the page:
protected void Page_Load(object sender, EventArgs e)
{
if (Request.Cookies["flag"] != null)
{
if (Page.Controls.Contains(updpnl_contact))
{
Page.Controls.Remove(updpnl_contact);
updpnl_contact.Dispose();
}
}
}
But I guess this tends to work with dynamically added controls only, and since the control is added at Design Time, it is not being removed.
Is there any way I can achieve this?
If you add a runat="server" attribute to your <div> element, it will be available in the code-behind. You'll need an id on it as well. Then you can just toggle the Visible property. If this property is false, the control won't be rendered to the client (i.e. no HTML markup).
What you're trying to do is not at all the usual workflow. I tend to think that it will not work as it would mess up control tree, maybe even corrupt the viewstate and so on.
As a possible solution, you can put it's visibility to hidden in the code behind. This, in the contrary to the usual 'gut feeling', doesn't work like the css propery 'display:none' for example - instead the control will not even be rendered into the page when it's not visible. This may be the workaround for you.
Happy coding.
A more efficient approach would be to create the panel as a UserControl and load it dynamically in codebehind when it's needed, then add it to your page. E.g, in code:
MyPopupControl popup = (MyPopupControl)Page.LoadControl("/path/to/usercontrol.ascx");
PopupPanel.Controls.Add(popup);
Where PopupPanel is an empty <asp:Panel>. Then, not even the markup will need to be loaded/processed except when its needed.
There is no reason that all the code you use to display and process this panel couldn't also be in the usercontrol, isolating it from the master page.
Can you build the panel dynamically, based on the cookie setting?
I got this Text box with default value as "First Name" ..Now when I click inside this text box to enter name , this value "First Name" keeps on displaying. What I want is to the text box to clear as soon as I click inside it. What property do I need to set in mt textbox tag ?
[Edit]
ok anything from Telerik that I can use to do that ?
There is not out of the box functionality in TextBox that will accomplish this, but the ASP.Net Ajax Toolkit has a Watermark Extender that will do everything you want.
I have used both, but now personally use a jQuery Watermark Plugin
Either will work just fine, choose based on your needs.
According to the Telerik docs you just have to set the EmptyMessage property on their TextBox control. Demo Page Here
In the code behind, on Page Load you can add the following code to achieve this
TextBox1.Attributes.Add("onClick", "javascript:if(this.value=='First Name'){this.value='';}");
You can use the method suggested by #Josh. If you do not want to use Ajax Toolkit controls or JQuery you could write it on your own using Javascript. Write a function which gets called when the foucs is received by the textbox control. I thik the function is called onfocus or just focus in Javascript.
Hi I just wrote this small function which will achieve your desired result
function clearInputBox(x,prefil){
if(x.value == prefil){
x.value = '';
}
}
Your input box looks like this
<input type='text' value='First Name' onfocus="clearInputBox(this,'First Name')" />
May be this will help you
Taking Shobans advice one step farther, you could add something like this to your Page subclass
protected override void OnInitComplete(EventArgs e)
{
string jsString = "javascript:if(this.value=='" + TextBox1.Text + "'){this.value='';}";
TextBox1.Attributes.Add("onFocus", jsString);
base.OnInitComplete(e);
}
What this will do is, it will always consider that default string is the one this controll contains at esign time (the initial one in your .aspx file), so you wont have to manually change it in codebehind every time you change your .aspx. Remember, that OnIinitComplete fires before any viewstate or postback data has been applied, but after the controlls on your page have been set to their default values.
P.S. As anishMarokey pointed, use onFocus vs onClick, since fields can gain focus without clicks via Tab key.