Drupal 7 - Submit function not triggered on theme table - drupal

I want to be able to select items from two select lists and then submit (which will take me to another form.
The following is the code I have however the submit function (submit_function) does not appear to get triggered (it just refreshes the form). What am I doing wrong?
function myfunction($form, &$form_state)
{
$output = drupal_render($element['form_id']);
$output .= drupal_render($element['form_build_id']);
$output .= drupal_render($element['form_token']);
$header = array(
'columnone' => t('Column 1'),
'columntwo' => t('Column 2'),
'columnthree' => t('Column 3'),
);
$rows = array(
array(
'columnone' => array(
'data' => array(
'#type' => 'select',
'#options' => columnoneoptions(),
),
),
'columntwo' => array(
'data' => array(
'#type' => 'select',
'#options' => columntwooptions(),
),
),
'columnthree' =>array(
'data' => array(
'#type' => 'submit',
'#value' => t('Add'),
'#weight' => 45,
'#submit' => array('submit_function'),
)
),
),
);
$output['table'] = array(
'#theme' => 'table',
'#header' => $header,
'#rows' => $rows,
'#weight' => 2,
);
return $output;
}

That is quite normal, you are mixing form elements with static renderable elements. A drupal_get_form function expects a form build.
What you need to create is your custom form theme table which outputs a theme within a form build. Here is some sample code that could help you further:
function YOURMODULE_theme()
{
// define a table form theme
return array(
'YOURMODULE_table_form' => array(
'render element' => 'element'
),
);
}
function theme_YOURMODULE_table_form($vars)
{
$element = $vars['element'];
$form_keys = false;
$rows = array();
// loop through each row form elements
foreach (element_children($element) as $key) {
if (!$form_keys) {
$form_keys = array();
// retrieve the form keys for each row
foreach (element_children($element[$key]) as $f_key) {
$form_keys[$f_key] = isset($element[$key][$f_key]['#title'])
? $element[$key][$f_key]['#title']
: '';
}
}
$row = array();
foreach ($form_keys as $fieldkey => $fieldname) {
// render each field in a separate row
$row[] = array(
'data' => drupal_render($element[$key][$fieldkey])
);
}
$rows[] = $row;
}
// return a build for the table
return theme('table', array(
'header' => $vars['element']['#header'],
'rows' => $rows,
'empty' => isset($vars['element']['#empty'])
? $vars['element']['#header']
: '',
));
}
And the form using your logic:
function myfunction($form, &$form_state)
{
$form['table'] = array(
'#theme' => 'YOURMODULE_table_form',
'#header' => array(
'columnone' => t('Column 1'),
'columntwo' => t('Column 2'),
'columnthree' => t('Column 3'),
),
'#tree' => true,
);
$form['table'][0] = array(
'columnone' => array(
'#type' => 'select',
'#options' => columnoneoptions(),
),
'columntwo' => array(
'#type' => 'select',
'#options' => columntwooptions(),
),
'columnthree' => array(
'#type' => 'submit',
'#value' => t('Add'),
'#weight' => 45,
'#submit' => array('submit_function'),
),
);
return $form;
}

Related

Add checkboxes in fieldset

i have this fieldset and these checkboxes inside...
function repository_search_filter_form($form, &$form_state){
$form['global_fieldset_container']['global_fieldset_by_metadata'] = array (
'#type' => 'fieldset',
'#title' => t('By Metadata'),
'#collapsible' => '1',
'#weight' => '99',
'#tree' => true,
'#collapsed' => 'true',
);
$form['global_fieldset_container']['global_fieldset_by_case_study'] = array (
'#type' => 'fieldset',
'#title' => t('By case study'),
'#collapsible' => '1',
'#weight' => '99',
'#tree' => true,
'#collapsed' => 'true',
);
$by_casestudy_options = array(
'1' =>'option1',
'2' => 'option2',
);
}
$form['global_fieldset_container']['global_fieldset_by_case_study']['bycasestudy'] = array(
'#type' => 'checkboxes',
'#options' => $by_casestudy_options
);
return $form;
}
i want in fieldset "global_fieldset_by_metadata" to add some dynamic checkboxes but in a callback function....
function ajaxforms_basic_callback($form, $form_state) {
$commands = array();
$form_filter = drupal_get_form('repository_search_filter_form');
$by_metadata_options = array(
'1' => 'Metadata1',
'2' => 'Metadata2',
);
$form_filter['global_fieldset_container']['global_fieldset_by_metadata']['bymetadata'] = array(
'#type' => 'checkbox',
'#options' => $by_metadata_options,
);
$form_filter = drupal_render($form_filter);
$commands[] = ajax_command_replace(".filter", $form_filter);
}
But the results are a empty checkbox...
PS. I tried and "checkboxes" in "#type" but i havent results in fieldset.

