? flexifilter_ui.patch
Index: flexifilter-admin-component-list.tpl.php
===================================================================
RCS file: flexifilter-admin-component-list.tpl.php
diff -N flexifilter-admin-component-list.tpl.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ flexifilter-admin-component-list.tpl.php	29 Jan 2008 05:32:01 -0000
@@ -0,0 +1,14 @@
+<?php
+// $Id$
+drupal_add_tabledrag('flexifilter-components', 'match', 'parent', 'flexifilter-pid', 'flexifilter-pid', 'flexifilter-cid', TRUE, 20);
+drupal_add_tabledrag('flexifilter-components', 'order', 'sibling', 'flexifilter-weight');
+?><table id="flexifilter-components">
+  <tbody>
+    <?php foreach ($table as $index => $row): ?>
+      <tr class="draggable <?php print $index % 2 == 0 ? 'odd' : 'even'; ?>">
+        <td><?php print $row['label']; ?></td>
+        <td><?php print $row['key'] . $row['cid'] . $row['pid'] . $row['weight']; ?></td>
+      </tr>
+    <?php endforeach; ?>
+  </tbody>
+</table>
\ No newline at end of file
Index: flexifilter-admin-list.tpl.php
===================================================================
RCS file: flexifilter-admin-list.tpl.php
diff -N flexifilter-admin-list.tpl.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ flexifilter-admin-list.tpl.php	29 Jan 2008 05:32:01 -0000
@@ -0,0 +1,20 @@
+<?php
+// $Id$
+?><table id="flexifilter-admin-list">
+  <thead>
+    <th><?php print $label; ?></th>
+    <th><?php print $description; ?></th>
+    <th></th>
+    <th><?php print $status; ?></th>
+  </thead>
+  <tbody>
+    <?php foreach ($table as $index => $row): ?>
+      <tr class="<?php print $index % 2 == 0 ? 'odd' : 'even'; ?>">
+        <td><?php print $row['label']; ?></td>
+        <td><?php print $row['description']; ?></td>
+        <td><?php print $row['edit']; ?></td>
+        <td><?php print $row['status']; ?></td>
+      </tr>
+    <?php endforeach; ?>
+  </tbody>
+</table>
\ No newline at end of file
Index: flexifilter.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/flexifilter/flexifilter.admin.inc,v
retrieving revision 1.13
diff -u -p -r1.13 flexifilter.admin.inc
--- flexifilter.admin.inc	24 Jan 2008 01:57:10 -0000	1.13
+++ flexifilter.admin.inc	29 Jan 2008 05:32:02 -0000
@@ -4,23 +4,53 @@
 /**
  * Generates the form for the admin overview page
  */
-function flexifilter_filter_list_form() {
+function flexifilter_admin_list_form($form_state) {
   drupal_set_title("Flexifilters overview");
   $path = drupal_get_path('module', 'flexifilter') .'/flexifilter.css';
   drupal_add_css($path, 'module', 'all', FALSE);
+  if (isset($form_state['values']['enabled'])) {
+    foreach ($form_state['values']['enabled']['statuses'] as $fid => $value) {
+      if ($value == 'disabled') {
+        db_query('UPDATE {flexifilters} SET enabled = 0 WHERE fid = %d', $fid);
+      }
+    }
+  }
+  if (isset($form_state['values']['disabled'])) {
+    foreach ($form_state['values']['disabled']['statuses'] as $fid => $value) {
+      if ($value == 'enabled') {
+        db_query('UPDATE {flexifilters} SET enabled = 1 WHERE fid = %d', $fid);
+      }
+    }
+  }
 
   $form = array();
   $form['enabled_header'] = array(
     '#value' => '<h3>'. t('Enabled Flexifilters') .'</h3>',
     '#suffix' => t('If a flexifilter is enabled, then it can be used within input formats, however there can only be 128 enabled at any one time.') .'<br/>',
   );
-  $form['enabled'] = flexifilter_filter_list_form_table(TRUE);
+  $form['enabled'] = flexifilter_admin_list_form_table(TRUE);
 
   $form['disabled_header'] = array(
     '#value' => '<h3>'. t('Disabled Flexifilters') .'</h3>',
     '#suffix' => t('If a flexifilter is disabled, then it cannot be used within input formats, although it can be used within other flexifilters.') .'<br/>',
   );
-  $form['disabled'] = flexifilter_filter_list_form_table(FALSE);
+  $form['disabled'] = flexifilter_admin_list_form_table(FALSE);
+
+  $form['submit'] = array(
+    '#type'  => 'submit', 
+    '#value' => t('Save'),
+    '#ahah'  => array(
+      'path'     => 'admin/build/flexifilters/js/list_form',
+      'selector' => '.flexifilter-status',
+      'wrapper'  => 'flexifilter-admin-list-form',
+      'event'    => 'change',
+      'effect'   => 'none',
+      'method'   => 'replace',
+    ),
+  );
+  if (!isset($form_state['values'])) {
+    $form['#theme'] = 'flexifilter_filter_admin_form';
+  }
 
   return $form;
 }
@@ -29,68 +59,189 @@ function flexifilter_filter_list_form() 
  * Helper function for flexifilter_filter_list_form. Returns the table for the overview page.
  *
  * @param $enabled
- *   Is TRUE if we're theming the currently enabled filters.s
+ *   Is TRUE if we're theming the currently enabled filters.
  */
-function flexifilter_filter_list_form_table($enabled) {
-  $show_disable_link = $enabled;
-  $show_enable_link  = !$enabled && flexifilter_get_number_enabled_filters() < FLEXIFILTER_MAX_FILTERS;
-  $header            = array(t('Label'), t('Description'), t('Edit'), t('Delete'), t($enabled ? 'Disable' : 'Enable'));
-  $rows              = array();
-  $filters           = flexifilter_get_filters();
+function flexifilter_admin_list_form_table($enabled) {
+  $options = array();
+  if (flexifilter_get_number_enabled_filters() < FLEXIFILTER_MAX_FILTERS) {
+    $options['enabled'] = t('Enabled');
+  }
+  $options['disabled'] = t('Disabled');
+  $rowinfo  = array();
+  $statuses = array();
+  $filters  = flexifilter_get_filters();
   foreach ($filters as $id => $filter) {
     if ($filter['enabled'] == $enabled) {
-      $row   = array($filter['label'], $filter['description']);
-      $row[] = l(t('Edit'), 'admin/build/flexifilters/'. $id .'/edit', array(), drupal_get_destination());
-      $row[] = l(t('Delete'), 'admin/build/flexifilters/'. $id .'/delete', array(), drupal_get_destination());
-      if ($show_disable_link) {
-        $row[] = l(t('Disable'), 'admin/build/flexifilters/'. $id .'/disable', array(), drupal_get_destination());
-      }
-      else if ($show_enable_link) {
-        $row[] = l(t('Enable'), 'admin/build/flexifilters/'. $id .'/enable', array(), drupal_get_destination());
-      }
-      else {
-        $row[] = '';
-      }
-      $rows[] = $row;
+      $rowinfo[] = array(
+        'label' => $filter['label'],
+        'description' => $filter['description'],
+        'edit' => l(t('Edit'), 'admin/build/flexifilters/'. $id .'/edit', array(), drupal_get_destination()),
+      );
+      $statuses[$filter['id']] = array(
+        '#type' => 'select',
+        '#title' => t('Status'),
+        '#options' => $options,
+        '#default_value' => ($enabled? 'enabled' : 'disabled'),
+        '#attributes' => array('class' => 'flexifilter-status'),
+      );
     }
   }
-  if (count($rows)) {
-    return array('#value' => theme('table', $header, $rows, array('class' => 'flexifilters-list')));
+  if (count($rowinfo)) {
+    return array('#theme' => 'flexifilter_admin_list', '#rowinfo' => $rowinfo, 'statuses' => $statuses, '#tree' => TRUE);
   }
   else {
-    return array('#value' => t('None.'));
+    return array('#value' => '<strong>'. t('There are no @status filters at this moment.', array('@status' => ($enabled? t('enabled') : t('disabled')))) .'</strong><br />');
   }
 }
 
 /**
- * Helper function for flexifilter_filter_edit_form; removes the automatic
- * naming of submit controls.
- * Our forms are complex and have submit controls nested within fieldsets,
- * and when pressed, we want the 'op' field to be set within the fieldset,
- * not at the top level, so we have to undo the automatic naming of submit
- * fields.
- * This function is a brutal rip of code from _form_builder_handle_input_element
- *
- * @param $form A form element to reset to the normal name.
+ * Preprocess for the admin list table
+ * 
+ * Takes the separate row info and statuses and combines them into a table.
+ */
+function template_preprocess_flexifilter_admin_list(&$variables) {
+  $variables['table'] = array();
+  foreach ($variables['form']['#rowinfo'] as $index => $rowinfo) {
+    $variables['table'][$index] = $rowinfo;
+  }
+  $count = 0;
+  foreach (element_children($variables['form']['statuses']) as $key) {
+    unset($variables['form']['statuses'][$key]['#title']);
+    $variables['table'][$count]['status'] = drupal_render($variables['form']['statuses'][$key]);
+    $count++;
+  }
+  $variables['label']       = t('Label');
+  $variables['description'] = t('Description');
+  $variables['status']      = t('Status');
+}
+
+function theme_flexifilter_filter_admin_form($form) {
+  unset($form['submit']);
+  return '<div id="flexifilter-admin-list-form">'. drupal_render($form) .'</div>';
+}
+
+/**
+ * The add/edit form for flexifilters.
+ */
+function flexifilter_admin_edit_form($form_state, $flexifilter = 'new') {
+  if (!isset($form_state['post']) || !isset($form_state['post']['fid'])) {
+    $data = array();
+    $data['fid'] = $flexifilter == 'new' ? 'new' : $flexifilter['id'];
+    $data['basic'] = array();
+    $data['basic']['label']       = $flexifilter == 'new' ? '' : $flexifilter['label'];
+    $data['basic']['description'] = $flexifilter == 'new' ? '' : $flexifilter['description'];
+    $data['basic']['advanced']    = $flexifilter == 'new' ? 0 : $flexifilter['advanced'];
+    $data['components']           = $flexifilter == 'new' ? array() : flexifilter_filter_edit_components_data($flexifilter['components']);
+    if (!isset($data['components']['id_prefix']) || $data['components']['id_prefix'] === 'component_new_') {
+      $data['components']['id_prefix'] = 'component_'. $data['fid'] .'_';
+    }
+    if (!isset($data['components']['id_next'])) {
+      $data['components']['id_next'] = 0;
+    }
+  }
+  else {
+    $data = $form_state['post'];
+    if (!isset($data['basic']['advanced'])) {
+      $data['basic']['advanced'] = 0;
+    }
+  }
+  $form = array();
+  $form['fid'] = array(
+    '#type' => 'hidden',
+    '#value' => $data['fid'],
+  );
+  $form['basic'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Settings'),
+    '#collapsible' => FALSE,
+    '#tree' => TRUE,
+  );
+  $form['basic']['label'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Label'),
+    '#required' => TRUE,
+    '#maxlength' => 127,
+    '#description' => t('Choose an appropriate label for this flexifilter.'),
+    '#default_value' => $data['basic']['label'],
+  );
+  $form['basic']['description'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Description'),
+    '#required' => TRUE,
+    '#maxlength' => 255,
+    '#description' => t('A short description of what this flexifilter does.'),
+    '#default_value' => $data['basic']['description'],
+  );
+  $form['basic']['advanced'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Show advanced options'),
+    '#default_value' => $data['basic']['advanced'],
+    '#description' => t('Advanced options currently only include the processing step option, which allows you to place some components into the filtering preparation step. You should only do so if it is critical that they be performed in the preparation step rather than the processing step.'),
+  );
+  $form['components'] = _flexifilter_filter_edit_form_components($data['components'], $data['components'], $data['basic']['advanced'] == 1);
+  $form['components']['id_prefix'] = array('#type' => 'hidden', '#value' => $data['components']['id_prefix']);
+  $form['components']['id_next'] = array('#type' => 'hidden', '#value' => $data['components']['id_next']);
+  $form['create'] = array(
+    '#type' => 'submit',
+    '#value' => $data['fid'] === 'new' ? t('Create') : t('Save'),
+  );
+  $form['create_edit'] = array(
+    '#type' => 'submit',
+    '#value' => $data['fid'] === 'new' ? t('Create and edit') : t('Save and edit'),
+  );
+  $form['#redirect'] = FALSE;
+  return $form;
+}
+
+/**
+ * Generates an FAPI array for a component list
  *
- * @return The updated form element
+ * @param $data FAPI values for the component list. Use flexifilter_filter_edit_components_data to
+ * convert a components array into coresponding FAPI values.
+ * @param $data_base FAPI values for the top-level component list
  */
-function flexifilter_undo_submit_default_name($form) {
-  $name = array_shift($form['#parents']);
-  $form['#name'] = $name;
-  if ($form['#type'] == 'file') {
-    // To make it easier to handle $_FILES in file.inc, we place all
-    // file fields in the 'files' array. Also, we do not support
-    // nested file names.
-    $form['#name'] = 'files['. $form['#name'] .']';
+function _flexifilter_filter_edit_form_components($data, $data_base, $show_advanced, $component_id = 0, $parent = 0) {
+  $components = array();
+  $form = array();
+  foreach ($data as $key => $component) {
+    if (strncmp($key, $data_base['id_prefix'], strlen($data_base['id_prefix'])) == 0) {
+      $components[$key] = $component;
+    }
   }
-  elseif (count($form['#parents'])) {
-    $form['#name'] .= '['. implode('][', $form['#parents']) .']';
+  foreach ($components as $key => $component) {
+    $component_id++;
+    $form['labels'][]  = array('#value' => $component['class']);
+    $form['keys'][]    = array('#type' => 'hidden', '#value' => $key);
+    $form['cids'][]    = array('#type' => 'textfield', '#attributes' => array('class' => 'flexifilter-cid'), '#value' => $component_id);
+    $form['pids'][]    = array('#type' => 'textfield', '#attributes' => array('class' => 'flexifilter-pid'), '#value' => $parent);
+    $form['weights'][] = array('#type' => 'weight', '#attributes' => array('class' => 'flexifilter-weight'), '#value' => $component_id);
+    if (isset($component['components'])) {
+      $children = _flexifilter_filter_edit_form_components($component['components'], $data_base, $show_advanced, $component_id, $component_id);
+      foreach (array('labels', 'keys', 'cids', 'pids', 'weights') as $key) {
+        foreach ($children[$key] as $value) {
+          $form[$key][] = $value;
+        }
+      }
+    }
+  }
+  if ($parent == 0) {
+    $form['#theme'] = 'flexifilter_admin_component_list';
+    $form['#tree'] = TRUE;
   }
-  array_unshift($form['#parents'], $name);
   return $form;
 }
 
+function template_preprocess_flexifilter_admin_component_list(&$variables) {
+  $form = $variables['form'];
+  $table = array();
+  foreach (array('labels', 'keys', 'cids', 'pids', 'weights', 'weights') as $index) {
+    foreach (element_children($form[$index]) as $key) {
+      $table[$key][substr($index, 0, -1)] = drupal_render($form[$index][$key]);
+    }
+  }
+  $variables['table'] = $table;
+}
+
 /**
  * Helper function for flexifilter_filter_edit_components_data; converts a condition
  * array from a flexifilter into a form data styled array.
@@ -282,6 +433,7 @@ function flexifilter_filter_edit_form_co
   return $form;
 }
 
+
 /**
  * Helper function for flexifilter_filter_edit_form_components; generates an FAPI array for a
  * single component.
@@ -405,164 +557,6 @@ function _flexifilter_components_sort_we
   return ((float)$a['weight']) > ((float)$b['weight']);
 }
 
-/**
- * Generates an FAPI array for a component list
- *
- * @param $data FAPI values for the component list. Use flexifilter_filter_edit_components_data to
- * convert a components array into coresponding FAPI values.
- * @param $data_base FAPI values for the top-level component list
- */
-function flexifilter_filter_edit_form_components($data, &$data_base, $show_advanced) {
-  $form = array(
-    '#type' => 'fieldset',
-    '#title' => t('Components'),
-    '#collapsed' => TRUE,
-    '#collapsible' => TRUE,
-    '#tree' => TRUE,
-  );
-  $components = array();
-  foreach ($data as $key => $component) {
-    if (strncmp($key, $data_base['id_prefix'], strlen($data_base['id_prefix'])) == 0) {
-      $components[$key] = $component;
-    }
-  }
-  if (isset($data['op'])) {
-    $components[$data_base['id_prefix'] . $data_base['id_next']] = flexifilter_filter_edit_form_new_component_data($data['new_list']);
-    $data_base['id_next'] = $data_base['id_next'] + 1;
-  }
-  foreach ($components as $key => $component) {
-    if (isset($component['op'])) {
-      switch ($component['move']) {
-        /*
-          Careful; this component is NOT VALIDATED by the FAPI. We only act upon certain
-          values ('top', 'up', 'down', 'bottom', 'remove'), which are always valid (even
-          if they have no effect). Other values are silently ignored.
-        */
-
-        case 'top':
-          $components[$key]['weight'] = -1000;
-          break;
-
-        case 'up':
-          $components[$key]['weight'] = $component['weight'] - 1.5;
-          break;
-
-        case 'down':
-          $components[$key]['weight'] = $component['weight'] + 1.5;
-          break;
-
-        case 'bottom':
-          $components[$key]['weight'] = 10001;
-          break;
-
-        case 'remove':
-          unset($components[$key]);
-          break;
-      }
-      $form['#collapsed'] = FALSE;
-    }
-  }
-  uasort($components, '_flexifilter_components_sort_weight');
-  $new_weight = 0;
-  $last_component_weight = count($components);
-  foreach ($components as $key => $component) {
-    $new_weight = $new_weight + 1;
-    $form[$key] = flexifilter_filter_edit_form_component($component, $new_weight, $new_weight == 1, $new_weight == $last_component_weight, $data_base, $show_advanced);
-    if ($form[$key]['#collapsed'] == FALSE) {
-      $form['#collapsed'] = FALSE;
-    }
-  }
-  $form['new_list'] = array(
-    '#type' => 'select',
-    '#options' => flexifilter_get_grouped_labels(flexifilter_get_component_list($show_advanced)),
-    '#title' => t('Add component'),
-  );
-  $form['op'] = array(
-    '#type' => 'submit',
-    '#value' => t('Add'),
-    '#process' => array('flexifilter_undo_submit_default_name', 'form_expand_ahah'),
-  );
-  return $form;
-}
-
-/**
- * The add/edit form for flexifilters.
- */
-function flexifilter_filter_edit_form($form_state, $flexifilter = 'new') {
-  if (!isset($form_state['post']) || !isset($form_state['post']['fid'])) {
-    $data = array();
-    $data['fid'] = $flexifilter === 'new' ? 'new' : $flexifilter['id'];
-    $data['basic'] = array();
-    $data['basic']['label'] = $flexifilter === 'new' ? '' : $flexifilter['label'];
-    $data['basic']['description'] = $flexifilter === 'new' ? '' : $flexifilter['description'];
-    $data['basic']['advanced'] = $flexifilter === 'new' ? 0 : $flexifilter['advanced'];
-    $data['components'] = $flexifilter === 'new' ? array() : flexifilter_filter_edit_components_data($flexifilter['components']);
-    if (!isset($data['components']['id_prefix']) || $data['components']['id_prefix'] === 'component_new_') {
-      $data['components']['id_prefix'] = 'component_'. $data['fid'] .'_';
-    }
-    if (!isset($data['components']['id_next'])) {
-      $data['components']['id_next'] = 0;
-    }
-    $expand_root_levels = TRUE;
-  }
-  else {
-    $data = $form_state['post'];
-    if (!isset($data['basic']['advanced'])) {
-      $data['basic']['advanced'] = 0;
-    }
-  }
-  $form = array();
-  $form['fid'] = array(
-    '#type' => 'hidden',
-    '#value' => $data['fid'],
-  );
-  $form['basic'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Basic settings'),
-    '#collapsed' => TRUE,
-    '#collapsible' => TRUE,
-    '#tree' => TRUE,
-  );
-  $form['basic']['label'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Label'),
-    '#required' => TRUE,
-    '#maxlength' => 127,
-    '#description' => t('Choose an appropriate label for this flexifilter.'),
-    '#default_value' => $data['basic']['label'],
-  );
-  $form['basic']['description'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Description'),
-    '#required' => TRUE,
-    '#maxlength' => 255,
-    '#description' => t('A short description of what this flexifilter does.'),
-    '#default_value' => $data['basic']['description'],
-  );
-  $form['basic']['advanced'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Show advanced options'),
-    '#default_value' => $data['basic']['advanced'],
-    '#description' => t('Advanced options currently only include the processing step option, which allows you to place some components into the filtering preparation step. You should only do so if it is critical that they be performed in the preparation step rather than the processing step.'),
-  );
-  $form['components'] = flexifilter_filter_edit_form_components($data['components'], $data['components'], $data['basic']['advanced'] == 1);
-  $form['components']['id_prefix'] = array('#type' => 'hidden', '#value' => $data['components']['id_prefix']);
-  $form['components']['id_next'] = array('#type' => 'hidden', '#value' => $data['components']['id_next']);
-  if (isset($expand_root_levels) && $expand_root_levels) {
-    $form['basic']['#collapsed'] = FALSE;
-    $form['components']['#collapsed'] = FALSE;
-  }
-  $form['submit1'] = array(
-    '#type' => 'submit',
-    '#value' => $data['fid'] === 'new' ? t('Create') : t('Save'),
-  );
-  $form['submit2'] = array(
-    '#type' => 'submit',
-    '#value' => $data['fid'] === 'new' ? t('Create and edit') : t('Save and edit'),
-  );
-  $form['#redirect'] = FALSE;
-  return $form;
-}
 
 /**
  * Helper function for flexifilter_filter_edit_form_components_from_data; converts a condition's
@@ -728,42 +722,6 @@ function flexifilter_filter_delete_form_
   $form_state['redirect'] = 'admin/build/flexifilters';
 }
 
-function flexifilter_filter_disable_form($form_state, $flexifilter) {
-  $form = array();
-  $form['fid'] = array('#type' => 'hidden', '#value' => $flexifilter['id']);
-
-  return confirm_form($form, t('Are you sure you want to disable the flexifilter "%flexifilter"?', array('%flexifilter' => $flexifilter['label'])), 'admin/build/flexifilters', t('If you disable the flexifilter, then it cannot be used in any Input Formats.'), t('Disable'), t('Cancel'));
-}
-
-function flexifilter_filter_disable_form_submit($form, &$form_state) {
-  $fid     = $form_state['values']['fid'];
-  $filters = flexifilter_get_filters();
-  $filter  = $filters[$fid];
-  if ($filter['enabled']) {
-    flexifilter_remove_from_filters($filter['delta']);
-    db_query('UPDATE {flexifilters} SET enabled = 0 WHERE fid = %d', $fid);
-    drupal_set_message(t('Flexifilter disabled.'));
-  }
-  $form_state['redirect'] = 'admin/build/flexifilters';
-}
-
-function flexifilter_filter_enable_form($form_state, $flexifilter) {
-  $form = array();
-  $form['fid'] = array('#type' => 'hidden', '#value' => $flexifilter['id']);
-
-  return confirm_form($form, t('Are you sure you want to enable the flexifilter "%flexifilter"?', array('%flexifilter' => $flexifilter['label'])), 'admin/build/flexifilters', t(''), t('Enable'), t('Cancel'));
-}
-
-function flexifilter_filter_enable_form_submit($form, &$form_state) {
-  $fid     = $form_state['values']['fid'];
-  $filters = flexifilter_get_filters();
-  $filter  = $filters[$fid];
-  if (!$filter['enabled'] && flexifilter_get_number_enabled_filters() < FLEXIFILTER_MAX_FILTERS) {
-    db_query('UPDATE {flexifilters} SET enabled = 1, delta = %d WHERE fid = %d', flexifilter_get_unused_delta(), $fid);
-    drupal_set_message(t('Flexifilter enabled.'));
-  }
-  $form_state['redirect'] = 'admin/build/flexifilters';
-}
 
 function flexifilter_filter_export_form($form_state, $flexifilter) {
   $form = array();
@@ -847,4 +805,46 @@ function flexifilter_filter_default_form
   }
   flexifilter_install_flexifilters('flexifilter', $to_be_saved);
   $form_state['redirect'] = 'admin/build/flexifilters';
-}
\ No newline at end of file
+}
+
+function flexifilter_js($parameter = '') {
+  switch ($parameter) {
+    case 'list_form':
+      $form = _flexifilter_js();
+      $output = '<div id="flexifilter-admin-list-form">';
+      foreach (element_children($form) as $key) {
+        $output .= drupal_render($form[$key]);
+      }
+      drupal_json(array('status' => TRUE, 'data' => $output .'</div>'));
+      break;
+  }
+}
+
+function _flexifilter_js() {
+  $form_state = array('storage' => NULL, 'submitted' => FALSE);
+  $form_build_id = $_POST['form_build_id'];
+  $form = form_get_cache($form_build_id, &$form_state);
+  // #parameters has $form_id, $form_state and then whatever was passed to
+  // drupal_get_form.
+  $args = $form['#parameters'];
+  $form_id = array_shift($args);
+  $form['#post'] = $_POST;
+  $form['#redirect'] = FALSE;
+  // This will set up $form_state['clicked_button'] and
+  // $form_state['storage']['mlid'].
+  drupal_process_form($form_id, $form, $form_state);
+  // Recreate and re-cache the form.
+  $form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
+  // Pick up the parents of the pressed button.
+  $array_parents = $form_state['clicked_button']['#array_parents'];
+  // The last parent is the button itself, we need the wrapper instead.
+  $button_index = array_pop($array_parents);
+  while ($array_parents) {
+    $parent = array_shift($array_parents);
+    $form = $form[$parent];
+  }
+  // Remove the button.
+  unset($form[$button_index]);
+  // Render messages and selects.
+  return $form;
+}
Index: flexifilter.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/flexifilter/flexifilter.module,v
retrieving revision 1.14
diff -u -p -r1.14 flexifilter.module
--- flexifilter.module	23 Jan 2008 22:43:16 -0000	1.14
+++ flexifilter.module	29 Jan 2008 05:32:02 -0000
@@ -21,7 +21,7 @@ function flexifilter_menu() {
     'description' => t('Create new flexible input filters without writing any code.'),
     'page callback' => 'drupal_get_form',
     'access arguments' => array('administer flexifilter'),
-    'page arguments' => array('flexifilter_filter_list_form'),
+    'page arguments' => array('flexifilter_admin_list_form'),
     'file' => 'flexifilter.admin.inc',
   );
   $items['admin/build/flexifilters/list'] = array(
@@ -57,7 +57,7 @@ function flexifilter_menu() {
     'title arguments' => array(3, 'label'),
     'type' => MENU_CALLBACK,
     'page callback' => 'drupal_get_form',
-    'page arguments' => array('flexifilter_filter_edit_form', 3),
+    'page arguments' => array('flexifilter_admin_edit_form', 3),
     'file' => 'flexifilter.admin.inc',
   );
   $items['admin/build/flexifilters/%flexifilter/edit'] = array(
@@ -78,23 +78,23 @@ function flexifilter_menu() {
     'page arguments' => array('flexifilter_filter_delete_form', 3),
     'file' => 'flexifilter.admin.inc',
   );
-  $items['admin/build/flexifilters/%flexifilter/enable'] = array(
-    'title' => t('Enable'),
+  $items['admin/build/flexifilters/js'] = array(
+    'title' => t('JavaScript Callback'),
     'type' => MENU_CALLBACK,
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('flexifilter_filter_enable_form', 3),
-    'file' => 'flexifilter.admin.inc',
-  );
-  $items['admin/build/flexifilters/%flexifilter/disable'] = array(
-    'title' => t('Disable'),
-    'type' => MENU_CALLBACK,
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('flexifilter_filter_disable_form', 3),
+    'page callback' => 'flexifilter_js',
     'file' => 'flexifilter.admin.inc',
   );
   return $items;
 }
 
+function flexifilter_theme() {
+  return array(
+    'flexifilter_admin_list' => array('template' => 'flexifilter-admin-list', 'file' => 'flexifilter.admin.inc', 'arguments' => array('form' => NULL)),
+    'flexifilter_admin_component_list' => array('template' => 'flexifilter-admin-component-list', 'file' => 'flexifilter.admin.inc', 'arguments' => array('form' => NULL)),
+    'flexifilter_filter_admin_form' => array('file' => 'flexifilter.admin.inc', 'arguments' => array('form' => NULL)),
+  );
+}
+
 /**
  * Implementation of hook_help()
  */
