Come posso ottenere jQuery per selezionare gli elementi con a. (punto) nel loro ID?


172

Dati i seguenti metodi di classe e azione del controller:

public School
{
  public Int32 ID { get; set; }
  publig String Name { get; set; }
  public Address Address { get; set; }
}

public class Address
{
  public string Street1 { get; set; }
  public string City { get; set; }
  public String ZipCode { get; set; }
  public String State { get; set; }
  public String Country { get; set; }
}

[Authorize(Roles = "SchoolEditor")]
[AcceptVerbs(HttpVerbs.Post)]
public SchoolResponse Edit(Int32 id, FormCollection form)
{
  School school = GetSchoolFromRepository(id);

  UpdateModel(school, form);

  return new SchoolResponse() { School = school };
}

E il seguente modulo:

<form method="post">
  School: <%= Html.TextBox("Name") %><br />
  Street: <%= Html.TextBox("Address.Street") %><br />
  City:  <%= Html.TextBox("Address.City") %><br />
  Zip Code: <%= Html.TextBox("Address.ZipCode") %><br />
  Sate: <select id="Address.State"></select><br />
  Country: <select id="Address.Country"></select><br />
</form>

Sono in grado di aggiornare sia l'istanza della Scuola sia il membro Indirizzo della scuola. Questo è abbastanza carino! Grazie al team ASP.NET MVC!

Tuttavia, come posso usare jQuery per selezionare l'elenco a discesa in modo da poterlo pre-compilare? Mi rendo conto che potrei fare questo lato server ma ci saranno altri elementi dinamici sulla pagina che influenzano l'elenco.

Quello che segue è quello che ho finora e non funziona in quanto i selettori non sembrano corrispondere agli ID:

$(function() {
  $.getJSON("/Location/GetCountryList", null, function(data) {
    $("#Address.Country").fillSelect(data);
  });
  $("#Address.Country").change(function() {
    $.getJSON("/Location/GetRegionsForCountry", { country: $(this).val() }, function(data) {
      $("#Address.State").fillSelect(data);
    });
  });
});

Risposte:


293

Da Google Gruppi :

Usa due barre rovesciate prima di ogni carattere speciale.

Una barra rovesciata in un selettore jQuery sfugge al carattere successivo. Ma ne servono due perché la barra rovesciata è anche il carattere di escape per le stringhe JavaScript. La prima barra rovesciata sfugge alla seconda, dandoti una barra rovesciata effettiva nella stringa, che sfugge al carattere successivo per jQuery.

Quindi, immagino tu stia guardando

$(function() {
  $.getJSON("/Location/GetCountryList", null, function(data) {
    $("#Address\\.Country").fillSelect(data);
  });
  $("#Address\\.Country").change(function() {
    $.getJSON("/Location/GetRegionsForCountry", { country: $(this).val() }, function(data) {
      $("#Address\\.State").fillSelect(data);
    });
  });
});

Guarda anche Come faccio a selezionare un elemento tramite un ID con caratteri usati nella notazione CSS? sulle FAQ di jQuery.


4
Mi chiedo quale sia la razionalizzazione per richiedere allo sviluppatore di fare questo, sembra che un semplice insieme di euristiche all'interno di jQuery risolverebbe questo problema, dal momento che non c'è niente di sbagliato con ID con punti in essi ...
Jason Bunting

