Drupal 7 模块开发 建立、验证、提交表单(Form) (hook_menu)

当访问 http://www.mysite.com/?q=myform 的时候,会见到如下的表单(Form)

---------------------------------------------------------------------

建立表table

参见《Drupal 7 模块开发 创建自定义表(table) (hook_schema)

写主模块

我们需要写一个表单(Form),这里就需要通过 hook_menu来完成。在主模块 my_first_module.module 文件里建立一个函数 my_first_module_menu()

function my_first_module_menu() {
  $item = array();
  
  $item['myform'] = array(
    'title' => '第一个表单',
    'description' => '我的第一个模块 —— 表单',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('myform_page_form'),
    'access callback' => TRUE,
    'file' => 'myform.page.inc', //把myform_page_form 函数写在myform.page.inc里
    'type' => MENU_CALLBACK,
  );
  
  return $item;
}

$item先定义路径,在访问 /myform 页面时候,去调用 myform_page_form 函数产生表单,myform_page_form() 函数放在'myform.page.inc'文件里。

每一个$item都是对应一个路径,写在 [ ] 里。当item用一样路径时候,就调用后写那个$items的。(有文章说和weight有关,我测试weight不会影响先后次序)

[ ] 里也可以用通配符,譬如: [node/%/edit]。详细参见:function hook_menu 里的Wildcards in Paths一段

$item数组里每个关键字对应的值如下。

  • title 必须
    未翻译的主题
     
  • title callback
    产生主题的函数。默认是 t()。如果你不想翻译,就设置FALSE (所以我们不必再写 'title' => t('第一个表单'))
     
  • title arguments
    传递到 t() 或者 你自定义函数 的参数。可以和路径组件结合
    参考:Menu item title and description callbacks, localization
     
  • description
    未翻译的说明描述。
     
  • page callback
    当用户访问页面路径的时候,调用一个显示网页的函数。如果不写,父菜单的回调函数将代替执行
     
  • page arguments
    传递给page callback函数的一串参数数组
     
  • delivery callback
    这个函数将调用page callback函数的结果,发送到浏览器上。默认是 drupal_deliver_html_page(),除非值继承了父菜单。
    值得注意的是,如果访问检查失败,这个函数也会被调用。所以任何自定义delivery callbcack函数都要考虑到这点。详见 drupal_deliver_html_page() 举例。
     
  • access callback
    如果用户有权访问这个菜单项,函数就返回TRUE,否则返回FALSE。它可以是一个布尔常量,而不是一个函数。你也可以用数字表达 (将会被转成布尔值)。默认为user_access(),除非从父菜单继承。只有 MENU_DEFAULT_LOCAL_TASK 项可以继承访问回调。要使用 user_access()默认回调,你必须有指定权限检查"access arguments"
     
  • access arguments
    传递给access callback函数的一串数组。如果access callback是继承父菜单,那么access arguments也将随同一起继承。除非子菜单覆盖
     
  • theme callback

     
  • theme arguments

     
  • file

     
  • file path

     
  • load arguments

     
  • weight

     
  • menu_name

     
  • expanded

     
  • context

     
  • tab_parent

     
  • tab_root

     
  • position

     
  • type
    描述菜单项属性的代码。许多快捷代码的常量在 menu.inc 里。
    默认是:MENU_NORMAL_ITEM
    常用的几个:
    •  

创建表单

建立一个 myform.page.inc 的文件,开头别忘记写 <?php,结尾不用写 ?>

 

