Wie bringe ich jQuery dazu, Elemente mit a auszuwählen? (Punkt) in ihrer ID?

172

Gegeben die folgenden Klassen und Controller-Aktionsmethode:

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 };
}

Und die folgende Form:

<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>

Ich kann sowohl die Schulinstanz als auch das Adressmitglied der Schule aktualisieren. Das ist ganz nett! Vielen Dank an das ASP.NET MVC-Team!

Wie verwende ich jedoch jQuery, um die Dropdown-Liste auszuwählen, damit ich sie vorab ausfüllen kann? Mir ist klar, dass ich diese Serverseite ausführen kann, aber es gibt andere dynamische Elemente auf der Seite, die sich auf die Liste auswirken.

Folgendes habe ich bisher und es funktioniert nicht, da die Selektoren nicht mit den IDs übereinstimmen:

$(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);
    });
  });
});
Doug Wilson
quelle

Antworten:

293

Von Google Groups :

Verwenden Sie vor jedem Sonderzeichen zwei Backslashes.

Ein Backslash in einem jQuery-Selektor entgeht dem nächsten Zeichen. Sie benötigen jedoch zwei davon, da Backslash auch das Escape-Zeichen für JavaScript-Zeichenfolgen ist. Der erste Backslash entgeht dem zweiten und gibt Ihnen einen tatsächlichen Backslash in Ihrer Zeichenfolge - der dann dem nächsten Zeichen für jQuery entgeht.

Also, ich denke du siehst

$(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);
    });
  });
});

Lesen Sie auch Wie wähle ich ein Element anhand einer ID aus, deren Zeichen in der CSS-Notation verwendet werden? auf den jQuery FAQ.

bdukes
quelle
4
Ich frage mich, was die Rationalisierung dafür ist, dass der Entwickler dies tun muss. Es scheint, als würde eine einfache Reihe von Heuristiken in jQuery dieses Problem lösen, da mit IDs mit Punkten in ihnen nichts falsch ist ...
Jason Bunting
5
Wenn Sie nicht entkommen müssten, wie würden Sie ein Element mit der ID-Adresse und dem Klassenstatus abfragen (vorausgesetzt, wenn Sie die ID kennen, fügen Sie durch Angabe der Klasse nicht viel hinzu, aber sie sollte immer noch gültig sein, würde ich denken)?
Bdukes
12
Aus diesem Grund müssen Sie in CSS selbst auch einen Punkt in einer ID maskieren. Alles, was jQuery tut, ist, dass Sie die von CSS festgelegten Regeln befolgen.
Bdukes
6
Sie können auch nach Name anstelle von ID auswählen. Zum Beispiel $ ('[name = "Address.Country"]')
Funka
25

Sie können keinen jQuery-ID-Selektor verwenden, wenn die ID Leerzeichen enthält. Verwenden Sie eine Attributauswahl:

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

Wenn möglich, geben Sie auch den Elementtyp an:

$('div[id=foo bar]').show();
Elliot Nelson
quelle
Ich mache es lieber so als mit den Escape-Zeichen. Offensichtlich ist die beste Problemumgehung, keine Punkte in der ID zu verwenden.
GordonB
Leerzeichen sind in IDs nicht zulässig, auch nicht in der liberaleren Akzeptanz von Zeichen in HTML5. stackoverflow.com/questions/70579/…
Jay Blanchard
Stimmt, aber ob sie erlaubt sind oder nicht, spielt für den armen Kerl keine Rolle, der feststeckt und einer schlecht geschriebenen Web-App, die Ende der 90er Jahre bereitgestellt wurde, eine Fensterdekoration hinzufügt.
Elliot Nelson
4
Es müssen Quates vorhanden sein, um arbeiten zu können: `$ (" div [id = '"+ variable +"'] ")` oder `$ (" div [id = 'foo bar'] ")`
olga
Wie @olga sagte, ist die Antwort nicht mehr legal. Insbesondere erhalten Sie eine Fehlermeldung "Nicht erfasster Fehler: Syntaxfehler, nicht erkannter Ausdruck: div [id = foo bar]"
James Moore
13

Entkomme ihm für Jquery:

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

Anwendungsbeispiel:

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

Mehr Infos hier .


quelle
2
Die Lösung gemäß den jQuery-Dokumenten besteht darin, nur ein "\" (Schrägstrich) hinzuzufügen. alert (EscapeSelector ("some.id")); wird als einige \ .id ausgegeben. Ich denke also, der Ersatz-Regex hätte ersetzt werden müssen (/(:|\.|[|‹)/g, "\\\\ $ 1");
Arun
Ich habe das gleiche Problem, warum sieht das niemand anderes?
TruthOf42
9

Der soeben veröffentlichte Release Candidate von ASP.NET MVC hat dieses Problem behoben. Er ersetzt jetzt die Punkte durch Unterstriche für das ID-Attribut.

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

