質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

Q&A

解決済

1回答

1042閲覧

asp.netでdiv要素の値を保持したい

ruuuki

総合スコア4

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

0グッド

1クリップ

投稿2023/05/28 09:40

編集2023/05/29 01:48

実現したいこと

contenteditableのdiv要素と、buttonを配置しています。
postback後も
TextBoxのようにdivの値を保持し、表示したいです。

発生している問題・エラーメッセージ

postback後も値を保持したいのですが、
保持できずに恐らく再描画にて初期化されてしまいます。

aspx

1<%@ Page Language="VB" ViewStateMode="Enabled" %> 2 3<%@ Import Namespace="System" %> 4<%@ Import Namespace="System.IO" %> 5<%@ Import Namespace="System.Web.UI.HtmlControls" %> 6<%@ Import Namespace="System.Windows.Forms" %> 7<%@ Import Namespace="System.Data" %> 8 9 10<script runat="server" lang="VB"> 11 Protected Sub Page_Load(sender As Object, e As EventArgs) 12 If Session("d") IsNot Nothing Then 13 Dim content As String = Session("d") 14 d.InnerHtml = content 15 Session.Remove("d") 16 End If 17 End Sub 18 19 Protected Sub btn1_Click(sender As Object, e As EventArgs) 20 Dim content As String = d.InnerHtml 21 Session("d") = content 22 End Sub 23</script> 24 25 26<html> 27<head> 28 <title></title> 29 <style> 30 div { 31 border: 1px solid black; 32 } 33 </style> 34</head> 35<body> 36 <form runat="server"> 37 <div runat="server" id="d" contenteditable="true"></div> 38 <asp:Button runat="server" ID="btn1" OnClick="btn1_Click" Text="post" /> 39 </form> 40</body> 41</html>

Page_Loadに、
If Page.IsPostBack = True Then
Dim content As String = d.InnerHtml
Session("d") = content
End If
や、Page_Unloadに、
Dim content As String = d.InnerHtml
Session("d") = content
としてみても思っているように保持できずにいます。

基本的なところで躓いてしまっています。

追記 開発環境

・Windows10
・Visual Studio 2019 Version 16.11.15
・ASP.NET Web Forms
・バージョン情報:Microsoft .NET Framework バージョン:4.0.30319;ASP.NET バージョン:4.8.4494.0
です。

ご教授いただけると幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2023/05/28 22:48

開発環境を質問欄を編集して追記してください。(例: Windows 10 の Visual Studio 2022 で ASP.NET Web Forms アプリをターゲットフレームワーク .NET Framework 4.8 で作っています・・・とか)
ruuuki

2023/05/29 01:48

ありがとうございます。情報の追記を致しました。
guest

回答1

0

ベストアンサー

contenteditableのdiv要素と、buttonを配置しています。postback後もTextBoxのようにdivの値を保持し、表示したいです。

ASP.NET Web Forms アプリは、サーバーコントロール + ViewState + ポストバックによって、ポストバック前後で状態を維持しています。

TextBox コントロールの場合は、ポストバック時にサーバー側で以下の操作を行います。

(1) ブラウザから送信されてきた ViewState の中に Text プロパティのデータが入っている場合 (それはポストバック前の値になります)、Text プロパティを ViewState の値に設定。

(2) 次に、ブラウザからポストされてきた TextBox へのユーザー入力と、(1) で設定された Text プロパティの値を比較し、異なっていると Text プロパティをポストされた値で書き換える。

それゆえポストバック前後で状態が維持されます。

div 要素の場合は、たとえそれに runat="server" 属性を追加してサーバーコントロールにしても、上の (1), (2) の機能はないので、単独では「postback後もTextBoxのようにdivの値を保持」はできません。

質問者さんのコードを見ると、Session を使って何とかしようとしているようですが、div 要素へのユーザー入力はサーバーには送信されないのでそれでは無理です。

そこを何とかしようとすると、例えば、隠しフィールド (HiddenField コントロール) と JavaScript を使って、form を submit する (ポストバックする) 前に隠しフィールドの value に div 要素の InnerHTML を設定し、ポストバックの応答で再描画されるときに div 要素の InnerHTML に隠しフィールドの value を設定・・・というようなコードを書くことになります。

HiddenField はサーバーコントロールなので ViewState を持っていて、ポストバック前後で状態が維持されます。Value プロパティの値はポストバックの際サーバーに送信されます。 

具体例は以下の通りです。

html

