I have 2 actions in my controller. First action to display form and fetch lists for the form fields from related HABTM models. Second action to perform searching and display results.
First action:
public function advancedSearch() {
$this->set($this->Restaurant->fetchRelatedData());
}
Also I have View for this action which displays the form: advancedSearch.ctp
echo $this->Form->create(null, array(
'type' => 'get',
'url' => '/restaurants/search', 'inputDefaults' => array(
'label' => false,
'div' => false
)));
echo $this->Form->input('companyname', array('label' => 'Name:'));
echo $this->Form->input('addr', array('label' => 'Address:'));
echo $this->Form->input('district_id', array('label' => 'District:'));
echo $this->Form->input('Station', array('label' => 'Subway station(s):'));
// etc.
echo $this->Form->end('Go!');
As you can see, this form sends data to my second action which performs actual searching.
I need to mention that I use pagination component in my search action and because of this I use the GET method.
My problem is that user may select some "simple" fields and some multiselect fields, send the form and after that he may want to refine search result.
So I need to implement functionality to pass data back to my form and populate fields with values which user has selected before.
How can I do that? Thanks.
Related
I am creating a modeless form based on the example given here. Once the user clicks the submit button, I retrieve some information from the database and display it in a table beneath the form. When I click on the submit button, the form displays the default values for start and end every time which is causing some confusion from my users using the page.
Is there any way to have the FormHelper display the values submitted by the end user rather than the defaults?
src/Form/StartEndForm.php
namespace App\Form;
use Cake\Form\Form;
class StartEndForm extends Form{
protected function _buildSchema(Schema $schema) {
return $schema->addField('start', [
'type' => 'date',
'default' => new Time('-1 month')
])
->addField('end', [
'type' => 'date',
'default' => new Time()
]);
}
protected function _buildValidator(Validator $validator) {
return $validator->add('start', 'date', [
'rule' => ['date'],
'message' => 'Please provide a valid date'
])
->add('end', 'date', [
'rule' => ['date'],
'message' => 'Please provide a valid date'
]);
}
protected function _execute(array $data) {
//do some SQL stuff and return the value
}
}
src/Template/Logs/index.ctp
echo $this->Form->create($form, [
'class' => 'start-end-date',
'type' => 'get'
]);
echo $this->Form->input('start');
echo $this->Form->input('end');
echo $this->Form->submit('Submit');
echo $this->Form->end();
//If values were returned, create a table
foreach(....)....
You are using a GET based form, ie the form values are being sent via the query string, and by default the form helper does not take the query string into account when looking for possible data to populate its controls, hence you'll end up with the forms being populated with the schema defaults.
You can either enable query string lookup (available as of CakePHP 3.4):
echo $this->Form->create($article, [
'class' => 'start-end-date',
'type' => 'get'
'valueSources' => [
'query', // < add this _before_ the default `context` source
'context'
]
]);
which will make the form helper explicitly look up the query data in the current request, or you could switch to using a POST form, which will automatically pick up the data as POST data is by default looked up by all built-in form contexts (Array, Entity, Form, Null), either as fallback, or as the primary source.
See also
Cookbook > Views > Helpers > Form > Getting form values from the query string
I'm new to symfony. I have a drop down in a form with data fetched from DB.
$builder->add('category', 'entity', array(
'label' => 'category',
'class' => 'MyBundle:category',
'expanded' => false,
'multiple' => false,
'mapped' => false,
'empty_value' => 'category'
));
$builder->add('other_category', 'text', array(
'label' => 'category',
'required' => false,
'invalid_message' => 'Please enter a valid category',
'mapped' => false,
));
the user can also add new category to the table. when other is selected from drop down, the 'other_category' input field is shown, else its hidden.
'Other' was added to drop down with the help of this code.
public function finishView(FormView $view, FormInterface $form, array $options)
{
$new_choice = new ChoiceView(array(), 'other', 'Other');
$view->children['category']->vars['choices'][] = $new_choice;
}
If a option is selected from drop down the form works fine. Data gets stored without any error. But if user selects 'other' and enters a new category the page reloads with 'This value is no valid' under the category options and there is no form validation for the 'other_category' entered by user.
Can someone help me with the form validation and also entering of a new category or suggest a better way to implement the above functionality.
The validation error is happening because the form field type is Entity, but there is no "MyBundle:category" entity with the identifying value "other".
You've not specified the "choice_label" property in your Entity form type so I'll assume your "MyBundle:category" entity has a __toString() function. This would mean none of the "MyBundle:category" entities return "other" in their __toString() function.
I can think of two options to work around this right now:
1) Add a "MyBundle:category" entity with value "other". This is the easiest way, but it's fairly assumed you don't want such a category to exist in your database.
2) Load the list of "MyBundle:category" entities in advance from your controller, build them into an associative array, append your "other" option to the array, then pass that array to the form. You'd need to swap the Entity form type for a Choice type and use the categories array as the choices.
If your form is a FormType class you'll need to pass the array in with the class constructor.
If you don't mind having a new category with an "other" value in your category table, just add it. Otherwise go for option 2, which won't make much difference to what you do after receiving the submitted form as this form field isn't mapped to an entity property anyway.
I have a typical Yii2 form for updating my model with a typical submit button. Next to it, I have a "Delete photo" button, that appears, if there is any photo to delete. The piece of view looks like that:
<?= Html::submitButton('Save changes', ['class' => 'btn btn-primary', 'name' => 'edit-button']) ?>
<?php $image = isset($page->photo) ? $page->photo->getImageUrl() : null; ?>
<?php if (isset($image)): ?>
<?= Html::a('Delete photo', ['delete-image', 'lab' => $lab->id, 'kind' => $page->kind], [
'class' => 'btn btn-danger',
'data' => [
'confirm' => 'Do you really want to delete this photo?',
'method' => 'post'
],
]) ?>
<?php endif; ?>
When there is a photo attached to this model and these two buttons appear next to each other, I must comment out 'method' => 'post' part in second button code. Because, if I don't this this, the second button is... submitting the form (just like the first one) instead of calling lab/delete-image route.
This is the first thing, that I don't understand. The entire code is either generated by Gii or copy-pasted from some Yii tutorials. Not even a bit of my invention and yet it works strangely. What am I missing?
It seems, that normal Html::a link (only styled by Twitter Bootstrap to look like a button, but not being a button at all) is submitting a form, instead of calling its action, when it contains data-method="post" attribute in element code. Is this a bug in Yii2 or am I missing something?
You need to place the link outside of the form. For calling actions from elements with data-method attribute yii has js function handleAction, and its documentation says:
This method recognizes the data-method attribute of the element. If the attribute exists, the method will submit the form containing this element. If there is no containing form, a form will be created and submitted using the method given by this attribute value (e.g. "post", "put").
For hyperlinks, the form action will take the value of the "href" attribute of the link.
Also if you use yii2 v2.0.3 or higher you can add data-params attribute which value should be JSON representation of the data, and this data will be submitted in request. As example:
echo Html::a('Delete image', ['delete-image'], [
'data' => [
'confirm' => 'Do you really want to delete this photo?'
'method' => 'post',
'params' => [
'lab' => $lab->id,
'kind' => $page->kind,
],
],
]);
In this example params array will be json encoded by yii2 internaly
CHtml::form();
echo CHtml::activeDropDownList($model,'imei', $model->getCategories(),
array('prompt' => 'Select Employe',
'submit'=>'/mobitracker/index.php?r=details/pathmap',
'params'=>array('imei'=>'js: $(this).val()'),
));
CHtml::endForm();
When a user selects a item am submitting it to another page and processing there.
but now I need another data also to be sent, i.e date am using DJui datepicker widget
$this->widget('zii.widgets.jui.CJuiDatePicker', array(
'name' => 'date_from',
'value' => $fromDateValue,
'htmlOptions' => array(
'size' => '10', // textField size
'maxlength' => '10', // textField maxlength
),
));
So once a user selects a employee and then selects a date I need data to be submitted.
How can I accomplish this using yii?
Thanks in advance.
Note: Am using PHP yii framework
<inputid="date_from" type="text" name="date_from" class="hasDatepicker">
The widget just simply generates a text box with the given settings including the name. You can totally take the name and process with it as usually by $_POST. Of cause you have to put that field into your form
...
$model->attributes=$_POST['Employee']; // access your form as you should have to do already
$model->date_from = $_POST['date_from']; // access date value
echo $this->Form->create('AmazonMatches', array('action' => 'selectMatches'));
echo $this->Form->input('option_id', array('options' => $allAmazonMatches, 'type' => 'radio'));
echo $this->Form->end(__('Submit', true));
Now I see a box around my radio buttons with a large red text saying "Option Id".
How can i get rid of it? Sorry I am a total Cake noob.
You need to set the 'legend' option to false if you don't want to show it, or to a string if you want to customize the message:
echo $this->Form->input('option_id', array(
'options' => $allAmazonMatches,
'type' => 'radio',
'legend' => false
));
$this->Form->input
Creates one input field with the id provided. You'll have to create multiple inputs inorder to make your checkboxes work separately.
There could be better methods, but doing it something likethis will work.
foreach($allAmazonMatches as $amazonMatch)
{
$this->Form->input...
}