I have a form created with Symfony forms.
and in the template i have this selectbox, displayed on the page with the render method.
<?php echo $form['field']->render() ?>
is it possible to set the selected option of this select box?
Or does this have to be done in the class that creates this form?
There is the creation of the field done:
public function configure() {
$this->widgetSchema['field'] = new sfWidgetFormSelect(
array("choices" =>
array('1' => 'test1','2' => 'test2')
)
);
}
yes, sure — you should have set corresponding form value — either via bind(), either via widget's default option.
For example,
public function configure()
{
$this->widgetSchema['field'] = new sfWidgetFormSelect(array(
"choices" => array('1' => 'test1','2' => 'test2'),
'default' => 2));
}
Hope I've answered your question.
Related
i have an ChoiceType::class input field in my form with, now just as an example, two choices:
'choices' => ['type1' => '1', 'type2' => '2']
now when the user select type2 i want to add an exta TextType::class inputfield to the form.
But i dont want to show the input field before and i want it to be required if selected type2 and not if selected type1.
I hope it make sense, i try it to to with javascript and set the attribute to hidden or not, but
then the form is not been send because of the required attribute.
I tried it with form events but did not get it to work in that way.
Thanks
You were on the right way, you have to do it in Javascript. You just need to manage the attr required in Javascript so that the form does not block you with something like this:
Remove the required attribute from a field: document.getElementById("id").required = false;
Make a field required : document.getElementById("id").required = true;
And you can check if the form can be sumitted with : document.getElementById("idForm").reportValidity();.
I using implementation of conditional fields with data-attributes, e.g.:
->add('typeField', EnumType::class, [
'label' => 'Type',
'class' => MyTypeEnum::Class,
])
->add('someField', TextField::class, [
'data-controller' => 'depends-on',
'data-depends-on' => 'my_form_typeField',
'data-depends-value' => MyTypeEnum::OTHER->value,
])
On frontend JS stimulus controller show/hide someField depend on typeField value.
And validation() function in object ('data_class' in formType) make custom validation, e.g.:
/**
* #Assert\Callback
*/
public function validate(ExecutionContextInterface $context)
{
if ($this->typeField !== MyTypeEnum::OTHER) {
$context->buildViolation('message')->atPath('typeField')->addViolation();
}
}
I have a SilverStripe site with some code to display a search form. The for allows you to search for something based on 3 things. Problem is, I'm not sure how to get the results to display correctly on a separate page.
My code:
class InstitutionSearchPage extends Page {
}
class InstitutionSearchPage_Controller extends Page_Controller {
private static $allowed_actions = array(
'Search'
);
public function Form() {
$fields = new FieldList(array(
DropdownField::create('DegreeType', 'Degree', QualificationType::get()->filter('ParentID', 0)->map()),
DropdownField::create('Course', 'Course', Qualification::get()->map()),
DropdownField::create('City', 'City', City::get()->map()),
));
$actions = new FieldList(array(
FormAction::create('Search')->setTitle('Find a College')
));
$validator = ZenValidator::create();
$validator->addRequiredFields(array(
'DegreeType' => 'Please select a Degree',
'Course' => 'Please select a course',
'City' => 'Please select a city',
));
$form = new Form($this, 'Search', $fields, $actions, $validator);
$form->setLegend('Criteria')->addExtraClass('form-horizontal')->setAttribute('data-toggle', 'validator');
// Load the form with previously sent data
$form->loadDataFrom($this->request->postVars());
return $form;
}
public function Search() {
return array('Content' => print_r($this->getRequest()->postVars(), true));
}
}
It seems to be displaying results on the same page but gives me a bunch of weird data. For example, I got this when I tested the form: Array ( [DegreeType] => 53 [Course] => 1 [City] => 1 [SecurityID] => 02718d0283e27eeb539eff19616e0b23eadd6b94 [action_Search] => Find a College )
The result is supposed to be an organized list of colleges (along with other data).
I guess that what you are seeing is expected behavior, as the form will post to the Search function, and that one is just returning a print_r of an array with the post vars which will be picked up by the template.
Otherwise, there are a lot of things not corresponding with the Silverstripe default way to handle forms. Please take a look here and change your form accordingly: https://docs.silverstripe.org/en/3.4/tutorials/forms/
For example, give the form the same name as your function (or in your case, change the function name to the form name). Then implement the action function.
Background: In Drupal 7, I have created a form with CCK (aka the Field UI). I used the Field group module to create a fieldgroup, but I need it to be conditional, meaning it will only display depending on a previous answer.
Previous research: To create a conditional field, you can use hook_form_alter() to edit the #states attribute like so:
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'person_info_node_form') {
// Display 'field_maiden_name' only if married
$form['field_maiden_name']['#states'] = array(
'visible' => array(
':input[name="field_married[und]"]' => array('value' => 'Yes'),
),
);
}
}
However, there seems to be no way to use the States API for fieldgroups. One thing to note is that, while fields are stored in $form, fieldgroups are stored in $form['#groups'] as well as in $form['#fieldgroups']. I don't know how to distinguish between these, and with this in mind, I have tried to apply a #states attribute to a fieldgroup in the same manner as above. However, it only produces server errors.
Question: Is there a way to make a fieldgroup display conditionally using the States API or some alternative approach?
you have to use the hook_field_group_build_pre_render_alter()
Simply :
function your_module_field_group_build_pre_render_alter(&$element) {
$element['your_field_group']['#states'] = array(
'visible' => array(
':input[name="field_checkbox"]' => array('checked' => TRUE),
),
);
}
This works perfecly. If the group A is in an another group, do this
$element['groupA']['groupB']['#states'] etc....
You may need to add an id attribute if none exists:
$element['your_field_group']['#attributes']['id'] = 'some-id';
$element['yout_field_group']['#id'] = 'some-id';
Here's the simplest solution I came up with. There are essentially 2 parts to this: (1.) programmatically alter the display of the form, and (2.) use the GUI to alter the display of the content.
(1.) First, I used hook_form_alter() to programmatically create the conditional fieldset and add existing fields to it. The code is shown below.
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'FORM_ID_node_form') {
// programmatically create a conditional fieldset
$form['MYFIELDSET'] = array( // do NOT name the same as a 'Field group' fieldset or problems will occur
'#type' => 'fieldset',
'#title' => t('Conditional fieldset'),
'#weight' => intval($form['field_PARENT']['#weight'])+1, // put this fieldset right after it's "parent" field
'#states' => array(
'visible' => array(
':input[name="field_PARENT[und]"]' => array('value' => 'Yes'), // only show if field_PARENT == 'Yes'
),
),
);
// add existing fields (created with the Field UI) to the
// conditional fieldset
$fields = array('field_MYFIELD1', 'field_MYFIELD2', 'field_MYFIELD3');
$form = MYMODULE_addToFieldset($form, 'MYFIELDSET', $fields);
}
}
/**
* Adds existing fields to the specified fieldset.
*
* #param array $form Nested array of form elements that comprise the form.
* #param string $fieldset The machine name of the fieldset.
* #param array $fields An array of the machine names of all fields to
* be included in the fieldset.
* #return array $form The updated form.
*/
function MYMODULE_addToFieldSet($form, $fieldset, $fields) {
foreach($fields as $field) {
$form[$fieldset][$field] = $form[$field]; // copy existing field into fieldset
unset($form[$field]); // destroy the original field or duplication will occur
}
return $form;
}
(2.) Then I used the Field group module to alter the display of the content. I did this by going to my content type and using the 'Manage display' tab to create a field group and add my fields to it. This way, the fields will appear to be apart of the same group on both the form and the saved content.
Maybe you can try to look at the code of this module to help you find an idea.
I am having a problem with the form select helper. On my page I have two forms.
One is a quick search form. This one uses state_id.
Upon searching in URL: state_id:CO
This will auto select the correct value in the drop down.
However, when I search with the advanced form. The Field is trail_state_id and
in URL: trail_state_id:CO
For some reason it will not default it to the correct value. It just resets the form to no selections. The values are searhed properly, just the form helper is not recognizing that a field with the same name in the url is set. Any thoughts?
<?php
class Trail extends AppModel {
public $filterArgs = array(
array('name' => 'state_id','field'=>'Area.state_id', 'type' => 'value'),
array('name'=>'trail_state_id','field'=>'Area.state_id','type'=> 'value'),
);
}
?>
in URL: trail_state_id:CO
<?php
echo '<h4>State*:</h4><div>'.$this->Form->select('trail_state_id', $stateSelectList, null, array('style'=>'width:200px;','escape' => false,'class'=> 'enhanced required','empty'=> false));
?>
Using the 3rd argument in the helper you can set a default. I did it the following way;
echo '<h4>State*:</h4><div>'.$this->Form->select('trail_state_id', $stateSelectList, (empty($this->params['named']['trail_state_id']) ? null: $this->params['named']['trail_state_id']), array('style'=>'width:200px;','escape' => false,'class'=> 'enhanced required','empty'=> false));
I'm using Symfony 1.2 in a standard Propel form class.
public function configure()
{
$this->setWidgets(array(
'graduate_job_title' => new sfWidgetFormInput( array(), array( 'maxlength' => 80, 'size' => 30, 'value' => '' ) )
));
//etc
}
However, I want the value of this field to come from the user information, which I'd normally access using $this->getUser()->getAttribute( '...' ). However, this doesn't seem to work in the form.
What should I be using?
It's a very bad idea to rely on the sfContext instance.
It's better to pass what you need during sfForm initialization in the options array parameter.
http://www.symfony-project.org/api/1_4/sfForm
__contruct method
for example in your action:
$form = new myForm(null,
array('attributeFoo' =>
$this->getUser()->getAttribute('attributeFoo'));
and then retrieve the value inside the form class:
$this->getOption('attributeFoo');
cirpo
Does that work?
sfContext::getInstance()->getUser()->getAttribute('...');
// Edit : See cirpo's recommandation on the use of sfContext instead.
If someone need the same in admin (backend) here is a solution:
http://blog.nevalon.de/en/wie-nutze-ich-die-rechteverwaltung-in-symfony-admin-generator-formularen-20100729
In Symfony 1.4, object $sf_user