Drupal Form autocomplete

I wanted to have a textfield in a form that autocompletes from the database. I have been reading the tutorials and trying to get it to work but thus far not much luck. I am farely new to Drupal so I'm mostly unsure what I am doing xD
My code thus far:
function my_module_menu() {
$items = array();
$items['my_module/form'] = array(
'title' => t('Add List'),
'page callback' => 'my_module_form',
'access arguments' => array('access content'),
'description' => t('My form'),
'type' => MENU_CALLBACK,
);
// path with autocomplete function for casters
$items['caster/autocomplete'] = array(
'title' => t('Autocomplete for casters'),
'page callback' => '_caster_autocomplete',
'access arguments' => array('use autocomplete'),
'type' => MENU_CALLBACK
);
return $items;
}
function my_module_form() {
return drupal_get_form('my_module_my_form');
}
function _caster_autocomplete($string) {
$matches = array();
$results = db_select('warnoun', 'w')
->fields('w', array('full_name'))
->condition('full_name', '%' . db_like($string) . '%', 'LIKE')
->execute();
// save the query to matches
foreach ($results as $result) {
$matches[$result->full_name] = check_plain($result->full_name);
}
// Return the result to the form in json
drupal_json_output($matches);
}
function my_module_my_form($form_state) {
$form['points'] = array(
'#type' => 'select',
'#title' => t('Points'),
'#required' => TRUE, // Added
'#options' => array(
0 => t('15'),
1 => t('25'),
2 => t('35'),
3 => t('50'),
),
);
$form['caster'] = array(
'#type' => 'textfield',
'#title' => t('Caster'),
'#maxlength' => 50,
'#autocomplete_path' => 'caster/autocomplete',
'#required' => TRUE,
);
$entries = db_query('SELECT id, short_name FROM factions ORDER BY id ASC');
$options = array();
foreach ($entries as $entry){
$options[$entry->id] = t($entry->short_name);
}
$form['faction'] = array(
'#type' => 'select',
'#title' => t('Faction'),
'#options' => $options,
);
// Simple Submit Button
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Submit',
'#required' => TRUE, // Added
);
return $form;
}
So basically there is a table called warnoun with a column full_name and it's with that content that I want to autocomplete the textfield caster.
Any idea what I'm missing/doing wrong?
Cheers

My Node Type wont Show It's Fields

I am trying to create my first drupal module that creates a simple node type wcNames. This node type has two fields, firstname & lastname.
I could get my module create the DB table for node type and add it in node_type table, but when I open node/add/wc-name fields firstname and lastname don't appear.
Below is my code. Please suggest.
<?php
// wc_name.install file
/*
* hook_schema Implementation: Creates the DB and it's fields
*/
function wc_name_schema(){
$schema['wc_name_names'] = array(
'fields' => array(
'nmid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
'firstname' => array('type' => 'varchar', 'length' => 50, 'not null' => FALSE),
'lastname' => array('type' => 'varchar', 'length' => 50, 'not null' => FALSE),
),
'primary key' => array('nmid'),
'unique keys' => array(),
'indexes' => array(
'nmid' => array('nmid'),
),
);
return $schema;
}
//function wc_name_install(){ } // Use this function to set variables for the module.
function wc_name_uninstall(){
//unset variables if any set
// Delete all wc_name nodes
db_delete('node')->condition('type', 'wc_name')->execute();
// Delete all wc_name tables
db_drop_table('wc_name_names');
}
?>
<?php
// wc_name.module
/*
* Implementation of _node_info(): define node
*/
function wc_name_node_info(){
return array(
'wc_name' => array(
'name' => t('wcName'),
'base' => 'wc_name',
'base' => 'page',
'description' => t("A smaple module to save names."),
'has_title' => TRUE,
'title_label' => t('Title'),
'has_body' => FALSE,
)
);
}
function wc_name_menu() {
$items = array();
$items['wc_name'] = array(
'title' => 'wcNames',
'page callback' => 'wc_name',
// 'access arguments' => array('access wcNames'),
);
}
?>
<?php
// wc_name_form.inc
function wc_name_form($node, &$form_state){
// Add fields
$form['first_name'] = array(
'#type' => 'textfield',
'#title' => t('First name'),
'#required' => FALSE,
'#default_value' => $node->wc_name['firstname'],
);
$form['last_name'] = array(
'#type' => 'textfield',
'#title' => t('Last name'),
'#required' => FALSE,
'#default_value' => $node->wc_name['lastname'],
);
return $form;
}
?>
What am I missing?
Try this:
function createTextFieldByName($type, $fieldname, $fieldlabel)
{
$field = field_info_field($fieldname);
if (empty($field)) {
$field = array(
'field_name' => $fieldname,
'type' => 'text',
'entity_types' => array('node'),
'translatable' => TRUE,
);
$field = field_create_field($field);
}
$instance = field_info_instance('node', $fieldname, $type);
if (empty($instance)) {
$instance = array(
'field_name' => $fieldname,
'entity_type' => 'node',
'bundle' => $type,
'label' => $fieldlabel,
);
$instance = field_create_instance($instance);
return $instance;
}
return null;
}
$type =
array(
'type' => 'MY_TYPE',
'name' => t('NAME'),
'base' => 'node_content',
'description' => t("DESCRIPTION"),
'custom' => 1,
'modified' => 1,
'locked' => 0,
);
$type = node_type_set_defaults($type);
node_type_save($type);
createTextFieldByName($type,'firstname','First name');
createTextFieldByName($type,'lastname','Last name');

