Drupal form API checkboxes hierarchy - forms

I am trying to setup a configuration page consisting of hierarchical checkboxes like the following:
-Parent#1
--option#1
--option#2
-Parent#2
--option#1
--option#2
To achieve the above layout, I am using the following code:
$form['categories']['templates']['parent1'] = array(
'#type' => 'checkboxes',
'#title' => t('Select the appropriate actions for the form based on the indicated template'),
'#options' => array("Parent#1"),
'#multiple' => TRUE,
);
$form['categories']['templates']['parent1']['actions'] = array(
'#type' => 'checkboxes',
'#options' => array("P1 - option#1", "P1 - option#2"),
'#multiple' => TRUE,
);
$form['categories']['templates']['parent2'] = array(
'#type' => 'checkboxes',
'#title' => t('Select the appropriate actions for the form based on the indicated template'),
'#options' => array("Parent#2"),
'#multiple' => TRUE,
);
$form['categories']['templates']['parent2']['actions'] = array(
'#type' => 'checkboxes',
'#options' => array("P2 - option#1", "P2 - option#2"),
'#multiple' => TRUE,
);
But the effect I am getting to not as desired. I attached an image of what the code is generating:

You can use the new Form API feature, #states to achieve this.
Note that, for ease of use, I'm wrapping the conditional checkboxes with a fieldset.
<?php
$form['categories']['templates']['parent1'] = array(
'#type' => 'checkboxes',
'#title' => t('Select the appropriate actions for the form based on the indicated template'),
'#options' => array(1 => 'Parent#1'), // Note this! You can't use 0 as a key in #options.
'#multiple' => TRUE,
);
$form['categories']['templates']['parent1']['wrapper'] = array(
'#type' => 'fieldset',
'#title' => t('Options for #option', array('#option' => 'Parent#1')),
'#states' => array(
'visible' => array(
':input[name="parent1[1]"]' => array('checked' => TRUE), // We use "parent1" and its Nth option. in above field, See #options in above checkboxes field.
),
),
);
$form['categories']['templates']['parent1']['wrapper']['actions'] = array(
'#type' => 'checkboxes',
'#options' => array("P1 - option#1", "P1 - option#2"), // This is also wrong. You must define a key => value pair for #options or somehow avoid using 0 as the key.
'#multiple' => TRUE,
);
?>
You might want to use #tree => TRUE in the fieldsets to avoid Drupal from merging same keys' values together.
Also, you won't need #multiple in checkboxes field type.
Update
Example with node types:
<?php
$node_types = node_type_get_names();
$form['categories']['templates']['parent1'] = array(
'#type' => 'checkboxes',
'#title' => t('Select the appropriate actions for the form based on the indicated template'),
'#options' => $node_types,
);
foreach ($node_types as $type => $label) {
$form['categories']['templates']['node-options'.$type] = array(
'#type' => 'checkboxes',
'#title' => t('Options for #type', array('#type' => $label)),
'#options' => array("Parent#1"),
'#multiple' => TRUE,
'#states' => array(
'visible' => array(
':input[name="parent1['.$type.']"]' => array('checked' => TRUE), // We use "parent1" and its Nth option. in above field, See #options in above checkboxes field.
),
),
);
}

Related

How to build a single 'flag' checkbox in prestashop with form helpers?

