Drupal 7 dependent dropdown not working in form alter - drupal-7

I am trying to implement the dependent dropdown option in Drupal 7 from this URL http://w3shaman.com/article/creating-ajax-dropdown-drupal-7. When changing the first dropdown value, it is showing the loading indicator but no value is fetching in dependent dropdown
.
. Here is the code I have tried so far.
This is the code of form alter module
function xyz_mod_alter(&$form, &$form_state, $form_id) {
$form['sandbox_ajax_dropdown']['province'] = array(
'#title' => t('Province'),
'#type' => 'select',
'#options' => _load_province(),
'#ajax' => array(
'event'=>'change',
'callback' =>'sandbox_ajax_dropdown_city',
'wrapper' => 'city-wrapper',
),
);
// Wrapper for city dropdown list
$form['sandbox_ajax_dropdown']['wrapper'] = array(
'#prefix' => '<div id="city-wrapper">',
'#suffix' => '</div>',
);
// Options for city dropdown list
$options = array('- Select city -');
if (isset($form_state['values']['province'])) {
// Pre-populate options for city dropdown list if province id is set
$options = _load_city($form_state['values']['province']);
}
// Province dropdown list
$form['sandbox_ajax_dropdown']['wrapper']['city'] = array(
'#title' => t('City'),
'#type' => 'select',
'#options' => $options,
);
}
Code for loading the default value of province and fetching city data function
function sandbox_ajax_dropdown_city($form, $form_state) {
// Return the dropdown list including the wrapper
return $form['sandbox_ajax_dropdown']['wrapper'];
}
function _load_province() {
$province = array('- Select province -');
$query = db_query("select tdd.tid as term_id, tdd.name as name
from taxonomy_term_data td
join taxonomy_vocabulary v on v.vid=td.vid
join taxonomy_term_hierarchy th on td.tid=th.parent
join taxonomy_term_data tdd on th.tid=tdd.tid
where td.tid='702269'
and v.name ='xx' and tdd.weight!=-1 ");
foreach($query as $result){
$province[$result->term_id] = $result->name;
}
return $province;
}
function _load_city($province_id) {
$city = array('--- Select city ---');
$query = db_query("select tdd.tid as term_id, tdd.name as name
from taxonomy_term_data td
join taxonomy_vocabulary v on v.vid=td.vid
join taxonomy_term_hierarchy th on td.tid=th.parent
join taxonomy_term_data tdd on th.tid=tdd.tid
where td.tid=".$province_id."
and v.name ='xx' and tdd.weight!=-1 ");
foreach($query as $result){
$city[$result->term_id] = $result->name;
}
return $city;
}
I am not sure about the mistake I am doing. I copied the exact code from the given link. Even I tried to change as per my need but it is not working.

Related

Autofill fields in drupal7

I'm trying to autofill text fields after selecting an item from select list. What I mean is: first I want user to choose an item from select list and then there will be 3 more text fields and I want to give them distinct values based on which was selected.
You need to use Drupal "Ajax framework". Please prepare your fields in hook_form_alter function.
function hook_form_alter(&$form, &$form_state, $form_id) {
if (isset($form['type']) && $form['type']['#value'] . '_node_settings' == $form_id) {
$form['select_field'] = array(
'#ajax' => array(
'callback' => '_mymodule_ajax_example_simplest_callback',
'wrapper' => 'replace_textfield_div',
),
);
// This entire form element will be replaced with an updated value.
$form['textfield_to_autofill'] = array(
'#prefix' => '<div id="replace_textfield_div">',
'#suffix' => '</div>',
);
}
}
function _mymodule_ajax_example_simplest_callback(&$form, $form_state) {
// The form has already been submitted and updated. We can return the replaced
// item as it is.
$commands = array();
if($form_state['values']['select_field'][LANGUAGE_NONE][0]['value'] == "some_value"){
$form['textfield_to_autofill'][LANGUAGE_NONE][0]['value']['#value'] = "some_value";
$commands[] = ajax_command_replace("#replace_textfield_div", render($form['textfield_to_autofill']));
}
$page = array('#type' => 'ajax', '#commands' => $commands);
ajax_deliver($page);
}
Here helping link for ajax framework.

Updating and deleting data in D7

I have made a form in D7 using form API, registered some users and retrieved their registered data from database;now what i want is to add an edit and a delete link in front of every row in the retrieved table;i have done that in PHP but how to implement same in Drupal?;anybody having any idea how to do that?
My retrieval code is:
function form_data_menu() {
$items['formdata'] = array(
'title' => 'Form Data',
'page callback' => 'form_data_form',
'access callback' => TRUE,
);
return $items;
}
function form_data_form()
{
$results = db_query('SELECT * FROM {drupal}');
$header = array(t('Id'),t('Name'),t('College'),t('Education'),t('Percentage'),t('Application'));
$rows = array();
foreach($results as $result) {
$rows[] = array(
$result->id,
$result->name,
$result->college,
$result->education,
$result->percentage,
$result->application,
);
}
return theme('table',array('header'=>$header,'rows'=>$rows));
}
I can add links though but the main problem is how to run update and delete queries in D7?
Any help will be appreciated. Thank you!
Start with the example module "dbtng_example.module".
https://www.drupal.org/project/examples
This will give an example of how to set up a module to save to the database. I used this recently to create a custom module to save data to a new database table within drupal. To figure out how to set up the hook_schema, you can look at ".install" files within the drupal core and contributed codebase.
Then to create an edit or delete link, you need to alter your hook_menu to pass in the unique id for that element:
$items['admin/structure/nates-custom-page/update/%'] = array(
'title' => 'Update entry',
'page callback' => 'drupal_get_form',
'page arguments' => array('nates_module_form_update', 5),
'weight' => -5,
'access arguments' => array('administer DFP'),
);
$items['admin/structure/nates-custom-page/delete/%'] = array(
'title' => 'Delete entry',
'page callback' => 'drupal_get_form',
'page arguments' => array('nates_module_form_delete', 5),
'access arguments' => array('administer DFP'),
);
Above is an example where I added the argument (indicated by the percentage sign in the array key, ("%"), that will represent the unique id for that item I want to edit or delete.
Then alter the edit form to load the item you want to edit by the id.
And add a delete form.
Here's an example of a delete form:
function nates_module_form_delete($form, &$form_state) {
$entry = nates_module_entry_load_by_pid(arg(5));
$form = array();
$form['pid'] = array(
'#type' => 'value',
'#value' => arg(5),
);
$output = "";
foreach($entry as $key => $value) {
$output .= "<p><strong>$key</strong>: $value</p>";
}
$form['markup'] = array(
'#type' => 'markup',
'#markup' => $output,
);
return confirm_form(
$form,
t('Are you sure you want to delete this item? '),
'example/list',
t('This action cannot be undone.'),
t('Delete'),
t('Cancel')
);
return $form;
}
Notice I return a confirmation form first.
And here's the submit handler function that processes it after they submit the request:
function nates_module_form_delete_submit($form, &$form_state) {
global $user;
nates_module_entry_delete($form_state['values']['pid']);
drupal_set_message(t("Deleted entry"));
}
Then, edit your listing page to add the edit links and delete links:
function nates_module_list() {
$output = '';
// Get all entries in the dfp_amobee2 table.
if ($entries = nates_module_entry_load_all()) {
$rows = array();
foreach ($entries as $entry) {
// Sanitize the data before handing it off to the theme layer.
$entry->editlink = l('edit','admin/structure/nates-custom-page/update/' . $entry->pid, array('query' => array('destination' => 'admin/structure/nates-custom-page')));
$entry->deletelink = l('delete','admin/structure/nates-custom-page/delete/' . $entry->pid, array('query' => array('destination' => 'admin/structure/nates-custom-page')));
unset($entry->pid);
if(!empty($entry->tid)) {
$entry->alias = l($entry->alias, 'taxonomy/term/'.$entry->tid);
}
else if(isset($entry->pages)) {
if(drupal_valid_path($entry->pages)) {
$entry->alias = l(drupal_lookup_path('alias', $entry->pages),$entry->pages);
} else {
$entry->alias = check_markup($entry->pages);
}
} else {
$entry->alias = "";
}
unset($entry->pages);
if(!$entry->tid) {
$entry->tid = "";
}
$rows[] = (array) $entry;
}
// Make a table for them.
$header = array(t('path'), t('tid'), t('dfp tag machine_name'),t('amobee_as'), '', '');
$output .= '<p>' . t('If the "tid" is filled in, amobee_as will be used on taxonomy pages and on node pages (where the main term id matches). If the path is filled it, will be used on that path. Path supercedes "tid" when there is a conflict.') . '</p>';
$output .= theme('table', array('header' => $header, 'rows' => $rows));
}
else {
drupal_set_message(t('No entries have been added yet.'));
}
return $output;
}

Custom Field with autcomplete

I am trying to build my own node reference custom field - I know several projects out there already do this, I am building this in order to learn... :)
My problem is the autocomplete path, it's not being triggered, I have checked the noderefcreate project and implemented my solution based on that project. But still; nothing is being triggered when I check firebug.
Here is my code:
function nodereference_field_widget_info() {
return array(
'nodereference_nodereference_form' => array(
'label' => t('Node Reference Form'),
'field types' => array('nodereference'),
'behaviors' => array(
'multiple values' => FIELD_BEHAVIOR_DEFAULT,
'default value' => FIELD_BEHAVIOR_DEFAULT,
),
'settings' => array(
'autocomplete_match' => 'contains',
'autocomplete_path' => 'nodereference/autocomplete',
),
),
);
}
function nodereference_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
if ($instance['widget']['type'] == 'nodereference_nodereference_form') {
$widget = $instance['widget'];
$settings = $widget['settings'];
$element += array(
'#type' => 'textfield',
'#default_value' => isset($items[$delta]['nid']) ? $items[$delta]['nid'] : NULL,
'#autocomplete_path' => $instance['widget']['settings']['autocomplete_path'],
);
}
return array('nid' => $element);
}
You need to define method from where auto compete will take suggestions.
It can be done like this:
/**
* implements hook_menu
*/
function your_module_name_menu() {
$items['master_place/autocomplete'] = array(
'page callback' => '_your_module_name_autocomplete',
'access arguments' => array('access example autocomplete'),
'type' => MENU_CALLBACK
);
return $items;
}
/**
* Auto complete method implementation
* #param $string
*/
function _your_module_name_autocomplete($string) {
$matches = array();
// Some fantasy DB table which holds cities
$query = db_select('target_db_table', 'c');
// Select rows that match the string
$return = $query
->fields('c', array('target_column'))
->condition('c.target_column', '%' . db_like($string) . '%', 'LIKE')
->range(0, 10)
->execute();
// add matches to $matches
foreach ($return as $row) {
$matches[$row->city] = check_plain($row->city);
}
// return for JS
drupal_json_output($matches);
}

Second taxonomy autocomplet depend on first taxonomy autocomplet

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();
}
}

