The FAPI allows you to do this without altering the $_SESSION messages array by using #limit_validation_errors.
/**
* Implements hook_form_alter().
*/
function my_module_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'my_form_id') {
$form['my_textfield'] = array(
'#type' => 'textfield',
'#title' => t('Some title'),
'#required' => TRUE,
'#element_validate' => array('my_element_validate'),
);
$form['preview'] = array(
'#type' => 'button',
'#value' => t('Preview'),
'#limit_validation_errors' => array(array('my_textfield')),
);
}
}
/**
* My textfield element validate handler.
*/
function my_element_validate($element, &$form_state, $form) {
// Check the value here.
// Checking if the element has a value can be set in the field, but just to demo...
if (empty($element['#value']) == '123') {
form_error($element, t('This field'123 isnot required.allowed!'));
}
}