Apex:如何在动态创建的页面项目上显示错误?

Apex : How to display an error on a page Item created dynamically?

我是 运行 Apex 19.2

我有一个页面,其中包含一些动态创建的项目,如下所示:

HTML clob;    
Html := APEX_ITEM.textarea(p_idx=>32, p_value=>'MyValue',p_item_id=>'MyId',p_attributes=>'class="textarea"');   
htp.p(HTML);

正确生成页面项目:

<textarea name="f32" rows="4" cols="40" wrap="VIRTUAL" class="textarea" id="MyId"></textarea>

我还添加了项目包装器以匹配从设计器创建的静态项目布局。

<div class="t-Form-inputContainer col">
    <div class="t-Form-itemWrapper">     
        <textarea name="f32" rows="4" cols="40" wrap="VIRTUAL" class="textarea" id="MyId"></textarea>
    </div>
    <span id="MyId_error_placeholder" class="a-Form-error"></span>                            
</div>

在验证中,我正在检查 apex_application.g_fn 数组中的一些规则,我想在通过以下方式创建的项目上显示错误:

apex_error.add_error(p_message => 'error', p_display_location => apex_error.c_inline_with_field_and_notif, p_page_item_name=> 'MyId');

验证后,错误未显示在创建的项目旁边。通知也会出现,但它是空的。但是,如果我尝试在设计器中创建的静态项目上显示相同的错误。错误显示正确。

有人可以帮忙吗? 谢谢

如您所见,APEX_ITEM 无法以您希望的方式与 APEX_ERROR 一起使用。 Marc 在这里的评论表明 APEX_ITEM 可能不会进一步开发,所以它可能永远不会。

您最好的选择可能是将验证逻辑移至存储过程。通过参数在一次调用中完成所有验证。除了常规参数外,添加一个参数来指示响应是否应为 JSON。如果是这样,就 return 一个有错误的 JSON 文档,否则使用 apex_error。这将允许您通过 Ajax 调用验证逻辑以在您喜欢的地方显示错误,而且还可以在 submit/page 处理(因为客户端验证不可信)。

您可以按照以下步骤了解其工作原理...首先,在您的架构中编译以下过程:

create or replace procedure validate_thing(
  p_description in  varchar2,
  p_return_json in  boolean,
  p_json_result out json_object_t
)
is

  l_errors_arr    json_array_t := json_array_t();
  l_error_obj     json_object_t := json_object_t();
  l_item_id       varchar2(30);
  l_error_message varchar2(255);
begin

  if length(p_description) > 10
  then
    l_item_id := 'description';
    l_error_message := 'Description should be less than 10 characters.';

    if p_return_json
    then
      l_error_obj := json_object_t();

      l_error_obj.put('pageItem', l_item_id);
      l_error_obj.put('message', l_error_message);

      l_errors_arr.append(l_error_obj);
    else
      -- Server-side code will not worry about displaying the error with the item as 
      -- this is just a backup for the client-side validation
      apex_error.add_error(
        p_message          => l_error_message,
        p_display_location => apex_error.c_inline_in_notification
      );
    end if;
  end if;

  if p_return_json
  then
    p_json_result := json_object_t();

    if l_errors_arr.get_size() > 0
    then
      p_json_result.put('status', 'error');
      p_json_result.put('errors', l_errors_arr);
    else
      p_json_result.put('status', 'success');
    end if;
  end if;

end;

如您所见,该过程具有执行客户端验证 (JSON) 或服务器端验证 (APEX_ERROR) 的逻辑。您需要根据需要为表单添加额外的参数和逻辑。

在您的应用程序中创建一个新的空白页面,然后转到新页面的页面设计器。右键单击 Content Body(在 Regions 下)并 select Create Region。将区域的类型设置为 PL/SQL 动态内容并将以下代码添加到 PL/SQL 代码属性:

declare

  html clob;