Drupal 6 create CRUD grid in settings form

I'm quite new to Drupal and I want to create a custom grid that has some editable columns, some other columns witch checkboxes etc.
I'm using the theme() function to create the table and render it at the settings. Since I cannot find any way to access the form/settings variables, inside the theme function, I create a custom table at the drupal database that will contain the gid values, and I render those rows. For testing purposes I fetch the 'variables' table rows. Here is the code so far:
$form['module_settings']['profile_grid'] = array(
'#type' => 'item',
'#title' => t('Profile Mapping'),
'#theme' => 'profile_mapping_grid'
);
function theme_profile_mapping_grid($sender) {
$header = array('', t('name'), t('value'));
$result = db_query('SELECT v.name, v.value from {variable} v');
while ($pair = db_fetch_object($result)) {
$format = array(
'#type' => 'textfield',
'#size' => 30,
'#value' => $pair->name
);
$hhfield = array(
'#type' => 'textfield',
'#size' => 30,
'#value' => $pair->value
);
$row = array('');
$row[] = drupal_render($format);
$row[] = drupal_render($hhfield);
$rows[] = array('data' => $row);
}
$output = theme('table', $header, $rows, array('id' => 'gridErrors'));
return $output;
}
The grid is generated correctly, but I have an issue. I cannot set the 'name' attribute to the textfield, in order to collect it's value later on, on a submit action.
Furthermore, I'm not sure if this is the best way to create a settings grid.
Any ideas, opinions etc are more than welcome.
According to Drupal 6 Form API Quickstart Guide:
Don't use the '#value' attribute for any form element that can be changed by the user. Use the '#default_value' attribute instead. Don't put values from $form_state['values'] (or $_POST) here! FormsAPI will deal with that for you; only put the original value of the field here.
You have to use '#default_value' => $pair->name not '#value' => $pair->value.
Here is the sample module with settings table.
install file:
<?php
// $Id$
/**
* #file
* The your_module module install file, which handles the install/uninstall tasks.
*
*/
function your_module_install() {
// Create tables.
drupal_install_schema('your_module');
}
/**
* Implementation of hook_schema().
*/
function your_module_schema() {
/* Settings table */
$schema['your_module_settings'] = array(
'description' => 'Stores module settings.',
'fields' => array(
'record_id' => array(
'description' => 'The primary identifier for a record.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE),
'item_code' => array(
'type' => 'varchar',
'length' => '255',
'not null' => TRUE),
'setting_one' => array(
'type' => 'varchar',
'length' => '255',
'not null' => TRUE),
'setting_two' => array(
'type' => 'varchar',
'length' => '255')),
'unique keys' => array(
'record_id' => array('record_id')),
'primary key' => array('record_id')
);
return $schema;
}
/**
* Implementation of hook_uninstall().
*/
function your_module_uninstall() {
// Remove tables.
drupal_uninstall_schema('your_module');
}
module file:
<?php
/**
* Implementation of hook_help()
*/
function your_module_help($path, $arg)
{
switch ($path)
{
case 'admin/help#your_module':
return '<p>'. t('Module description.') .'</p>';
}
}
/**
* Implementation of hook_menu()
*/
function your_module_menu()
{
$items = array();
/* module settings page */
$items['admin/settings/your_module'] = array(
'description' => 'Administer your_module module settings.',
'title' => 'Some title',
'page callback' => 'drupal_get_form',
'page arguments' => array('your_module_admin_settings'),
'access arguments' => array('access administration pages'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
/**
* Implementation of hook_theme().
*/
function your_module_theme() {
return array(
'your_module_products_settings' => array(
'arguments' => array('form' => NULL),
),
);
}
/**
* Settings form
*/
function your_module_admin_settings(&$form_state)
{
$form['your_module'] = array(
'#type' => 'fieldset',
'#title' => t('Settings'),
'#description' => t('Settings description.'),
);
$form['your_module']['products_settings_table'] = array(
'#theme' => 'your_module_products_settings',
'#tree' => TRUE,
);
$form['your_module']['products_settings_table']['products_settings'] = array();
$result = db_query('SELECT record_id, item_code, setting_one, setting_two FROM {your_module_settings} ORDER BY item_code');
while ($product_setting = db_fetch_object($result)) {
$form['your_module']['products_settings_table']['products_settings'][$product_setting->record_id] = array();
$form['your_module']['products_settings_table']['products_settings'][$product_setting->record_id]['item_code'] = array(
'#type' => 'textfield',
'#default_value' => $product_setting->item_code,
'#size' => 8,
'#maxlength' => 16,
);
$form['your_module']['products_settings_table']['products_settings'][$product_setting->record_id]['setting_one'] = array(
'#type' => 'textfield',
'#default_value' => $product_setting->setting_one,
'#size' => 16,
'#maxlength' => 16,
);
$form['your_module']['products_settings_table']['products_settings'][$product_setting->record_id]['setting_two'] = array(
'#type' => 'textfield',
'#default_value' => $product_setting->setting_two,
'#size' => 40,
'#maxlength' => 255,
);
}
/* "add new row" fields */
$form['your_module']['products_settings_table']['products_settings_new'] = array();
/* new item_code */
$form['your_module']['products_settings_table']['products_settings_new']['item_code'] = array(
'#type' => 'textfield',
'#size' => 8,
'#maxlength' => 16,
'#description' => t('description'),
);
/* new setting_one */
$form['your_module']['products_settings_table']['products_settings_new']['setting_one'] = array(
'#type' => 'textfield',
'#size' => 16,
'#maxlength' => 16,
'#description' => t('description'),
);
/* setting_two */
$form['your_module']['products_settings_table']['products_settings_new']['setting_two'] = array(
'#type' => 'textfield',
'#size' => 40,
'#maxlength' => 255,
'#description' => t('description'),
);
/* Submit button */
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save Settings'),
'#name' => 'SubmitButton',
);
return $form;
}
/**
* Custom theme function for a table of products settings
*/
function theme_your_module_products_settings($form) {
$header = array(t('Item Code'), t('Setting One'), t('Setting Two'));
$rows = array();
/* saved rows */
foreach (element_children($form['products_settings']) as $key) {
$row = array();
$row[] = drupal_render($form['products_settings'][$key]['item_code']);
$row[] = drupal_render($form['products_settings'][$key]['setting_one']);
$row[] = drupal_render($form['products_settings'][$key]['setting_two']);
$rows[] = $row;
}
/* new row to add */
$row = array();
$row[] = drupal_render($form['products_settings_new']['item_code']);
$row[] = drupal_render($form['products_settings_new']['setting_one']);
$row[] = drupal_render($form['products_settings_new']['setting_two']);
$rows[] = $row;
$output = theme('table', $header, $rows);
return $output;
}
/**
* Submission function for your_module_admin_settings form.
*/
function your_module_admin_settings_submit($form, &$form_state) {
/* processing changes */
if (isset($form_state['values']['products_settings_table']['products_settings'])) {
foreach ($form_state['values']['products_settings_table']['products_settings'] as $record_id => $data) {
if (empty($data['item_code']) && empty($data['setting_one']) && empty($data['setting_two'])) {
/* delete saved row if all fields are empty */
db_query("DELETE FROM {your_module_settings} WHERE record_id=%d", $record_id);
drupal_set_message(t('Deleted.'), 'status');
}
else {
/* update */
db_query("UPDATE {your_module_settings} SET item_code='%s', setting_one='%s', setting_two='%s' WHERE record_id=%d",
$data['item_code'], $data['setting_one'], $data['setting_two'], $record_id);
}
}
}
/* adding new row */
$item_code = $form_state['values']['products_settings_table']['products_settings_new']['item_code'];
$setting_one = $form_state['values']['products_settings_table']['products_settings_new']['setting_one'];
$setting_two = $form_state['values']['products_settings_table']['products_settings_new']['setting_two'];
if (!empty($item_code) && !empty($setting_one) && !empty($setting_two)) {
db_query("INSERT INTO {your_module_settings} (item_code, setting_one, setting_two) VALUES ('%s', '%s', '%s')",
$item_code, $setting_one, $setting_two);
drupal_set_message(t('Added new setting.'), 'status');
}
drupal_set_message(t('Settings updated.'), 'status');
}
You're generating the fields in the theme function and it will not work because the submit function will only act on the fields generated by your form function.
The correct way is to generate all fields in the form function (basically what you're doing now in the theme function) and render them in the theme using drupal_render.
Since I cannot find any way to access the form/settings variables, inside the theme function
The form is passed to the theme function as an argument, in your case $sender, and that's how you access them.
Here's some code, untested, but you get the idea. Remember that the call $output .= drupal_render($form); is very important because it renders the hidden fields needed by the Form API such as the form_id and the CSRF protection. Without this call submit won't work.
function mymodule_grid_form($form_state) {
$form = array();
$form['variables'] = array();
$result = db_query('SELECT v.name, v.value from {variable} v');
while ($pair = db_fetch_object($result)) {
$form['variables'][$pair->name][$pair->name . '_name'] = array(
'#type' => 'textfield',
'#size' => 30,
'#value' => $pair->name
);
$form['variables'][$pair->name][$pair->name . '_value'] = array(
'#type' => 'textfield',
'#size' => 30,
'#value' => $pair->value
);
}
return $form;
}
function theme_mymodule_grid_form($form) {
$header = array('', t('name'), t('value'));
foreach ($form['variables'] as $variable => $values) {
$row = array('');
$row[] = drupal_render($values[$variable . '_name']);
$row[] = drupal_render($values[$variable . '_value']);
$rows[] = array('data' => $row);
}
$output = theme('table', $header, $rows, array('id' => 'gridErrors'));
$output .= drupal_render($form);
return $output;
}
function mymodule_theme() {
return array(
'mymodule_grid_form' => array(
'arguments' => array('form' => NULL),
),
);
}

how to load database content to dropdown options (select)

i'm still working on my own drupal 7 module, and i'm having some trouble. I'm trying to load database content to dropdown option (select), i have read and write the same code from drupal example, but my database still not loading, only empty option.
what i'm asking is there anything wrong on my code or is there any faster way to load database to dropdown option other than the drupal example???
here the code i'm working on
function prod_entry_load($entry = array()) {
$select = db_select('aa_1122','aa');
$select->fields('aa');
foreach ($entry as $field => $value) {
$select->condition($field, $value);
}
return $select->execute()->fetchAll();
}
function prod(){
return drupal_get_form('prod_form');
}
function prod_form($form_state){
$form = array(
'#prefix' => '<div id="updateform">',
'#suffix' => '</div>',
);
$entries = prod_entry_load();
$keyed_entries = array();
if (empty($entries)) {
$form['no_values'] = array(
'#value' => t("No entries exist in the table dbtng_example table."),
);
return $form;
}
foreach ($entries as $entry) {
$options[$entry->no] = t("#no: #name ", array('#no' => $entry->no, '#name' => $entry->name));
$keyed_entries[$entry->no] = $entry;
}
$default_entry = !empty($form_state['values']['no']) ? $keyed_entries[$form_state['values']['no']] : $entries[0];
$form_state['entries'] = $keyed_entries;
$form['no'] = array(
'#type' => 'select',
'#title' => t('Choose'),
'#default_value' => $default_entry->no,
'#ajax' => array(
'wrapper' => 'updateform',
'callback' => 'prod_form_update_callback',
),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Submit',
'#ajax' => array(
'callback' => 'ajax_alert',
),
);
return $form;
}
function prod_form_update_callback($form, $form_state) {
$entry = $form_state['entries'][$form_state['values']['no']];
foreach (array('name') as $item) {
$form[$item]['#value'] = $entry->$item;
}
return $form;
}
You've just forgotten to add the #options key to your select element, the code should read like this:
$form['no'] = array(
'#type' => 'select',
'#title' => t('Choose'),
'#default_value' => $default_entry->no,
'#options' => $options, // This is the bit that was missing
'#ajax' => array(
'wrapper' => 'updateform',
'callback' => 'prod_form_update_callback',
),
);
You could shorten your query/options code slightly using a combination of string concatenation in MySQL and the db fetchAllKeyed() method:
$query = db_select('aa_1122', 'aa')->fields('aa', array('no'));
$query->addExpression("CONCAT(no, ': ', name)", 'display');
$options = $query->execute()->fetchAllKeyed();

Resources