I'm working on a language choice form:
$currentLocale = "en_US"; // This is indeed sent to the formType
$langs = array(
'fr_FR' => 'fr',
'en_US' => 'en'
);
$builder->add('language', 'language', array(
'choices' => $langs,
'expanded' => true,
'multiple' => false,
'required' => false,
'label' => false,
));
The HTML code looks like this (simplified):
<div id="languageForm_language">
<input type="radio" value="fr_FR">
<input type="radio" value="en_US">
</div>
How could I get the second item pre-selected, according to the $currentLocale value ?
In your $langs array you can specify key value pairs like this:
array(
0 => 'value1',
1 => 'value2'
)
Now, e.g. you want to preselect value2, you can set the data attribute to the key from value2:
$builder->add('language', 'choice', array(
'choices' => $langs,
'expanded' => true,
'multiple' => false,
'required' => false,
'label' => false,
'data' => 1
));
According to this, you can set your data attribute to your $currentLocale variable to preselect it. Your code should look like this:
$currentLocale = "en_US"; // This is indeed sent to the formType
$langs = array(
'fr_FR' => 'fr',
'en_US' => 'en'
);
$builder->add('language', 'choice', array(
'choices' => $langs,
'expanded' => true,
'multiple' => false,
'required' => false,
'label' => false,
'data' => $currentLocale
));
Note: the second parameter from the add() method should be choice not language.
If the form is used with a model object, just set the language on the object itself before passing it to the form:
$object->setLanguage($currentLocale);
$form = $this->createForm('some_form_type', $object);
Otherwise, set the data option to the default language key:
$builder->add('language', 'language', array(
'choices' => $langs,
'data' => $currentLocale,
// ...
));
Related
I have created a form on a Symfony CRM using the buildForm() function in a form type file. This form includes a choice drop down consisting of simple "yes" and "no" options which map to 1 and 0 respectively. I need to be able to have "no" as the default as my client more often will select this option over the "yes". After reading the documentation here I figured that the preferred_choices option would suit my needs.
Here is my entry in the buildForm() :
$builder->add('non_rider', ChoiceType::class,
array(
'label' => 'Is Non-Rider',
'required' => true,
'placeholder' => false,
'choices' => array(
'Yes' => 1,
'No' => 0
),
'preferred_choices' => array(0,1),
'label_attr' => array(
'class' => 'control-label'
),
'attr' => array(
'class' => 'form-control required'
)
));
However, this brings out the order as "Yes" then "No" with "Yes" as the default selected option. I was wondering if it reads 0 as null, which means it doesn't register? Is there any way to make "No" the auto-selected option on form load?
You can use the "data" option as mentioned here symfony.com/doc/current/reference/forms/types/choice.html, and show in action here http://stackoverflow.com/a/35772605/2476843
$builder->add('non_rider', ChoiceType::class,
array(
'label' => 'Is Non-Rider',
'required' => true,
'placeholder' => false,
'choices' => array(
'Yes' => 1,
'No' => 0
),
'data' => 0,
'preferred_choices' => array(0,1),
'label_attr' => array(
'class' => 'control-label'
),
'attr' => array(
'class' => 'form-control required'
)
));
Whenever I submit the form I get this message:
The input was not found in the haystack.
This is for the shipping-method element (radio button). Can't figure out what it means, the POST data for that element is not null.
public function getInputFilter()
{
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
// Some other basic filters
$inputFilter->add(array(
'name' => 'shipping-method',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim')
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'max' => 20,
),
),
array(
'name' => 'Db\RecordExists',
'options' => array(
'table' => 'shipping',
'field' => 'shipping_method',
'adapter' => $this->dbAdapter
)
),
),
));
$inputFilter->get('shipping-address-2')->setRequired(false);
$inputFilter->get('shipping-address-3')->setRequired(false);
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
I only keep finding solutions for <select>.
Here's the sample POST data:
object(Zend\Stdlib\Parameters)#143 (1) {
["storage":"ArrayObject":private] => array(9) {
["shipping-name"] => string(4) "TEST"
["shipping-address-1"] => string(4) "test"
["shipping-address-2"] => string(0) ""
["shipping-address-3"] => string(0) ""
["shipping-city"] => string(4) "TEST"
["shipping-state"] => string(4) "TEST"
["shipping-country"] => string(4) "TEST"
["shipping-method"] => string(6) "Ground"
["submit-cart-shipping"] => string(0) ""
}
}
UPDATE:
form.phtml
<div class="form-group">
<?= $this->formRow($form->get('shipping-method')); ?>
<?= $this->formRadio($form->get('shipping-method')
->setValueOptions(array(
'Ground' => 'Ground',
'Expedited' => 'Expedited'))
->setDisableInArrayValidator(true)); ?>
</div>
ShippingForm.php
$this->add(array(
'name' => 'shipping-method',
'type' => 'Zend\Form\Element\Radio',
'options' => array(
'label' => 'Shipping Method',
'label_attributes' => array(
'class' => 'lbl-shipping-method'
),
)
));
The problem lies with when you use the setValueOptions() and the setDisableInArrayValidator(). You should do this earlier within your code as it is never set before validating your form and so the inputfilter still contain the defaults as the InArray validator. As after validation, which checks the inputfilter, you set different options for the shipping_methods.
You should move the setValueOptions() and the setDisableInArrayValidator() before the $form->isValid(). Either by setting the right options within the form itsself or doing this in the controller. Best way is to keep all of the options in one place and doing it inside the form class.
$this->add([
'name' => 'shipping-method',
'type' => 'Zend\Form\Element\Radio',
'options' => [
'value_options' => [
'Ground' => 'Ground',
'Expedited' => 'Expedited'
],
'disable_inarray_validator' => true,
'label' => 'Shipping Method',
'label_attributes' => [
'class' => 'lbl-shipping-method',
],
],
]);
Another small detail you might want to change is setting the value options. They are now hardcoded but your inputfilter is checking against database records whether they exist or not. Populate the value options with the database records. If the code still contains old methods but the database has a few new ones, they are not in sync.
class ShippingForm extends Form
{
private $dbAdapter;
public function __construct(AdapterInterface $dbAdapter, $name = 'shipping-form', $options = [])
{
parent::__construct($name, $options)
// inject the databaseAdapter into your form
$this->dbAdapter = $dbAdapter;
}
public function init()
{
// adding form elements to the form
// we use the init method to add form elements as from this point
// we also have access to custom form elements which the constructor doesn't
$this->add([
'name' => 'shipping-method',
'type' => 'Zend\Form\Element\Radio',
'options' => [
'value_options' => $this->getDbValueOptions(),
'disable_inarray_validator' => true,
'label' => 'Shipping Method',
'label_attributes' => [
'class' => 'lbl-shipping-method',
],
],
]);
}
private function getDbValueOptions()
{
$statement = $this->dbAdapter->query('SELECT shipping_method FROM shipping');
$rows = $statement->execute();
$valueOptions = [];
foreach ($rows as $row) {
$valueOptions[$row['shipping_method']] = $row['shipping_method'];
}
return $valueOptions;
}
}
Just had this happen yesterday.
The select and multi select ZF2+ elements have a built in in_array validator.
Remember filters occur before validators.
You may be doing too much here -- it is very rare to need to filter or add validators ot select and multi select form elements in ZF2 forms. The built in element validator is robust, ZF does a lot of work for us.
Try removing both filter and validator for the element, such as:
$inputFilter->add(array(
'name' => 'shipping-method',
'required' => true,
));
There is another edge case that I have seen: changing the select element's valueOptions somewhere in the controller (or view) resulting in different valueOptions used in view vs form validation (in our case it was replacing the element with a new one before validation).
I think your problem lies in the fact you are adding your value options after the InArray validator has been set, hence the validator has no haystack.
Try this
$this->add(array(
'name' => 'shipping-method',
'type' => 'Zend\Form\Element\Radio',
'options' => array(
'label' => 'Shipping Method',
'label_attributes' => array(
'class' => 'lbl-shipping-method'
),
'value_options' => array(
'Ground' => 'Ground',
'Expedited' => 'Expedited'
),
'disable_inarray_validator' => TRUE,
)
));
and remove setValueOptions and setDisableInArrayValidator from your view.
Hope this works.
I have following code in my Form.php
$fieldset->addField('name', 'textarea', array(
'label' => Mage::helper('module')->__('Name'),
'class' => 'required-entry',
'required' => true,
'name' => 'name',
));
I want to restrict the number of rows to display it like a single row, the code: 'rows' => 1 doesn't work here.
You can use styling to do this
$fieldset->addField('name', 'textarea', array(
'label' => Mage::helper('module')->__('Name'),
'class' => 'required-entry',
'required' => true,
'name' => 'name',
'style' => "height: 1em;",
));
Just had to change 'textarea' to 'text'
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
);
I want to make custom form in magento with two section like (two green box)
Also I wand to make three fields instead of one like
I have make code like
protected function _prepareForm() {
$form = new Varien_Data_Form();
$this->setForm($form);
$fieldset = $form->addFieldset('slider_form', array('legend' => Mage::helper('slider')->__('Slider information')));
$fieldset->addField('link_title', 'text', array(
'label' => Mage::helper('slider')->__('Link Title'),
'class' => 'required-entry',
'required' => true,
'name' => 'link_title',
));
$fieldset->addField('link', 'text', array(
'label' => Mage::helper('slider')->__('Link'),
'class' => 'required-entry',
'required' => true,
'name' => 'link',
));
$fieldset->addField('content', 'text', array(
'label' => Mage::helper('slider')->__('Text'),
'class' => 'required-entry',
'required' => true,
'name' => 'content',
));
....
....
}
Can anybody help!!!