【问题标题】:drupal multiple node forms on one page一页上的drupal多个节点表单
【发布时间】:2009-11-10 22:03:55
【问题描述】:

我有一个显示多个节点的视图。我想将节点表单放在每个显示的节点下方。直接在 template.php 中的 node_adddrupal_get_form 都可以正常工作,但我得到的表单 ID 相同为 NODETYPE_node_form 并且验证和提交无法按预期工作。

如果您必须在一个页面上放置多个节点表单,您的一般做法是什么?

目前的进展...

在 template.php 中预处理节点 $author_profile 和 $content 是之前设置的。

$unique = $vars['node']->nid;

$node = new StdClass();
$node->uid = $vars['user']->uid;
$node->name = $vars['user']->name;
$node->type = 'review';
$node->language = '';
$node->title = t('Review of ') . $vars['node']->realname . t(' by ') . $vars['user']->realname . t(' on ') . $content->title;
$node->field_review_to_A[0]['nid'] = $nodeA->nid;
$node->field_review_to_B[0]['nid'] = $vars['node']->nid;
$node->field_review_to_profile[0]['nid'] = $author_profile->nid;

if(!function_exists("node_object_prepare")) {
    include_once(drupal_get_path('module', 'node') . '/node.pages.inc');
}

//$vars['A_review_form'] = drupal_get_form('review_node_form', $node);
$vars['A_review_form'] = mymodule_view($node, $unique);

在 mymodule 模块中

function mymodule_view($node, $unique) {
    if(!function_exists("node_object_prepare")) {
        include_once(drupal_get_path('module', 'node') . '/node.pages.inc');
    }
    $output = drupal_get_form('review_node_form_' . $unique, $node);
    return $output;
}

function mymodule_forms($form_id, $args) {
    $forms = array();
    if (strpos($form_id, "review_node_form_") === 0) {
        $forms[$form_id] = array('callback' => 'node_form');
    }
    return $forms;
}


function mymodule_form_alter(&$form, $form_state, $form_id) {
    if (isset($form['type']) && isset($form['#node']) && $form_id != $form['type']['#value'] .'_node_form' && $form['type']['#value'] == 'review') {
        $type = content_types($form['#node']->type);
        if (!empty($type['fields'])) {
            module_load_include('inc', 'content', 'includes/content.node_form');
            $form = array_merge($form, content_form($form, $form_state));
        }
        $form['#pre_render'][] = 'content_alter_extra_weights';
        $form['#content_extra_fields'] = $type['extra'];

        //$form['#id'] = $form_id;
        //$form['#validate'][0] = $form_id . '_validate';

        $form['title']['#type'] = 'value';
        $form['field_review_to_A']['#type'] = 'value';
        $form['field_review_to_B']['#type'] = 'value';
        $form['field_review_to_profile']['#type'] = 'value';
    }
}

问题

我对总结不清楚的问题的看法......

  1. 这是在同一页面上显示多个节点表单的通用方法吗?
  2. 是否可以从content 模块content_form_alter 函数mymodule_form_alter 中复制/粘贴代码?如果content 模块更新,它不会刹车吗?
  3. 我应该设置$form['#id']吗?没有它,所有表单都具有相同的 HTML 表单 ID node_form,它的 ID 是唯一的,例如 review_node_form_254。问题是表单的提交方式没有区别。设置$form['#validate'][0] 似乎也没有影响。也许我应该将$form[button]['#submit'][0] 设置为别的?现在是node_form_submit
  4. 为什么即使使用唯一的表单 ID 和表单验证功能也无法进行验证?如果我提交最后一个表单而没有必填字段,则所有以前的表单都会将特定字段变为红色。我应该制作自己的验证功能吗?什么级别 - 表单或字段?关于从哪里开始的任何提示?

【问题讨论】:

  • 将一个标记为已接受,也非常感谢欧宝。很多问题都不清楚,但我猜这个网站的格式要求在单独的问题中发布每个问题......所以谢谢,当我深入了解它时,我会在某个地方发布教程。

标签: api drupal forms


【解决方案1】:

你需要实现hook_forms()来将不同的id映射到同一个builder函数。

您提到的NODETYPE_node_form id 已经是这种机制的一个示例,因为它们都映射到节点模块node_forms() 实现中的相同构建器函数(node_form())。

您可以在drupal_get_form() 函数的“参数”说明中找到更多示例的链接。

