Click here to Skip to main content
15,881,687 members
Articles / Web Development / HTML

Persist JavaScript changes on postback

Rate me:
Please Sign up or sign in to vote.
4.93/5 (9 votes)
6 Jun 2013CPOL3 min read 29.5K   12   6
Use JavaScript to let your web user make changes, and then retrieve those changes server-side on postback.

The Problem

I have been developing a simple XML-based message board (I'll write an article on that when the project is done.) I wanted to let forum users select an image to serve as their avatar on the boards, but having to reload the page every time the user selected an image was a pain: the reload time was noticeable, and each postback created a history entry that was annoying. The obvious answer was to use JavaScript to update the user's image; that worked fine. Unfortunately, changing the src attribute of the generated img did not persist when I did want a postback to save the information.

The Solution

First off, here is my original HTML:

HTML
<table>
  <tr>
    <td rowspan='2'><asp:Image ID="UserAvatar" runat="server" /></td>
    <th><asp:Literal ID="UserName" runat="server" /></th>
  </tr>
  <tr>
    <td>Click on an image below to change your avatar.</td>
  </tr>
  <tr>
    <td></td>
    <td><asp:Button ID="SaveButton" runat="server" Text="Save" OnClick="SaveButton_Click" /></td>
  </tr>
  <tr>
    <td colspan='2'><asp:Literal ID="ConfirmationText" runat="server" Visible="false" 
      Text="Your choice has been saved." /></td>
  </tr>
</table>

Pretty straightforward. The second row has only a single cell, as the cell containing UserAvatar stretches down to fill the first cell position thanks to the rowspan attribute.

The solution I found starts with adding a hidden input field somewhere on the form; I put this underneath the code for my table:

HTML
<input type="hidden" id="persistAvatar" value="*" runat="server" />

Note the use of the runat attribute. This is important. Just as an ASP control gets rendered as vanilla HTML, you can effectively turn vanilla HTML into an ASP control by using this attribute: it instructs the compiler to allocate space in the view state and allow it to be accessed in code-behind. I think this is functionally equivalent to using a asp:HiddenField control, but I haven't tested it. The default value is so that I can test if the field has been used or not.

The next step was to add the JavaScript that would update the UserAvatar image:

JavaScript
function setAvatar(e) {
  var img = document.getElementById('ctl00_ContentHolder_UserAvatar');
  var hold = document.getElementById('ctl00_ContentHolder_persistAvatar')
  img.src = e.getAttribute('src'); ;
  hold.value = e.getAttribute('src');
  return true;
}

Note that, because of the runat, the id for persistAvatar is mangled with the master page, exactly as if it were an ASP control. e is the image that the user clicked. The src of UserAvatar  and the value of persistAvatar are set to the source of the clicked image. The available images are arranged in a table on the page; a typical image looks like this:

HTML
<img src='myserver/images/avatar/angry_baby.jpg' alt='' onclick='setAvatar(this);' />

So now, all of the pieces are in place: the user clicks an image, the selected image appears in the form, and the name of the file is saved to a hidden field, all without a postback.

One other piece of infrastructure needs to be added, to make sure that the avatar image is loaded properly out of the view state. In the page's Load event, I have this code:

VB.NET
If IsPostBack AndAlso persistAvatar.Value <> "*" Then            
    UserAvatar.ImageUrl = persistAvatar.Value
Else
    UserAvatar.ImageUrl = String.Format("/images/avatar/{0}", MyUser.ForumAvatar)
End If

When the page is first loaded, or on postback if the user made no change to the avatar image, UserAvatar is set to show image that already exists in the data store. If the user has clicked something else, then UserAvatar is set to the src of the selected image, which had been saved in persistAvatar. When the page is delivered to the user, the displayed image will be correct.

And so we come to the last bit, when the user actually clicks on the Save button and a postback occurs. Simplicity in itself:

VB.NET
Protected Sub SaveButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)
    Dim U As User = Access.GetUser(MyUser.UserId)
    U.ForumAvatar = System.IO.Path.GetFileName(UserAvatar.ImageUrl)
    ConfirmationText.Visible = Access.UpdateUser(U)
End Sub

I retrieve the currently stored data for the web user, parse out the name of the designated image file, save it to the data structure, and update the data store.

Moving On

It was a bit of a challenge finding out how to do this, as it's not exactly intuitive. But once I found some examples (and many thanks to Tadit Dash for pointing me in the right direction) I realized that it is pretty simple. This technique should be easily extensible, with a hidden field for each piece of data that you need to persist.

If you have anything to add, let me know in the comments. And as always, if you found this useful, please vote up.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
Gregory Gadow recently graduated from Central Washington University with a B.S. that combined economics and statistical analysis, and currently works for the Washington Department of Fish & Wildlife as an IT developer. He has been writing code for 30 years in more than a dozen programming languages, including Visual Basic, VB.Net, C++, C#, ASP, HTML, XML, SQL, and R.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Ștefan-Mihai MOGA13-Jul-13 20:51
professionalȘtefan-Mihai MOGA13-Jul-13 20:51 
QuestionIt's kind of ironic Pin
B. Clay Shannon6-Jun-13 5:33
professionalB. Clay Shannon6-Jun-13 5:33 
AnswerRe: It's kind of ironic Pin
Gregory Gadow6-Jun-13 7:59
Gregory Gadow6-Jun-13 7:59 
GeneralMy vote of 5 Pin
HaBiX5-Jun-13 19:57
HaBiX5-Jun-13 19:57 
GeneralRe: My vote of 5 Pin
Gregory Gadow6-Jun-13 3:31
Gregory Gadow6-Jun-13 3:31 
GeneralMy vote of 5 Pin
Tadit Dash (ତଡିତ୍ କୁମାର ଦାଶ)5-Jun-13 6:09
protectorTadit Dash (ତଡିତ୍ କୁମାର ଦାଶ)5-Jun-13 6:09 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.