2009-03-13 11 views
44

Cuando los controles ASP.NET se procesan, sus identificadores a veces cambian, como si estuvieran en un contenedor de nombres. Button1 puede tener una identificación de ctl00_ContentMain_Button1 cuando se representa, por ejemplo.Referencia Control de ASP.NET por ID en JavaScript?

Sé que puede escribir su JavaScript como cadenas en su archivo .cs, obtener el ID de cliente del control e inyectar el script en su página utilizando clientscript, pero ¿hay alguna forma de referenciar un control directamente desde JavaScript utilizando ASP? .NET Ajax?

He encontrado que escribir una función para analizar el dom recursivamente y encontrar un control que CONTIENE la identificación que deseo no es confiable, por lo que estaba buscando una mejor práctica en lugar de una solución alternativa.

Respuesta

1

Ah, y también encontré esto, en caso de que alguien más tenga este problema.

utiliza un selector de jQuery personalizado para controles ASP.NET: http://john-sheehan.com/blog/custom-jquery-selector-for-aspnet-webforms/

+0

El enlace está roto: - | – fujiFX

+0

Lo siento, fue de hace 7 años (wow) Pruebe este http://codehunk.com/jquery-selector-for-asp-net-web-form-controls/ – NetHawk

+0

No se preocupe, tales cosas carpas suceden. Solo como sugerencia, para evitar tales situaciones, es mejor incluir algunos extractos del enlace y dejar el enlace como referencia para más detalles. – fujiFX

0

No creo que haya una sola "mejor práctica" para hacer esto. Hay un montón de prácticas bastante buenas. Aquí es nuestra:

Cada control que tiene la funcionalidad del lado del cliente haga que el bloque en línea de la escritura, directamente debajo del margen de beneficio para el control:

<span id="something_crazy_long"> 
    control markup 
</span> 
<script type="text/javascript">new CustomControl('something_crazy_long');</script> 

Cada control tiene un JS que se acompañan como:

var CustomControl = function(id) { 
    this.control = document.getElementByID(id); 
    this.init(); 
}; 

CustomControl.prototype.init = function() { 
    //do stuff to wire up relevant events 
}; 

En el código subyacente, hacemos algo como:

class CustomControl : Control 

override void Render(HtmlTextWriter writer) 
{ 
    writer.WriteBeginTag("span"); 
    writer.WriteAttribute("id", this.ClientID); 
    writer.Write(HtmlTextWriter.TagRightChar); 
    //write control markup 
    writer.WriteEndTag("span"); 
    writer.WriteBeginTag("script"); 
    writer.WriteAttribute("type", "text/javascript"); 
    writer.Write(HtmlTextWriter.TagRightChar); 
    writer.Write(
     string.Format("new CustomControl('{0}');", this.ClientID) 
    ); 
    writer.WriteEndTag("script"); 
} 
+0

Gracias, Rex. Me preguntaba si era posible hacer esto solo a través de la interfaz js. Pero es interesante ver otra forma de hacerlo cambiando la representación. – NetHawk

12

Pareja de miles ghts en esto:

1) He tenido mucha suerte obteniendo elementos por clase css en lugar de id porque los identificadores de asp.net no son confiables como usted indicó. Yo uso esta función y realiza razonablemente bien:

function getElementsByClass(searchClass,node,tag) { 
var classElements = new Array(); 
if (node == null) 
    { 
     node = document; 
    } 

if (tag == null) 
    { 
     tag = '*'; 
    } 

var els = node.getElementsByTagName(tag); 
var elsLen = els.length; 
var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)"); 

for (i = 0, j = 0; i < elsLen; i++) 
    { 
     if (pattern.test(els[i].className)) 
      { 
       classElements[j] = els[i]; 
       j++; 
      } 
     } 
return classElements; 
} 

2) jQuery ayuda aquí mucho. Usando jQuery puedes obtener de manera confiable elementos donde el ID termina con una cierta cadena. Si bien esta no es "la" razón para usar jQuery, definitivamente es una ventaja.

3) Este problema se solucionará en asp.net 4.0 por lo que colgar en él :-) http://weblogs.asp.net/asptest/archive/2009/01/06/asp-net-4-0-clientid-overview.aspx