begin

  -- The div and fieldset wrappers are needed so that APEX will generate an error
  -- message template automatically to display the error inline.
  html := '<div><fieldset>';
  html := html || APEX_ITEM.textarea(p_idx=>32, p_value=>'MyValue',p_item_id=>'description',p_attributes=>'class="textarea apex-item-textarea"');
  html := html || '</fieldset></div>';

  htp.p(html);

end;

该代码使用 apex_item 向页面动态添加项目。请注意,传递给 p_item_id 的值很重要。错误样式需要 apex-item-textarea class,内联显示错误消息需要 divfieldset 包装器。

Select 页面设计器中的“处理”选项卡。右键单击 Ajax 回调 和 select 创建进程 。将Name设置为DO_VALIDATIONS,在PL/SQLCode中输入以下代码] 字段。

declare

  l_result json_object_t;

begin

  validate_thing(
    p_description => apex_application.g_x01,
    p_return_json => true,
    p_json_result => l_result
  );

  htp.p(l_result.to_string());

end;

这是调用 validate_thing 并将 p_return_json 设置为 true 的代码。请注意,"description" 的值是通过 apex_application.g_x01 传入的。您有 g_x01 - g_x20 以这种方式工作。您可以利用多种选项通过 Ajax 发送值,这只是一个示例。有关更多信息,请参阅 apex.server.process 上的文档(接下来使用)。

Return到渲染选项卡,右击新区域,select创建按钮。将 按钮名称 设置为 SUBMIT。右键单击 提交 按钮和 select 创建动态操作。将 Name 设置为 SUBMIT clicked。 Select默认Show动作,设置其ActionExecuteJavaScriptCode,然后将以下代码添加到代码字段:

apex.server.process(
  'DO_VALIDATIONS',
  {
    x01: $x('description').value
  },
  {
    success: function(result)  {
      apex.message.clearErrors();

      if (result.status === 'error') {  
        for (var idx = 0; idx < result.errors.length; idx++) {
          result.errors[idx].type = 'error';
          result.errors[idx].location = ['page', 'inline'];
          result.errors[idx].unsafe = false;
        }

        apex.message.showErrors(result.errors);
      } else if (result.status === 'success') {
        apex.page.submit('SUBMIT');
      }
    },
    error: function( jqXHR, textStatus, errorThrown ) {
      console.log(jqXHR, textStatus, errorThrown)
    }
  }
);

这是将调用新的 DO_VALIDATIONS Ajax 进程的 JavaScript 代码。如果错误是从服务器 return 编辑的,apex.message.showErrors 将显示它们。否则,提交页面进行处理。

Select 处理选项卡,右键单击处理,然后 select 创建进程。将 Name 设置为 Do Validations 并在 PL/SQL 代码属性中输入以下代码:

declare

  -- Only needed to call validate_thing, not used.
  l_result json_object_t;

begin

  validate_thing(
    p_description => apex_application.g_f32(1), -- This is where the item's value will be when submitting normally
    p_return_json => false, -- This tells validate_thing to use apex_error
    p_json_result => l_result
  );

end;

该代码将调用 validate_thing 并将 p_return_json 设置为 false。这将重新运行 服务器端的验证以确保它们在那里被强制执行。因为它只是客户端调用的备份,所以我不担心在项目中显示错误(JS 会这样做)。

再次右键单击 Processing 并 select Create Process。将 Name 设置为 Do Work 并为 PL/SQL 代码属性输入 null;。将成功消息设置为它运行.。在服务器端条件下,将类型设置为 PL/SQL 表达式并在 PL/SQL 表达式字段中输入 not apex_error.have_errors_occurred

此过程表示您希望在验证通过后 运行 的实际业务逻辑。如果 Ajax 和服务器端验证均已通过,您只会在单击提交后看到成功消息。

如果您希望测试服务器端验证,请在动态操作中添加这行 JavaScript 代码,就在提交页面的行之前:

$x('description').value = '12345678910';

这将更新文本区域的值以超过服务器强制执行的限制。