I have a classical index page with a form where I can filter my records.
One of my fields is year. Let's say that I want the records to be pre-filtered by current year when the user first visit the page (i.e. when the query string is empty)
what have I done:
in my controller I did something like this
if(empty($this->request->query))
{
$this->request->query['year'] = date('Y');
}
and then with the help of friendsofcake/search plugig:
$this->MyTable->find('search', [
'search' => $this->request->getQuery()
]);
In this way the records are filtered and the form is pre compiled with the current year since in my view I have
'valueSources' => 'query'
Now with cake 3.6 direct modification of the query is deprecated (see this issue I opened). In fact I get deprecation warnings when I try to change the query array.
My question:
So I want to know what is the best way to achieve the same behavior without getting warnings. I would also like to know if and why my approach is wrong.
In controller:
$searchValues = $this->request->getQueryParams() ?: ['year' => date('Y')];
$this->MyTable->find('search', [
'search' => $searchValues
]);
$this->set(compact('searchValues'));
In template:
$this->Form->create(['schema' => [], 'defaults' => $searchValues]);
Ideally you would also set proper values in schema as shown here https://api.cakephp.org/3.6/class-Cake.View.Form.ArrayContext.html
Try something like this (not tested):
$this->setRequest($this->getRequest()->withQueryParams([
'year' => date('Y'),
]);
Related
I am wondering how I can implement this the best way:
I have a site where a user can make a post, he has 2 checkboxes there for "resumes" and "more documents". Those two are not required, but when they are I need to save a "true" in the database in the column for this.
I thought I could implement it by writing if loops, like:
if both are present this code:
Post::create([ 'resumee' => true, 'more_docs' => true,]);
If only resume is present like this:
Post::create(['resumee' => true, 'more_docs' => false]);
and if only more_docs is present then the other way around.
however I figured there would be a way better approach to implement this, but I am fairly new to laravel so I cant think about any.
My first guess was to do something like this inside the create statement:
Post::create([
'resumee' => true,
if($request->has(more_docs)
'more_docs' => true,
else ....
]);
But all I got were red lines haha. So maybe someone of you more experienced guys have an idea, any help appreciated!
You can use something like this:
Product::create([
// ... other fields
'resumee' => $request->filled('resumee'),
'more_docs' => $request->filled('more_docs'),
]);
If you would like to determine if a value is present on the request and is not empty, you may use the filled method. I think this mthod will more appropriate for your task.
I'm working on a project using Symfony 3.0 version, and I added a place where users can see how many time ago did the item was added. To be able to use this, i added the date extension to the services.yml file like this:
twig.extension.date:
class: Twig_Extensions_Extension_Date
tags:
- { name: twig.extension }
Now I can use the following code: {{ answer.answeredAt|time_diff }} and everything is right, because it shows for example "2 hours ago".
My problem is, that some of this "answers" can be added by a javascript call. I searched a bit and the best option was to render this twig bit in the controller as a string and send it back in the javascript response. This way:
$now = new \DateTime();
$template = $this->get('twig')->createTemplate('{{ answeredAt|time_diff }}');
$date = $template->render(['answeredAt' => $now]);
$response = new JsonResponse([
'answer' => [
'id' => $answer->getId(),
'text' => $answer->getText(),
'date' => $date
]
]);
I thought this should work fine, but it didn't. Although no error was trown, the date field always comes back empty. Do I need to do something special on services.yml to make the extensions available on controllers?
The problem is related to when the difference of dates does not exist, in other words, when both dates are the same, the functions will return blank, and that was misleading me into thinking something was wrong.
If you check my code I was looking for a difference between now and new \DateTime() which is also now, so, no difference at all.
If you still want to show something to the user, just like my case, you can use the following code:
$date = $template->render(['answeredAt' => $now->modify('-1 second')]);
This will show to users: "1 second ago".
I'm very new at working with a framework like symfony, but I must say that i am turning in to a fan quite fast. Unfortunately i'm totally stuck for the last few days in a row.
The Context
I'm trying to refactor my old-school php CMS to the symfony3 framework. A user can manage his pages by adding en editing them. Adding a new page to the database works like a charm. Editing a page is also working fine, except one small part of it. The form prefills al fields like it should and a post will edit the entity.
But... for some reason the selectbox won't pre-select with the selected templatetype. This list is build with use of the EntityType::class and fetches the available data from the database by using AppBundle:Templates.
A piece of the code i use for loading and building the form:
// Fetch selected page
$page = $this->getDoctrine()->getRepository('AppBundle:PageMan')->find($id);
// Generate form
$form = $this->createFormBuilder($page)
->add('templateId', EntityType::class, array(
'label' => 'Template type',
'class' => 'AppBundle:Templates',
'placeholder' => 'Kies een template',
'choice_label' => 'name',
'choice_value' => 'id',
'multiple' => false,
'expanded' => false,
'required' => true,
))->getForm();
The last few days i have tried every possibility i could think of and google. I've also checked the following:
templateId is filled with a value after loading the repository. When I change the field to a plain textfield, the value is shown.
AppBundle:Templates returns unique values (only two entity's in the database with id 1 and 2)
The selected="selected" attribute is set when posting (and not redirecting away)
Removing cashe doesn't solve the problem
At his moment i'm out of possible solutions, hope some one can help. It could be something so simple, but i'm just not seeing it anymore.
--Update--
Just found the following inconsistency in a vardump of the generated form. In the 'name'-object you see modelData, normData and viewData pre-filled. But 'templateId' misses content in viewData.
screenshot vardump formbuilder
In the documentation of symfony it states the folowing:
View Data - This is the format that's used to fill in the form fields themselves. It's also the format in which the user will submit the data. When you call Form::submit($data), the $data is in the "view" data format. Source
This could be a possible leed to a solution.
--Update 2--
Just hardcoded $this->viewData in \vendor\symfony\symfony\src\Symfony\Component\Form\Form.php to a hardcoded value that is present in the selectbox. This adds a value to the empty setting as mentioned in the the update above. Now the default value gets selected as it should. I'm going to follow this variable in the code. Hope to find the reason why it doesnt get prefilled.
Actually choice_value is callable, so you can make a function:
'choice_value' => function($page){
return strval( $page->getId() );
}
I think that might work in this case. Please try it.
Finally fixed my problem. Don't know if it's the official way, but in my case it works like a charm.
In my EntityType setting, i'm now passing 'data' => $page, as an extra object to the formbuilder. This results in viewData being filled with a value and that was what i needed to get a pre-selectid selectbox on pageload.
Here the final snippet:
->add('templateId', EntityType::class, array(
'label' => 'Template type',
'class' => TemplateMan::class,
'placeholder' => 'Kies een template',
'choice_label' => 'name',
'choice_value' => 'templateId',
'data' => $page,
'data_class' => null,
'multiple' => false,
'expanded' => false,
'required' => true,
))
i have a module that have different render with different conditions so i have used like
if($p_id != '') {
$this->render('view', array(
'model' => $this->loadModel($id, 'Supplier'),
'modeln' => $this->loadModel($p_id, 'Permit'),
));
} else {
$this->render('view', array(
'model' => $this->loadModel($id, 'Supplier'),
));
it works fine but i have 5 to 6 conditions like this ,so how can i handle this? any easy way than this? thanks
There are several approaches.
Switch cases to return the view and model datas as array.
Make $p_id and view name more meaning ful. Or even, as:
$views = array(
'p_id' => 'corresponding_view file'
);
And then later, use it as $this->loadModel($p_id, $views[$p_id]),
There are two solutions for this problem:
Adding condition inside controller and rendering multiple views based on condition.(As you do)
Having just one view and adding condition inside the view and showing desired parts of view based on condition.
All these two solution is achievable, But I believe first solution is better. Because second solution has inconsistency with MVC structure. It's not a good idea to put logic inside the view. So I think rendering different views based on condition is better.
In my form, I want to set the selected (default) value for a select element. However, using setDefaults is not working for me.
Here is my code:
$gender = new Zend_Form_Element_Select('sltGender');
$gender->setMultiOptions(array(
-1 => 'Gender',
0 => 'Female',
1 => 'Male'
))
->addValidator(new Zend_Validate_Int(), false)
->addValidator(new Zend_Validate_GreaterThan(-1), false);
$this->setDefaults(array(
'sltGender' => 0
));
$this->addElement($gender);
My controller is simply assigning the form to a view variable which just displays the form.
It works by using $gender->setValue(0), but it would be easier to set them all at once with an array of default values. Am I misunderstanding something here?
Also, where is the Zend Framework documentation for classes and methods? I am looking for something similar to the Java documentation. The best I could find is this one, but I don't like it - especially because every time I try to search, it crashes.
Have you tried:
$this->addElement($gender);
$this->setDefaults(array(
'sltGender' => 0
));
Also, take a look at http://framework.zend.com/issues/browse/ZF-12021 .
As you can see, the above issue is similar to the issue you're describing. It seems Zend is very particular about the order you create objects and assign settings.
I'm afraid you're going to have to do things in the order Zend wants you to do them (which doesn't seem well documented, but is only discovered thru trial and error), or hack their library to make it do what you want it to do.