I am using Yii::$app->formatter in one of my attribute like:
Controller code
$model->discharge_date=Yii::$app->formatter->asDatetime
($model->discharge_date, 'php:d-M-Y H:i');
Model Code
[['admission_date','discharge_date'],'date','format' => 'php:d-M-Y H:i'],
Everything is working fine except when discharge date is left blank, on update it is filled with this line:
<span class="not-set">(not set)</span>
I couldn't make out from where this is coming, as in the DB the value is NUll
Thanks.
It's default and expected behavior.
See documentation for $nullDisplay property of Formatter.
You can cnahge that across application through application configuration:
'formatter' => [
'nullDisplay' => '',
],
For specific view you can change it through formatter component (note that you should add that code before view is rendered):
use Yii;
...
Yii::$app->formatter->nullDisplay = '';
Related
In my Symfony Application i have a From which contains a lot of checkboxes, radios, textfields and also DateTime Objects.
Everything but the DateTime Objects work fine, but with them i always get the error "Object of class DateTime could not be converted to string"
So i wanted to use this tutorial to change the datetime object to a string.
The thing is i am using a FormFactory and when i use the addModelTransformer()-Method like this...
1st Option:
$form->add($formFactory->createNamed('value', 'date', null, $fieldOptions));
$form->get('value')->addModelTransformer(new CallbackTransformer(
function($dateAsDate){
return $dateAsDate->format('Y-m-d');
},
function ($dateAsString){
return "test"; //TODO: to be changed to make string to date
}
));
...i get the Error "Call to undefined method Symfony\Component\Form\Form::addModelTransformer() "
When i use the builder function outside the Formfactory like this...
2nd Option:
//$builder->addEventListener Stuff is above
$builder->get('value')->addModelTransformer(new CallbackTransformer(
function($dateAsDate){ return $dateAsDate->format('Y-m-d'); },
function ($dateAsString){ return 'null'; } //TODO: to be changed to make string to date
));
...i get the Error "The child with the name "value" does not exist."
Does anybody have an idea how to make this work?
There is no need to use any custom Tranformer here.
The DateType field handles DateTime objects correctly by itself.
You may want to specify some options like 'format' and 'widget' depending on how you want to render your field, but the default 'input' should work fine with DateTime.
For example :
$builder->add('value', DateType::class, [
'format' => 'y-MM-dd',
'widget' => 'single_text', // To have a single input text box
'input' => 'datetime' // This is the default value
];
I'm new in Yii2 framework. To give structure to my web application, I want to put each controller in a subfolder and make a separate controller for each action in each subfolder. Like that one!
controllers
**User**
IndexController
EditController
UpdateController
**Profile**
IndexController
EditController
UpdateController
How can I arrange that in Yii2.
thanks in advance
Well your example is right.
controllers/user/IndexController.php
views/user/index/index.php
Then in IndexController/EditController/UpdateController you have actionIndex and if you run domain.com/user/index or domain.com/user/edit it will execute actionIndex in current controller (IndexController or EditController)
domain.com/user/index = domain.com/user/index/index
and
domain.com/user/edit = domain.com/user/edit/index
Not sure if there are other more effective ways, but one that works would be the following.
Note: This example assumes that you're using https://github.com/yiisoft/yii2-app-advanced but it can work for the basic app also, just changing the namespaces.
So, let's say you say we have a controller, and we want to store some of its actions into different php files.
<?php
// frontend\controllers\SiteController.php
namespace frontend\controllers;
use yii\web\Controller;
class SiteController extends Controller {
public function actions() {
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
'captcha' => [
'class' => 'yii\captcha\CaptchaAction',
'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
],
'hello-world' => [
'class' => 'frontend\controllers\site\HelloWorldAction',
],
];
}
public function actionIndex() {
// ...
}
So you can see we've got 3 external actions and one internal one.
The first two ones, are framework's tools for Error page and Captcha generation, actually they've inspired my answer.
And the third one, is defined by us:
'hello-world' => [
'class' => 'frontend\controllers\site\HelloWorldAction',
],
So we've named the action and we created our new action class into a separate directory.
<?php
// frontend\controllers\site\HelloWorldAction.php
namespace frontend\controllers\site;
use yii\base\Action;
class HelloWorldAction extends Action {
public function run($planet='Earth') {
return $this->controller->render('hello-world', [
'planet'=>$planet,
]);
}
}
And last, our view:
<?php
// frontend\views\site\hello-world.php
/* #var $this yii\web\View */
use yii\helpers\Html;
$this->title = 'Hello world page';
?>
<h1>Hello world!</h1>
<p>We're on planet <?php echo Html::encode($planet); ?></p>
And seeing it in action:
Update
After posting the answer I realized that maybe you could benefit from another technique also.
The previous answer is good if you want to do just that: Extract actions into individual files.
But, if your application will be of certain size, maybe you should consider using Modules.
You can create them manually or generate them with Gii:
And once generated, include it in your config:
<?php
......
'modules' => [
'profile' => [
'class' => 'frontend\modules\profile\Module',
],
],
......
Modules do just that, group application logic into one directory, controllers, models, views, components, etc.
Two more tips:
Now to access your module, simply visit http://www.your-site.local/profile/default/index, as you can see, it goes like module/controller/action.
And if you want to generate links to actions inside modules, you would do:
<?php
echo Url::to([
'profile/default/index',
'param'=>'value',
]);
?>
Again as you can see we're using module/controller/action as the route.
Last thing, if you're inside a module, let's say profile/picture/edit, and you want to link to Contact page from SiteController, you would do:
<?php
echo Url::to([
'//site/contact',
'param'=>'value',
]);
?>
Note the double slash // at the beginning of the route. Without it, it will generate the url to the current module profile/site/contact.
I have a base extension so i can version my website. That means i have not a controller or a repository on the extension. So what i want to do, is to create my own settings on existing elements. I was experimenting around with a text align values on the header content element.
Keep in mind, there is already a setting for this, but i am just
experimenting.
I figured out how to add them and the values are saved on the database.
What i now want to do, is to take the values and add them as a class on FLUID. This is where i stuck. I can not get the values. Any idea how to do it?
After this guide How to enable header_position in TYPO3 7.6
i manage to get my code that far:
On the folder /Configuration/TCA/Overrides/tt_content.php
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
ExtensionManagementUtility::addTCAcolumns('tt_content',[
'header_position_custom' => [
'exclude' => 1,
'label' => 'header position',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'items' => [
['left', 'left'],
['right', 'right'],
['center', 'center']
]
]
]
]);
ExtensionManagementUtility::addFieldsToPalette('tt_content', 'header', '--linebreak--,header_position_custom', 'after:header_layout');
ExtensionManagementUtility::addFieldsToPalette('tt_content', 'headers', '--linebreak--,header_position_custom', 'after:header_layout');
On the folder /Configuration/Typoscript/Constants/Base.typoscript
styles.templates.templateRootPath = EXT:my_website_base/Resources/Private/Extensions/Fluid_styled_content/Resources/Private/Templates/
styles.templates.partialRootPath = EXT:my_website_base/Resources/Private/Extensions/Fluid_styled_content/Resources/Private/Partials/
styles.templates.layoutRootPath = EXT:my_website_base/Resources/Private/Extensions/Fluid_styled_content/Resources/Private/Layouts/
On the /Resources/Private/Extensions/Fluid_styled_content/Resourcs/Private/Partials/Header.html
<h1 class="{positionClass} {header_position_custom} {data.header_position_custom} showed">
<f:link.typolink parameter="{link}">{header}</f:link.typolink>
</h1>
I 've put the class showed just to make sure that i am reading the
file from the path i gave on the constants
File ext_tables.php
TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile($_EXTKEY,'Configuration/TypoScript', 'Website Base');
File ext_tables.sql
CREATE TABLE tt_content (
header_position_custom varchar(255) DEFAULT '' NOT NULL,
);
With all these i get my selectbox where i wanted to be and i get the values on the database. That means that if i select the value "Center" in the selectbox, then it will be saved on the database. How can i get this value and use it as class on the FLUID?
Thanks in advance,
You will find your field in the data object.
For inspecting your fluid variables you can use the f:debug-VH:
<f:debug title="the data">{data}</f:debug>
for inspecting all (in the current context) available variables you can debug _all:
<f:debug title="all data">{_all}</f:debug>
Hint: use the title attribute to identify the output
and don't forget to write a get* and set* function for new fields!
I've been making some basic CRUD pages for my cakePHP app using the HtmlHelper for the views. This is handy for building forms but for date inputs the helper by default generates 3 select boxes for the date which is quite cumbersome to use.
HTML5 introduces the input[type=date] and most browsers now incorporate some nice native interfaces to deal with it; e.g. Chrome produces a nice date-picker for date inputs.
I know it is possible to make the HtmlHelper just make the input a text box instead of the 3 dropdown by doing the following:
echo $this->Form->input('my_date', array('type' => 'text'));
But when I do
echo $this->Form->input('my_date', array('type' => 'date'));
it ignores the 2nd arguement and goes back to the 3 selects.
Is there a way to get the helper to make a date input?
It seem the HtmlHelper has not yet evolved to make use of the "date" input.
If you tell the helper to generate the date input as a text field, adding a jQuery one-liner can convert it to a date input.
So:
echo $this->Form->input('my_date', array('type' => 'text'));
to generate the field. Then:
$('#idOfMyDate').attr('type', 'date');
To change it to a date input.
If anyone has a better way I'd be keen to hear it.
The CakePHP FormHelper uses Widgets to render different input types. For "datetime" types, it uses the DateTimeWidget per default.
To get a regular input with the attribute type="date", you just have to tell CakePHP which widget to use.
In the View (usually App\AppView.php), you can configure the FormHelper:
<?php
namespace App\View;
use Cake\View\View;
class AppView extends View
{
public function initialize() {
$this->loadHelper('Form', [
'widgets' => [
'datetime' => ['Basic'],
],
]);
}
}
?>
The BasicWidget is the most basic widget which is used to render regular text inputs.
Then, in your view, you can just use 'type' => 'date' as expected:
echo $this->Form->input('my_date', array('type' => 'date'));
Or, since CakePHP already sets the type to "date" since the database column is a datetime field you can just leave it like this:
echo $this->Form->input('my_date');
The result is a regular text input with type="date".
For future readers: In the most recent version of CakePHP, you would use the method Form::control instead of Form::input. Everything else still applies.
Try this:
echo $this->Form->text('my_date',array('type' => 'date');
Like this it'll work as a charm
<div class="form-group">
<label for="Description"><?php echo __('Date'); ?></label>
<div class='input-group date' id='datetimepicker1'>
<?php echo $this->Form->input('scheduled_date', array('label'=> false, 'div' => false, 'class'=>'form-control', 'type' => 'text')); ?>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
Some explanation:
'div' => false: it's necessary to desable the div rendered by input() FormHelper function
'label' => false: it's necessary to desable the label rendered by input() FormHelper function
Take a look at cake PHP form helper doc for more details
I solved this problem with jquery
PHP
<?= $this->Form->control('birth_date', ['value' => $birth_date->i18nFormat('yyyy-MM-dd'), 'type' => 'text']); ?>
JS
$('#birth-date').attr('type', 'date');
It's obvious that Cake's FormHelper is messing up with <input type "date">. Therefore I solved this problem the following way (in CakePHP 2.x)
Copy FormHelper.php from lib\Cake\View\Helper\
Paste it to app\View\Helper. Now Cake will use your Form Helper instead of its own.
Open the new FormHelper.php, go to protected function _getInput($args) {, search for case 'date': and change it from:
case 'date':
$options += array('value' => $selected);
return $this->dateTime($fieldName, $dateFormat, null, $options);
to:
case 'date':
return $this->{$type}($fieldName, $options);
Cake will now stop transforming <input type="date"> into select boxes.
Keep in mind that with every future release of Cake 2.x you will have to transfer possible changes in Cake's Form Helper into your own Form Helper manually.
I've got some problem with symfony form value (i guess it's the clean value, but not so clear yet). Here's the problem :
I got a sfFormDateJQueryUI widget setup like this in my form :
$this->setWidgets(array(
'needDate' => new sfWidgetFormDateJQueryUI(),
));
$this->setValidators(array(
'needDate' => new sfValidatorDate(array(
'required' => true,
'date_format' => '/^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$/',
'date_output' => 'd/m/Y'
)),
));
Then when i submit, say 26/06/2010, it turns out right in the HTTP Header (viewed via Firebug) and $request (i just print it). But after i get the value via
$formVal = $form->getValues();
the date value in $formVal["needDate"] become today's date (03/06/2010). I really don't understand, and after checking in the API documentation it says that the getValues will return the 'cleaned' value. Is that because of it ? I don't understand what's 'clean'.
Thanks before..
Somehow I solved the problem.
It turns out that the value can't validate, so when I changed the validator to:
'needDate' => new sfValidatorRegex(array(
'pattern' => '/^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$/'
))
everything works fine.