2009-06-15 26 views
50

私はこれを期待:ASP.Net RadioButtonとCheckBoxがSpan内でレンダリングされるのはなぜですか?

<input id="CheckBox1" type="checkbox" class="myClass" /> 
<input id="RadioButton1" type="radio" class="myClass" /> 
<input id="TextBox1"  type="text"  class="myClass" /> 

...実際には、RadioButtonCheckBox

<asp:CheckBox ID="CheckBox1" runat="server" CssClass="myClass" /> 
<asp:RadioButton ID="RadioButton1" runat="server" CssClass="myClass" /> 
<asp:TextBox  ID="TextBox1"  runat="server" CssClass="myClass" /> 
が...この のようにレンダリングするために(いくつかの単純化のために削除する属性を持ちます) spanタグでラップされ、そこにCSSクラスが適用されます。

<span class="myClass"><input id="CheckBox1" type="checkbox" /></span> 
<span class="myClass"><input id="RadioButton1" type="radio" /></span> 
<input type="text" id="TextBox1" class="myClass" /> 

これには理由がありますが、避ける方法はありますか?

$("input.myClass") 

確かにそれだけに起こっている:あなたがそれらのすべてをキャッチすることはできませんので、それはjQueryのセレクタが醜いになり

$("input.myClass, span.myClass input") 

を...しかし、それは醜いです。私は自分自身のセレクターを書くことができましたが、やはりエレガントではありません。

+0

どのようにちょうど$( "。myClass")? – Hardwareguy

+1

答えはありませんが、ちょっと待ってください - 数年前に.NETプラットフォームで作業を始め、JSを使ってチェックボックスの値を調べていたのですが、なぜ私の値が警告する。スペックタグとは何でしょうか。私はいつもMSがラジオボタンとチェックボックスの冗長タグを追加した理由を疑問に思ってきました! – Dhana

+0

@Hardwareguy時にはそれがスパンになり、時にはそれが入力になります。それが問題だ。 $( "input.myclass")は多少特殊性があるかもしれませんが、$( "。myClass")は同じ頭痛を与えます。 – Mark

答えて

42

System.Web.UI.WebControls名前空間内のWebコントロールが、異なるブラウザでレンダリングされることがあります。同じ要素を常にレンダリングすることはできません。特定のブラウザで動作させるために必要と思われるものを追加することがあります。

コントロールがHTMLとしてレンダリングされる方法を制御したい場合は、代わりにSystem.Web.UI.HtmlControlsのコントロールを使用する必要があります。つまり:

<input type="checkbox" id="CheckBox1" runat="server" class="myClass" /> 
<input type="radio" name="RadioButton1" runat="server" class="myClass" /> 
<input type="text" id="TextBox1" runat="server" class="myClass" /> 

追加の要素を追加せずに、対応するhtml要素と同じようにレンダリングされます。これはもちろん、コントロールとは異なり、ブラウザの互換性について責任を負わなければならないことを意味します。また、これらのコントロールには、WebControls名前空間のコントロールのすべての機能が含まれていません。

+0

ポストバックがいくつ発生するかで、これはもっと頭痛になると思います。私は、デフォルトでこれらのコントロールを使用し、必要に応じてWebControlsを強化する必要があることに同意します。 – Mark

+14

これを行うつもりならば、ASP.Net MVCだけを使うかもしれません;) – womp

+5

@womp私はこれをオプションにするのが大好きです。 – Mark

5

デフォルトでは、すべてのWebControlは、<span>タグと、コントロールの作成者が追加するカスタムレンダリングとしてレンダリングされます。

カスタムWebControlを作成するときに最初に行うことの1つは、「TagKey」プロパティをオーバーライドしてdivなどをレンダリングすることです。このプロパティの既定値はHtmlTextWriterTag.Spanです。

チェックボックス項目をサブクラス化し、TagKeyプロパティをオーバーライドして別のものをレンダリングすることもできますが、すべてのチェックボックスを独自のバージョンにする必要があります。

+0

私はあなたの毒を選ぶ必要があると思います。一貫性のあるレンダリングのための醜いjQueryセレクタまたは散発的なサブクラス化されたコントロール。 _all_入力コントロールがスパンでレンダリングされた場合、私は涼しいでしょう。一貫性は途中でまともなことです。 – Mark

