diff --git a/avatar.php b/avatar.php
index d0dced7de27d45d72642320a112d52c2de2f3ada..77c0a7fbeb566b8b3b91226a1d254a2d64b2c0d1 100644
--- a/avatar.php
+++ b/avatar.php
@@ -1,8 +1,8 @@
 <?php
 /*********************************************************************
-    file.php
+    avatar.php
 
-    File download facilitator for clients
+    Simple download utility for internally-generated avatars
 
     Peter Rotich <peter@osticket.com>
     Jared Hancock <jared@osticket.com>
diff --git a/include/ajax.staff.php b/include/ajax.staff.php
index 444f8ebb53d82bc9310b14b27deda0352a13771f..5356e9ccf6c52efb3f550da04c6cb3fb3ced1d75 100644
--- a/include/ajax.staff.php
+++ b/include/ajax.staff.php
@@ -222,7 +222,11 @@ class StaffAjaxAPI extends AjaxController {
         if (!($avatar = $staff->getAvatar()))
             Http::response(404, 'User does not have an avatar');
 
-        if ($avatar->toggle())
-            return $avatar;
+        if ($code = $avatar->toggle())
+          return $this->encode(array(
+            'img' => (string) $avatar,
+            // XXX: This is very inflexible
+            'code' => $code,
+          ));
     }
 }
diff --git a/include/class.avatar.php b/include/class.avatar.php
index 3896e7c693b7dc77cb0272d4b214ab8d067b15ff..54994d9206aa45e41e389742d6d7d7bc9ebafab3 100644
--- a/include/class.avatar.php
+++ b/include/class.avatar.php
@@ -102,6 +102,7 @@ AvatarSource::register('LocalAvatarSource');
 class LocalAvatar
 extends Avatar {
     var $mode;
+    var $code;
 
     function __construct($user, $mode) {
         parent::__construct($user);
@@ -112,8 +113,8 @@ extends Avatar {
         if (false && ($file = $this->user->getAvatarFile()))
             return $file->getDownloadUrl();
 
-        $code = false;
-        if (method_exists($this->user, 'getExtraAttr'))
+        $code = $this->code;
+        if (!$code && method_exists($this->user, 'getExtraAttr'))
             $code = $this->user->getExtraAttr('avatar');
 
         if ($code)
@@ -127,9 +128,8 @@ extends Avatar {
     }
 
     function toggle() {
-        $code = Misc::randCode(21);
-        $this->user->setExtraAttr('avatar', $code);
-        return $this->user->save();
+        $this->code = Misc::randCode(21);
+        return $this->code;
     }
 
     function isChangeable() {
diff --git a/include/class.staff.php b/include/class.staff.php
index 407ab13e20290dbdd4ca6b7f958f20f9344bd4ce..c1ed5a32fdd50d538896b9b03401e5c3d09e2380 100644
--- a/include/class.staff.php
+++ b/include/class.staff.php
@@ -622,6 +622,9 @@ implements AuthenticatedUser, EmailContact, TemplateVariable {
         $this->lang = $vars['lang'];
         $this->onvacation = isset($vars['onvacation'])?1:0;
 
+        if (isset($vars['avatar_code']))
+          $this->setExtraAttr('avatar', $vars['avatar_code']);
+
         if ($errors)
             return false;
 
diff --git a/include/staff/profile.inc.php b/include/staff/profile.inc.php
index b707371368b06a3e7038361a1ccab38291915bad..85a7a1338fe16f097c3dee80f88fe85886982819 100644
--- a/include/staff/profile.inc.php
+++ b/include/staff/profile.inc.php
@@ -18,7 +18,7 @@ if(!defined('OSTSTAFFINC') || !$staff || !$thisstaff) die('Access Denied');
     <table class="table two-column" width="940" border="0" cellspacing="0" cellpadding="2">
       <tbody>
         <tr><td colspan="2"><div>
-        <div class="avatar pull-left" style="margin: 10px 15px; width: 100px;">
+        <div class="avatar pull-left" style="margin: 10px 15px; width: 100px; height: 100px;">
 <?php       $avatar = $staff->getAvatar();
             echo $avatar;
 if ($avatar->isChangeable()) { ?>
@@ -27,12 +27,20 @@ if ($avatar->isChangeable()) { ?>
                 href="#ajax.php/staff/<?php echo $staff->getId(); ?>/avatar/change"
                 onclick="javascript:
     event.preventDefault();
-    var a = this;
+    var $a = $(this),
+        form = $a.closest('form');
     $.ajax({
-        url: $(this).attr('href').substr(1),
-        success: function(html) {
-          $(a).closest('.avatar').find('img').replaceWith($(html));
-        }
+      url: $a.attr('href').substr(1),
+      dataType: 'json',
+      success: function(json) {
+        if (!json || !json.code)
+          return;
+        var code = form.find('[name=avatar_code]');
+        if (!code.length)
+          code = form.append($('<input>').attr({type: 'hidden', name: 'avatar_code'}));
+        code.val(json.code).trigger('change');
+        $a.closest('.avatar').find('img').replaceWith($(json.img));
+      }
     });
     return false;"><i class="icon-retweet"></i></a>
           </div>
diff --git a/scp/js/scp.js b/scp/js/scp.js
index f5a6f26abac192dc504a34cc03d9590c20437d36..e756370c6c5e122cca9012869fad6c667198db5f 100644
--- a/scp/js/scp.js
+++ b/scp/js/scp.js
@@ -146,11 +146,11 @@ var scp_prep = function() {
         }
     };
 
-    $("form#save :input[name]").change(function() {
+    $("form#save").on('change', ':input[name]', function() {
         if (!$(this).is('.nowarn')) warnOnLeave($(this));
     });
 
-    $("form#save :input[type=reset]").click(function() {
+    $("form#save").on('change', ':input[type=reset]', function() {
         var fObj = $(this).closest('form');
         if(fObj.data('changed')){
             $('input[type=submit]', fObj).removeClass('save pending');