none
Visual C# 2008 / document.getelementbyid(...).value / IE8以降 エラー RRS feed

  • 質問

  • Visual Studio 2008 C#でASP.NETを 開発をしております。

    IE8以降で実行すると下記の箇所でエラーが発生します。

    (IE10の開発者ツール-ブラウザモードでIE7~IE10まで検証したところIE7のみエラーになりませんでした)

    発生個所:document.getElementById("...").value

    エラーメッセージ:プロパティ 'value' の値を取得できません: オブジェクトは Null または未定義です。

    何か知恵をおかしいただけると幸いです、

    2013年8月28日 2:17

回答

  • > わたくしが示したソースではどの様に呼び出せばよろしいでしょうか?
    > 示していただいた例のようにascxでTextBoxClientIDを宣言をしている箇所が見当たりません。

    先のレスで「ユーザーコントロール (.ascx)  に、C# のコードで TextBox の ClientID を取得するためのパブリック・プロパティを追加」と説明し、サンプルコードまで書きましたが、分かりませんか? 質問者さんが自分で「既存ソース」に追加するのです。


    > document.getElementById("<%=thismonthBegin.ClientID%>");
    >
    > で呼び出すと、以下のように認識されてしまい"_Control_Date"がぬけてしまいます。

    それは、ユーザーコントロールの ClientID を取得しているからです。

    そうではなくて、ユーザーコントロールで使っている TextBox の ClientID を取得しないとダメです。そのために「ユーザーコントロール (.ascx)  に、C# のコードで TextBox の ClientID を取得するためのパブリック・プロパティを追加」が必要なのです。

    ソースのないカスタムコントロールならともかく、ユーザーコントロールで「既存ソース」なのだから簡単に追加できると思ったのですが。

    • 回答としてマーク xxxxxyz 2013年9月18日 1:52
    2013年8月28日 8:55

