How to override form just on one page? - php

OK so this is my hook form alter function.It is causing all the registration forms on site to be over written which I do not want as I just want it on this page.
function special_registration_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'user_register') {
drupal_set_title(t('Custom registration'));
$form['firstname'] = array('#type' => 'textfield',
'#title' => t('First Name: *'),
'#required' => TRUE,
'#size' => 45,
'#weight' => - 100,);
$form['lastname'] = array('#type' => 'textfield',
'#title' => t('Last Name: *'),
'#required' => TRUE,
'#size' => 45,
'#weight' => - 99,);
}
I only first name and last name to be captured and stored in a different table just on this page.
On other pages I just want the good old fashioned form. Do I still need to change the weight? I know I am missing something elementary.

You just need a check for the current page, using either arg or $_GET['q'].
eg:
function special_registration_form_alter(&$form, $form_state, $form_id) {
if ($_GET['q'] !== 'whatever/path' ) { return false; }
..rest of code..
}

If you want to restrict your form alterations to a specific page, you can simply add a check for the page to your form id check, e.g.:
function special_registration_form_alter(&$form, $form_state, $form_id) {
// Alter the registration form, but only on 'user/register' pages
if ($form_id == 'user_register' && 'user' == arg(0) && 'register' == arg(1)) {
// snipped alteration code
}
}

You could make use of the Profile module in the Core list of modules as well. It will solve this without any programming, fyi.

Implement hook_user(); the function allow to alter the form presented to the users when they register on a site.
hook_user() is used by user.module, and it is independent from the profile module.
Defining the hook as hook_user($op, &$edit, &$account, $category = NULL), the parameter $op will contain the value 'register' when the registration form is being presented to the user. In that case, the module returns the form fields it wants to add to the registration form.

If you don't really need to create user accounts, like for a simple event registration. If instead you're collecting just names, you could use the webform module instead.

Related

Adding additional fields in drupal's default contact form

I am trying to learn drupal so right now my website resides on my localhost. I am using DRUPAL 7. I have created a contact us page in my drupal site using drupal's contact module. I want to add one more fields(Phone Number) to the existing contact form and need to sent the value along with the email. How is it possible to do something like this.
I have used the following code in my contact module page
function mymodulename_form_contact_site_form_alter(&$form, &$form_state) {
$form['phone'] = array(
'#title' => t('Phone'),
'#type' => 'textfield',
'#required' => TRUE,
);
$order = array(
'name',
'mail',
'phone',
'subject',
'cid',
'message',
'copy',
'submit'
);
foreach ($order as $key => $field) {
// Set/Reset the field's
// weight to the array key value
// from our order array.
$form[$field]['#weight'] = $key;
}
}
But the field is not showing up on the website page. Please help.
Thanks
Now its all fine. I had placed the code in the existing contact module file. That was the issue. Now I create a custom module and placed the similar code there. Now its all fine.
Only change needed to make it working is instead of using this
function mymodulename_form_contact_site_form_alter(&$form, &$form_state) {
use the below line
function mymodulename_form_contact_site_form_alter(&$form, &$form_state, &$form_id) {
Hope this helps someone.

Conditional fieldgroups/fieldsets in Drupal 7

Background: In Drupal 7, I have created a form with CCK (aka the Field UI). I used the Field group module to create a fieldgroup, but I need it to be conditional, meaning it will only display depending on a previous answer.
Previous research: To create a conditional field, you can use hook_form_alter() to edit the #states attribute like so:
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'person_info_node_form') {
// Display 'field_maiden_name' only if married
$form['field_maiden_name']['#states'] = array(
'visible' => array(
':input[name="field_married[und]"]' => array('value' => 'Yes'),
),
);
}
}
However, there seems to be no way to use the States API for fieldgroups. One thing to note is that, while fields are stored in $form, fieldgroups are stored in $form['#groups'] as well as in $form['#fieldgroups']. I don't know how to distinguish between these, and with this in mind, I have tried to apply a #states attribute to a fieldgroup in the same manner as above. However, it only produces server errors.
Question: Is there a way to make a fieldgroup display conditionally using the States API or some alternative approach?
you have to use the hook_field_group_build_pre_render_alter()
Simply :
function your_module_field_group_build_pre_render_alter(&$element) {
$element['your_field_group']['#states'] = array(
'visible' => array(
':input[name="field_checkbox"]' => array('checked' => TRUE),
),
);
}
This works perfecly. If the group A is in an another group, do this
$element['groupA']['groupB']['#states'] etc....
You may need to add an id attribute if none exists:
$element['your_field_group']['#attributes']['id'] = 'some-id';
$element['yout_field_group']['#id'] = 'some-id';
Here's the simplest solution I came up with. There are essentially 2 parts to this: (1.) programmatically alter the display of the form, and (2.) use the GUI to alter the display of the content.
(1.) First, I used hook_form_alter() to programmatically create the conditional fieldset and add existing fields to it. The code is shown below.
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'FORM_ID_node_form') {
// programmatically create a conditional fieldset
$form['MYFIELDSET'] = array( // do NOT name the same as a 'Field group' fieldset or problems will occur
'#type' => 'fieldset',
'#title' => t('Conditional fieldset'),
'#weight' => intval($form['field_PARENT']['#weight'])+1, // put this fieldset right after it's "parent" field
'#states' => array(
'visible' => array(
':input[name="field_PARENT[und]"]' => array('value' => 'Yes'), // only show if field_PARENT == 'Yes'
),
),
);
// add existing fields (created with the Field UI) to the
// conditional fieldset
$fields = array('field_MYFIELD1', 'field_MYFIELD2', 'field_MYFIELD3');
$form = MYMODULE_addToFieldset($form, 'MYFIELDSET', $fields);
}
}
/**
* Adds existing fields to the specified fieldset.
*
* #param array $form Nested array of form elements that comprise the form.
* #param string $fieldset The machine name of the fieldset.
* #param array $fields An array of the machine names of all fields to
* be included in the fieldset.
* #return array $form The updated form.
*/
function MYMODULE_addToFieldSet($form, $fieldset, $fields) {
foreach($fields as $field) {
$form[$fieldset][$field] = $form[$field]; // copy existing field into fieldset
unset($form[$field]); // destroy the original field or duplication will occur
}
return $form;
}
(2.) Then I used the Field group module to alter the display of the content. I did this by going to my content type and using the 'Manage display' tab to create a field group and add my fields to it. This way, the fields will appear to be apart of the same group on both the form and the saved content.
Maybe you can try to look at the code of this module to help you find an idea.

