Drupal hook_form_alter Not redirecting - drupal

I am using hook form_alter and setting the $form['#redirect'] = 'dir1/dir2/mypage'. But the form refuses to go there.
Form seems to work otherwise, but keeps sending back to the original form instead of the redirect.
The form I am altering is from the root user module.
mymodule_form_alter( ){
... code...
$form['account']['pass'] = array(
'#type' => 'password_confirm',
'#size' => 25, '#description' => t(''),
'#required' => TRUE
);
unset($form['Birthdate']['profile_birthdate']);
unset($form['Birthdate']);
unset($form['#action']);
$form['#validate'] = array('_mymodule_school_registration_validate');
$form['#submit'] = array( '_mymodule_school_registration_submit');
$form['#redirect']= "dir1/dir2/mypage";
}
Please help trying to meet an overdue dead line!! : (
Thanks in advance.

Your hook_form_alter() implementation is not correct:
Without parameters, you're aren't modifying anything, so none of your changes get registered,
$form['#submit'] and $form['#validate'] are already arrays with content, so you should not be resetting them with array(),
unsetting $form['#action'] causes the form to do nothing when submitted,
setting $form['#redirect'] in hook_form_alter() will get overridden by other handlers, and
your hook_form_alter() implementation would affect (and break) every form.
More info: Forms API Reference
Instead, try the following:
function mymodule_form_alter(&$form, $form_state, $form_id) {
if ($form_id === 'form_id_goes_here') {
// Code here
$form['account']['pass'] = array(
'#type' => 'password_confirm',
'#size' => 25,
'#description' => t(''),
'#required' => TRUE
);
unset($form['Birthdate']['profile_birthdate']);
unset($form['Birthdate']);
$form['#validate'][] = '_mymodule_school_registration_validate';
$form['#submit'][] = '_mymodule_school_registration_submit';
}
}
function _mymodule_school_registration_submit($form, &$form_state) {
// Code here
$form_state['redirect'] = 'dir1/dir2/mypage';
}

Try
$form_state['redirect'] = "dir1/dir2/mypage";

If you've only got one handler for your submit you could easily redirect with
function _mymodule_school_registration_submit(..args...) {
...
drupal_goto('somewhere');
}
I think the functionality is the same.
http://api.drupal.org/api/function/drupal_goto/6
I tend to avoid redirects so once you have met your deadline I would refactor your code. You can usually get away with out redirecting.

Related

WordPress: Customize Ajax request response via filter

There is a function in parent theme and I want to customize success message, I don't want to make change in parent theme file. And the function is not pluggable so I can't override it. After digging, I found that I can use add_filter hook to filter response.
I wrote this code:
add_filter( 'wp_ajax_sync-data', 'custom_sync_data' );
function custom_sync_data(){
$response = array(
'success' => true,
'message' => 'Date is updated'
);
wp_send_json($response);
}
It does the job but it always returns success message, without any validation. I don't know, how to pass parameter for validation or decision making.
Can you try this
function custom_sync_data($params){
//$params can be data or parameters you will have to pass
//or you will have to check
//based on that your setup validation or logic
$response = array(
'success' => true,
'message' => 'Date is updated'
);
}
wp_send_json($response);
You may also use var_dump($params) to check if anything is passed to function.
Hope this helps.

Disable a Field in a Paragraphs Form

Does anyone know how to alter a field in a paragraphs (ajax) backend form in Drupal 8? I want to disable a field, but keep it visible.
Thanks
function hook__form_FORM_ID_alter(&$form,\Drupal\Core\Form\FormStateInterface
$form_state, $form_id) {
//output your form structure to know what to target in the form array($form[])
#kint( $form['title']);
$form['title']['#disabled'] = TRUE;
}
The above code disables the title field (Drupal 8.5) in the 'FORM_ID' you want to modify.
You can disable a form field by either using hook_form_alter() or by hook_form_FORM_ID_alter().
I would always suggest you to use hook_form_FORM_ID_alter(). Suppose test is your modules name and user_register_form is the Id of the form.
test_form_user_register_form_alter(&$form, &$form_state, $form_id) {
$form['fieldname'] = array(
'#type' => 'textfield',
'#title' => t('Text label'),
'#attributes' => array('disabled' => 'disabled'),
);
}
Happy coding!!!

Check if form failed validation

I added a validation hook to a node creation form.
For my project, i need this validation only ONE time: basically i just check if a value already exists in the DB and i notify it to the user. If the user still submits the form, i must add it anyway.
i would like to do something like that:
if (form_did_not_fail_validation_before) {
$form['#validate'][] = 'my_module_validation_hook';
}
in my hook_form_alter, so that validation hook is only called the first time.
I can't find a way to check if the form already failed validation, any ideas?
Here is one way of solving this issue your issue. But if you using some form input like text form I suggest that you use Ajax callback since it will feel more dynamic. Let me know if you want an example of how to solve it with Ajax callback?
I guess the key here is that I use $form_state['rebuild'] = true; so that form is rebuilt and than it easy to get the value from the $form_state['values']
Here is the code:
function example_form(array $form, array &$form_state)
{
$form['temp'] = array(
'#type' => 'value',
'#value' => array_key_exists('values', $form_state) ? $form_state['values']['temp'] + 1 : 1,
);
if (array_key_exists('values', $form_state) && $form_state['values']['temp'] == 1)
{
$form['message'] = array(
'#markup' => t('I only give you one warning'),
'#prefix' => '<p>',
'#suffix' => '</p>',
);
}
$form['submit_button'] = array(
'#type' => 'submit',
'#value' => t('Click Here!'),
);
return $form;
}
function example_form_validate(array $form, array &$form_state)
{
$form_state['rebuild'] = true;
}
function example_form_submit(array $form, array &$form_state)
{
if($form_state['values']['temp'] == 1) {
// I will not store anything
} else {
// now I will store it :)
}
}

Using Drupal's node form in a new page

In a custom module I want to have a page defined in hook_menu, that shows the add form for a specific content type, with some modifications to the form.
So far it's working, and even saving the new node, but only with the default values I'm setting in the code, i.e. it's not picking up anything the user types into the form. I checked and $form_state['input'] contains the inputted values, but $form_state['values'] doesn't, so the new node gets saved wrong.
Here's the relevant code:
function mymodule_menu() {
return array(
'admin/content/myadd/%' => array(
'title' => 'my custom add page',
'page callback' => 'mymodule_node_add',
'page arguments' => array(3),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
),
);
}
function mymodule_node_add() {
module_load_include('inc', 'node', 'node.pages');
//I'm doing a print here instead of returning because I'm calling this page
//in an AJAX popup, so I don't want the whole page to output, only the form.
print render(drupal_get_form('mymodule_node_add_form'));
}
function mymodule_node_add_form($form, &$form_state) {
if (!isset($form_state['node']) {
global $user;
$node = (object) array(
'uid' => $user->uid,
'type' => 'mycontenttype',
'language' => LANGUAGE_NONE,
);
//this is setting a default value
$node->myfield = array(LANGUAGE_NONE => array(array('value' => arg(3))));
$form_state['build_info']['args'] = array($node);
$form = drupal_build_form('mycontenttype_node_form', $form_state);
$form['actions']['submit']['#submit'][0] = 'mymodule_node_add_form_submit';
//there's a lot more customization of the form here, like adding fields, etc.
}
return $form;
}
function mymodule_node_add_form_submit($form, &$form_state) {
//here's where $form_state['input'] is correct but $form_state['values'] isn't.
$node = node_form_submit_build_node($form, $form_state);
node_save($node);
$form_state['values']['nid'] = $node->nid;
$form_state['nid'] = $node->nid;
$form_state['redirect'] = 'some/other/page';
}
So, am I doing something wrong here? Should I be concerned about form ids being wrong? (my form's id is mymodule_node_add_form, but the actual form might output mycontenttype_node_form), would this affect me?
You want hook_form_alter() (see api.drupal.org). I would try to use the existing content type's form and simply alter it with hook_form_alter(). I would also try to first get it working as a standard, non-AJAX page, so you can get all the advantages of dpm() and other debugging techniques. When you have it down solid, then modify it to take advantage of the AJAX techniques.
mymodule_form_alter(&$form, &$form_state, $form_id) {
// use this with your devel module turned on to verify
// your $form_id and contents of all forms that load on a given page
dpm($form);
// once you verify your $form_id, you can begin accessing your form and altering it
switch( $form_id ) {
case 'my_target_form_id' :
// this part is just pseudocode, I haven't memorized the $form structure,
// you can get it from your dpm().
if( $form['node']->type == 'my_target_content_type' ) {
$form['actions']['submit']['#submit'][0] = 'mymodule_node_add_form_submit';
}
break;
}
}

Select list in Drupal 7 custom form element

I have created several custom elements in a module, which work great for grouping several controls in a single form field.
However, I now need to add one that contains a drop-down list. The idea is to have a drop-down list of country codes, and a text field for the phone number.
It displays correctly and looks good until the form is submitted, which results in the error, "An illegal choice has been detected. Please contact the site administrator." This would seem to indicate that Drupal isn't recognising the options as being part of the select control.
Here's my code:
function my_module_element_info() {
$types = array(
'phone' => array(
'#input' => TRUE,
'#process' => array('my_module_phone_process'),
'#element_validate' => array('my_module_phone_validate'),
'#autocomplete_path' => FALSE,
'#theme_wrappers' => array('my_module_inline_form_element'),
),
);
return $types;
}
function my_module_phone_process($element, &$form_state, $complete_form) {
$element['#tree'] = TRUE;
$element['prefix'] = array(
'#type' => 'select',
'#value' => $element['#value']['prefix'] ,
'#options' => $element['#options'],
'#required' => $element['#required'],
);
$element['number'] = array(
'#type' => 'textfield',
'#size' => 20,
'#maxlength' => 40,
'#value' => $element['#value']['number'],
'#required' => $element['#required'],
);
if (isset($element['#attributes'])) {
$element['prefix']['#attributes'] = $element['#attributes'];
$element['number']['#attributes'] = $element['#attributes'];
}
$element['prefix']['#attributes']['class'][] = 'form-phone-prefix';
$element['number']['#attributes']['class'][] = 'form-phone-number';
if (isset($element['#ajax'])) {
$element['prefix']['#ajax'] = $element['#ajax'];
$element['number']['#ajax'] = $element['#ajax'];
}
return $element;
}
function my_module_phone_validate($element) {
if (!preg_match('/^[0-9 ]+$/', $element['#value']['number'])) {
form_error($element['number'], t('Phone number may contain only digits and spaces.'));
}
return $element;
}
Any help getting this working would be greatly appreciated.
Thanks for looking.
James
you can add the following attribute to the element causing this error.
'#validated' => TRUE,
This problem got parked on the back burner for a while, but I got back to it this week.
I think I now understand the reason for the error. If an element has a "#options" property, it is expected to behave like a select control, and one of the options should be submitted. As the field itself is a container for other controls, so has no input directly, there is no posted value matching an entry in "#options" so Drupal flags it as an invalid form submission.
After a lot of trial and error, I hit on something very simple. The "#options" are used to populate the child control, but once it's been populated, they are no longer needed on the parent. So I added a "#after_build" function to the element, and used it to remove the "#options", and it worked perfectly.
function common_pricing_phone_after_build($element, &$form_state) {
unset($element['#options']);
return $element;
}

Resources