Index: django/contrib/admin/media/js/admin/DateTimeShortcuts.js
===================================================================
--- django/contrib/admin/media/js/admin/DateTimeShortcuts.js	(revision 12799)
+++ django/contrib/admin/media/js/admin/DateTimeShortcuts.js	(working copy)
@@ -120,6 +120,7 @@
     },
     handleClockQuicklink: function(num, val) {
        DateTimeShortcuts.clockInputs[num].value = val;
+       DateTimeShortcuts.clockInputs[num].focus();
        DateTimeShortcuts.dismissClock(num);
     },
     // Add calendar widget to a given field.
@@ -247,12 +248,13 @@
         format = format.replace('\n', '\\n');
         format = format.replace('\t', '\\t');
         format = format.replace("'", "\\'");
-        return "function(y, m, d) { DateTimeShortcuts.calendarInputs["+num+"].value = new Date(y, m-1, d).strftime('"+format+"');document.getElementById(DateTimeShortcuts.calendarDivName1+"+num+").style.display='none';}";
+        return "function(y, m, d) { DateTimeShortcuts.calendarInputs["+num+"].value = new Date(y, m-1, d).strftime('"+format+"');DateTimeShortcuts.calendarInputs["+num+"].focus();document.getElementById(DateTimeShortcuts.calendarDivName1+"+num+").style.display='none';}";
     },
     handleCalendarQuickLink: function(num, offset) {
        var d = new Date();
        d.setDate(d.getDate() + offset)
        DateTimeShortcuts.calendarInputs[num].value = d.strftime(get_format('DATE_INPUT_FORMATS')[0]);
+       DateTimeShortcuts.calendarInputs[num].focus();
        DateTimeShortcuts.dismissCalendar(num);
     },
     cancelEventPropagation: function(e) {
Index: django/contrib/admin/media/js/prepopulate.js
===================================================================
--- django/contrib/admin/media/js/prepopulate.js	(revision 0)
+++ django/contrib/admin/media/js/prepopulate.js	(revision 0)
@@ -0,0 +1,34 @@
+(function($) {
+    $.fn.prepopulate = function(dependencies, maxLength) {
+        /*
+            Depends on urlify.js
+            Populates a selected field with the values of the dependent fields,
+            URLifies and shortens the string. 
+            dependencies - selected jQuery object of dependent fields
+            maxLength - maximum length of the URLify'd string 
+        */
+        return this.each(function() {
+            var field = $(this);
+
+            field.data('_changed', false);
+            field.change(function() {
+                field.data('_changed', true);
+            });
+
+            var populate = function () {
+                // Bail if the fields value has changed
+                if (field.data('_changed') == true) return;
+ 
+                var values = [];
+                dependencies.each(function() {
+                    if ($(this).val().length > 0) {
+                        values.push($(this).val());
+                    }
+                });
+                field.val(URLify(values.join(' '), maxLength));
+            };
+
+            dependencies.keyup(populate).change(populate).focus(populate);
+        });
+    };
+})(jQuery.noConflict());
Index: django/contrib/admin/options.py
===================================================================
--- django/contrib/admin/options.py	(revision 12799)
+++ django/contrib/admin/options.py	(working copy)
@@ -273,6 +273,7 @@
             js.extend(['js/jquery.min.js', 'js/actions.min.js'])
         if self.prepopulated_fields:
             js.append('js/urlify.js')
+            js.append('js/prepopulate.js')
         if self.opts.get_ordered_objects():
             js.extend(['js/getElementsBySelector.js', 'js/dom-drag.js' , 'js/admin/ordering.js'])
 
@@ -1204,6 +1205,7 @@
         js = ['js/jquery.min.js', 'js/inlines.min.js']
         if self.prepopulated_fields:
             js.append('js/urlify.js')
+            js.append('js/prepopulate.js')
         if self.filter_vertical or self.filter_horizontal:
             js.extend(['js/SelectBox.js' , 'js/SelectFilter2.js'])
         return forms.Media(js=['%s%s' % (settings.ADMIN_MEDIA_PREFIX, url) for url in js])
Index: django/contrib/admin/templates/admin/edit_inline/tabular.html
===================================================================
--- django/contrib/admin/templates/admin/edit_inline/tabular.html	(revision 12799)
+++ django/contrib/admin/templates/admin/edit_inline/tabular.html	(working copy)
@@ -94,6 +94,20 @@
                 })
             }
         }
+        var initPrepopulatedFields = function(row) {
+            $(row).find('td.prepopulated_field').each(function() {
+                var field = $(this);
+                var input = null;
+                var dependencies = null;
+
+                dependencies = row.find($.data(field.attr('id')).join(','));
+
+                if (dependencies.length) {
+                    input = field.find('input');
+                    input.prepopulate(dependencies, input.attr('maxlength'));
+                }
+            });
+        }
         $(rows).formset({
             prefix: "{{ inline_admin_formset.formset.prefix }}",
             addText: "{% blocktrans with inline_admin_formset.opts.verbose_name|title as verbose_name %}Add another {{ verbose_name }}{% endblocktrans %}",
@@ -103,6 +117,7 @@
             emptyCssClass: "empty-form",
             removed: alternatingRows,
             added: (function(row) {
+                initPrepopulatedFields(row);
                 reinitDateTimeShortCuts();
                 updateSelectFilter();
                 alternatingRows(row);
Index: django/contrib/admin/templates/admin/prepopulated_fields_js.html
===================================================================
--- django/contrib/admin/templates/admin/prepopulated_fields_js.html	(revision 12799)
+++ django/contrib/admin/templates/admin/prepopulated_fields_js.html	(working copy)
@@ -1,11 +1,24 @@
 <script type="text/javascript">
+(function($) {
+    var field = null;
+
 {% for field in prepopulated_fields %}
-    document.getElementById("{{ field.field.auto_id }}").onchange = function() { this._changed = true; };
+    $('.empty-form td.{{ field.field.name }}').addClass('prepopulated_field');
+
+    field = {
+        id: '#{{ field.field.auto_id }}',
+        dependency_ids: [],
+        dependency_names: [],
+        maxLength: {{ field.field.field.max_length|default_if_none:"50" }}
+    };
+
     {% for dependency in field.dependencies %}
-    document.getElementById("{{ dependency.auto_id }}").onkeyup = function() {
-        var e = document.getElementById("{{ field.field.auto_id }}");
-        if (!e._changed) { e.value = URLify({% for innerdep in field.dependencies %}document.getElementById("{{ innerdep.auto_id }}").value{% if not forloop.last %} + ' ' + {% endif %}{% endfor %}, {{ field.field.field.max_length|default_if_none:"50" }}); }
-    }
+    field['dependency_ids'].push('#{{ dependency.auto_id }}');
+    field['dependency_names'].push('{{ dependency.name }}');
     {% endfor %}
+
+    $.data('{{ field.field.auto_id }}', field['dependency_names']);
+    $(field.id).prepopulate($(field['dependency_ids'].join(',')), field.maxLength);
 {% endfor %}
+})(jQuery.noConflict());
 </script>