【讨论】:

  • 问题是页面上有多个表单,所以表单 id 必须是唯一的,例如 NODETYPE_node_form_UNIQUENUMBER。使用节点 hook_forms() 我可以将回调“node_form”添加到 NODETYPE_node_form_UNIQUENUMBER,但作为回报,我得到的是通用节点表单,而不是我的 NODETYPE 节点表单。
  • 我已经尝试过computerminds.co.uk/…drupal.org/node/336870 的解决方案,但运气不佳
  • @henrijs:您在第一条评论中描述的方法应该有效 - 您如何称呼drupal_get_form()? (您需要在自定义表单 id 之后将节点对象作为第二个参数传递)
  • @henrijs:也许您可以编辑您的问题并添加到目前为止的表单注入代码?
【解决方案2】:

这对我特别有用。

关于所有 drupal API 的文档都非常缺乏 - 我正忙得不可开交。对我来说至关重要的一点,我认为网络上其他任何地方都没有:

CCK 通过 hook_form_alter() 将其字段添加到您的表单中。但它是根据 form_id 执行此操作的。因此,如果表单 ID 不同(因为您希望在同一页面上有多个 ID),则需要复制一些 CCK 代码以将字段添加到表单中。

这就是它的出色之处。

【讨论】:

  • 这应该是对您正在评论的帖子的评论。除了不是一个答案,现在很难理解你在说谁:Henrik? OP?我?没什么可怕的......但我只是想提一下,因为我看到你是网站上的新人...... :)
【解决方案3】:

我真的没有深入挖掘,但在我看来,你几乎自己完成了所有相关的挖掘。

根据我仅通过检查代码的理解,您认为content_form_alter() 是显示停止器是正确的。

也许这是一个幼稚的建议,但是从 content_form_alter() 代码开始编写您自己的hook_form_alter() 实现,但更改发生更改的条件呢?我正在考虑以下几点:

function modulename_form_alter(&$form, $form_state, $form_id) {
  if (isset($form['type']) && isset($form['#node']) && 
  stripos($form_id, $form['type']['#value'] .'_node_form')) {
    ...
  }
}

我确实没有实际测试了上面的代码,但我希望它是不言自明的:如果 MYCCKTYPE_node_form 是实际 form_id 的子字符串( es: MYCCKTYPE_node_form_234)。

希望这至少能有所帮助...祝你好运! :)

编辑:另外两件事

  1. 我突然想到,由于您的 hook_form_alter() 自定义实现将与 CCK 无关,您希望添加一个检查以避免表单被修改两次,例如:

    && $form_id != $form['type']['#value'] .'_node_form'

  2. 1234563 /li>

【讨论】:

  • 是的,现在我得到了正确的 MYCCKTYPE 节点形式。确实很酷,但所有表单的表单 ID 仍然相同 - “node_form”。实际上,themer 模块告诉我 form['#id'] 是 "node_form" 而 form['form_id']['#value'] 是 MYCCKTYPE_node_form_234 我将如何获得 form['#id'] 并因此获得实际的 html 表单id 为 MYCCKTYPE_node_form_234 + “在光标处拆分摘要”中完整的 javascript + 正确验证并提交。嗯...
  • 好吧,我想我可以粗暴地添加 $form['#id'] = $form_id;到我的 modulename_form_alter,我得到了很好的 $form['#id'] = 'MYCCKTYPE_node_form_234' 以及 html 表单 id 现在可以,表单提交很好,但“光标处拆分摘要”中的 javascript 仍然是错误的(显示第一个表单的按钮仅,其他表单的复选框,就像单击了按钮一样)并且验证也不好 - 它可以工作,但在提交表单后将表单标记为红色字段
  • 很高兴看到提示很有用。不能肯定地说,但验证中的红色轮廓通常由api.drupal.org/api/function/form_set_error/6 设置,它通常在验证函数中调用,并且在其参数中没有 $form 或 $form_state 。因此,可能是这些参数在验证中是错误的,或者是核心中的错误。您可以尝试通过$form['#validate'] 明确指示每个表单的验证函数来分配验证,或者甚至深入到每个元素的验证,看看是否可以解决它...
  • 除非您粘贴您的代码以便我(或其他任何人)可以尝试调试它,否则我认为我无能为力。我能给你的唯一一般提示是查看一些类似的代码,并尝试通过比较来查看你遇到的错误在哪里......虽然它不是 CCK 而是标准形式,但 ubercart 有一种非常相似的方式来处理多种形式的uc_product.module 中的页面上的相同类型(即通过向 form_id 附加一个数字)。查找 uc_product_add_to_cart_form 相关代码。
  • 奇怪...我的最后一条评论是对您现在消失的评论的回应...:-/
猜你喜欢
  • 1970-01-01
  • 2023-04-05
  • 2017-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多