Drupal-7
Second taxonomy autocomplet depend on first taxonomy autocomplet.
Add offer:
step 1) Country with autocomplet , City is empty
Country: U
------------USA
City:
step 2) when we select USA then we can use City with autocomplet
Country: USA
City: Be
-------Berkeley
Step 3) but we just insert new item Bexxx
Country: USA
City: Bexxx
Search offer:
Step 1) Country - select USA from the list, City is empty
Country: USA
-----------Germany
City:
Step 2) when we select USA then we have 3 items on the list
Country: USA
City: Berkeley
-------Berlin
-------Bexxxxx
I use Drupal 6, module Hierarchical select and Views. Then in Views I used field with exposed filter.
This is a simple example of dependent fields. Make a simple module named "myajx" and placed this code as it is. Now access through url ie "http://localhost/mypage". Now select a value from first field and you will see only its dependent values are listed in below field.
<?php
/**
* Implementation of hook_menu().
* Registers a form-based page that you can access at "http://localhost/mypage"
*/
function myajx_menu(){
return array(
'mypage' => array(
'title' => 'A page to test ajax',
'page callback' => 'drupal_get_form',
'page arguments' => array('myajx_page'),
'access arguments' => array('access content'),
)
);
}
/**
* A form with a dropdown whose options are dependent on a
* choice made in a previous dropdown.
*
* On changing the first dropdown, the options in the second are updated.
*/
function myajx_page($form, &$form_state) {
// Get the list of options to populate the first dropdown.
$options_first = myajx_first_dropdown_options();
$value_dropdown_first = isset($form_state['values']['dropdown_first']) ? $form_state['values']['dropdown_first'] : key($options_first);
$form['dropdown_first'] = array(
'#type' => 'select',
'#title' => 'First Dropdown',
'#options' => $options_first,
'#default_value' => $value_dropdown_first,
// Bind an ajax callback to the change event (which is the default for the
// select form type) of the first dropdown. It will replace the second
// dropdown when rebuilt
'#ajax' => array(
// When 'event' occurs, Drupal will perform an ajax request in the
// background. Usually the default value is sufficient (eg. change for
// select elements), but valid values include any jQuery event,
// most notably 'mousedown', 'blur', and 'submit'.
'event' => 'change',
'callback' => 'myajx_ajax_callback',
'wrapper' => 'dropdown_second_replace',
),
);
$form['dropdown_second'] = array(
'#type' => 'select',
'#title' => 'Second Dropdown',
'#prefix' => '<div id="dropdown_second_replace">',
'#suffix' => '</div>',
'#options' => myajx_second_dropdown_options($value_dropdown_first),
'#default_value' => isset($form_state['values']['dropdown_second']) ? $form_state['values']['dropdown_second'] : '',
);
return $form;
}
/**
* Selects just the second dropdown to be returned for re-rendering
*
* Since the controlling logic for populating the form is in the form builder
* function, all we do here is select the element and return it to be updated.
*
* #return renderable array (the second dropdown)
*/
function myajx_ajax_callback($form, $form_state) {
return $form['dropdown_second'];
}
/**
* Helper function to populate the first dropdown. This would normally be
* pulling data from the database.
*
* #return array of options
*/
function myajx_first_dropdown_options() {
return array(
'colors' => 'Names of colors',
'cities' => 'Names of cities',
'animals' => 'Names of animals',
);
}
function myajx_second_dropdown_options($key = '') {
$options = array(
'colors' => array(
'red' => 'Red',
'green' => 'Green',
'blue' => 'Blue'
),
'cities' => array(
'paris' => 'Paris, France',
'tokyo' => 'Tokyo, Japan',
'newyork' => 'New York, US'
),
'animals' => array(
'dog' => 'Dog',
'cat' => 'Cat',
'bird' => 'Bird'
),
);
if (isset($options[$key])) {
return $options[$key];
}
else {
return array();
}
}
Related
I am building my first Drupal 7 module and am having trouble with the screen to edit a fieldable entity. I am using field_attach_form and it is working great for all accept one field which is displaying the field default rather than the current content of that field for that entity.
I have a text field, a number field, a number of Boolean fields and the one list_text field which is failing.
Any ideas what I a doing incorrectly? Code below is what I think is needed but please do let me know if you need more.
Code to create the field in hook_enable:
if (!field_info_field('field_available')) {
$field = array (
'field_name' => 'field_available',
'type' => 'list_text',
'settings' => array(
'allowed_values' => array('No', 'Provisionally', 'Yes'),
),
);
field_create_field($field);
Code to create the instance, also in hook_enable:
if (!field_info_instance('appointments_status', 'field_available', 'appointments_status')) {
$instance = array(
'field_name' => 'field_available',
'entity_type' => 'appointments_status',
'bundle' => 'appointments_status',
'label' => t('Available?'),
'required' => TRUE,
'default_value' => array(array('value' => 'No')),
'description' => t('Set to No if appointments with this status make this slot unavailable, Provisionally means that it will only reserve a space temporarily'),
);
field_create_instance($instance);
This entity has only the one bundle with the same name as the entity.
The code to create the URL in hook_menu:
$items['admin/appointments/appointments_statii/%/edit'] = array(
'title' => 'Edit appointment status',
'description' => 'Edit the parameters of the selected status code',
'page callback' => 'drupal_get_form',
'page arguments' => array('appointments_status_edit_form',3),
'access arguments' => array('access administration pages'),
'type' => MENU_CALLBACK,
);
The form function is:
function appointments_status_edit_form($form, &$form_state) {
// Get the status id from the form_state args
$status_id = $form_state['build_info']['args'][0];
// Load the chosen status entity
$status = entity_load_single('appointments_status', $status_id);
// Set up the fields for the form
field_attach_form('appointments_status', $status, $form, $form_state);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Save changes',
'#weight' => 99,
);
return $form;
}
I have used the Devel module's dpm to check that the data is loaded correctly by entity_load_single and it is.
Thanks
Rory
I have answered my own question!
I was also programmatically loading some entities and was not loading this field with the numbers that a list_text field stores, instead I was loading the visual text.
I used a metadata wrapper and the code looked like this:
$w_appointments_status->$appointments_availability= 'Yes';
I changed it to:
$w_appointments_status->$appointments_availability = 2;
In this example 'Yes' was the third allowed value - hence 2.
So the code in my question was in fact correct although I have since added 'widget' and 'formatter' parameters to the instance.
I am sorry if this got some of you scratching your heads thinking ' but that code is correct'!!
Regards
Rory
I'm looking for a way, to handle the Pagination-options in a dropdown menu.
I'd like my users to select the sorting order in the same form with my filtering options, so when they hit "Send", pagination-order is already set.orm
e.g. like:
$this->Form->input('paginationorder',array(
'label' => 'order',
'options' => array(
'sort:id/direction:desc' => 'New Items, desc',
'sort:id/direction:asc' => 'New Items,asc',
),
'div' => false
)
);
$(function() {
$('#sort-properties').change(function() { // replace the ID_OF_YOUR_SELECT_BOX with the id to your select box given by Cake
var price = $(this).val();
window.location = baseUrl + 'properties/property_view/'+price;
});
});
<?php
echo $this->Form->input('orderby', array(
'id' => 'sort-properties',
'options' => array(
'sort:sale_rent_price/direction:asc' => 'Sort by Price Low to High',
'sort:sale_rent_price/direction:desc' => 'Sort by Price High to Low',
'sort:created/direction:asc' => 'Sort by Date Old to New',
'sort:created/direction:desc' => 'Sort by Date New to Old'
),
'label' => false,
'empty' => 'Default Order'
));
?>
I would change the values of the options to e.g. fieldname.desc, like :
$this->Form->input('paginationorder',array(
'label' => 'order',
'options' => array(
'id.desc' => 'New Items, desc',
'id.asc' => 'New Items,asc',
),
'div' => false
)
);
Afterwards in the controller put the values to an array via the explode method:
$order = explode(".", $this->request->data['Model']['field']);
then you can use the values in your find condition, like:
$result = $this->Model->find('all', array(
'order' => array( $order[0] => $order[1] )
));
There is propably a more elegant way to make this, but this should work.
Hi being a newbie to drupal , kindly guide how to add a new user , i know user module with user_save can be used but how and where to implement it ?
Do i have to write this function in submit handler of my custom form below-
function registerme_newform($form, &$form_state)
{
$form = array();
$form['account details'] = array(
'#type' => 'fieldset',
'#title' => t('Account Details'),
'#description' => t('Enter Personal Credentials'),
);
$form['account details']['first name'] = array(
'#type' => 'textfield',
'#title' => t('First Name'),
'#default_value' => t('Be sure of your first name'),
'#attributes' => array(
'onblur' => "if (this.value == '') {this.value = 'Be sure of your first name'}",
'onfocus' => "if (this.value == 'Be sure of your first name') {this.value = ''}"
, ),
);
$form['account details']['last name'] = array(
'#type' => 'textfield',
'#title' => t('Last Name'),
'#default_value' => t('Be sure of your last name'),
'#attributes' => array(
'onblur' => "if (this.value == '') {this.value = 'Be sure of your last name'}",
'onfocus' => "if (this.value == 'Be sure of your last name') {this.value = ''}"
, ), );
$form['account details']['email'] = array(
'#type' => 'textfield',
'#title' => t('E-Mail'),
'#required' => TRUE,
'#default_value' => t('Email acts as username.Dont forget it!'),
'#attributes' => array(
'onblur' => "if (this.value == '') {this.value = 'Email acts as username.Dont forget
it!'}",
'onfocus' => "if (this.value == 'Email acts as username.Dont forget it!')
{this.value = ''}"
, ),
);
$form['account details']['password'] = array(
'#type' => 'password',
'#title' => t('Password'),
'#maxlength' => 60,
'#size' => 60,
'#required' => TRUE,
'#description' => t('Password should be atleast 6 characters long.'),
);
$form['home'] = array(
'#type' => 'fieldset',
'#title' => 'Home Address',
'#description' => t('Enter Personal Residential Credentials')
);
$form['home']['street'] = array(
'#type' => 'textfield',
'#title' => 'Street Address',
);
$form['home']['city'] = array(
'#type' => 'textfield',
'#title' => 'City',
);
$form['work'] = array(
'#type' => 'fieldset',
'#title' => 'Work Address',
'#description' => t('Enter Official Address')
);
$form['work']['street'] = array(
'#type' => 'textfield',
'#title' => 'Street Address',
);
$form['work']['city'] = array(
'#type' => 'textfield',
'#title' => 'City',
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Register Me'),
);
return $form;
}
function registerme_newform_validate(&$form, &$form_state)
{
if($form_state['values']['account details']['first name']=='Be sure of your first
name')
{
form_set_error('first name',t('Please enter your first name'));
}
}
function registerme_newform_submit(&$form, &$form_state)
{
dsm($form_state);
}
Also would like to know how will values be entered in database , i mean how will these custom fields be added to database? Kindly guide thanks.
First of all please check if the first name is allowed user name. I recommend you providing another field to enter username as its not uncommon that username is already used by somebody else. Then also check that there are no users registered with the given email address.
function registerme_newform_validate(&$form, &$form_state) {
if($form_state['values']['account details']['first name']=='Be sure of your first
name') {
form_set_error('first name',t('Please enter your first name'));
}
// TODO: Provide user with a chance to enter a name ( drupal user name )
// Also do the following two checks and report an error.
// check using user_load_by_name($form_state['values']['account details']['first anme'])
// check using user_load_by_mail($form_state['values']['account details']['email'])
}
Next in your submit function map the form values to an array that could be passed to user_save as shown bellow. If you want to know exactly how other fields map, use the devel module to inspect the structure by vising an already existing user profile.
function registerme_newform_submit(&$form, &$form_state){
$new_user = array(
// The below name field must be unique.
'name' => $form_state['values']['account details']['name'],
'pass' => $form_state['values']['account details']['password'],
'mail' => $form_state['values']['account details']['email'],
'init' => $form_state['values']['account details']['email'],
'field_first_name' => array(LANGUAGE_NONE => array(array('value' => $form_state['values']['account details']['first name']))),
'field_last_name' => array(LANGUAGE_NONE => array(array('value' => $form_state['values']['account details']['last name']))),
// Map all the extra fields to user objects as shown above.
...
'status' => 1,
'access' => REQUEST_TIME,
'roles' => $roles,
);
// $account returns user object
$account = user_save(null, $new_user);
//after user_save you can use the following code to send notification email.
drupal_mail('user', 'register_no_approval_required', $account->mail, NULL, array('account' => $account), variable_get('site_mail', 'noreply#mysite.com'));
}
I have implemented a different approach to this problem. I created an entity form (https://drupal.org/project/entityform)
where I prompt for key user information. I have also installed the profile2 module allowing me to create alternate profiles. When the form is submitted it triggers a rule. That rule allows me to create the user, create a linked profile and then send an email to the administrator with a link to the new user entry allowing them to review and activate.
A nice alternative if you dont want to solve via PHP or want to create additional content on creation.
For ecommerce, that expected name value pair I have the following approved code:
function create_example_purchase() {
set_credentials();
$purchase = array(
'name' => 'Digital Good Purchase Example',
'description' => 'Example Digital Good Purchase',
'amount' => '12.00', // sum of all item_amount
'items' => array(
array( // First item
'item_name' => 'First item name',
'item_description' => 'a description of the 1st item',
'item_amount' => '6.00',
'item_tax' => '0.00',
'item_quantity' => 1,
'item_number' => 'XF100',
),
array( // Second item
'item_name' => 'Second Item',
'item_description' => 'a description of the 2nd item',
'item_amount' => '3.00',
'item_tax' => '0.00',
'item_quantity' => 2,
'item_number' => 'XJ100',
),
)
);
return new Purchase( $purchase);
}
I would like to get $items Array inside associative $purchase array dynamically from shipping cart.
Is there a way to generate exactly the same output above?
My dirty solution, to write $purchase array as string inclusive the generated $items array in a file and include it
later in the called script.
Help appreciated.
$itemsArray = function_that_returns_your_2d_item_array();
$purchase['items'] = $itemsArray;
or if the function_that_returns_your_2d_item_array() returns a 2d array indexed by 'items' you could do:
$purchase = array_merge($purchase, $itemsArray);
I am trying to put together a module which will have it's own configuration page. For that purpose, I am using the following code as my menu page-callback:
function webform_customizations_customize() {
$form = array();
// Text field for the e-mail subject.
$form['webform_customizations']['user_warn_e-mail_subject'] = array(
'#type' => 'textfield',
'#title' => t('Warning e-mail subject'),
'#description' => t('The subject of the e-mail which will be sent
to users.'),
'#size' => 40,
'#maxlength' => 120,
'#required' => TRUE,
);
$options = array('A', 'B', 'C');
$form['test'] = array(
'#type' => 'radios',
'#options' => array(
'one' => t('one'),
'two' => t('two'),
),
'#title' => t('roles that should see a minimal webforms setting area'),
'#title_display' => t('testing'),
);
$form['high_school']['tests_taken'] = array(
'#type' => 'checkboxes',
'#options' => drupal_map_assoc(array(t('SAT'), t('ACT'))),
'#title' => t('What standardized tests did you take?'),
'#states' => array(
'visible' => array(// action to take.
':input[name="student_type"]' => array('value' => 'high_school'),
),
),
);
return $form;
}
My problem is my attempts to display checkboxes are failing. The first field shows a textfield successfully. But the next two are checkboxes which never show on my configuration page - and the tests_taken checkbox code is lifted directly from this drupal doc page without any amendments.
I tried a single checkbox and that works.
You should have read the comments that were along with the code you took:
// This #states rule says that this checkboxes array will be visible only
// when $form['student_type'] is set to t('High School').
// It uses the jQuery selector :input[name=student_type] to choose the
// element which triggers the behavior, and then defines the "High School"
// value as the one that triggers visibility.
Simply remove the #states element, and it should work.
Happy drupaling!