Index: dynfields/htdocs/dynfields.js
===================================================================
--- dynfields/htdocs/dynfields.js	(revision 17507)
+++ dynfields/htdocs/dynfields.js	(working copy)
@@ -39,13 +39,14 @@
   };
 
   window.setup_triggers = function () {
-    if (window.dynfields_rules == undefined)
-      window.dynfields_rules = {};
+    var rules = window.dynfields_rules;
+    if (rules === undefined)
+      window.dynfields_rules = rules = {};
 
     for (var prop in triggers) {
       triggers[prop].selector = get_selector(prop);
       triggers[prop].forEach(function (spec) {
-        spec.rule = window.dynfields_rules[spec.rule_name];
+        spec.rule = rules[spec.rule_name];
       });
     }
   };
Index: dynfields/htdocs/layout.js
===================================================================
--- dynfields/htdocs/layout.js	(revision 17507)
+++ dynfields/htdocs/layout.js	(working copy)
@@ -1,6 +1,3 @@
-/*
- * Layout 'class'
- */
 var Layout = function (name) {
   this.name = name;
 
@@ -16,35 +13,36 @@
   // Move a field's tds and ths to slot i
   this.move_field = function (field, i) {};
 
-  // Returns true of the field needs its own row
+  // Returns true if the field needs its own row
   this.needs_own_row = function (field) {
-    var $field = jQuery('#field-' + field);
-    if ($field.length)
-      return $field.is('TEXTAREA');
-    return false;
+    var element = document.getElementById('field-' + field);
+    return element !== null && element.tagName.toLowerCase() === 'textarea';
   };
 
   // Update the field layout given a spec
   this.update = function (spec) {
     var this_ = this;
+    var name = this.name;
 
     // save original field order
-    if (window.dynfields_orig_field_order == undefined)
-      window.dynfields_orig_field_order = Object();
-
-    if (window.dynfields_orig_field_order[this.name] == undefined) {
-      window.dynfields_orig_field_order[this.name] = [];
+    var orig_field_order = window.dynfields_orig_field_order;
+    if (orig_field_order === undefined)
+      window.dynfields_orig_field_order = orig_field_order = {};
+
+    var field_order = orig_field_order[name];
+    if (field_order === undefined) {
+      orig_field_order[name] = field_order = [];
       jQuery(this.selector).each(function (i, e) {
         var field = this_.get_field($(this));
         if (field)
-          window.dynfields_orig_field_order[this_.name].push(field);
+          field_order.push(field);
       });
     }
 
     // get visible and hidden fields
     var visible = [];
     var hidden = [];
-    jQuery.each(window.dynfields_orig_field_order[this.name], function (i, field) {
+    jQuery.each(field_order, function (i, field) {
       var tx = this_.get_tx(field);
       if (tx.hasClass('dynfields-hide')) {
         hidden.push(field);
@@ -68,12 +66,12 @@
     jQuery(this.selector).each(function (i, e) {
       var old_field = this_.get_field($(this));
       var old_slot = -1;
-      if (old_field.length)
+      if (old_field.length !== 0)
         old_slot = jQuery.inArray(old_field, new_fields);
       var new_field = new_fields[i];
 
       // check to allow *this* field be in its own row
-      if (i % 2 == 1 && old_field.length && this_.needs_own_row(new_field))
+      if (i % 2 === 1 && old_field.length !== 0 && this_.needs_own_row(new_field))
         skip_slot += 1;
 
       var new_slot = i + skip_slot;
@@ -107,9 +105,13 @@
 
 // get_field
 inputs_layout.get_field = function (td) {
-  var input = td.find(':input:first');
-  if (!input.length || !input.is('[id]')) return '';
-  return input.attr('id').slice(6);
+  var name = td.attr('data-dynfields-name');
+  if (!name) {
+    var input = td.find(':input:first');
+    name = input.length !== 0 ? input[0].id.slice(6) : '<missing>';
+    td.attr('data-dynfields-name', name);
+  }
+  return name !== '<missing>' ? name : '';
 };
 
 // move_field
@@ -125,16 +127,16 @@
 
   // find correct column (tx) to insert field
   var col = 'col' + ((i % 2) + 1);
-  if (tr.find('th').length) {
+  var old_th = tr.find('th:first');
+  if (old_th.length !== 0) {
     if (col == 'col1') {
-      var old_th = tr.find('th:first');
-      if (old_th.get(0) != th.get(0)) { // don't move self to self
+      if (old_th[0] != th[0]) { // don't move self to self
         old_th.before(th);
         old_th.before(td);
       }
     } else {
       var old_td = tr.find('td:has(:input):last');
-      if (old_td.get(0) != td.get(0)) { // don't move self to self
+      if (old_td[0] != td[0]) { // don't move self to self
         old_td.after(td);
         old_td.after(th);
       }
@@ -168,7 +170,12 @@
 
 // get_field
 header_layout.get_field = function (th) {
-  return (th.attr('id') ? th.attr('id').slice(2) : '');
+  var name = th.attr('data-dynfields-name');
+  if (!name) {
+    var name = th.length !== 0 ? th[0].id.slice(2) : '<missing>';
+    th.attr('data-dynfields-name', name);
+  }
+  return name !== '<missing>' ? name : '';
 };
 
 // move_field
@@ -178,19 +185,19 @@
 
   // find correct row (tr) to insert field
   var row = Math.round(i / 2 - 0.5); // round down
-  var tr = jQuery('#ticket').find('.properties tr:eq(' + row + ')');
+  var tr = jQuery('#ticket .properties').find('tr:eq(' + row + ')');
 
   // find correct column (tx) to insert field
-  if (tr.find('th').length) {
+  var old_th = tr.find('th:first');
+  if (old_th.length !== 0) {
     if (i % 2 == 0) {
-      var old_th = tr.find('th:first');
-      if (old_th.get(0) != th.get(0)) { // don't move self to self
+      if (old_th[0] != th[0]) { // don't move self to self
         old_th.before(th);
         old_th.before(td);
       }
     } else {
       var old_td = tr.find('td:last');
-      if (old_td.get(0) != td.get(0)) { // don't move self to self
+      if (old_td[0] != td[0]) { // don't move self to self
         old_td.after(td);
         old_td.after(th);
       }
Index: dynfields/htdocs/rules.js
===================================================================
--- dynfields/htdocs/rules.js	(revision 17507)
+++ dynfields/htdocs/rules.js	(working copy)
@@ -9,7 +9,7 @@
   this.query = function (spec) {}; // for query page
 
   // register this rule by adding to global variable
-  if (window.dynfields_rules == undefined)
+  if (window.dynfields_rules === undefined)
     window.dynfields_rules = {};
   window.dynfields_rules[name] = this;
 };
@@ -27,7 +27,7 @@
 
   var target = spec.target;
 
-  if (spec.clear_on_change == undefined)
+  if (spec.clear_on_change === undefined)
     return;
 
   var field = jQuery('#field-' + target);
@@ -50,7 +50,7 @@
 
 // apply
 copyrule.apply = function (input, spec) {
-  var id = input.attr('id');
+  var id = input[0].id;
   if (spec.value === undefined ||
       !((id.endsWith('_reassign_owner') && spec.trigger == 'owner') ||
         id.slice(6) === spec.trigger))
@@ -92,7 +92,7 @@
 
 // apply
 defaultrule.apply = function (input, spec) {
-  if (input.attr('id').slice(6) !== spec.trigger)
+  if (input[0].id.slice(6) !== spec.trigger)
     return;
 
   var $field = jQuery(get_selector(spec.target));
@@ -150,11 +150,12 @@
 
 // setup
 hiderule.setup = function (input, spec) {
-  var id = input.attr('id');
+  var id = input[0].id;
   if (id) { // no input fields when on /query page
     // show and reset elements controlled by this input field
     var trigger = id.substring(6); // ids start with 'field-'
-    jQuery('.dynfields-' + trigger)
+    jQuery('#properties, #ticket .properties')
+      .find('.dynfields-' + trigger)
       .removeClass('dynfields-hide dynfields-' + trigger)
       .show();
   }
@@ -165,11 +166,7 @@
   var trigger = spec.trigger;
   var target = spec.target;
 
-  // hide field in the header if cleared or always hidden
-  var clear_on_hide = spec.clear_on_hide.toLowerCase() == 'true';
-  var hide_always = spec.hide_always.toLowerCase() == 'true'
-
-  if (input.attr('id').slice(6) !== spec.trigger)
+  if (input.attr('id').slice(6) !== trigger)
     return;
 
   // process hide rule
@@ -179,11 +176,12 @@
   else
     v = input.val();
   var l = spec.trigger_value.split('|'); // supports list of trigger values
-  if ((jQuery.inArray(v, l) != -1 && spec.op == 'hide') ||
-    (jQuery.inArray(v, l) == -1 && spec.op == 'show')) {
-
+  var idx = jQuery.inArray(v, l);
+  if (idx !== -1 && spec.op === 'hide' || idx === -1 && spec.op === 'show') {
     // we want to hide the input fields's td and related th
-    var field = jQuery('#field-' + target + ',input[name="field_' + target + '"]');
+    var field = jQuery(
+        '#field-<target>, #properties input[name="field_<target>"]'
+        .replace(/<target>/g, target));
     var td = field.closest('td');
     var th = td.prev('th');
     var cls = 'dynfields-hide dynfields-' + trigger;
@@ -193,31 +191,36 @@
     th.addClass(cls);
 
     // let's also clear out the field's value to avoid confusion
-    if (clear_on_hide && field.val() && field.val().length) { // Chrome fix - see #8654
-      if (field.attr('type') == 'checkbox') {
-        if (field.is(':checked')) {
-          field.removeAttr('checked').change();
+    var clear_on_hide = spec.clear_on_hide.toLowerCase() == 'true';
+    var hide_always = spec.hide_always.toLowerCase() == 'true'
+    if (clear_on_hide) {
+      var oldval = field.val();
+      if (oldval && oldval.length) { // Chrome fix - see #8654
+        if (field.attr('type') == 'checkbox') {
+          if (field.is(':checked')) {
+            field.removeAttr('checked').change();
+          }
+        } else {
+          // only cascade rules if value changes
+          var newval = field.val('').val();
+          if (oldval != newval)
+            field.change(); // cascade rules
         }
-      } else {
-        // only cascade rules if value changes
-        var oldval = field.val();
-        var newval = field.val('').val();
-        if (oldval != newval)
-          field.change(); // cascade rules
-      }
-      if (clear_on_hide || hide_always) {
-        th = jQuery('#h_' + spec.target);
-        td = th.next('td');
-        td.addClass('dynfields-hide dynfields-' + trigger);
-        th.addClass('dynfields-hide dynfields-' + trigger);
       }
     }
+    // Hide fields in ticket properties box
+    if (clear_on_hide || hide_always) {
+      th = jQuery('#h_' + target);
+      td = th.next('td');
+      td.addClass(cls);
+      th.addClass(cls);
+    }
   }
 };
 
 // complete
 hiderule.complete = function (input, spec) {
-  jQuery('.dynfields-hide').hide();
+  jQuery('#properties .dynfields-hide, #ticket .properties .dynfields-hide').hide();
 
   // update layout (see layout.js)
   inputs_layout.update(spec);
@@ -231,7 +234,7 @@
         '    <a href="#no3" onClick="jQuery(\'.dynfields-link\').show(); jQuery(\'#dynfields-show-link\').remove();">Show hidden fields</a>' +
         '  </td>' +
         '</tr>';
-      jQuery('.dynfields-link:last').parents('tbody:first').append(html);
+      jQuery('.dynfields-link:last').closest('tbody').append(html);
     }
   }
 };
@@ -241,23 +244,24 @@
   // hide hide_always fields on /query page
   if (spec.hide_always.toLowerCase() == 'true') {
     // hide from columns section
+    var target = spec.target;
     var query_form = jQuery('form#query')
     var filters_fieldset = query_form.find('fieldset#filters');
-    filters_fieldset.find('input[value="' + spec.target + '"]')
+    filters_fieldset.find('input[value="' + target + '"]')
       .prop('checked', false)
       .parent().hide();
     // hide from and/or column filters/dropdowns
-    filters_fieldset.find('#add_filter option[value="' + spec.target + '"]') // trac <= 0.12.1
+    filters_fieldset.find('#add_filter option[value="' + target + '"]') // trac <= 0.12.1
       .hide();
-    filters_fieldset.find('.actions option[value="' + spec.target + '"]') // trac 0.12.2
+    filters_fieldset.find('.actions option[value="' + target + '"]') // trac 0.12.2
       .hide();
     var columns_fieldset = query_form.find('fieldset#columns');
-    columns_fieldset.find('input[value="' + spec.target + '"]')
+    columns_fieldset.find('input[value="' + target + '"]')
       .prop('checked', false)
       .parent().hide();
     // Hide from "Group results by" dropdown.
     var group_select = query_form.find('#group');
-    group_select.find('option[value="' + spec.target + '"]')
+    group_select.find('option[value="' + target + '"]')
       .hide();
   }
 };
@@ -273,8 +277,8 @@
   var id = 'field-' + spec.target;
   var field = jQuery('#' + id);
   var label = jQuery('label[for="' + id + '"]');
-  var submit = jQuery('input[name=submit]');
-  var form = submit.parents('form');
+  var form = jQuery('#propertyform');
+  var submit = form.find('input[name=submit]');
 
   // reset "alert only once per form submission"
   submit.click(function () {
@@ -341,16 +345,16 @@
 
 // setup
 setrule.setup = function (input, spec) {
-  if (spec.value == undefined)
+  if (spec.value === undefined)
     return;
 
   // ensure trigger field's new value is in spec's list
   // supports list of trigger values
-  if (spec.trigger_value.length != 0 &&
+  if (spec.trigger_value.length !== 0 &&
       jQuery.inArray(input.val(), spec.trigger_value) == -1)
     return;
 
-  if (spec.trigger_not_value.length != 0 &&
+  if (spec.trigger_not_value.length !== 0 &&
       jQuery.inArray(input.val(), spec.trigger_not_value) > -1)
     return;
 
