diff --git a/dynamicfieldsplugin/trunk/dynfields/htdocs/layout.js b/dynamicfieldsplugin/trunk/dynfields/htdocs/layout.js
index 0d7c8269c..7c6fddc75 100755
--- a/dynamicfieldsplugin/trunk/dynfields/htdocs/layout.js
+++ b/dynamicfieldsplugin/trunk/dynfields/htdocs/layout.js
@@ -112,44 +112,71 @@ inputs_layout.get_field = function (td) {
   return input.attr('id').slice(6);
 };
 
-// move_field
-inputs_layout.move_field = function (field, i) {
-  var td = this.get_tx(field);
-  var th = td.prev('th');
-
-  // find correct row (tr) to insert field
-  var row = Math.round(i / 2 - 0.5); // round down
-  var $properties = jQuery('#properties');
-  row += $properties.find('td.fullrow').length; // skip fullrows
-  var tr = $properties.find('tr:eq(' + row + ')');
-
-  // find correct column (tx) to insert field
-  var col = 'col' + ((i % 2) + 1);
-  if (tr.find('th').length) {
-    if (col == 'col1') {
-      var old_th = tr.find('th:first');
-      if (old_th.get(0) != th.get(0)) { // don't move self to self
-        old_th.before(th);
-        old_th.before(td);
+inputs_layout.order_fields = function (new_fields) {
+  var this_ = this;
+  var properties = jQuery('#properties');
+  var target_row = properties.find('textarea[name=field_description]')
+                             .closest('tr');
+  var cells = {};
+  var fullrows = {};
+  jQuery.each(new_fields, function(idx, name) {
+    var cell = this_.get_tx(name);
+    cells[name] = cell;
+    fullrows[name] = cell.hasClass('fullrow');
+  });
+  var groups = [];
+  var group_buf = [];
+  var length = new_fields.length;
+  for (var i = 0; i < length; i++) {
+    var name = new_fields[i];
+    if (fullrows[name]) {
+      if (group_buf.length !== 0) {
+        groups.push(group_buf.slice(0, 2));
+        group_buf = [];
       }
+      groups.push([name, true]);
     } else {
-      var old_td = tr.find('td:has(:input):last');
-      if (old_td.get(0) != td.get(0)) { // don't move self to self
-        old_td.after(td);
-        old_td.after(th);
+      group_buf.push(name);
+      if (group_buf.length == 2) {
+        groups.push(group_buf.slice(0, 2));
+        group_buf = [];
       }
     }
-  } else {
-    // no columns so just insert
-    tr.append(th);
-    tr.append(td);
   }
-
-  // let's set col
-  td.removeClass('col1 col2');
-  th.removeClass('col1 col2');
-  td.addClass(col);
-  th.addClass(col);
+  if (group_buf.length !== 0) {
+    groups.push(group_buf.slice(0, 2));
+  }
+  jQuery.each(groups, function(idx, group) {
+    var col1 = group[0];
+    var col2 = group[1];
+    var cell1 = cells[col1];
+    var row = jQuery('<tr>').append(cell1.prev('th'), cell1);
+    if (col2 === true) {
+      cell1.removeClass('col2');
+      cell1.addClass('col1');
+    } else {
+      var cell2, header2;
+      if (col2) {
+        cell2 = cells[col2];
+        cell2.removeClass('col1');
+        header2 = cell2.prev('th');
+      } else {
+        cell2 = jQuery('<td>');
+        header2 = jQuery('<th>');
+      }
+      cell2.addClass('col2');
+      row.append(header2, cell2);
+    }
+    target_row.after(row);
+    target_row = row;
+  });
+  properties.find('> table > tbody > tr').each(function() {
+    var row = $(this);
+    var cells = row.children('th, td');
+    if (cells.length === 0 || cells.children(':first-child').length === 0) {
+      row.remove();
+    }
+  });
 };
 
 