Matching data from a drop down menu in add.cpt to view.ctp

Title seems a bit odd as I am trying to find way's to explain my dilema in layman's terms.
What I am trying to achieve is is from what I can gather, fairly simple but.. I just can't seem to place my finger on it.
I have a drop down selection menu which users can select a country of residence which resides in a helper - example below:
class CountryListHelper extends FormHelper {
var $helpers = array('Form');
function select($fieldname) {
$list = $this->Form->input($fieldname , array(
'type' => 'select', 'label' => 'Country of Residence', 'options' => array(
'' => 'Please select a country',
'AF' => 'Afganistan',
'AL' => 'Albania',
'DZ' => 'Algeria',
.................
),
'error' => 'Please select a country'));
return $this->output($list);
}
}
in the add.ctp:
<?php echo $this->CountryList->select('country');?>
Pretty simple stuff - on save it writes the acronym to the country field.
My issue is.. When pulling the data to view.ctp, how would I go about displaying the full country name as apposed to the acronym saved in the database without having to write the entire list down in view.ctp and matching the acronym to Country name there..
<dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Country of Residence'); ?></dt>
<dd<?php if ($i++ % 2 == 0) echo $class;?>>
<?php echo $user['User']['country']; ?>
</dd>
Any and all help is very much appreciated!
Add a new function to the helper that returns the full name of the country.
class CountryListHelper extends FormHelper {
var $helpers = array('Form');
var $countryList = array(
'AF' => 'Afganistan',
'AL' => 'Albania',
'DZ' => 'Algeria',
.................
);
function select($fieldname) {
$list = $this->Form->input($fieldname , array(
'type' => 'select', 'label' => 'Country of Residence',
'options' => $this->countryList,
'empty' => 'Please select a country',
'error' => 'Please select a country'));
return $this->output($list);
}
function fullName( $abbr ) {
return $this->countryList[ $abbr ];
// + error checking
}
}

Resources