当前位置: 首页 > 编程笔记 >

覆盖Drupal 6自动选择元素验证

漆雕育
2023-03-14
本文向大家介绍覆盖Drupal 6自动选择元素验证,包括了覆盖Drupal 6自动选择元素验证的使用技巧和注意事项,需要的朋友参考一下

尽管最近在Drupal 6中创建了一个大型而复杂的表单,但是我遇到了一个问题,这个问题花了我几个小时才能解决,因此我将解决方案发布在这里,以防其他人同样陷入困境。我也将其写下来,这样我就可以记住该策略,以防万一我不得不再次做同样的事情。

我正在做的是创建活动预订表。该表格允许用户从选择列表中的多个时段中进行选择,但每次预订的数量均有限。当用户提交表单并且所有分配给他们所选时间的空位都已被预订满时,他们会看到一条消息,要求他们选择其他时间空位。原始时间已从选择列表中删除,以便用户不再尝试再次选择它。很好,一切都按预期工作,但是当发生这种情况时,我还收到了Drupal的以下错误消息。

An illegal choice has been detected. Please contact the site administrator.

此错误消息是_form_validate()Drupal进行的内部表单验证(通过函数)产生的,以确保您为select元素发布的项目与列表中的项目之一匹配。如果您允许用户选择一个项目,然后在发布请求后重新创建表单时将其删除,则您将收到此消息,因为选择表单中不存在发布值。这是一种安全措施,可防止用户入侵HTML并将自己的项目添加到选择列表中。Drupal会仔细检查输入的元素是否与列表中的现有元素之一匹配,如果不匹配,将使验证失败。

在尝试了各种不同的策略以消除这种情况下的这种情况后,我最终想到了按正常方式创建表单并将临时值添加到表单选择列表中的想法。然后使用表单主题挂钩来扫描并删除已被人为添加的选择项。这使我可以绕过(至少在一定程度上)内部的Drupal表单验证,并包括我自己的表单验证,以确保不允许再次预订所有已预订的空位。

我没有从客户项目中复制代码,而是创建了一个小示例模块,该模块执行了上面已详述的操作,以便可以描述每个步骤。我已经使用随机数生成了select元素,其效果与使用实数据相同。第一步是创建一个名为select_validate的模块文件夹以及.info和.module文件。这是.info文件的内容。

; $Id:$
name = Select Validate
description = "Select validate"
core = 6.x

通过创建菜单挂钩(带有关联的页面回调)和主题挂钩来启动模块文件,稍后我们将使用它们。由于尚未创建select_validate_select_form()定义,因此该代码将不会运行。

<?php
 
/**
 * Implementation of hook_menu
 *
 * @return array An array of menu items.
 */
function select_validate_menu() {
  $items = array();
 
  $items['select_validate'] = array(
    'page callback' => 'select_validate_print_form',
    'title' => 'Menu Example',
    'access callback' => TRUE,
  );
 
  return $items;
}
 
/**
 * Callback function for the select_validate page.
 *
 * @return string The contents of the page.
 */
function select_validate_print_form() {
  $output = '';
  $output .= drupal_get_form('select_validate_select_form');
  return $output;
}
 
/**
 * Implementation of hook_theme.
 *
 * @return array An associative array of theme hook information.
 */
function select_validate_theme() {
    return array(
        'select_validate_select_form' => array(
            'arguments' => array('form' => NULL),
        ),
    );
}

下一步是创建表单定义功能。该函数将创建一个简单的表单,其中包含由5个随机数组成的单个选择元素。重要的部分在第23行附近,在该行中,我在此select语句中添加了对以前发布的值的检查。如果此处不存在选择列表中存在的任何内容则将它们添加到选项的$random_list数组中,并带有“ DELETE”标签。然后,我们可以在对表单进行主题设置时使用此字符串来删除该值。

/**
 * Generates the select validate form.
 * 
 * @param array $form_state The form state array.
 *
 * @return array An associative array of form items.
 */
function select_validate_select_form(&$form_state) {
    $form = array();
 
    $form['#method'] = 'post';
    $form['#validate'][] = 'select_validate_select_form_validate';
    $form['#submit'][] = 'select_validate_select_form_submit';
 
    $random_list = array('' => '--');
 
    for ($i = 0; $i < 5; ++$i) {
        $rand = rand();
        $random_list[$rand] = $rand;
    }
 
    // 检查以前发布的值。
    if (isset($form_state['post']['randselect']) && !in_array($form_state['post']['randselect'], array_keys($random_list))) {
         $random_list[$form_state['post']['randselect']] = 'DELETE';
    }
 
    $form['randselect'] = array(
        '#type' => 'select',
        '#title' => t('Please select'),
        '#required' => TRUE,
        '#options' => $random_list,
    );
 
    $form['submit'] = array(
        '#type' => 'submit',
        '#value' => t('Go'),
    );
 
    return $form;
}