set the attributes in PHP 5

In my Zend framework I have two row one rows contains state dropdown with label state and the other contains a text box with label other state. Below is the code:
'state' => array('select', array(
'required' => true,
'decorators' => $elementDecorators,
'label' => 'State:',
'multiOptions' => $values["state"]
)),
'other_state' => array('text', array(
'required' => true,
'filters' => array('StringTrim'),
'decorators' => $elementDecorators,
'label' => 'Other State:',
'class' => 'other_state',
))
Here the other state is set as required. I need it required only when the user select "Other" value from the state drop down.
Client Side:
jQuery solution:
Showing your HTML output would have been a help here. But the following will add the attribute required if other is selected - this will also enable the input and disable it so the user can only enter something in other state, if they select other:
$("#state").change(function(){
if ($(this).val() == "other"){
$("#other_state").removeAttr("disabled");
$("#other_state").attr("required", "required");
}
else {
$("#other_state").removeAttr("required");
$("#other_state").attr("disabled", "true");
}
});
See a demo here
The above will do the validation on the clients side - with jQuery, however if the user has javascript turned off, it would allow the user to select other and leave other_state blank!
Server Side:
Zend solution:
What you should also do is add some validation to the zend_form. However, you can't add them the normal way - if you added a validator to say other_state can't be empty - you would have an error when a state is selected and you want it to be empty.
In your form class you could override the isValid call to add your custom validation, see the discussion here: There is another example on how to do this here
/**
/* override the isValid function of Zend_Form
/* to set a required field based on a condition
*/
public function isValid($value) {
// Check the key exists in the stack, and if its set to other:
if (array_key_exists('state', $value) && $value['state'] == 'other') {
// It is so make sure other_state is a required field:
$this->other_state->setRequired(true);
}
parent::isValid($value);
}

How can I submit my Drupal form to any other internal page?

