jQueryに。(期間)IDに?


172

次のクラスとコントローラーアクションメソッドを考えます。

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

そして次のフォーム:

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

学校のインスタンスと学校の住所メンバーの両方を更新できます。これはとてもいいです!ASP.NET MVCチームに感謝します。

ただし、jQueryを使用してドロップダウンリストを選択し、事前入力できるようにするにはどうすればよいですか?私はこのサーバー側を実行できることを理解していますが、ページにリストに影響を与える他の動的要素があります。

以下は私が今まで持っているものであり、セレクターが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);
    });
  });
});

回答:


293

Googleグループから:

各特殊文字の前に2つの円記号を使用します。

jQueryセレクターのバックスラッシュは、次の文字をエスケープします。ただし、バックスラッシュはJavaScript文字列のエスケープ文字でもあるため、2つ必要です。最初のバックスラッシュは2番目のバックスラッシュをエスケープし、文字列に実際のバックスラッシュを1つ与えます-次に、jQueryの次の文字をエスケープします。

だから、私はあなたが見ていると思います

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

また、CSS表記で使用されている文字を含むIDで要素を選択するにはどうすればよいかを確認してくださいjQuery FAQをご覧ください。


4
開発者がこれを行うことを要求するための合理化は何だろうと思います。ピリオドが含まれるIDには何の問題もないので、jQuery内の単純なヒューリスティックのセットがこの問題を解決するようです...
Jason Bunting

5
エスケープする必要がなかった場合、ID AddressとクラスStateを使用して要素をどのようにクエリしますか(クラスを指定することで追加していないIDがわかっていても、それが有効であることは確かですが、思う)?
bdukes

12
そのため、CSS自体では、IDのドットもエスケープする必要があります。jQueryが行うすべてのことは、CSSによって設定されたルールに従うことを要求します。
bdukes

6
IDの代わりに名前で選択することもできます。たとえば、$( '[name = "Address.Country"]')
Funka

25

IDにスペースが含まれている場合は、jQuery IDセレクターを使用できません。属性セレクターを使用します。

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

可能であれば、要素タイプも指定します。

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

エスケープ文字を使用するよりも、この方法を使用することをお勧めします。
GordonB 2010

スペースは、IDでは使用できません。HTML5でより自由に文字を受け入れることもできません。stackoverflow.com/questions/70579/…–
Jay Blanchard

真実ですが、許可されているかどうかは、90年代後半に展開された不十分に作成されたWebアプリにウィンドウのドレッシングを追加することで立ち往生している貧しい樹液には関係ありません。
Elliot Nelson

4
機能するにはクオートが必要です: `$(" div [id = '"+ variable +"'] ")`または `$(" div [id = 'foo bar'] ")`
olga

@olgaが言ったように、答えはもはや合法ではありません。具体的には、「Uncaught Error:Syntax error、unrecognized expression:div [id = foo bar]」というエラーメッセージが表示されます
James Moore

13

Jqueryのためにそれをエスケープします:

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

使用例:

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

詳細はこちら


2
jQueryドキュメントによる解決策は、「\」(スラッシュ)を1つだけ追加することです。alert(escapeSelector( "some.id")); some \ .idとして出力されます。したがって、置換正規表現はs.replace(/(:|\.|[|])/g、 "\\\\ $ 1");である必要があると思います。
2015

私は同じ問題を抱えていますが、なぜ他の誰もこれを見ないのですか?
TruthOf42

9

リリースされたばかりのASP.NET MVCのリリース候補では、この問題が修正され、ID属性のドットがアンダースコアに置き換えられました。

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

レンダリング先

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

詳細については、14ページから始まるリリースノートを参照してください。


1
これが「修正」であることがわかりません-なぜASP.NET MVCはIDをjQueryが必要とするものに変更しなければならないのですか?jQueryは、を使用するのではなく、問題がある場所だと思います。IDで。
Jason Bunting

7
CSSではドットを使用してクラスを識別/結合するという特別な意味があるため、IDでドットを使用するのは面倒です。「問題」はjqueryではありません。
Funka、

4

これはjQueryセレクターのドキュメントに記載されています:

!"#$%&'()*+,./:;<=>?@[\]^`{|}~名前のリテラル部分としてメタ文字(など)を使用するには、 2つのバックスラッシュでエスケープする必要があります\\。たとえば、を含む要素は id="foo.bar"、セレクターを使用できます$("#foo\\.bar")

要するに、接頭辞.\\次のように:

$("#Address\\.Country")

.自分のIDで機能しないのはなぜですか?

問題は、.特別な意味があることです。次の文字列はクラスセレクターとして解釈されます。そう$('#Address.Country')一致し<div id="Address" class="Country">ます。

としてエスケープする\\.と、ドットは通常のテキストとして扱われ、特別な意味はなく、目的のIDに一致します<div id="Address.Country">

これは!"#$%&'()*+,./:;<=>?@[\]^`{|}~、jQueryのセレクターとして特別な意味を持つすべての文字に適用されます。\\それらを通常のテキストとして扱うには、先頭に追加します。

なぜ2 \\

bdukesの回答で述べたように、2 \文字が必要な理由があります。\JavaScriptでは次の文字をエスケープします。JavaScriptは、文字列を解釈する際のSe "#Address\.Country"、それが表示されます\、を意味するためにそれを解釈litterally次の文字を取る削除文字列が引数として渡されたときに、それを$()。つまり、jQueryは文字列をとして認識し"#Address.Country"ます。

2番目\が出番です。最初のものはJavaScriptに2番目をリテラル(非特殊)文字として解釈するように指示します。これは、2番目がjQueryによって認識され、次の. 文字がリテラル文字であることを理解することを 意味します。

ふew!多分それを視覚化することができます。

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

2

2つのバックスラッシュを使用しても問題ありません。ただし、動的な名前、つまり変数名を使用している場合は、文字を置き換える必要があります。

変数名を変更したくない場合は、次のようにします。

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

そして、あなたはあなたのjqueryオブジェクトを持っています。


0

追加情報:このASP.NET MVCの問題#2403を確認してください。

問題が修正されるまで、Html.TextBoxFixedなどの独自の拡張メソッドを使用します。これは、(name属性ではなく)id属性でドットをアンダースコアに置き換えるだけなので、$( "#Address_Street")のようなjqueryを使用します。サーバー上では、Address.Streetのようになります。

サンプルコードは次のとおりです。

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
上記の問題から:「UpdateModel()は、フォーム要素の入力方法であるため、ドットを使用します。フォーム要素は、HTMLヘルパー呼び出しでの指定方法により、ドットを使用します。HTMLヘルパー呼び出しでは、ドットが使用されます。 ViewData.Eval()は機能します。最後に、ViewData.Eval()はドットを使用します。これは、メインの.NET Framework言語でオブジェクトとそのプロパティを分離する方法だからです。このチェーンの任意のポイントでドット以外の区切り文字を使用すると、壊れます。チェーン全体の流れ。」
Simon_Weaver

0

私はjquery docsによって与えられた解決策で問題を解決しました

私の機能:

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

function jq(myid){


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


}

注:コードでIDを別のテキストと連結するため、「#」を削除します

フォント: jquery Docs select element with especial chars

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.