5
Se non dovessi scappare, come interrogheresti un elemento con ID ID e stato della classe (ammesso che se conosci l'ID non stai aggiungendo molto specificando la classe, ma dovrebbe comunque essere valido, pensare)?
bdukes il

12
Per tale motivo, nel CSS stesso, è necessario evitare anche un punto in un ID. Tutto ciò che jQuery sta facendo richiede di seguire le regole stabilite dai CSS.
bdukes

6
Puoi anche selezionare per nome anziché per ID. Ad esempio, $ ('[name = "Address.Country"]')
Funka

25

Non è possibile utilizzare un selettore ID jQuery se l'id contiene spazi. Usa un selettore di attributi:

$('[id=foo bar]').show();

Se possibile, specificare anche il tipo di elemento:

$('div[id=foo bar]').show();

Preferisco farlo in questo modo piuttosto che usare i caratteri di escape .... Ovviamente la soluzione migliore è non usare i punti nell'ID.
GordonB,

Gli spazi non sono consentiti negli ID, nemmeno nell'accettazione più liberale dei caratteri da parte di HTML5. stackoverflow.com/questions/70579/…
Jay Blanchard il

È vero, ma se sono permessi o meno non importa per la povera linfa che è bloccata aggiungendo la decorazione della finestra a un'app Web scritta male distribuita alla fine degli anni '90.
Elliot Nelson,

4
ci devono essere delle domande per funzionare: `$ (" div [id = '"+ variabile +"'] ")` o `$ (" div [id = 'foo bar'] ")`
olga

Come ha detto @olga, la risposta non è più legale. In particolare, riceverai un messaggio di errore "Errore non rilevato: errore di sintassi, espressione non riconosciuta: div [id = foo bar]"
James Moore,

13

Fuga per Jquery:

function escapeSelector(s){
    return s.replace( /(:|\.|\[|\])/g, "\\$1" );
}

esempio di utilizzo:

e.find('option[value='+escapeSelector(val)+']')

maggiori informazioni qui .


2
La soluzione secondo i documenti jQuery sta aggiungendo solo un "\" (barra). alert (escapeSelector ( "some.id")); verrà emesso come some \ .id. Quindi immagino che il regex sostitutivo avrebbe dovuto essere s.replace (/(:|\.|[|× )/g, "\\\\ $ 1");
Arun,

Ho lo stesso problema, perché nessuno lo vede?
TruthOf42

9

Il Release Candidate di ASP.NET MVC appena rilasciato risolto questo problema, ora sostituisce i punti con caratteri di sottolineatura per l'attributo ID.

<%= Html.TextBox("Person.FirstName") %>

Rende a

<input type="text" name="Person.FirstName" id="Person_FirstName" />

Per ulteriori informazioni, consultare le note di rilascio, a partire da pagina 14.


1
Non riesco a vedere come questa sia una "correzione" - perché ASP.NET MVC dovrebbe cambiare l'ID in qualcosa di cui jQuery ha bisogno? Penso che jQuery sia il problema, non usando a. in un ID.
Jason Bunting,

7
il punto ha un significato speciale nei CSS per identificare / combinare le classi, motivo per cui averlo in un ID è problematico. Il "problema" non è con jquery.
Funka,

4

Questo è documentato nei documenti di jQuery Selectors :

Per utilizzare uno dei meta-caratteri (come ad esempio !"#$%&'()*+,./:;<=>?@[\]^`{|}~) come una parte letterale di un nome, deve essere sfuggito con con due barre rovesciate: \\. Ad esempio, un elemento con id="foo.bar", può utilizzare il selettore $("#foo\\.bar").

In breve, il prefisso .con \\il seguente:

$("#Address\\.Country")

Perché non .funziona nel mio ID?

Il problema è che .ha un significato speciale, la stringa seguente è interpretata come un selettore di classe. Quindi $('#Address.Country')corrisponderebbe<div id="Address" class="Country"> .

Se sfuggito a \\., il punto verrà trattato come un testo normale senza alcun significato speciale, corrispondente all'ID desiderato <div id="Address.Country">.

Questo vale per tutti i personaggi !"#$%&'()*+,./:;<=>?@[\]^`{|}~che altrimenti avrebbero un significato speciale come selettore in jQuery. Basta anteporre \\per trattarli come un normale testo.

Perché 2 \\?

Come notato nella risposta di bdukes, c'è un motivo per cui abbiamo bisogno di 2 \caratteri. \sfuggirà al seguente carattere in JavaScript. Se JavaScript interpreta la stringa "#Address\.Country", vedrà \, interpretarla nel senso che prende il seguente carattere letteralmente e lo rimuove quando la stringa viene passata come argomento a $(). Ciò significa che jQuery vedrà comunque la stringa come"#Address.Country" .

È qui che \entra in gioco il secondo . Il primo dice a JavaScript di interpretare il secondo come un carattere letterale (non speciale). Questo significa che il secondo sarà visto da jQuery e comprenderà che il seguente . personaggio è letterale.

Accidenti! Forse possiamo visualizzarlo.

//    Javascript, the following \ is not special.
//         | 
//         |
//         v    
$("#Address\\.Country");
//          ^ 
//          |
//          |
//      jQuery, the following . is not special.

2

Usando due barre rovesciate va bene, funziona. Ma se stai usando un nome dinamico, intendo un nome variabile, dovrai sostituire i caratteri.

Se non vuoi cambiare i nomi delle tue variabili puoi farlo:

var variable="namewith.andother";    
var jqueryObj = $(document.getElementById(variable));

e poi hai il tuo oggetto jquery.


0

Ulteriori informazioni: controlla questo numero ASP.NET MVC # 2403 .

Fino a quando il problema non viene risolto, utilizzo i miei metodi di estensione come Html.TextBoxFixed, ecc. Che sostituisce semplicemente i punti con caratteri di sottolineatura nell'attributo id (non nell'attributo name), in modo da utilizzare jquery come $ ("# Address_Street") ma sul server, è come Address.Street.

Segue un codice di esempio:

public static string TextBoxFixed(this HtmlHelper html, string name, string value)
{
    return html.TextBox(name, value, GetIdAttributeObject(name));
}

public static string TextBoxFixed(this HtmlHelper html, string name, string value, object htmlAttributes)
{
    return html.TextBox(name, value, GetIdAttributeObject(name, htmlAttributes));
}

private static IDictionary<string, object> GetIdAttributeObject(string name)
{
    Dictionary<string, object> list = new Dictionary<string, object>(1);
    list["id"] = name.Replace('.', '_');
    return list;
}

private static IDictionary<string, object> GetIdAttributeObject(string name, object baseObject)
{
    Dictionary<string, object> list = new Dictionary<string, object>();
    list.LoadFrom(baseObject);
    list["id"] = name.Replace('.', '_');
    return list;
}

1
dal problema di cui sopra: "UpdateModel () usa un punto perché è così che arrivano gli elementi del modulo. Gli elementi del modulo usano un punto perché è così che sono specificati nelle chiamate helper HTML. Le chiamate helper HTML usano un punto perché è così ViewData.Eval () Infine, ViewData.Eval () usa un punto perché è così che si separa un oggetto e la sua proprietà nei principali linguaggi di .NET Framework. L'uso di un delimitatore diverso da un punto in qualsiasi punto di questa catena si spezzerebbe il flusso per l'intera catena ".
Simon_Weaver,

0

Ho risolto il problema con la soluzione fornita dai documenti jquery

La mia funzione:

//funcion to replace special chars in ID of  HTML tag

function jq(myid){


//return "#" + myid.replace( /(:|\.|\[|\]|,)/g, "\\$1" );
return myid.replace( /(:|\.|\[|\]|,)/g, "\\$1" );


}

Nota: rimuovo "#" perché nel mio codice concedo l'ID con un altro testo

Carattere: Jquery Docs seleziona l'elemento con caratteri speciali

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.