I'm having a problem with Drupal forms. Can't think of a way to solve it and I was wondering if any brain out there has the solution to my problem.
I have this form:
<?php
function mymodule_myform(){
$form['#action'] = url('search/cards');
$form['whatwhere']['what'] = array(
'#type' => 'textfield',
'#title' => t('What?'),
'#maxlength' => 80,
'#required' => TRUE,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Search'),
);
}
?>
Which, as you can see, is supposed to submit all info to www.example.com/search/cards.
This will indeed submit my form to the desired URL. However, without the mymodule_menu() hook defining the path, it will end in a 404.
So I add:
<?php
function mymodule_menu(){
$items['search/%'] = array(
'title' => t('Search Results'),
'page callback' => 'mymodule_main',
'access arguments' => array('access content'),
'file' => 'mymodule.inc',
);
}
?>
And, at mymodule.inc file I'll create my function mymodule_main():
<?php
function mymodule_main(){
print_r($_POST);
die(); // ### Note the die(); ###
return 'Just searched: '. $_POST['what'];
}
?>
If I leave it exactly like it is, of course PHP will end the script execution right after printing my form info on the screen. All good!
However, if I remove the die(), it seems the function is called twice, and the second call does not have $_POST filled up anymore.. Seems mymodule_menu() overrides in some way whatever the form submit handler is doing...
The question is: How can I submit my form to any other internal page without having the 404 and keep my form info?
Thanks in advance.
I think you need to use the method described in http://api.drupal.org/api/function/search_box_form_submit/6
function MODULE_block_form_submit($form, &$form_state)
{
if (isset($_REQUEST['destination'])) {
unset($_REQUEST['destination']);
}
if (isset($_REQUEST['edit']['destination'])) {
unset($_REQUEST['edit']['destination']);
}
$form_state['redirect'] = 'search/cards/'. trim($form_state['values']['whatwhere']);
}
I don't know exactly, but maybe your code conflicts with drupal's builtin search module?
After some debate # drupal forums (which can be followed here) conclusion is that: it is not possible to have a menu callback handling form results. You can instead, use a form submit handler (as always) and then redirect to your menu callback.
It's not a POST to the menu callback but it's as good as it gets.
Thanks for your help.

Create a VERY simple form in Drupal

All I need to do is have a form that does this:
User enters postcode in text box
Upon submit user is redirected to mysite.com/[user postcode]
That's it! I know validation etc. would be desirable as well, but I just need to get this working for now. I don't mind if it's harcoded or utilises the Drupal form API (actually I'd prefer the former!).
I know this is dead simple, but unfortunately I'm coming from a front-end background and have a bit to learn about this sort of thing :(
Cheers!
This is pretty easy with the Form API and a custom module. You'll build a form using the Form API and add a submit handler that changes the redirect for the form to whatever you'd like. Finally, you'll need to create a way to access the form (either by creating a menu item or by creating a block).
Here's an example that implements a form like you want: you'll want to peruse the Form API reference to see all the options you have when building a form. It also provides two ways to access the form:
Using hook_menu() to provide a page for the form at http://example.com/test
Using hook_block() to provide a block containing the form that you can add and move around on the block administration page.
Example code:
// Form builder. Form ID = function name
function test_form($form_state) {
$form['postcode'] = array(
'#type' => 'textfield',
'#title' => t('Postcode'),
'#size' => 10,
'#required' => TRUE,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Go'),
);
return $form;
}
// Form submit handler. Default handler is formid_submit()
function test_form_submit($form, &$form_state) {
// Redirect the user to http://example.com/test/<Postcode> upon submit
$form_state['redirect'] = 'test/' . check_plain($form_state['values']['postcode']);
}
// Implementation of hook_menu(): used to create a page for the form
function test_menu() {
// Create a menu item for http://example.com/test that displays the form
$items['test'] = array(
'title' => 'Postcode form',
'page callback' => 'drupal_get_form',
'page arguments' => array('test_form'),
'access arguments' => array('access content'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
// Implementation of hook_block(): used to create a movable block for the form
function test_block($op = 'list', $delta = 0, $edit = array()) {
switch ($op) {
case 'list': // Show block info on Site Building -> Blocks
$block['postcode']['info'] = t('Postcode form');
break;
case 'view':
switch ($delta) {
case 'postcode':
$block['subject'] = t('Postcode');
$block['content'] = drupal_get_form('test_form');
break;
}
break;
}
return $block;
}
More info:
Creating modules - a tutorial: Drupal 6.x
Form API Quickstart Guide
Form API Reference
hook_menu() API reference
hook_block() API reference
Example of hook_block in Drupal 6
The Drupal Form API -is- dead simple and its something you need to learn as a developer eventually. Might as well jump in and do it through the API since its not too hard, what you are trying to do.
Creating forms in Drupal is fairly easy once you get the hang of it. I would recommend reading the following link. http://drupal.org/node/751826 It gives a good overview of how to create the form.
In the _submit hook, you can then redirect to the appropriate page by setting $form_state['redirect'].
This is assuming of course that you already have the hang of creating custom modules. If you need more info on that, go here.

Categories