Click here to Skip to main content
12,957,731 members (61,517 online)
Click here to Skip to main content
Add your own
alternative version


12 bookmarked
Posted 5 Jun 2013

Persist JavaScript changes on postback

, 6 Jun 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
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:

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

      Text="Your choice has been saved." /></td>

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:

<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:

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:

<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:

If IsPostBack AndAlso persistAvatar.Value <> "*" Then            
    UserAvatar.ImageUrl = persistAvatar.Value
    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:

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.


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


About the Author

Gregory Gadow
Software Developer (Senior)
United States United States
Gregory Gadow is currently a student at Central Washington University, studying for a B.S. in Actuarial Science with plans to graduate in June, 2019. He has been writing code for almost 30 years in more than a dozen programming languages. Previously, he worked for a mid-size brokerage firm as the company's programming department doing VB6, VB.Net, ASP, HTML, XML and SQL. He also held the Series 7 and Series 66 brokerage licenses.

You may also be interested in...

Comments and Discussions

GeneralMy vote of 5 Pin
Mihai MOGA13-Jul-13 20:51
professionalMihai MOGA13-Jul-13 20:51 
QuestionIt's kind of ironic Pin
Member 90401376-Jun-13 5:33
memberMember 90401376-Jun-13 5:33 
AnswerRe: It's kind of ironic Pin
Gregory.Gadow6-Jun-13 7:59
memberGregory.Gadow6-Jun-13 7:59 
GeneralMy vote of 5 Pin
HaBiX5-Jun-13 19:57
memberHaBiX5-Jun-13 19:57 
GeneralRe: My vote of 5 Pin
Gregory.Gadow6-Jun-13 3:31
memberGregory.Gadow6-Jun-13 3:31 
GeneralMy vote of 5 Pin
Tadit Dash5-Jun-13 6:09
professionalTadit Dash5-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.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170525.1 | Last Updated 6 Jun 2013
Article Copyright 2013 by Gregory Gadow
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid