Search code examples
drupaldrupal-6themes

Drupal 6 create CRUD grid in settings form


I'm quite new to Drupal and I want to create a custom grid that has some editable columns, some other columns witch checkboxes etc.

I'm using the theme() function to create the table and render it at the settings. Since I cannot find any way to access the form/settings variables, inside the theme function, I create a custom table at the drupal database that will contain the gid values, and I render those rows. For testing purposes I fetch the 'variables' table rows. Here is the code so far:

 $form['module_settings']['profile_grid'] = array(
        '#type' => 'item',
        '#title' => t('Profile Mapping'),
        '#theme' => 'profile_mapping_grid'
    );


function theme_profile_mapping_grid($sender) {
    $header = array('', t('name'), t('value'));
    $result = db_query('SELECT v.name, v.value from {variable} v');
    while ($pair = db_fetch_object($result)) { 
        $format = array(
            '#type' => 'textfield',
            '#size' => 30,
            '#value' => $pair->name
        );
        $hhfield = array(
            '#type' => 'textfield',
            '#size' => 30,
            '#value' => $pair->value
        );
        $row = array('');
        $row[] = drupal_render($format);
        $row[] = drupal_render($hhfield);
        $rows[] = array('data' => $row);    
    }

    $output = theme('table', $header, $rows, array('id' => 'gridErrors'));
    return $output;
}

The grid is generated correctly, but I have an issue. I cannot set the 'name' attribute to the textfield, in order to collect it's value later on, on a submit action. Furthermore, I'm not sure if this is the best way to create a settings grid.

Any ideas, opinions etc are more than welcome.