I can't figure out from official docs how to build a single checkbox element from the standard helpers. I already have the relevant boolean entity in database and I can build radios or selects as well for it, and they work.
But what I'd really like is to have a single checkbox to use as a boolean flag.
Anyone knows how?
Ok, the answer is to just use the 'switch' type: that will build a 'slider' switch on backoffice page. For future reference, I'm gonna report 3 different ways to accomplish the same task: radio, select and switch.
They have all been tested on AdminAddressesController and are bound to a custom DB boolean field called 'expo'.
//SELECT
$s_options = array(
array( 'expo' => 1, 'name' => 'Yes' ),
array( 'expo' => 0, 'name' => 'No' )
);
$temp_fields[] = array(
'type' => 'select',
'label' => $this->l('Is Expo'),
'name' => 'expo',
'required' => false,
'options' => array(
'query' => $s_options,
'id' => 'expo',
'name' => 'name'
)
);
//RADIO
$s_options = array(
array( 'id' => 'expo_on', 'value' => 1, 'label' => $this->l('Yes')),
array( 'id' => 'expo_off', 'value' => 0, 'label' => $this->l('No')),
);
$temp_fields[] = array(
'type' => 'radio',
'label' => $this->l('Is Expo'),
'name' => 'expo',
'required' => false,
'class' => 't',
'is_bool' => true,
'values' => $s_options
);
//SWITCH
$s_options = array(
array( 'id' => 'expo_on', 'value' => 1, 'label' => $this->l('Yes')),
array( 'id' => 'expo_off', 'value' => 0, 'label' => $this->l('No')),
);
$temp_fields[] = array(
'type' => 'switch',
'label' => $this->l('Is Expo'),
'name' => 'expo',
'required' => false,
'is_bool' => true,
'values' => $s_options
);

Prestashop Module : Add multi select dropdown

I'm working on a module and I would like to know how to add multiple dropdown with fields_options.
$this->fields_options = array(
'Test' => array(
'title' => $this->l('Test'),
'icon' => 'delivery',
'fields' => array(
'IXY_GALLERY_CREATION_OCCASION' => array(
'title' => $this->l('DropdownList'),
'type' => 'select',
'multiple' => true , // not working
'identifier' => 'value',
'list' => array(
1 => array('value' => 1, 'name' => $this->l('Test 1 ')),
2 => array('value' => 2, 'name' => $this->l('Test 2)'))
)
),
),
'description' =>'',
'submit' => array('title' => $this->l('Save'))
)
);
This is how I'm doin if you're meaning that :
$combo = $this->getAddFieldsValues();
$fields_form = array(
'form' => array(
'legend' => array(
'title' => $this->l('Title'),
'icon' => 'icon-cogs'
),
'input' => array(
array(
'type' => 'select',
'lang' => true,
'label' => $this->l('Nom'),
'name' => 'nom_matiere',
'options' => array(
'query' => $combo[0],
'id' => 'id_option',
'name' => 'name'
)
),
array(
'type' => 'select',
'lang' => true,
'label' => $this->l('Nom'),
'name' => 'name',
'options' => array(
'query' => $combo[1],
'id' => 'id_option',
'name' => 'name'
)
),
),
),
'submit' => array(
'title' => $this->l('Save'),
'name' => $this->l('updateData'),
)
),
);
the answer are not correctly .. due its not only dfined the field in the database, also must capture and stored in special way the values, in this example i demostrate to store as "1,2,3,6,8" using a single field
THE COMPLETE CODE AND ALL THE STEPS ARE AT: https://groups.google.com/forum/m/?hl=es#!topic/venenuxsarisari/z8vfPsvFFjk
here i put only the most important parts..
as mentioned int he previous link, added a new fiel in the model definition, class and the table sql
this method permits to stored in the db as "1,2,3" so you can use only a single field to relation that multiple selected values, a better could be using groupbox but its quite difficult, take a look to the AdminCustomers controller class in the controllers directory of the prestachop, this has a multiselect group that used a relational table event stored in single field
then in the helper form list array of inputs define a select as:
at the begining dont foget to added that line:
// aqui el truco de guardar el multiselect como una secuencia separada por comas, mejor es serializada pero bueh
$this->fields_value['id_employee[]'] = explode(',',$obj->id_employee);
this $obj are the representation of the loaded previous stored value when go to edit ... from that object, get the stored value of the field of your multiselect, stored as "1,3,4,6"
and the in the field form helper list of inputs define the select multiple as:
array(
'type' => 'select',
'label' => $this->l('Select and employee'),
'name' => 'id_employee_tech',
'required' => false,
'col' => '6',
'default_value' => (int)Tools::getValue('id_employee_tech'),
'options' => array(
'query' => Employee::getEmployees(true), // el true es que solo los que estan activos
'id' => 'id_employee',
'name' => 'firstname',
'default' => array(
'value' => '',
'label' => $this->l('ninguno')
)
)
),
an then override the post process too
public function postProcess()
{
if (Tools::isSubmit('submitTallerOrden'))
{
$_POST['id_employee'] = implode(',', Tools::getValue('id_employee'));
}
parent::postProcess();
}
this make stored in the db as "1,2,3"

