hatch22
hatch22

Reputation: 807

ASP (.NET 4) ViewState enabled Literal control not retaining changes to HTML contents on PostBack

I am populating a ListView with HTML from a database using a Literal with Text='<%#Eval("HTMLData")'%>. When I trigger a PostBack, changes to the loaded HTML are not being reflected in litRowData.Text.

ViewState is enabled for the page, the ListView, and the Literal in the ItemTemplate, and I am making sure to only populate the ListView with initial values from the database when if(!IsPostBack) is true in Page_Load.

<asp:ListView ID="lvForm" runat="server"
            DataKeyNames="RowID" ItemPlaceholderID="phRow"
            EnableViewState="true">
    <LayoutTemplate>
        <asp:PlaceHolder ID="phRow" runat="server" />
    </LayoutTemplate>
    <ItemTemplate>
        <asp:Literal ID="litRowData" runat="server" Text='<%#Eval("HTMLData")%>'
        EnableViewState="true"></asp:Literal>
    </ItemTemplate>
</asp:ListView>

I need to be able to capture changes to the contents of the loaded HTML controls. Since this HTML comes from a database table, I can't just use ASP controls inside the ItemTemplate. Can anyone see something I'm missing, or suggest an alternative way to do this?

Edit: To clarify a little more, I'm trying to load form input elements dynamically from a database, render them as HTML controls on the page, allow the user to modify their contents by entering text or selecting options, then capture the modified HTML and save it back to the database when the user clicks a save button.

Upvotes: 0

Views: 3596

Answers (2)

welegan
welegan

Reputation: 3043

This answer builds on the prior one now that you have a .NET TextBox control that is correctly posting back the value of edits. Right below it, you can add to code behind:

protected void Page_Load(object sender, EventArgs e)
{
    litRowData.Attributes.Add("onKeyUp", "WriteText(this.value)");
}

Html:

<ItemTemplate>
    <asp:TextBox ID="litRowData" runat="server"  />
</ItemTemplate>

<div id="yourPreview"></div>
<script type="text/javascript">
   function WriteText(val){
       document.getElementById("yourPreview").innerHTML=val
    }
</script>

Upvotes: 0

welegan
welegan

Reputation: 3043

The way postback works in .NET is actually a wrapper around the more basic idea of HTML forms. A basic example of HTML forms is:

<html>
<body>
<form action="" method="POST">
    <input type="text" value="type here" />
    <input type="submit" value="go" />
</form>
</body>
</html>

Roughly, what the .NET abstraction adds is:

<html>
<body>
<form action="" method="POST">
    <input type="hidden" name="__VIEWSTATE" value="string-encoded-value" />
    <input type="text" name="bob" value="type here" />
    <input type="submit" value="go" />
</form>
</body>
</html>

Whereby on postback to your page, all input elements with names are mapped back into properties of your Page object, and the __VIEWSTATE hidden field is deserialized into all properties of objects that do not correspond to values of html input tags. For example, if Page.bob had a DateTime property associated with it, it would be stored in __VIEWSTATE possibly.

ASP.NET Literal tags in Page markup will get printed into the browser exactly as is, meaning that if you have <span>bob</span> as its value, that is how it will appear within the <form> tag. However, in plain HTML world, <form> tags when posted will only contain the values of certain form elements (aka not every div, span, p etc. gets posted back, only input, select, textarea and some others). So if your literal doesn't contain an input then it won't even get posted back meaning __VIEWSTATE will be used to restore the Value property of the Literal back to its initial state.

To fix this, you probably don't want to stick html into a Literal because even if you do it's not clear that it will get associated with the right property of your page. Instead, try a TextBox element or something else that gets written as an input element directly by the ASP.NET webforms code. Alternatively, try using javascript to allow modifications of flat text in divs if you don't need to persist the data.

Upvotes: 1

Related Questions