Solution

  • According to Drupal 6 Form API Quickstart Guide:

    1. Don't use the '#value' attribute for any form element that can be changed by the user. Use the '#default_value' attribute instead. Don't put values from $form_state['values'] (or $_POST) here! FormsAPI will deal with that for you; only put the original value of the field here.

    You have to use '#default_value' => $pair->name not '#value' => $pair->value.

    Here is the sample module with settings table.

    install file:

    <?php
    // $Id$
    
    /**
     * @file
     * The your_module module install file, which handles the install/uninstall tasks.
     *
     */
    
    function your_module_install() {
      // Create tables.
      drupal_install_schema('your_module');
    }
    
    /**
     * Implementation of hook_schema().
     */
    function your_module_schema() {
    
    /* Settings table */
    $schema['your_module_settings'] = array(
        'description' => 'Stores module settings.',
        'fields' => array(
            'record_id' => array(
                'description' => 'The primary identifier for a record.',
                'type' => 'serial', 
                'unsigned' => TRUE, 
                'not null' => TRUE),
            'item_code' => array(
                'type' => 'varchar', 
                'length' => '255', 
                'not null' => TRUE),
            'setting_one' => array(
                'type' => 'varchar', 
                'length' => '255', 
                'not null' => TRUE),
            'setting_two' => array(
                'type' => 'varchar', 
                'length' => '255')),
        'unique keys' => array(
            'record_id' => array('record_id')),
        'primary key' => array('record_id')
    );
    
      return $schema;
    }
    
    /**
     * Implementation of hook_uninstall().
     */
    function your_module_uninstall() {
      // Remove tables.
      drupal_uninstall_schema('your_module');
    }
    

    module file:

    <?php
    
    /**
     * Implementation of hook_help()
     */
    function your_module_help($path, $arg) 
    {
      switch ($path) 
      {
        case 'admin/help#your_module':
          return '<p>'. t('Module description.') .'</p>';
      }
    }
    
    /**
     * Implementation of hook_menu()
     */
    function your_module_menu()
    {
      $items = array();
    
      /* module settings page */
      $items['admin/settings/your_module'] = array(
        'description' => 'Administer your_module module settings.',
        'title' => 'Some title',
        'page callback' => 'drupal_get_form',
        'page arguments' => array('your_module_admin_settings'),
        'access arguments' => array('access administration pages'),
        'type' => MENU_NORMAL_ITEM,
        );
    
      return $items;
    }
    
    /**
     * Implementation of hook_theme().
     */
    function your_module_theme() {
      return array(
        'your_module_products_settings' => array(
          'arguments' => array('form' => NULL),
        ),
      );
    }
    
    /**
     * Settings form
     */
    function your_module_admin_settings(&$form_state)
    {
      $form['your_module'] = array(
          '#type' => 'fieldset',
          '#title' => t('Settings'),
          '#description' => t('Settings description.'),
        );
    
      $form['your_module']['products_settings_table'] = array(
          '#theme' => 'your_module_products_settings',
          '#tree' => TRUE,
        );
    
      $form['your_module']['products_settings_table']['products_settings'] = array();
    
      $result = db_query('SELECT record_id, item_code, setting_one, setting_two  FROM {your_module_settings} ORDER BY item_code');
    
      while ($product_setting = db_fetch_object($result)) {
        $form['your_module']['products_settings_table']['products_settings'][$product_setting->record_id] = array();
    
        $form['your_module']['products_settings_table']['products_settings'][$product_setting->record_id]['item_code'] = array(
          '#type' => 'textfield',
          '#default_value' => $product_setting->item_code,
          '#size' => 8,
          '#maxlength' => 16,
        );
    
        $form['your_module']['products_settings_table']['products_settings'][$product_setting->record_id]['setting_one'] = array(
          '#type' => 'textfield',
          '#default_value' => $product_setting->setting_one,
          '#size' => 16,
          '#maxlength' => 16,
        );
    
        $form['your_module']['products_settings_table']['products_settings'][$product_setting->record_id]['setting_two'] = array(
          '#type' => 'textfield',
          '#default_value' => $product_setting->setting_two,
          '#size' => 40,
          '#maxlength' => 255,
        );
      }
    
      /* "add new row" fields */
      $form['your_module']['products_settings_table']['products_settings_new'] = array();
    
      /* new item_code */
      $form['your_module']['products_settings_table']['products_settings_new']['item_code'] = array(
        '#type' => 'textfield',
        '#size' => 8,
        '#maxlength' => 16,
        '#description' => t('description'),
      );
    
      /* new setting_one */
      $form['your_module']['products_settings_table']['products_settings_new']['setting_one'] = array(
        '#type' => 'textfield',
        '#size' => 16,
        '#maxlength' => 16,
        '#description' => t('description'),
      );
    
      /* setting_two */
      $form['your_module']['products_settings_table']['products_settings_new']['setting_two'] = array(
        '#type' => 'textfield',
        '#size' => 40,
        '#maxlength' => 255,
        '#description' => t('description'),
      );
    
      /* Submit button */
      $form['submit'] = array(
        '#type' => 'submit',
        '#value' => t('Save Settings'),
        '#name' => 'SubmitButton',
      );
    
      return $form;
    }
    
    /**
     * Custom theme function for a table of products settings
     */
    function theme_your_module_products_settings($form) {
      $header = array(t('Item Code'), t('Setting One'), t('Setting Two'));
      $rows = array();
    
      /* saved rows */
      foreach (element_children($form['products_settings']) as $key) {
        $row = array();
        $row[] = drupal_render($form['products_settings'][$key]['item_code']);
        $row[] = drupal_render($form['products_settings'][$key]['setting_one']);
        $row[] = drupal_render($form['products_settings'][$key]['setting_two']);
        $rows[] = $row;
      }
    
      /* new row to add */
      $row = array();
      $row[] = drupal_render($form['products_settings_new']['item_code']);
      $row[] = drupal_render($form['products_settings_new']['setting_one']);
      $row[] = drupal_render($form['products_settings_new']['setting_two']);
      $rows[] = $row;
    
      $output = theme('table', $header, $rows);
      return $output;
    }
    
    /**
     * Submission function for your_module_admin_settings form.
     */
    function your_module_admin_settings_submit($form, &$form_state) {
    
      /* processing changes */
      if (isset($form_state['values']['products_settings_table']['products_settings'])) {
        foreach ($form_state['values']['products_settings_table']['products_settings'] as $record_id => $data) {
          if (empty($data['item_code']) && empty($data['setting_one']) && empty($data['setting_two'])) {
            /* delete saved row if all fields are empty */
            db_query("DELETE FROM {your_module_settings} WHERE record_id=%d", $record_id);
    
            drupal_set_message(t('Deleted.'), 'status');
          }
          else {
            /* update */
            db_query("UPDATE {your_module_settings} SET item_code='%s', setting_one='%s', setting_two='%s' WHERE record_id=%d",
              $data['item_code'], $data['setting_one'], $data['setting_two'], $record_id);
          }
        }
      }
    
      /* adding new row */
      $item_code = $form_state['values']['products_settings_table']['products_settings_new']['item_code'];
      $setting_one = $form_state['values']['products_settings_table']['products_settings_new']['setting_one'];
      $setting_two = $form_state['values']['products_settings_table']['products_settings_new']['setting_two'];
    
      if (!empty($item_code) && !empty($setting_one) && !empty($setting_two)) {
    
        db_query("INSERT INTO {your_module_settings} (item_code, setting_one, setting_two) VALUES ('%s', '%s', '%s')",
            $item_code, $setting_one, $setting_two);
    
        drupal_set_message(t('Added new setting.'), 'status');
      }
    
      drupal_set_message(t('Settings updated.'), 'status');
    }