How to add ErrorDescription to Zend Sub Form Element?

I have the following code that makes a sub form from a table, I have the error description saved in the database, I know how to set it for normal elements but not when it is a subform, how can I add a custom error message per subform element?
$subForm = new Zend_Form_SubForm();
foreach($configuration as $config){
$elements[] = array(
new Zend_Form_Element_Text($config->configuration_key, array(
'required' => (($config->is_required == 1) ? true : false),
'label' => $config->configuration_title,
'filters' => array('StringTrim'),
'value' => $config->configuration_value,
'Options' => array('style'=>'width:90%;'),
'Description' => $config->configuration_description,
'errorMessage' => $config->errorMessage,
))
);
}
$subForm->addElements($elements);
$this->addSubForm($subForm, 'configuration');
After playing a lot with the different options and trial/error I found out that I needed to add 'ErrorMessages' as an array, I rewrote my snippet
$elementSettings = array(
'required' => (($config->is_required == 1) ? true : false),
'label' => $config->configuration_title,
'filters' => array('StringTrim'),
'value' => $config->configuration_value,
'Options' => array('style'=>'width:90%;'),
'Description' => $config->configuration_description,
'ErrorMessages' => array($config->errorMessage)
);
$elements[] = array(new Zend_Form_Element_Text($config->configuration_key, $elementSettings));

Drupal - #states visible option not working with the date type

I am trying to create a filtering form for a Drupal module that show hours. I am trying to get a date field to only show if the user wants to filter by it. I have a text field further down in the code that is hiding. I am not sure what I should do. Here is my code for the field:
$form['filters']['start-do'] = array(
'#type' => 'checkbox',
'#title' => t('Filter by start date'),
);
$form['filters']['start'] = array(
'#type' => 'date',
'#title' => t('Start Date'),
'#description' => t('Show hours that started after this date.'),
'#states' => array(
'invisible' => array(
':input[name="start-do"]' => array('checked' => FALSE)
)
)
);
You have forgotten about "container" type form element in your example.
Try something like this:
$form['filters']['start-do'] = array(
'#type' => 'checkbox',
'#title' => t('Filter by start date'),
);
$form['filters']['container'] = array(
'#type' => 'container',
'#states' => array(
'invisible' => array(
'input[name="start-do"]' => array('checked' => FALSE)
)
)
);
$form['filters']['container']['start'] = array(
'#type' => 'date',
'#title' => t('Start Date'),
'#description' => t('Show hours that started after this date.'),
);
It's always worth to check Forms API reference: http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html/7#states

ZendFrame work - how to disable a text box

I am using zend_form in my project. In a form i want to disable a text box. Here is the code:
$personal_information = new Zend_Form(array(
'method' => 'post',
'elements' => array(
'first_name' => array('text', array(
'required' => true,
'filters' => array('StringTrim'),
'validators' => array(
array('NotEmpty', true),
array(),
array('stringLength', false, array(1, 40))
),
'decorators' => $elementDecorators,
'label' => 'First name:'
)),
// THE "NEXT" BUTTON
'signup' => array('submit', array(
'decorators' => $buttonDecorators,
'label' => 'Next',
'required' => false,
'ignore' => true,
))
)
));
How to disable a text box in zend_form?
here is an example of disabled and readonly text field
$lati = new Zend_Form_Element_Text("lati" , array("readonly" => "readonly"));
$lati = new Zend_Form_Element_Text("lati" , array("disabled" => "disabled"));
i think this way is more clear than the way you add elements to the form ,