+1

Gracias, Brendan. Como todavía no se ha construido, el # 2 parece ser la mejor opción. Ya estoy usando jquery en el proyecto. Tiene el mismo problema que mi función de búsqueda, que es que podría querer 'caja' y encuentra el control 'otra caja', pero es mejor que esperar hasta 2010. – NetHawk

0

hago algo similar a Rex M excepto para evitar múltiples etiquetas de script que utilizo una función en mi clase base a la página registre los controles que voy a usar en el lado del cliente, luego escupirlos a html dentro de 1 etiqueta de script.

Incluso podría crear una subclase de sus controles para que se registre automáticamente con la función o use una propiedad booleana para establecer si va a usarlos en el lado del cliente.

67

Este mensaje por Dave Ward podría tener lo que estás buscando:

http://encosia.com/2007/08/08/robust-aspnet-control-referencing-in-javascript/

Extracto del artículo:

De hecho, existe. La mejor solución es usar ASP en línea.código NET para inyectar ClientID de propiedades del control:

$get('<%= TextBox1.ClientID %>') 

Ahora el ID de elemento de cliente correcto se referencia, independientemente de la estructura de la página y la anidación nivel del control. En mi opinión, el muy bajo costo de este método bien vale la pena hacer su scripting cliente más resistente para cambiar.

Y algunos ejemplos de código por Dave desde el hilo de comentarios de ese mensaje:

<script> 
    alert('TextBox1 has a value of: ' + $get('<%= TextBox1.ClientID %>').value); 
</script> 

El hilo de comentarios a este artículo he vinculado anteriormente tiene una buena discusión.

+0

Lo mismo pero para un control ASP.NET [aquí] (http://stackoverflow.com/questions/15835767/how-to-refer-to-a-textbox-in-javascript-inside-an-asp-net-control). –

0

, usted puede obtener el ID mediante el uso de document.getElementById método.

0

prefiero datos de etiquetas con destino en el margen de beneficio document.getElementById ('<% #% TextBox1.ClientID>'). Valor, sobre el uso de la implementación de la etiqueta del lado del servidor <% = TextBox1.ClientID%>.

Las etiquetas del lado del servidor le prohíben agregar controles al dom en el código subyacente. Esta necesidad surge comúnmente a medida que desarrolla su aplicación y el enfoque de datos puede salvarlo de las reescrituras principales.

Al utilizar etiquetas del lado del servidor también conocido como 'bloques de código' para realizar esta operación común

this.Form.Controls.Add (myContorl);

genera este error en tiempo de ejecución:

La colección Controls no se puede modificar porque el control contiene bloques de código (es decir <% ...%>).

Desafortunadamente, esto a menudo solo se vuelve inherentemente obvio después de haber construido su sitio web.

Cuando la aplicación de los datos ligados de control '<% # TextBox1.ClientID%>' resolver el valor de las propiedades de control de referencia en el marcado, en el lugar apropiado, tal como el final de bind datos Page_Load como esto:

Página.DataBind()

Tenga en cuenta Page.DataBind() hace que los controles secundarios en la página para DataBind También, esto puede ser un efecto secundario no deseado si la página se ocupa de la unión de cierto niño de datos controla por separado. Si este es el caso, el enlace de datos se pueden realizar en el control individual de la siguiente manera:

TextBox1.DataBind()

Una evolución aplicaciones finalmente conduce a una especie de sitio de base amplia funcionalidad donde Es posible que desee agregar controles base, una vez que haya salpicado su aplicación de sitio web con etiquetas del lado del servidor reemplazándolas con databinds se vuelve problemático, especialmente cuando las páginas han sido codificadas para manejar el enlace de datos por sí mismas.

14

Usted puede cambiar a ClienIDMode propiedad del control de 'Static' que dará como resultado el mismo ID que le dan el control en el código .NET.

<asp:TextBox ID="TextBox1" ClientIDMode="Static" runat="server"></asp:TextBox> 

dará como resultado:

<input name="ctl00$MainContent$TextBox1" type="text" id="TextBox1"> 

por lo que tiene el mismo ID.

Cuestiones relacionadas