1<%@ Page Language="C#" AutoEventWireup="true" 2 CodeBehind="WebForm25.aspx.cs" Inherits="WebForms1.WebForm25" %> 3 4<!DOCTYPE html> 5 6<html xmlns="http://www.w3.org/1999/xhtml"> 7<head runat="server"> 8 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 9 <title></title> 10 <style> 11 div { 12 border: 1px solid black; 13 } 14 </style> 15 <script type="text/javascript"> 16 //<![CDATA[ 17 18 let form, div, hidden; 19 20 // DOMContentLoaded イベントで初期設定を行う 21 window.addEventListener('DOMContentLoaded', () => { 22 form = document.getElementById("<%=form1.ClientID%>"); 23 div = document.getElementById("d"); 24 hidden = document.getElementById("<%=HiddenField1.ClientID%>"); 25 26 // div 要素の InnerHTML に隠しフィールドの value を設定 27 div.innerHTML = hidden.value; 28 29 // form を submit する (ポストバックする) 前に隠しフィールド 30 // の value に div 要素の InnerHTML を設定 31 form.addEventListener('submit', () => { 32 hidden.value = div.innerHTML; 33 }); 34 }); 35 36 //]]> 37 </script> 38</head> 39<body> 40 <form id="form1" runat="server"> 41 42 <div id="d" contenteditable="true"></div> 43 <asp:Button runat="server" ID="btn1" Text="post" /> 44 45 <asp:HiddenField ID="HiddenField1" runat="server" /> 46 47 </form> 48</body> 49</html>

サーバー側で div 要素へのユーザー入力を取得する場合は、HiddenField の Value プロパティから取得してください。

投稿2023/05/29 03:27

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ruuuki

2023/05/29 06:01

ご丁寧にASP.NET WebFormsアプリの仕組みまで教えてくださりありがとうございます。 ・div要素はサーバーコントロールではない (今後、ツールボックスでサーバコントロールかどうかで判断するようにします) ・サーバーコントロールではないためrunat="server"属性をつけてもダメ ・サーバーコントロールではないものの値をPostBack後に取得したい場合は、クライアントサイドの処理が必要 ・具体的には一度サーバーコントロールのHiddenFieldに値をsubmitで一時的に渡しておいて、Loadの際に取り出す ということですね。 おかげさまで無事に出来ました。 ありがとうございます! ひとつ気になったことなのですが… SurferOnWww様からご回答頂く前に海外サイトで、 この件について調べていました。 その際、サーバーコントロールのPanelはレンダリングの際に、divに変換されるという情報を得て、 値を保持できるのではと思い、divではなく、panelに書き換えました。 しかし、結果はダメでした。 divの元々の性質上、 要素をグループ化するためのだから、 runat属性をつけても、そもそも値を保持するといった役割ではないため、たとえサーバーコントロールであっても値を保持出来るものと出来ないものがあり、panel(レンダリング時div)にはその機能がないため出来なかったということかなと感じたのですが、そういうことでしょうか? しかし、 PanelにもViewStateModeというものがあるのが気になります… Panelを起点に、子要素のものに反映されるということなのでしょうか。
退会済みユーザー

退会済みユーザー

2023/05/29 08:55 編集

HTML の基本的なことを勉強することをお勧めします。 TextBox が ASP.NET によって html に変換されると、input type="text" 要素にになります。ちなみに、HiddenFiled は input type="hidden" に、Button は input type="submit" になります。 input 要素はブラウザから送信されてくるデータを受け取るためのもので、input 要素が form 要素に含まれている場合、form を submit する(ポストバックする)と、それら input 要素の value 属性の値がサーバーに送信されます。 なので、Button クリックでポストバックされると、それらの input 要素の value 属性の値がサーバーに送信され、上の回答の (1), (2)に書いたようになりますので、TextBox の場合 Text プロパティから値を取得できます。 一方、そもそも div 要素は input 要素のようなサーバーにデータを送信する機能は持ちません。 div 要素に runat="server" 属性を追加してサーバーコントロールにすることはできますが、そうするとサーバー側の C# または VB.NET のプログラムでアクセスできるようになるというだけで、やはりサーバーにデータを送信する機能は持たないことに変わりありません。 なので、 > ・div要素はサーバーコントロールではない その通りです。でも、そこは今回の話の本質ではありません。 > ・サーバーコントロールではないためrunat="server"属性をつけてもダメ 上に書いたように、runat="server" 属性をつければサーバーコントロールにはなります。ダメなのは、div 要素はサーバーにデータを送信する機能は持たないというところです。 > ・サーバーコントロールではないものの値をPostBack後に取得したい場合は、クライアントサイドの処理が必要 サーバーコントロールでなくても、input 要素であれば「クライアントサイドの処理」は不要で、単にポストバックするだけで値が送信され、サーバー側で値を取得できます。 div がダメなのは上に書いたようにサーバーにデータを送信する機能は持たないからで、div 要素の innerHTML の値をサーバーに送るためには何らかのクライアント側での処理が必要ということです。 > ・具体的には一度サーバーコントロールのHiddenFieldに値をsubmitで一時的に渡しておいて、Loadの際に取り出すということですね。 必ずしもサーバーコントロールである必要はありません。普通の HTML の input type="hidden" でもサーバーに値を送信し、サーバー側で値を取得することはできます。 サンプルコードで HiddenField を使った理由は、サーバーコントロールなので自動的に ViewState に Value プロパティの値が保持されるからです。 > Panelを起点に、子要素のものに反映されるということなのでしょうか。 違います。Panel の ViewState は Panel 自身のプロパティの値に反映されます。子要素には関係ありません。
ruuuki

2023/05/29 09:48

ひとつひとつ教えてくださりありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問