3

私はこの問題を遭遇し、制御アダプターを使用して解決しようとしています。

これをラジオボタンリストに表示する例は、hereを参照してください。

私は私のRadioButtonAdaptor-

using System; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Web.UI.WebControls.Adapters; 

public class RadioButtonAdapter : WebControlAdapter 
{ 
    protected override void Render(HtmlTextWriter writer) 
    { 
     RadioButton targetControl = this.Control as RadioButton; 

     if (targetControl == null) 
     { 
      base.Render(writer); 

      return; 
     } 

     writer.WriteBeginTag("input"); 
     writer.WriteAttribute("type", "radio"); 
     writer.WriteAttribute("name", targetControl.GroupName); 
     writer.WriteAttribute("id", targetControl.ClientID);    

     if (targetControl.CssClass.Length > 0) 
     { 
      writer.WriteAttribute("class", targetControl.CssClass); 
     }  

     writer.Write(" />"); 

    } 
} 

としてこれで終わった、これは私のブラウザに追加はもちろん

<browser refID="Default"> 
     <controlAdapters>    
      <adapter controlType="System.Web.UI.WebControls.RadioButton" 
       adapterType="RadioButtonAdapter" /> 
     </controlAdapters> 
</browser> 

をファイル - 、これにはいくつかの欠点があります。the above linkに記載されているものに加えて、すべてを含意しないと機能が失われます(上記のコードではラジオボタンがチェックされません)。 CSSに優しいコントロールアダプターがいくつかありますが、ラジオボタンコントロールはカバーしていません。 Reflectorを使用して、デフォルトのコントロールアダプタを開始点として取得することができます。

+0

私はこの提案が好きです!遅いコメント私は知っているが、これは今日私の多くを助けた! –

104

inputAttributesプロパティが見つかるまで、これは私を夢中にしていました。

例えば、ここではスパンナンセンスずにチェックボックスコントロールに直接クラスを追加する方法です:

myCheckBoxControl.InputAttributes.Add("class", "myCheckBoxClass") 
+7

もし私ができるなら、私は+1を与えることができないので、+100を与えるでしょう+1 :)ありがとう! – k25

+6

これは素晴らしい仕事です。また、 'LabelAttributes'はそれに応じて対応するチェックボックスのラベルをスタイルすることにも注意してください。 – magnattic

+0

'myCheckBoxControl.Attributes.Add'は' 'タグで' myCheckBoxControl.CssClass'と同じ振る舞いをトリガーしますが、 'myCheckBoxControl.InputAttributes.Add'はそうではありません。 –

0

は、同様の問題を発見/無効にするチェックボックスと親スパン

を有効にするために、単純なjQueryのベースの機能を書きました
function resetChk(ctl, bEnable) { 

      if (bEnable){ 
       ctl.removeAttr('disabled').parent().removeAttr('disabled'); 
      }else{ 
       ctl.attr('disabled', true).parent().attr('disabled', true); 
      } 

     } 
0

私が考える最良の方法はこれです:

 

    public class HtmlTextWriterNoSpan : HtmlTextWriter 
    { 
     public HtmlTextWriterNoSpan(TextWriter textWriter) : base(textWriter) 
     { 
     } 

     protected override bool OnTagRender(string name, HtmlTextWriterTag key) 
     { 
      if (name == HtmlTextWriterTag.Span) 
      { 
       return false; 
      } 

      return base.OnTagRender(name, key); 
     } 
    } 
 

私を使用するには、 tカスタムコントロール:

 

    protected override void Render(HtmlTextWriter writer) 
    { 
     writer = new HtmlTextWriterNoSpan(writer); 
     base.Render(writer); 
     // HERE MORE CODE 
    } 
 
1

プレーンラジオボタンは、多くの場合、スパンなしでレンダリングされます。 CssClass、Style、Enabledの各プロパティを設定すると、RadioButtonはスパンでレンダリングされます。クライアントサイドのスクリプトでラジオボタンを操作する必要があるとき、この矛盾は本当に苦痛です。私が通常やっているのは、ダミーのCssClassを適用して常にスパンを一貫してレンダリングすることです。

関連する問題