I created a zend form. I want to make a group of elements that output html like this:
<div class="form_wrapper">
<div class="form_label">
<label class="txtlabel" for="salary_type">Salary type</label>
<span>*</span>
</div>
<div class="form_element">
<select class="jp_select" id="salary_type" name="salary_type">
<option>..1..</option>
<option>2</option>
<option>3</option>
</select>
<input type="text" id="salary_min" class="txtinput" name="salary_min" value="Min" onfocus="if(this.value=='Min') this.value='';" onblur="if(this.value=='') this.value=('Min');">
<input type="text" id="salary_max" class="txtinput" name="salary_max" value="Max" onfocus="if(this.value=='Max') this.value='';" onblur="if(this.value=='') this.value=('Max');">
</div>
</div> <!-- end .form_wrapper -->
My code:
$this->addElement('select', 'salary_type', array(
'label' => 'Salary type',
'multiOptions' => $salary_types,
'class'=>'jp_select'
));
$this->addElement('text', 'salary_min', array(
'label' => 'Min',
'class'=>'txtinput'
));
$this->addElement('text', 'salary_max', array(
'label' => 'Max',
'class'=>'txtinput'
));
$this->addDisplayGroup(array('salary_type','salary_min','salary_max'), 'salary_group');
How can I set decorators to have html output like above
As far as I know, you are not able to render that exact html structure with simple Decorators alone.
One way to solve this problem is by using the ViewScript Decorator within your displayGroup decorator stack. Within the view script, you are able to retrieve the individual elements by using $this->element->getElements(); ($this->element is an instance of Zend_Form_DisplayGroup)
For example:
$this->addDisplayGroup(
array('salary_type','salary_min','salary_max'),
'salary_group',
array(
'decorators' => array(
array('ViewScript', array('viewScript' => 'path/to/viewscript.phtml')),
),
)
);
Haven't tried it myself, but it should work.
Related
How is is possible to include a prepend icon or an append icon using form_input();
<?php
$email = array(
'name' => '',
'value' => '',
'id' => null,
'placeholder' => 'Email',
'class' => 'mail form-control'
);
echo form_input($email);
?>
What I would like to do is add, for example, the following bootstrap 3 styling to the email input box:
<span class="input-group-addon" id="basic-addon2">#example.com</span>
I am unsure how that would fit into the array. I have looked at the manual for CI3, however, it does not mention anything in particular. Any suggestions, etc, appreciated.
This is what I am aiming for:
Unfortunately, you can't. form_input() is used to build the input element only. If you take a closer look at the html structure. <span> comes right after <input> and not within <input>. So, you have to add it after the input element
....
<?php echo form_input($email); ?>
<span class="input-group-addon" id="basic-addon2">#example.com</span>
...
Taking code from bootstrap website:
<form class="form-horizontal">
<div class="form-group has-success has-feedback">
<label class="control-label col-sm-3" for="inputSuccess3">Input with success</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="inputSuccess3" aria-describedby="inputSuccess3Status">
<span class="glyphicon glyphicon-ok form-control-feedback" aria-hidden="true"></span>
<span id="inputSuccess3Status" class="sr-only">(success)</span>
</div>
</div>
<div class="form-group has-success has-feedback">
<label class="control-label col-sm-3" for="inputGroupSuccess2">Input group with success</label>
<div class="col-sm-9">
<div class="input-group">
<span class="input-group-addon">#</span>
<?php
$email = array(
'type' => 'text',
'class' => 'form-control'
'id' => 'inputGroupSuccess2',
'aria-describedby' => 'inputGroupSuccess2Status',
'name' => 'email',//name field is mandatory to be able to control it in form_validation library
'placeholder' => 'Email',
);
echo form_input($email);
?>
</div>
<span class="glyphicon glyphicon-ok form-control-feedback" aria-hidden="true"></span>
<span id="inputGroupSuccess2Status" class="sr-only">(success)</span>
</div>
</div>
</form>
you can see that span tag and input tag doesn't collide. So you would just use:
<?php
$email = array(
'name' => '',
'value' => '',
'id' => null,
'placeholder' => 'Email',
'class' => 'mail form-control'
);
echo form_input($email);
?>
instead of bootstrap input field. Everything else can stay the same in view file. If you would like to make input field like second one from example above, you should code it like:
<?php
$email = array(
'type' => 'text',
'class' => 'form-control'
'id' => 'inputGroupSuccess2',
'aria-describedby' => 'inputGroupSuccess2Status',
'name' => 'email',//name field is mandatory to be able to control it in form_validation library
'placeholder' => 'Email',
);
echo form_input($email);
?>
This could be example like "Optional icons in horizontal and inline forms" on Forms page.
I have a form with Radio-button:
$this->add([
'name' => 'time',
'options' => [
'value_options' => [
'0' => '9:00 - 12:00',
'1' => '12:00 - 16:00',
'2' => '16:00 - 19:00',
],
'label_attributes' => [
'class' => 'WW_OBJ_fm-label',
]
],
'type' => 'Radio'
]);
In the view I make the output like this:
<div>
<?php echo $this->formElement($form->get('time')); ?>
</div>
and get the output (formatted for readability):
<div>
<label class="WW_OBJ_fm-label">
<input type="radio" name="time" value="0"/>
9:00 - 12:00
</label>
<label class="WW_OBJ_fm-label">
<input type="radio" name="time" value="1"/>
12:00 - 16:00
</label>
<label class="WW_OBJ_fm-label">
<input type="radio" name="time" value="2"/>
16:00 - 19:00
</label>
</div>
But I need, that label text ist wrapped by a <span>:
<div>
<label class="WW_OBJ_fm-label">
<input type="radio" name="time" value="0"/>
<span class="WW_label-text">9:00 - 12:00</span>
</label>
<label class="WW_OBJ_fm-label">
<input type="radio" name="time" value="1"/>
<span class="WW_label-text">12:00 - 16:00</span>
</label>
<label class="WW_OBJ_fm-label">
<input type="radio" name="time" value="2"/>
<span class="WW_label-text">16:00 - 19:00</span>
</label>
</div>
What is the best way to achieve it?
I see three possible solutions for your problem.
1) Extend the Zend\Form\View\Helper\FormRadio class, overriding the renderOptions method, replicating almost entirely the one that you can find in Zend\Form\View\Helper\FormMultiCheckbox but maybe adding an option to pass optional attributes to the span element
2) Very subtle, but could save you writing some code: using the translator. Since the radio value options are translated, you could keep your values defined in the configuration but adding the span element in the transation
3) Do not use $this->formElement to display the element, but actually write all the html
A solution is to use labelOption 'disable_html_escape' :
$this->add([
'name' => 'time',
'options' => [
'value_options' => [
'0' => '<span class="WW_label-text">9:00 - 12:00</span>',
'1' => '<span class="WW_label-text">12:00 - 16:00</span>',
'2' => '<span class="WW_label-text">16:00 - 19:00</span>',
],
'label_attributes' => [
'class' => 'WW_OBJ_fm-label',
]
],
'type' => 'Radio'
]);
$element = $this->get('time');
$element->setLabelOptions(['disable_html_escape' => true]);
I am trying to remove or change the wrapping div that CakePHP uses on its form helper.
When I use this code:
echo $this->Form->input('contact', ['label' => false]);
The output is:
<div class="input text">
<input type="text" id="contact" maxlength="255" name="contact">
</div>
And what I want is:
<div class="myOwnClass">
<input type="text" id="contact" maxlength="255" name="contact">
</div>
I used to do that on CakePHP 2 adding more options to the input method, however on the latest CakePHP version this isn't working. Any clues?
Thanks
Use FormHelper Templates
To change wrapping for all inputs in form use:
$this->Form->templates([
'inputContainer' => '<div class="myOwnClass">{{content}}</div>'
]);
// or remove completely
$this->Form->templates([
'inputContainer' => '{{content}}'
]);
// now get input with desired wrapping
echo $this->Form->input('contact', [
'label' => false
]);
To change wrapping for single input use:
echo $this->Form->input('contact', [
'templates' => [
'inputContainer' => '<div class="myOwnClass">{{content}}</div>'
],
'label' => false
]);
For complete reference on templates read: Customizing the Templates FormHelper Uses
CakePHP 2 style of customizing the wrappings is not supported anymore in version 3. From migration guide:
The div, before, after, between and errorMessage options have been
removed from input(). You can use templates to update the wrapping
HTML. The templates option allows you to override the loaded templates
for one input.
I'm working with a UI purchased and there have been several problems with cakephp3. For me it is not so easy to remove the <div> initial, most to the solution provided here, after much testing:
echo $this->Form->control('username', [
'templates' => ['inputContainer' => '{{content}}'],
"type" => "text",
"aria-invalid" => "false",
"aria-required" => "true",
"class" => "form-control valid",
"placeholder" => "Ingrese su usuario o email ...",
"autocomplete" => "on",
'label' => false
]);
the result
<input name="username" aria-invalid="false" aria-required="true" class="form-control valid" placeholder="Ingrese su usuario o email ..." autocomplete="on" id="username" type="text">
only adds an input tag (sorry for my Google-English)
I think it is a better way to define the templates global in the config folder:
<?= $this->Form->create($user, array(
"class" => "ui form",
"templates" => "semantic" // The filename in your config folder without .php
)); ?>
In the config folder create the file "semantic.php" (You can name it to whatever you want) with the content:
return array(
"inputContainer" => '{{content}}' // Here the magic happens
);
Hope this helps!
When i create a form on CakePHP with radio inputs, the label generated not match with the id of the radio input, the label "for" duplicates the name of the form. Here is my code:
echo $this->Form->create(
'test',
array(
'action' => 'index',
'type' => 'post',
'class' => 'fill-up',
'inputDefaults' => array('div' => 'input')));
$options = array('option1' => '1',
'option2' => '2');
$attributes = array('legend' = > false);
echo $this->Form->radio('Type', $options, $attributes);
echo $this->Form->end(
array(
'label' = > 'end',
'class' = > 'button',
'div' = > false));
and the generated HTML is something like:
<input type="hidden" name="data[test][options]" id="testOptions_" value="">
<input type="radio" name="data[test][options]" id="TestOptionsOption1" value="option1">
<label for="testTestOptionsOption1">1</label>
<input type="radio" name="data[test][options]" id="TestOptionsOption2" value="option2">
<label for="testTestOptionsOption2">2</label>
as you can see, cake duplicate the form name "test" on the label. How I can fix this? I try with the exact code of the documentations and still have the same issue
hope you can help me, thx very much
I auto-answer my question. That was a bug of cakephp, solved on the last version:
https://github.com/cakephp/cakephp/releases/tag/2.4.2
Try using
'label' => array(
'class' => 'thingy',
'text' => 'The User Alias'
)
Currently, i have succeeded in creating the checkbox.
The array which i have setup is as below:
$emailName = $this->User->find('list', array(
'fields' => array('User.username', 'User.email')
));
The output is as follows:
array
'admin' => string 'asd#asd.asd' (length=11)
'test' => string 'test#test.test' (length=14)
'Floo' => string 'XXXX#gmail.com' (length=16)
I'm trying to make the checkbox shows the username instead of the user email in view.ctp.
I have tried using the following code in view.ctp
<?php echo $this->Form->input('Address_list.['.$emailName['username'].']', array(
'type' => 'select',
'multiple' => 'checkbox',
'options' => $emailName['email']
)); ?>
However, it seems that this doesn't work. Any ideas?
You are not formatting your form field for the checkbox list correctly. Try changing it to this:
echo $this->Form->input('Address_list', array(
'multiple' => 'checkbox',
'options' => $emailName,
));
However, this will return the value of Username based on the selection of Email the user chooses. It creates the form like this:
<label for="Address_list">Address List</label>
<input type="hidden" id="Address_list" value="" name="data[Address_list]"/>
<div class="checkbox"><input type="checkbox" id="AddressListAdmin" value="admin"
name="data[Address_list][]"/><label for="AddressListAdmin">asd#example.com</label></div>
<div class="checkbox"><input type="checkbox" id="AddressListTest" value="test"
name="data[Address_list][]"/><label for="AddressListTest">test#example.com</label></div>
<div class="checkbox"><input type="checkbox" id="AddressListFloo" value="Floo"
name="data[Address_list][]"/><label for="AddressListFloo">XXX#example.com</label></div>