下一步是为我们的表单创建主题功能。因为我们用与表单相同的ID(或函数名)设置了主题注册表,所以我们可以只包含一个称为的函数theme_select_validate_select_form(),它将自动使用。通过向select_validate_select_form()函数添加以下代码行,可以在表单定义中对表单的主题进行硬编码。

$form['#theme'] = 'select_validate_select_form';

主题功能仅用于扫描randselect选择元素以查找带有“ DELETE”标签的选项。如果找到它,则在发送表单以通过drupal_render()调用呈现之前将其删除。

/**
 * Theme the select validate form.
 *
 * @param array $form An associative array of form items.
 *
 * @return string The rendered form.
 */
function theme_select_validate_select_form($form) {
    foreach ($form['randselect']['#options'] as $id => $option) {
        if ($option == 'DELETE') {
            unset($form['randselect']['#options'][$id]);
        }
    }
 
    $output = drupal_render($form);
    return $output;
}

为了使上述代码完全运行,表单必须通过验证。下面的两个函数绑定到表单的validate和Submit调用中,但是在这种情况下,validate函数将始终引发错误。只需要证明上面的代码有效,并允许其他人根据自己的需要修改此代码,因此在此实例中不需要任何其他操作。

/**
 * Validation function for the select validate form.
 *
 * @param array $form An associative array of form elements.
 * @param array $form_state An associative array of the form state.
 */
function select_validate_select_form_validate($form, &$form_state) {
 
    form_set_error('randselect', t('Please select another option.'));
}
 
/**
 * Submit function for the select validate form.
 *
 * @param array $form An associative array of form elements.
 * @param array $form_state An associative array of the form state.
 */
function select_validate_select_form_submit($form, &$form_state) {
    // 保存数据
}

最后一点是,尽管可以执行此操作,但仅应在确实需要时使用它。内部验证功能是有充分理由的,在不十分确定自己的验证功能会很痛苦(或至少很危险)的情况下,像这样覆盖它们。我故意没有研究hacking内核,因为内部_form_validate()功能的动作对于阻止将胭脂项目添加到选择表单中很有用。

 类似资料:
  • 我有一个选择元素,里面有多个选项: 对于这里看到的每个选项元素,我都有另一个select元素。基本上,我在一个选择元素中列出了一系列音乐流派,在它下面,是与每一个“主流派”相关的子流派。 我想做的是使子体裁只有在相对体裁被选中时才可见。例如,如果用户选择“Pop”,我想向他们显示包含Pop子类型的相关选择字段。 我的HTML标记实际上是由WordPress插件生成的,不幸的是,我无法编辑它。也就是

  • 我想使用道具从标题h1-h6中选择,然后将样式和文本插入标题中。我现在有: 然后我意识到我以前从来没有自动选择元素类型,甚至不知道从哪里开始。这可以用反应来完成吗,怎么做?

  • 问题内容: 我的网站上有一个选择控件。我正在使用页面对象与页面进行交互。如果我这样做(在我的课程下的前两行和我的方法中) 它以空指针失败。我也尝试了没有。 现在,如果我在我的方法中执行此操作,则一切正常,然后选择正确的项目 这是该控件的实际网页摘要(已编辑以保护无辜者) 让我说我可以解决我的问题, 但是 我不明白为什么“ 正常 ”路径无法正常工作。 问题答案: 那是因为该类具有以下构造函数: 见J

  • 问题内容: 我目前在UI测试自动化的元素上放置了一些ID。这些ID仅用于测试。我应该添加数据属性,而不是使其对将来的开发人员更具可读性(data-testHandle =“ mybutton”),还是应该坚持使用ID。 w3.org说: 定制数据属性旨在存储页面或应用程序专用的定制数据,对于这些数据,没有更多合适的属性或元素。 我倾向于保留ID,但是我中的某些人认为将来的开发人员会认为ID未被使用

  • 本文向大家介绍覆盖HTML5验证,包括了覆盖HTML5验证的使用技巧和注意事项,需要的朋友参考一下 要忽略HTML验证,可以使用JavaScript删除单击按钮时的属性。 您必须从每个匹配的元素中删除一个属性。

  • 本文向大家介绍jQuery 选择元素的子元素,包括了jQuery 选择元素的子元素的使用技巧和注意事项,需要的朋友参考一下 示例 要选择元素的子代,可以使用children()方法。 更改元素所有子.parent元素的颜色: 该方法接受一个可选selector参数,该参数可用于过滤返回的元素。