Rendern zu

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

Weitere Informationen finden Sie in den Versionshinweisen ab Seite 14.

Dale Ragan
quelle
1
Ich sehe nicht, wie dies ein "Fix" ist - warum sollte ASP.NET MVC die ID in etwas ändern müssen, das jQuery benötigt? Ich denke, in jQuery liegt das Problem, nicht in der Verwendung von a. in einer ID.
Jason Bunting
7
Der Punkt hat in CSS eine besondere Bedeutung für die Identifizierung / Kombination von Klassen, weshalb es schwierig ist, ihn in einer ID zu haben. Das "Problem" liegt nicht bei jquery.
Funka
4

Dies ist in den Dokumenten von jQuery Selectors dokumentiert :

Um eines der Metazeichen (z. B. !"#$%&'()*+,./:;<=>?@[\]^`{|}~) als wörtlichen Teil eines Namens zu verwenden, muss es mit zwei umgekehrten Schrägstrichen versehen werden : \\. Beispielsweise kann ein Element mit id="foo.bar"den Selektor verwenden $("#foo\\.bar").

Kurz gesagt, das Präfix der .mit \\wie folgt:

$("#Address\\.Country")

Warum funktioniert das nicht .in meiner ID?

Das Problem ist, dass .die folgende Zeichenfolge eine besondere Bedeutung hat und als Klassenselektor interpretiert wird. Also $('#Address.Country')würde passen <div id="Address" class="Country">.

Wenn als \\.maskiert, wird der Punkt als normaler Text ohne besondere Bedeutung behandelt, der der gewünschten ID entspricht <div id="Address.Country">.

Dies gilt für alle Zeichen, !"#$%&'()*+,./:;<=>?@[\]^`{|}~die sonst als Selektor in jQuery eine besondere Bedeutung hätten. Stellen Sie \\sie einfach als normalen Text vor.

Warum 2 \\?

Wie in der Antwort von bdukes erwähnt, gibt es einen Grund, warum wir 2 \Zeichen benötigen . \wird das folgende Zeichen in JavaScript maskieren. Wenn JavaScript die Zeichenfolge interpretiert "#Address\.Country", wird die Zeichenfolge angezeigt und so \interpretiert, dass das folgende Zeichen wörtlich genommen und entfernt wird , wenn die Zeichenfolge als Argument an übergeben wird $(). Das bedeutet, dass jQuery die Zeichenfolge weiterhin als sieht "#Address.Country".

Hier kommt der zweite \ins Spiel. Der erste weist JavaScript an, den zweiten als wörtliches (nicht spezielles) Zeichen zu interpretieren. Dies bedeutet, dass das zweite von jQuery gesehen wird und dass das folgende . Zeichen ein wörtliches Zeichen ist.

Puh! Vielleicht können wir uns das vorstellen.

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

Mit zwei Backslashes ist es in Ordnung, es funktioniert. Wenn Sie jedoch einen dynamischen Namen verwenden, dh einen Variablennamen, müssen Sie Zeichen ersetzen.

Wenn Sie Ihre Variablennamen nicht ändern möchten, können Sie dies tun:

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

und dann hast du dein jquery Objekt.

Daniel
quelle
0

Nur zusätzliche Informationen: Überprüfen Sie dieses ASP.NET MVC-Problem Nr. 2403 .

Bis das Problem behoben ist, verwende ich meine eigenen Erweiterungsmethoden wie Html.TextBoxFixed usw., die einfach Punkte durch Unterstriche im id-Attribut (nicht im name-Attribut) ersetzen, sodass Sie eine Abfrage wie $ ("# Address_Street") verwenden. aber auf dem Server ist es wie Address.Street.

Beispielcode folgt:

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;
}
gius
quelle
1
aus dem oben genannten Problem: "UpdateModel () verwendet einen Punkt, weil die Formularelemente so eingehen. Die Formularelemente verwenden einen Punkt, weil sie in den HTML-Hilfsaufrufen so angegeben sind. Die HTML-Hilfsaufrufe verwenden einen Punkt, weil dies so ist." ViewData.Eval () funktioniert. Schließlich verwendet ViewData.Eval () einen Punkt, da auf diese Weise ein Objekt und seine Eigenschaft in den wichtigsten .NET Framework-Sprachen getrennt werden. Die Verwendung eines anderen Trennzeichens als eines Punkts an einem beliebigen Punkt in dieser Kette würde unterbrochen der Fluss für die gesamte Kette. "
Simon_Weaver
0

Ich habe das Problem mit der Lösung von jquery docs gelöst

Meine Funktion:

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

function jq(myid){


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


}

Hinweis: Ich entferne das "#", weil ich in meinem Code die ID mit einem anderen Text verknüpfe

Schriftart: Jquery Docs-Auswahlelement mit speziellen Zeichen

Gabriel Molina
quelle