c# - tag - Cómo eliminar la etiqueta span de WebControl cuando se procesa
que es un elemento span (15)
Cuando se utiliza un CheckBox
ASP.NET (y, en el caso de ser heredado de un CheckBox
), genera un intervalo alrededor del control de entrada de la casilla de verificación, este control de intervalo afecta a los scripts de jQuery.
¿Es posible eliminar este intervalo al renderizar?
¿Por qué no eliminas el span utilizando .remove with jquery?
¿Puedes usar un control literal en su lugar? Hay una gran diferencia entre estas dos alternativas:
<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>
Acabo de probar esto en una página de prueba y no estoy usando los controles de CheckBox ... ¿está seguro de que es el CheckBox el que está renderizando esto? ¿Es condicional?
ACTUALIZACIÓN: OK, parece depender de si el CheckBox tiene o no atributos adicionales, incluida una configuración CssClass ... o un atributo "deshabilitado".
Acabo de tener este problema y utilicé la respuesta de Jon, que es buena y funciona. La desventaja es que su clase está definida dentro del código y no en su marca.
Así que tomé la respuesta e hice una manera progresiva de recuperar todos los atributos para el control, copiarlos en InputAttributes y eliminar esos atributos copiados de los atributos.
Tenga en cuenta que si bien esto se extiende desde RadioButton, puede usar el método para extender cualquier control, como etiquetas o casillas de verificación.
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);
}
}
}
De esta manera, todo lo que necesita hacer es lo siguiente, y generará etiquetas sin el intervalo.
<namespace:CleanRadioButton class="class1" />
<namespace:CleanRadioButton class="class2" />
Salida HTML: (note que "generado" es autogenerado)
<input id="generated" type="radio" name="generated" value="generated" class="class1">
<input id="generated" type="radio" name="generated" value="generated" class="class2">
Descubrí que al implementar un constructor como el que se muestra a continuación, puede especificar la etiqueta contenedora para su control.
public MyCustomControl() : base(HtmlTextWriterTag.Div)
{
}
Puede reemplazar el HtmlTextWriterTag
con cualquiera de las opciones disponibles, como Div en el ejemplo anterior. El valor predeterminado es Span
.
Encontró este consejo útil:
En Code Behind, use InputAttributes en lugar de Attributes.
Por ejemplo, escriba esto:
chk.InputAttributes.Add("onchange", "updateFields()")
en lugar de esto:
chk.Attributes.Add("onchange", "updateFields()")
o en lugar de declaraciones en línea:
<asp:CheckBox ID="chk" runat="server" onchange="updateFields()" />
Los dos últimos causarán el lapso de envoltura.
Intenta agregar un constructor a tu clase que se vea así:
public MyControl() : base()
{
}
Si se da cuenta, los controles se representarán como intervalos predeterminados, ya que eso es lo que utiliza el "Control web" (si usa Reflector):
protected WebControl() : this(HtmlTextWriterTag.Span) { }
Referencia: http://aspnetresources.com/blog/stripping_span_from_webcontrol
Me pregunto, ¿hay alguna razón por la que no1 mencionó esto?
public MyControl() : base(string.Empty)
obtuve esta lectura http://aspnetresources.com/blog/stripping_span_from_webcontrol que flaviotsf mencionó
No sé si esto funcionará en este ejemplo en particular. Pero si crea su propio WebControl y nunca quiere que se vean tramos alrededor de sí mismo, puede anular el método de procesamiento de Controles de esta manera:
public class MyWebControl : WebControl
{
/* Your code
between here */
protected override void Render(HtmlTextWriter writer)
{
RenderContents (writer);
}
}
Supongo que podría agregar lo mismo a un CheckBox heredado ... algo como esto:
public class MyCheckBox : CheckBox
{
/* Your code
between here */
protected override void Render(HtmlTextWriter writer)
{
RenderContents (writer);
}
}
El problema básico con la solución se explica mejor aquí:
http://www.marten-online.com/net/stripping-span-tag-from-webcontrol.html
Pasé las últimas 3 horas tirando de mi cabello para encontrar una solución a este problema.
Esto es lo que salió:
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);
}
}
Junto con el control personalizado, necesitarás un HtmlTextWriter personalizado:
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);
}
}
Solo para tu información, usando:
checkbox.InputAttributes.Add("disabled", "disabled");
tiene el mismo efecto pero:
- No es tan conveniente como checkbox.Enalbed = false;
- El atributo se elimina después de una devolución cuando la casilla de verificación está en un ListView.
Puede usar el control de entrada / casilla de verificación directamente si no necesita una etiqueta, o puede poner una:
<input type="checkbox" id="CheckBox1" runat="server" />
<label for="CheckBox1">My Label</label>
Es posible que un adaptador CSS pueda eliminar el espacio alrededor de la casilla de verificación / etiqueta, pero no he visto ninguno para ese propósito.
Usando jquery
<script>
$(".selector input").unwrap().addClass("cssclass");
</script>
$(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>
<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''); });
Esto le permitirá usar la casilla de verificación normalmente, aún así tendrá que llamar al código del lado del servidor, y usar la tecla para alternar desde el arranque. (Estoy usando el tema Inspina pero debería ser el mismo formato para otras alternaciones)
protected override HtmlTextWriterTag TagKey
{
get
{
return HtmlTextWriterTag.Div;
}
}
debería hacer