问题
When using an ASP.NET CheckBox
(and in out case, inherited from a CheckBox
) it renders a span around the checkbox input control, this span control is affecting jQuery scripts.
Is it possible to remove this span when rendering?
回答1:
Found this useful tip:
In Code Behind, use InputAttributes instead of Attributes.
For Example, type this:
chk.InputAttributes.Add("onchange", "updateFields()")
instead of this:
chk.Attributes.Add("onchange", "updateFields()")
or instead of inline declarations:
<asp:CheckBox ID="chk" runat="server" onchange="updateFields()" />
The last two will cause the wrapping span.
回答2:
I just tried this on a test page and I'm not getting the around my CheckBox controls... are you sure it's the CheckBox that's rendering this? Is it conditional?
UPDATE: OK, it appears to be conditional on whether or not the CheckBox has extra attributes, including a CssClass setting... or a "disabled" attribute.
回答3:
I don't know if this will work on this particular example. But if you make your own WebControl and you never want it to render spans around itself you can override the Controls render method like this:
public class MyWebControl : WebControl
{
/* Your code
between here */
protected override void Render(HtmlTextWriter writer)
{
RenderContents (writer);
}
}
I guess that you could add the same to an inherited CheckBox... something like this:
public class MyCheckBox : CheckBox
{
/* Your code
between here */
protected override void Render(HtmlTextWriter writer)
{
RenderContents (writer);
}
}
The basic problem with the solution is better explained here:
http://www.marten-online.com/net/stripping-span-tag-from-webcontrol.html
回答4:
I spent the last 3 hours pulling my hair to find a solution at this problem.
Here is what came out:
using System.Web.UI;
using System.Web.UI.WebControls;
/// <summary>
/// Represents a custom checkbox web control.
/// Prevents itself to be wrapped into a <span> tag when disabled.
/// </summary>
public class CustomCheckBox : CheckBox
{
/// <summary>
/// Renders the control to the specified HTML writer.
/// </summary>
/// <param name="writer">The HtmlTextWriter object that receives the control content.</param>
protected override void Render(HtmlTextWriter writer)
{
// Use custom writer
writer = new HtmlTextWriterNoSpan(writer);
// Call base class
base.Render(writer);
}
}
Along with the custom control, you'll need a custom HtmlTextWriter:
using System.IO;
using System.Web.UI;
/// <summary>
/// Represents a custom HtmlTextWriter that displays no span tag.
/// </summary>
public class HtmlTextWriterNoSpan : HtmlTextWriter
{
/// <summary>
/// Constructor.
/// </summary>
/// <param name="textWriter">Text writer.</param>
public HtmlTextWriterNoSpan(TextWriter textWriter)
: base(textWriter)
{ }
/// <summary>
/// Determines whether the specified markup element will be rendered to the requesting page.
/// </summary>
/// <param name="name">Name.</param>
/// <param name="key">Tag key.</param>
/// <returns>True if the markup element should be rendered, false otherwise.</returns>
protected override bool OnTagRender(string name, HtmlTextWriterTag key)
{
// Do not render <span> tags
if (key == HtmlTextWriterTag.Span)
return false;
// Otherwise, call the base class (always true)
return base.OnTagRender(name, key);
}
}
Just FYI, using:
checkbox.InputAttributes.Add("disabled", "disabled");
has the same effect but:
- It's not as convenient as checkbox.Enalbed = false;
- The attribute is removed after a postback when the checkbox is in a ListView.
回答5:
Using Jquery
<script>
$(".selector input").unwrap().addClass("cssclass");
</script>
回答6:
You can use the input/checkbox control directly if you don't need a label, or can put one yourself:
<input type="checkbox" id="CheckBox1" runat="server" />
<label for="CheckBox1">My Label</label>
A CSS Adapter may be able to remove the span around the checkbox/label, but I haven't seen one for that purpose.
回答7:
Why don't you remove the span using .remove with jquery ?
回答8:
Can you use a literal control instead? There's a big difference between these two alternatives:
<p>12345<asp:Label ID="lblMiddle" runat="server" Text="6"></asp:Label>7890</p>
<p>12345<asp:Literal ID="ltlMiddle" runat="server" Text="6"></asp:Literal>7890</p>
回答9:
I've found that by implementing a constructor like the one below, you can specify the container tag for your control.
public MyCustomControl() : base(HtmlTextWriterTag.Div)
{
}
You can replace the HtmlTextWriterTag
with any of the aviable options, such as Div in the example above. The default is Span
.
回答10:
protected override HtmlTextWriterTag TagKey
{
get
{
return HtmlTextWriterTag.Div;
}
}
should do
回答11:
$(document).ready(function() {
/* remove the relative spam involving inputs disabled */
$('input[type="checkbox"]').parent('.aspNetDisabled').each(function() {
var $this = $(this);
var cssClass = $this.attr('class');
$this.children('input[type="checkbox"]').addClass(cssClass).unwrap().parent('label[for],span').first().addClass('css-input-disabled');
});
});
/* CSS Example */
.css-input {
position: relative;
display: inline-block;
margin: 2px 0;
font-weight: 400;
cursor: pointer;
}
.css-input input {
position: absolute;
opacity: 0;
}
.css-input input:focus + span {
box-shadow: 0 0 3px rgba(0, 0, 0, 0.25);
}
.css-input input + span {
position: relative;
display: inline-block;
margin-top: -2px;
margin-right: 3px;
vertical-align: middle;
}
.css-input input + span:after {
position: absolute;
content: "";
}
.css-input-disabled {
opacity: .5;
cursor: not-allowed;
}
.css-checkbox {
margin: 7px 0;
}
.css-checkbox input + span {
width: 20px;
height: 20px;
background-color: #fff;
border: 1px solid #ddd;
-webkit-transition: background-color 0.2s;
transition: background-color 0.2s;
}
.css-checkbox input + span:after {
top: 0;
right: 0;
bottom: 0;
left: 0;
font-family: "FontAwesome";
font-size: 10px;
color: #fff;
line-height: 18px;
content: "\f00c";
text-align: center;
}
.css-checkbox:hover input + span {
border-color: #ccc;
}
.css-checkbox-primary input:checked + span {
background-color: #5c90d2;
border-color: #5c90d2;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Generate from asp.net -->
<label for="CheckBox1" id="Label4" class="css-input css-checkbox css-checkbox-primary">
<span class="aspNetDisabled">
<input id="CheckBox1"
type="checkbox"
checked="checked"
disabled="disabled">
</span>
<span></span>Disabled
</label>
回答12:
Try adding a constructor to your class that looks like this:
public MyControl() : base()
{
}
If you notice, controls will render as spans as default since that's what the "WebControl" uses (if you use Reflector) :
protected WebControl() : this(HtmlTextWriterTag.Span) { }
Reference: http://aspnetresources.com/blog/stripping_span_from_webcontrol
回答13:
i wonder, is there a reason no1 mentioned this:
public MyControl() : base(string.Empty)
i got this reading http://aspnetresources.com/blog/stripping_span_from_webcontrol that flaviotsf mentioned
回答14:
<div class="onoffswitch">
<asp:CheckBox ID="example1" runat="server" AutoPostBack="true" OnCheckedChanged="chkWifiRequired_CheckedChanged" CssClass="aspNetDisabled onoffswitch-checkbox"/>
<label class="onoffswitch-label" for='<%= example1.ClientID.ToString() %>'>
<span class="onoffswitch-inner"></span>
<span class="onoffswitch-switch"></span>
</label>
</div>
/* remove the relative spam involving inputs disabled */ $('input[name=""]').parent('.aspNetDisabled').each(function () { var $this = $(this); var cssClass = "onoffswitch-checkbox"; $('input[name=""]').addClass(cssClass).unwrap().parent('label[for],span').first().addClass('onoffswitch-checkbox'); });
This will allow you to use the check box normally, still have it call server side code, and use the toggle from bootstrap. (I'm using the Inspina theme but it should be the same format for other toggles)
回答15:
I just had this issue and used Jon's answer, which is good and it works. The downside is that your class is defined within the codebehind and not your markup.
So I took the answer and made a progamatic way to retrieve all attributes for the control, copy them to InputAttributes and remove those copied attributes from attributes.
Note that while this extends from RadioButton, you could use the method to extend any control, such as labels or checkboxes.
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Hidistro.UI.Common.Controls
{
/// <summary>
/// Just like a normal RadioButton, except that the wrapped span is disabled.
/// </summary>
public class CleanRadioButton : RadioButton
{
protected override void Render(HtmlTextWriter writer)
{
List<string> keysToRemove = new List<string>();
foreach (object key in Attributes.Keys)
{
string keyString = (string)key;
InputAttributes.Add(keyString, Attributes[keyString]);
keysToRemove.Add(keyString);
}
foreach (string key in keysToRemove)
Attributes.Remove(key);
base.Render(writer);
}
}
}
This way, all you need to do is the following, and it will output tags without the span.
<namespace:CleanRadioButton class="class1" />
<namespace:CleanRadioButton class="class2" />
HTML output: (note that "generated" is autogenerated)
<input id="generated" type="radio" name="generated" value="generated" class="class1">
<input id="generated" type="radio" name="generated" value="generated" class="class2">
来源:https://stackoverflow.com/questions/2173331/how-to-remove-span-tag-from-webcontrol-when-rendered