すべての返信

  • getElementById() というメソッド名です。メソッド名の意味する通り "..." の 部分は実在する id なのでしょうか? つまりHTMLには <input id="..." /> のようにidが書かれていますか?

    # IE7以前は名前に反して id 以外にも name での検索結果も返します。

    2013年8月28日 2:27
  • ご返信ありがとうございます。

    下記の定義になっています。

    スクリプト部分

    document.getElementById("ctl00_body_thismonthBegin_Control_Date").value

    HTML部分

    <input name="ctl00$Body$thismonthBegin$Control_Date" type="text" value="2013/08/10" id="ctl00_Body_thismonthBegin_Control_Date" class="imeDisabled" autocomplete="on" style="width:70px;text-align:justify" />

     
    2013年8月28日 2:43
  • ご返信ありがとうございます。

    下記の定義になっています。

    スクリプト部分

    document.getElementById("ctl00_body_thismonthBegin_Control_Date").value

    HTML部分

    <input name="ctl00$Body$thismonthBegin$Control_Date" type="text" value="2013/08/10" id="ctl00_Body_thismonthBegin_Control_Date" class="imeDisabled" autocomplete="on" style="width:70px;text-align:justify" />

     

    idの大文字小文字が一致してませんが。(bodyとBody)
    • 回答の候補に設定 星 睦美 2013年8月28日 7:14
    2013年8月28日 2:57
  • サーバーコントロールの TextBox を ASP.NET が <input type="text" ... にレンダリングした際、ClientID として ctl00_Body_thismonthBegin_Control_Date を付与したということですよね。

    であれば、それを JavaScript のコードにハードコーディングすべきではありません。今はよくても、将来 ClientID の命名規則が変わると動かなくなりますし、コードの可読性もよくないので保守の問題もありそうです。

    インラインのスクリプトであれば、以下のようにすることをお勧めします。

    document.getElementById("<%=TextBox1.ClientID%>").value
    


    外部ファイルのスクリプトであれば、例えば関数の引数として ClientID を渡せるよう、サーバー側の C# のコードを工夫してみてください。
    2013年8月28日 3:59
  • >Hongliangさん

    ご指摘の通り大文字、小文字の不整合を修正したところエラーが解消されました。

    IE8以降大文字。小文字を区別するようになったのでしょうか。

    2013年8月28日 5:56
  • >SurferOnWwwさん

    正確に申しますと

    同一aspxX内に

    ・JavaScript

    document.getElementById("ctl00_body_thismonthBegin_Control_Date").value

    ・HTML

    <Ctrl:DateCtrl ID="thismonthBegin" runat="server"  />

    が定義されており、ブラウザでソースを参照するとコントロールは下記が展開されています。

     <!--日付コントロール-->
     <input name="ctl00$Body$thismonthBegin$Control_Date" type="text" value="2013/08/10" id="ctl00_Body_thismonthBegin_Control_Date" class="imeDisabled" autocomplete="on" style="width:70px;text-align:justify" />
     <input type="hidden" name="ctl00$Body$thismonthBegin$Control_DateMaskEditExtender_ClientState" id="ctl00_Body_thismonthBegin_Control_DateMaskEditExtender_ClientState" />
     <span id="ctl00_Body_thismonthBegin_Control_DateMaskEditValidator" style="color:Red;display:none;"></span>

    今回、ctl00_Body_thismonthBegin_Control_Dateをdocument.getElementByIdで呼び出したいのですが、

    ご指摘の修正を適用すべきでしょうか。

    元が既存ソースの為修正箇所が膨大です。

    Ctrl:DateCtrlのascx

    <!--日付コントロール-->
     <asp:TextBox ID="Control_Date" runat="server" Width="130px" MaxLength="1" CssClass="imeDisabled" style="text-align:justify" autocomplete="on" ValidationGroup="MKE" />
     <Ajax:MaskedEditExtender ID="Control_DateMaskEditExtender" runat="server"
                TargetControlID="Control_Date"
                Mask="9999/99/99"
                MessageValidatorTip="true"
                OnFocusCssClass="MaskedEditFocus"
                OnInvalidCssClass="MaskedEditError"
                MaskType="Date"
                DisplayMoney="Left"
                AcceptNegative="Left"
                ErrorTooltipEnabled="True" />
     <Ajax:MaskedEditValidator ID="Control_DateMaskEditValidator" runat="server"
                ControlExtender="Control_DateMaskEditExtender"
                ControlToValidate="Control_Date"
                Display="Dynamic"
                EmptyValueBlurredText="*"
                ValidationGroup="MKE" />
     <Ajax:CalendarExtender ID="Control_CalendarExtender"  Format="yyyy/MM/dd" runat="server" TargetControlID="Control_Date" PopupButtonID="ImgBntCalc" />
    

     

    2013年8月28日 6:00
  • 以下のようなことと理解してます。理解が違っていたら、具体的にどのように違うかを連絡ください。

    (1) ASP.NET 標準の TextBox と AJAX Control Toolkit の Extender を使ったユーザーコントロール (.ascx) がある。

    (2) そのユーザーコントロールを使用している .aspx ページで、JavaScript の getElementById メソッドを使用して、ユーザーコントロールの TextBox に該当する input 要素を取得し、その value 属性の値を取得したい。

    (3) JavaScript のコードは、.aspx ページにインラインで書かれている。

    (4) ユーザーコントロールの TextBox の ClientID を、JavaScript のコードの getElementById メソッドの引数に埋め込みたい。


    上記の理解が正しければ、ユーザーコントロール (.ascx)  に、C# のコードで TextBox の ClientID を取得するためのパブリック・プロパティを追加し、.aspx ページではそのパブリック・プロパティをコードブロック(即ち、<% ... %>)で埋め込んでやればいいはずです。

    具体的には以下のような感じです。

    ユーザーコントロール (.ascx)

    <%@ Control Language="C#" ClassName="WebUserControl" %>
    
    <script runat="server">
    
        public string TextBoxClientID
        {
            get { return Control_Date.ClientID; }
        }
    </script>
    
    <asp:TextBox ID="Control_Date" 
        runat="server" 
        Width="130px" 
        MaxLength="1" 
        CssClass="imeDisabled" 
        style="text-align:justify" 
        autocomplete="on" 
        ValidationGroup="MKE" />
    ・・・以下省略・・・

    .aspx ページ

    <body>
        <form id="form1" runat="server">
        <asp:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server">
        </asp:ToolkitScriptManager>
        <div>
            <Ctrl:DateCtrl ID="thismonthBegin" runat="server" />
        </div>
        </form>
        <script type="text/javascript">
        //<![CDATA[
            window.onload = function () {
                var element = document.getElementById("<%=thismonthBegin.TextBoxClientID%>");
                element.onchange = function () {
                    alert(element.value);
                }
            }
        //]]>
        </script>
    </body>

    AJAX Control Toolkit の TabContainer や Calendar を使用する際、head 要素内にコードブロック(即ち、<% ... %>)を定義すると例外がスローされるという問題があるので注意してください。詳細は下記ページを参照してください。回避策はコードブロックを head タグの外に移動するだけです。

    ACT の TabContainer
    http://surferonwww.info/BlogEngine/post/2010/11/05/Ploblem-in-TabCaintainer-and-Calendar-of-AJAX-Control-Toolkit.aspx

    2013年8月28日 7:51
  • ご回答ありがとうございます。

    上記の認識で合っています。


    ただ、呼び出し方で1点確認させてください。

    示していただいた例では下記で呼び出していますが、

    document.getElementById("<%=thismonthBegin.TextBoxClientID%>");

    わたくしが示したソースではどの様に呼び出せばよろしいでしょうか?


    示していただいた例のようにascxでTextBoxClientIDを宣言をしている箇所が見当たりません。

    document.getElementById("<%=thismonthBegin.ClientID%>");

    で呼び出すと、以下のように認識されてしまい"_Control_Date"がぬけてしまいます。

    document.getElementById("ctl00_body_thismonthBegin")

     

    回答に必要な情報ぬけていましたらお知らせください。

    2013年8月28日 8:17
  • > わたくしが示したソースではどの様に呼び出せばよろしいでしょうか?
    > 示していただいた例のようにascxでTextBoxClientIDを宣言をしている箇所が見当たりません。

    先のレスで「ユーザーコントロール (.ascx)  に、C# のコードで TextBox の ClientID を取得するためのパブリック・プロパティを追加」と説明し、サンプルコードまで書きましたが、分かりませんか? 質問者さんが自分で「既存ソース」に追加するのです。


    > document.getElementById("<%=thismonthBegin.ClientID%>");
    >
    > で呼び出すと、以下のように認識されてしまい"_Control_Date"がぬけてしまいます。

    それは、ユーザーコントロールの ClientID を取得しているからです。

    そうではなくて、ユーザーコントロールで使っている TextBox の ClientID を取得しないとダメです。そのために「ユーザーコントロール (.ascx)  に、C# のコードで TextBox の ClientID を取得するためのパブリック・プロパティを追加」が必要なのです。

    ソースのないカスタムコントロールならともかく、ユーザーコントロールで「既存ソース」なのだから簡単に追加できると思ったのですが。

    • 回答としてマーク xxxxxyz 2013年9月18日 1:52
    2013年8月28日 8:55