// in AppView
public function initialize() {
$this->loadHelper('Html');
$this->loadHelper('Form');
$this->loadHelper('Flash');
$this->loadHelper('Paginator');
}
// link
$this->Html->link(__'リンク', [
'action' => 'add',
'?' => ['id' => $user->id],
]);
// disuse escape for fontawesome
$this->Html->link(
"<i class='fa fa-edit'></i>",
['action' => 'edit', $user->id],
['escape' => false]
);
$this->Form->input()
について 3.4 からForm::input()
からForm::control()
に名称変更されてます。今のところどっちも同じ挙動ぽいけどさっさと変えたほうがいいのかしら。
またcontrol()
input()
は常に<div>
で WRAP されdate()
やtext()
は WRAP されない。もっと細かいカスタマイズをする場合は ウィジェットテンプレート なるものをカスタマイズする必要がある。だるい。参考 - CakePHP3 のFormHelperが生成するHTMLをカスタマイズしたい
echo $this->Form->create($user /* ← ここに Entity オブジェクトぶちこむ、なければ null を */ ,[
'type'=>'post',
'url'=>['controller'=>'Users', 'action'=>'index'],
'onsubmit' => 'return confirm(\'実行しますか?\');'
]);
echo $this->Form->hidden('id',['default'=>$id]);
echo $this->Form->input('name'); //スキーマからインプットタイプをよしなに
echo $this->Form->input('password',['label'=>'パスワード','type'='password');
// テンプレート編集しないでできるのはこんくらい
echo $this->Form->input('birthday', [
'label' => '誕生日',
'type' => 'date',
'dateFormat' => 'YMD',
'monthNames' => false,
'maxYear' => date('Y')+1,
'minYear' => date('Y')-100,
'empty' => ['year' => '年', 'month' => '月', 'day' => '日'],
// 'default' => date('Y-m-d'),
]);
// Date 日本対応
echo $this->Form->templates([
'dateWidget' => '<ul class="list-inline"><li class="year">{{year}} 年</li><li class="month"> {{month}} 月 </li><li class="day"> {{day}} 日 </li><li class="hour"> {{hour}} 時 </li><li class="minute"> {{minute}} 分 </li></ul>'
]);
echo $this->Form->input('start_datetime', array(
'type' => 'datetime',
'label' => '開始日時',
'dateFormat' => 'YMD',
'monthNames' => false,
'minYear' => date('Y'),
'maxYear' => date('Y')+1,
'default' => date('Y-m-d')
));
// その他
$this->Form->input('open', [
'type'=>'time', //日付なし
'format' => 24, //24h表記
'interval'=>15 //15分刻み
]);
$this->Form->text('class',[
'default'=>$default,
'readonly'=>'readonly' // text や textarea は readonly とかも可能
]);
<?php
/**
* @see Using material design lite.
*/
// In Controller
$colors = [
'red' => 'レッド',
'blue' => 'ブルー',
];
$colorOptions = [];
foreach ($COLORS as $key => $value) {
$colorOptions += [
'text' => $value,
'value' => $key,
'class' => 'mdl-color-text--white mdl-color--'.$key,
];
}
$this->set(compact('colorOptions'));
// In view.
<?php echo $this->Form->input('color', [
'options' => $colorOptions ?? [],
'empty' => '選択してください',
]) ?>
FormHelper でうまいこと POST データ練り上げて newEntity()
patchEntity()
なりに $this->request->getData()
を渡してあげると エンティティの関連データ (アソシエーション) を一括で save()
できる のでとっても便利。
/**
* Example Associations.
*
* - articles
* - belongsTo: authors
* - hasOne: profiles
* - hasMany: comments
* - belongsToMany: tags
*/
$this->Form->create($article);
// Article
echo $this->Form->hidden('id', ['value' => $article->id])
echo $this->Form->control('title');
// Article > Author (belongsTo)
echo $this->Form->control('author.id');
echo $this->Form->control('author.first_name');
echo $this->Form->control('author.last_name');
// Article > Author > Profile (belongsTo > hasOne)
echo $this->Form->control('author.profile.id');
echo $this->Form->control('author.profile.username');
// Article > Comments (hasMany)
echo $this->Form->control('comments.0.id');
echo $this->Form->control('comments.0.comment');
echo $this->Form->control('comments.1.id');
echo $this->Form->control('comments.1.comment');
// Article > Tags (belongsToMany) -- input-pattern
echo $this->Form->control('tags.0.id');
echo $this->Form->control('tags.0.name');
echo $this->Form->control('tags.1.id');
echo $this->Form->control('tags.1.name');
// Article > Tags (belongsToMany) -- select-pattern
echo $this->Form->control('tags._ids', [
'type' => 'select',
'multiple' => true,
'options' => $tagList,
]);
// Article > ArticleTags (belongsToMany, ['joinTable' => 'articles_tags'])
echo $this->Form->control('tags.0._joinData.starred');
echo $this->Form->control('tags.1._joinData.starred');
// in view
<?php echo $this->Form->postLink(
'<i class="tiny material-icons md-18">delete</i> 削除',
[
'action' => 'delete',
$event->id,
],
[
'confirm' => '削除しますか?',
'method' => 'delete',
'escape' => false,
'class' => 'btn waves-effect waves-light red accent-4',
'tabindex' => -1 // タブで選択しないようにするやつ
]
) ?>
// in controller
public function delete(int $id=null) {
$this->request->allowMethod(['delete']);
$event = $this->Events->get($id);
if ($this->Events->delete($event)) {
$this->Flash->success(MSG_DELETE_SUCCESS);
} else {
$this->Flash->error(MSG_DELETE_ERROR);
}
return $this->redirect(['action' => 'index']);
}
通常 Form タグネストはできないが Form ヘルパーで作った Form 内で postLink()
を ['block' => true]
で生成し Form の外で $this->fetch()
でバッファリングする手段で実装できちゃう。ごいすー!
<?= $this->Form->create($hoge, ['type' => 'file']) ?>
<?= $this->Form->postLink(__('画像を削除'),
['controller' => 'Hoges', 'action' => 'deleteImage', $hoge->id],
['block' => true, 'confirm' => __('画像を削除しますか?')]
)
?>
<?= $this->Form->button(__('保存')) ?>
<?= $this->Form->end() ?>
<?= $this->fetch('postLink') ?>
- http://book.cakephp.org/3.0/en/views/helpers/form.html#creating-file-inputs
- http://stackoverflow.com/questions/29648335/cakephp-3-0-uploading-images
// In View.
echo $this->Form->create($Users, [
'url' => ['action' => 'confirm'],
'type' => 'post',
'enctype' => 'multipart/form-data', // 'type' => 'file' でもよいケドこっちのが安定している気がする...
]);
echo $this->Form->input('img_data',['type'=>'file']);
echo $this->Form->hidden('img_user',['value'=>$user['id']]);
echo $this->Form->button('登録', ['class' => 'c-btn']);
echo $this->Form->end();
// In Controller
try {
$fileName = $this->request->data('file.name');
$fileTmp = $this->request->data('file.tmp_name');
$fileSize = $this->request->data('file.size');
$FileApi = new File($fileTmp);
$fileExt = pathinfo($fileName, PATHINFO_EXTENSION);
$filePath = $fileName.'.'.$fileExt;
$fileDest = FILE_DEST.'/'.$filePath;
// Verify it that allowed extension.
if (!in_array($fileExt, ALLOW_EXTENSIONS)) throw new \Exception('Denied file extensions.');
// Validation of file size.
if ($fileSize > UPLOAD_FILE_SIZE_MAX) throw new \Exception('Denied over file size.');
$FileApi->copy($fileDest);
$FileApi->close();
$this->Flash->success('Upload was success.');
} catch (\Exception $e) {
if (!empty($FileApi)) $FileApi->close();
$this->Flash->error($e->getMessage());
}
return $this->redirect($this->referer());