function myform_page_form($form, &$form_state) {
  $form['title'] = array(
    '#title' => t('标题'), // 字段名称
    '#type' => 'textfield', // 字段类型,此处为单行文本
    '#required' => true, // 是否必填
    '#default_value' => '', // 默认值,可选
  );
  
  $form['fullname'] = array(
    '#title' => '姓名',
    '#type' => 'textfield',
    '#required' => true,
    '#description' => '请输入您的姓名,不低于 2 个字符'
  );
  
  $form['email'] = array(
    '#title' => '电子邮件',
    '#type' => 'textfield',
    '#required' => true,
    '#description' => '请输入您的常用邮件,便于我们联系您'
  );
  
  $form['body'] = array(
    '#title' => '内容',
    '#type' => 'textarea', // 多行文本
    '#required' => true,
  );
  
  /**
   * 表单验证函数,可指定多个,如:array('test_validate1', 'test_validate2');
   * 系统将根据顺序,依次调用,若所有函数均通过验证,将进行提交环节。
   * 
   * 如果表单没有指定验证函数,drupal 将默认为表单绑定一个函数,名称为:表单函数+下划线+validate
   * 本例中为:myform_page_form_validate。若此函数存在,将调用此函数来验证表单
   */
  $form['#validate'] = array('myform_page_form_validate');
  
  /**
   * 表单提交函数绑定在 submit 类型的表单字段上,可绑定多个提交函数,如:array('test_submit1', 'test_submit2');
   * 系统将根据顺序,依次调用。如果在第一个函数中,页面被重定向,后面的函数将不会被调用。
   * 
   * 如果表单没有指定提交函数,drupal 将默认为表单绑定一个函数,名称为:表单函数+下划线+submit
   * 本例中为:myform_page_form_submit。若此函数存在,在验证通过后,将调用此函数。
   */
  $form['submit'] = array(
    '#type' => 'submit', // 提交按钮
    '#value' => t('确认提交'), // 按钮值
    '#submit' => array('myform_page_form_submit'), // 提交函数
  );

  return $form;
}

 

 

 

 

 

#type 说明参考:https://api.drupal.org/api/drupal/developer!topics!forms_api_reference.html/7

验证表单函数

/**
 * 表单验证
 * @param (array) &$form
 *  表单字段
 * @param (array) &$form_state
 *  表单值,用做判断表单的各种参数,包括用户提交的所有数据
 */
function myform_page_form_validate(&$form, &$form_state) {
  
  /**
   * 用户提交的所有数据在 $form_state['values'] 之中,相当于 $_POST
   * 根据需求,验证昵称是否少于 2 个字符,中英文均算一个字符
   * 可使用封装好的计算字符串长度函数:drupal_strlen
   */
  if (drupal_strlen($form_state['values']['name']) < 2) {
    /**
     * 如果少于 2 个字符,调用  form_set_error() 写入错误信息,系统将显示错误信息,同时阻止表单提交
     * form_set_error() 的格式,第一个参数:字段名称,第二个参数:用户将看到的错误信息
     */
    form_set_error('name', '昵称不能少于 2 个字符');
  } else if (drupal_strlen($form_state['values']['title']) > 255) {
    form_set_error('title', '标题长度不能大于 255 个字符');
  }
  
  // 如验证通过,将进入表单提交环节
}

提交表单(写入数据库)

 

/**
 * 表单提交
 * @param (array) &$form
 * @param (array) &$form_state
 */
function myform_page_form_submit(&$form, &$form_state) {
  /**
   * 写入数据库
   */
  db_query("INSERT INTO {myform} (id, title, name, mail, timestamp, body) 
  VALUES (null, '%s', '%s', '%s', %d, '%s')", $form_state['values']['title'], 
  $form_state['values']['name'], $form_state['values']['mail'], 
  $_SERVER['REQUEST_TIME'], $form_state['values']['body']);
  
  // 获取上一条 insert sql 返回的主键,以此判断是否执行成功
  if (db_last_insert_id('myform', 'id')) {
    
    /**
     * 执行成功了,到数据库去看看,是不是有这条记录了
     * 显示一条信息给用户
     */
    drupal_set_message('感谢您,反馈已经提交,我们将尽快和您取得联系');
    
    // 如果想将用户重定向到一个页面,可修改 $form['#redirect'] 值,如:
    
    $form['#redirect'] = 'test/abcde';
    
    /**
     * 这里也可以使用 drupal_goto 来重定向,但这并不是个好方法
     * 因为可能还有其它提交函数在 后面排队,被这儿一重定向,后面就没机会执行了
     */
    
  } else {
    
    // 数据写入失败了
    drupal_set_message('抱歉,遇到问题,提交失败了', 'error');
    
  }
  
}
 

 

 

 

 

 

 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值