Skip to main content.

Monday, February 28, 2005

In Nucleus 3.2, there are some changes to how comment and member mail forms work. To the end user, this is visible in two ways:

  1. When an error occurs, the error will appear together with the comment form, rather than on a separate page.
  2. When an error occurs, the comment form is pre-filled with what the user had originally entered. This solves the problem of finding out that everything you wrote has gone after hitting the back button on an error page.

This article describes how all of this works, what has changed and how you can style the error message using the error class.

Styling the error message

Easiest things first: styling the error message can be done through the error class, since the commentform templates (e.g. nucleus/forms/commentform-notloggedin.template) looks sort of like this:

<div class="commentform">
  <%errordiv%>

   ...form fields...
</div>

This results in the following HTML code:

<div class="commentform">
  <div class="error">Something was wrong with your comment.</div>

   ...form fields...
</div>

If the form is displayed like that, no div class="error" tag is inserted.

An example style could be:

.commentform .error {
  font-size: larger;
  font-weight: bold;
  color: red;
  border: 1px solid red;
}

How it works

In earlier Nucleus versions, posting a comment or member mail message was done through action.php, which redirected back to the item page after the comment was added. The new way of working posts the form back to the page itself (a "postback", if you're familiar with ASP.NET). That's why the form templates now have action="#nucleus_cf" instead of action="<%formdata(actionurl)%>"

The code from action.php has been moved into a new class: libs/ACTION.php. To keep sites that explicitly relied on action.php working, it has been replace by a version that calls the ACTION class. It's pretty simple:

$action = requestVar('action');
$a =& new ACTION();
$errorInfo = $a->doAction($action);

OK then, what happens when posting back a comment form to the item page? Well, the page loads as usual, but inside the selector() in globalfunctions.php, a piece of code triggers:

$actionNames = array('addcomment', 'sendmessage',
'createaccount',
'forgotpassword', 'votepositive',
'votenegative', 'plugin');
$action = requestVar('action');
if (in_array($action, $actionNames))
{
  global $DIR_LIBS, $errormessage;
  include_once($DIR_LIBS . 'ACTION.php');
  $a =& new ACTION();
  $errorInfo = $a->doAction($action);
  if ($errorInfo)
    $errormessage = $errorInfo['message'];
}

This code is pretty straightforward: it checks if a known action was requested. If so, the action is executed and an errormessage (if there is one) is stored in a global variable.

One thing to note is that the doAction method in the ACTION class only returns when the action failed. When it succeeds, it does as action.php would have done before: redirect the user or exit the script. It can do this, since the code is called before any page output has been done.

Plugins

Plugins that subscribe to the ValidateForm event, get the chance to verify comments. The error message returned by this event will also be displayed in the same way. One of the plugins using this is NP_Captcha

Filling out the form with the previous values

One last topic to address is how the form is filled out with the values from the original request.

For this, the commentform templates now have tags like <%formdata(body)%> to prefill the old values. For example, the comment textarea looks like this:

<textarea name="body" ...><%formdata(body)%></textarea>

The actual values are set in SKIN.php, where the parse_commentform method now contains the following piece of code:

// values to prefill
$user = cookieVar($CONF['CookiePrefix'] .'comment_user');
if (!$user) $user = postVar('user');
$userid = cookieVar($CONF['CookiePrefix'] .'comment_userid');
if (!$userid) $userid = postVar('userid');
$body = postVar('body');

$this->formdata = array(
  'destinationurl' => htmlspecialchars($destinationurl),
  'itemid' => $itemid,
  'user' => htmlspecialchars($user),
  'userid' => htmlspecialchars($userid),			
  'body' => htmlspecialchars($body),			
   ...
);

$this->doForm('commentform-notloggedin');

Similar changes apply to other forms.

Comments

Nice article :)

Posted by TeRanEX at Monday, February 28, 2005 20:43:12

Add Comment

This item is closed, it's not possible to add new comments to it or to vote on it