How can I create cakephp 3 custom template - cakephp

I am new in cakephp 3.
I want to create form helper that will generate code like this.
<div class="form-group">
<label for="inputEmail3" class="col-sm-3 control-label">Email</label>
<div class="col-sm-9">
<input type="email" class="form-control" id="inputEmail3" placeholder="Email" required="">
</div>
</div>
I am using this
<?php
$myTemplates = [
'inputContainer' => '<div class="form-group">{{label}}<div class="col-sm-9">{{input}}</div></div>',
'inputContainerError' => '<div class="input {{class}} {{type}}{{required}} error">{{content}}{{error}}</div>'
];
?>
<?= $this->Form->create('Users',['templates' => $myTemplates]) ?>
<?= $this->Form->input('email',['class' => 'form-control','templates' => ['formGroup' => '{{input}}{{label}}']]) ?>
But it will generate wrong

Per the docs - to change theme inline at runtime use setTemplate:
$myTemplates = [
'inputContainer' => '<div class="form-group">{{label}}<div class="col-sm-9">{{input}}</div></div>',
'inputContainerError' => '<div class="input {{class}} {{type}}{{required}} error">{{content}}{{error}}</div>'
];
?>
<?= $this->Form->create('Users') ?>
<? $this->Form->setTemplates($myTemplates); ?>
<?= $this->Form->input('email',['class' => 'form-control','templates' => ['formGroup' => '{{input}}{{label}}']]) ?>
You can't use the templates option on the Form for a dynamic template, it will only look for a config file listing template items in /config.

First of all create Template code
<?php $myTemplates = [
'label' => '<label class="col-sm-3 col-form-label">{{text}}</label>',
'select' => '<div class="col-sm-9"><select class="form-control" name="{{name}}"{{attrs}}>{{content}}</select></div>',
'input' => '<div class="col-sm-9"><input class="form-control" type="{{type}}" name="{{name}}"{{attrs}}></div>',
'inputContainer' => '<div class="form-control">{{content}}</div>',
'inputSubmit' => '<input type="{{type}}"{{attrs}}>',
'inputContainer' => '<div class="form-group row">{{content}}</div>',
'submitContainer' => '<div class="form-group row"><label class="col-sm-3 col-form-label"> </label><div class="col-sm-9 ">{{content}}</div></div>',
]; ?>
Now Use this template code inside in form
<?php echo $this->Form->create($schoolAccount); ?>
<?php $this->Form->setTemplates($myTemplates); ?>
<?php echo $this->Form->control('account_holder',['label'=>'Name of Account Holder']); ?>
<?php echo $this->Form->end(); ?>

Related

CakePHP 3.x - File Upload Results in Token Mismatch

I have a form that is type => file, with an file upload control.
When I submit this form without a file, it submits as expected.
However, When I submit the form with a file attached, I get a CSRF Token Mismatch.
Any ideas why this might be happening?
EDIT: I noticed that the csrf token is the same when i refresh the page, maybe this is part of the problem?
EDIT-2: When I disable the CSRF protection, the $this->request->getData() array is empty
EDIT-3: I have hooked XDebug up and these are the results...
Apparently $post and $header are null/empty on line 194, resulting in token mismatch
Here is my Form
<div class="col-lg-offset-1 col-lg-10">
<?php if(isset($ledger->id)) { ?>
<?= $this->Form->create($ledger, ['url' => '/shortcut/ledger_save/' . $ledger->id, 'type' => 'file', 'class' => 'form-horizontal']); ?>
<?php } else { ?>
<?= $this->Form->create($ledger, ['url' => '/shortcut/ledger_new', 'type' => 'file', 'class' => 'form-horizontal']); ?>
<?php } ?>
<?php $this->Form->setTemplates(['inputContainer' => '{{content}}', 'submitContainer' => '{{content}}']); ?>
<!-- Default box -->
<div class="box">
<div class="box-header with-border">
<?php if(isset($ledger->id)) { ?>
<h3 class="box-title">Edit <?= $ledger->ledger_title ?> Form</h3>
<?php } else { ?>
<h3 class="box-title">Create Ledger Form</h3>
<?php } ?>
</div>
<div class="box-body">
<div class="form-group">
<center>
<?php if($ledger->disabled == 'n') { ?>
<?= $this->Form->control('disabled', ['type' => 'checkbox', 'label' => false, 'class' => 'minimal']) ?> Check to disable (hide) ledger.
<?php } else { ?>
<?= $this->Form->control('disabled', ['type' => 'checkbox', 'label' => false, 'class' => 'minimal', 'checked']) ?> Uncheck to enable (show) ledger.
<?php } ?>
</center>
</div>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">Ledger Title</label>
<div class="col-sm-10">
<?= $this->Form->control('ledger_title', ['label' => false, 'class' => 'form-control', 'placeholder' => 'Ledger Title', 'autofocus']) ?>
</div>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">Total Plates</label>
<div class="col-sm-10">
<?= $this->Form->control('total_plates', ['label' => false, 'class' => 'form-control', 'placeholder' => 'Total Plates (Total Images)']) ?>
</div>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">Total Pages</label>
<div class="col-sm-10">
<?= $this->Form->control('total_pages', ['label' => false, 'class' => 'form-control', 'placeholder' => 'Total Pages (Total Physical Pages)']) ?>
</div>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">Check Tribes</label>
</div>
<div class="form-group">
<?php $x = 0; ?>
<?php foreach($tribes as $tribe) { ?>
<?php if($x == 0) { echo '<div class="form-group"><div class="col-sm-3"> </div>'; } ?>
<div class="col-sm-4">
<?php if(in_array($tribe->id, $ledger_tribes)) { ?>
<?= $this->Form->control('tribe_id[]', ['type' => 'checkbox', 'label' => false, 'class' => 'minimal', 'value' => $tribe->id, 'checked']) ?> <?= $tribe->name ?>
<?php } else { ?>
<?= $this->Form->control('tribe_id[]', ['type' => 'checkbox', 'label' => false, 'class' => 'minimal', 'value' => $tribe->id]) ?> <?= $tribe->name ?>
<?php } ?>
</div>
<?php $x = $x + 1; ?>
<?php if($x == 2) { echo '</div>'; $x = 0; } ?>
<?php } ?>
<?php if($x == 1) { echo '</div>'; $x = 0; } ?>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">Custodian</label>
<div class="col-sm-10">
<?= $this->Form->control('custodian', ['type' => 'textarea', 'label' => false, 'class' => 'form-control', 'style' => 'width: 100%', 'placeholder' => 'Custodian']) ?>
<?php if(!isset($ledger->overwrite_custodian) || $ledger->overwrite_custodian == 'n') { ?>
<?= $this->Form->control('overwrite_custodian_checkbox', ['type' => 'checkbox', 'label' => false, 'class' => 'minimal', 'value' => 'y']); ?> Overwrite Plate Custodian
<?php } else { ?>
<?= $this->Form->control('overwrite_custodian_checkbox', ['type' => 'checkbox', 'label' => false, 'class' => 'minimal', 'value' => 'y', 'checked']); ?> Overwrite Plate Custodian
<?php } ?>
</div>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">Image Source</label>
<div class="col-sm-10">
<?= $this->Form->control('image_source', ['label' => false, 'type' => 'text', 'class' => 'form-control', 'placeholder' => 'Image Source']) ?>
</div>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">Provenance</label>
<div class="col-sm-10">
<?= $this->Form->control('provenance', ['type' => 'textarea', 'label' => false, 'class' => 'form-control', 'style' => 'width: 100%', 'placeholder' => 'Provenance']) ?>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Global Keywords</label>
<div class="col-sm-10">
<?php $keywordOptions = []; ?>
<?php $keywordValues = []; ?>
<?php $foundKeywords = []; ?>
<?php foreach($keywords as $keyword) { ?>
<?php if(trim($keyword->keyword) == '') { continue; } ?>
<?php $keywordOptions[$keyword->keyword] = $keyword->keyword; ?>
<?php if(in_array($keyword->keyword, $ledger_keywords)) { $keywordValues[$keyword->id] = $keyword->keyword; $foundKeywords[] = $keyword->keyword; } ?>
<?php } ?>
<?= $this->Form->select('keyword', $keywordOptions, ['class' => 'form-control select2', 'value' => $keywordValues, 'multiple' => true]); ?>
</div>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">Additional Keywords</label>
<div class="col-sm-10">
<?php $additionalKeywords = ''; ?>
<?php foreach($ledger_keywords as $keyword) { ?>
<?php if(in_array($keyword, $foundKeywords) == false) { ?>
<?php $additionalKeywords = $additionalKeywords . $keyword . ', '; ?>
<?php } ?>
<?php } ?>
<?php $additionalKeywords = substr($additionalKeywords, 0, strlen($additionalKeywords) - 2); ?>
<?= $this->Form->control('additional_keywords', ['type' => 'textarea', 'value' => $additionalKeywords, 'label' => false, 'class' => 'form-control', 'style' => 'width: 100%', 'placeholder' => 'Additional Keywords']) ?>
<p class="help-block">Seperated by commas.</p>
</div>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">Arist</label>
<div class="col-sm-10">
<?= $this->Form->control('artist', ['label' => false, 'class' => 'form-control', 'placeholder' => 'Artist']) ?>
</div>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">Media</label>
<div class="col-sm-10">
<?= $this->Form->control('media', ['label' => false, 'class' => 'form-control', 'placeholder' => 'Media']) ?>
</div>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">Dimensions</label>
<div class="col-sm-10">
<?= $this->Form->control('dimensions', ['label' => false, 'class' => 'form-control', 'placeholder' => 'Dimensions']) ?>
</div>
</div>
<?php if(!isset($ledger->id)) { ?>
<div class="form-group">
<label for="exampleInputFile" class="col-sm-2 control-label">Batch Upload</label>
<div class="col-sm-10">
<?= $this->Form->file('uploadfile', array('label' => false, 'type' => 'file')) ?>
<p class="help-block">Select the ledger images archive here.</p>
</div>
</div>
<?php } ?>
</div>
<!-- /.box-body -->
<div class="box-footer">
<?= $this->Form->button('Submit', ['type' => 'submit', 'class' => 'btn btn-success btn-pill pull-right']) ?>
</div>
<!-- /.box-footer-->
</div>
<?= $this->Form->end() ?>
<!-- /.box -->
</div>
Here is the Form html output
<!-- Main content -->
<section class="content">
<div class="col-lg-offset-1 col-lg-10">
<form enctype="multipart/form-data" method="post" accept-charset="utf-8" class="form-horizontal" action="/shortcut/ledger_new"><div style="display:none;"><input type="hidden" name="_method" value="POST"/><input type="hidden" name="_csrfToken" autocomplete="off" value="06d11527d1e431fd1d1b73a6b96e9af1eec6a1fd6c2ede60cfdb06afdcff5b3c02216614f61ba68bf1bf0beeba8b5f7500319ec94ec278141ee4f480b4a4505f"/></div>
..... SNIPPED TO MAKE MAX CHARS ALLOWED ....
<div class="box-footer">
<button type="submit" class="btn btn-success btn-pill pull-right">Submit</button> </div>
<!-- /.box-footer-->
</div>
</form> <!-- /.box -->
</div>
</section>
Here is the inspection headers
Here is the inspection headers without the file upload populated, as you can see, in the above picture there is no Form Data, and in the below picture there is.
The post_max_size inside the /etc/php.ini file was set to 8M, it has to be set larger than the uploaded file size.
So, what I did was, I set
post_max_size = 80M
and I set
upload_max_filesize = 60M
and the form submitted as expected after that

cahephp formhelper template for generate chekbox

I am using cakephp formhelper and I want to generate checkbox
I want cakephp to generate checkbox like this
<div class="form-group form-md-line-input">
<label class="col-md-2 control-label"
for="form_control_1">checkbox_title</label>
<div class="col-md-10">
<div class="md-checkbox-inline">
<div class="md-checkbox">
<input id="***this_part_should_be_match"
class="md-check"
type="checkbox">
<label for="***this_part_should_be_match">
<span></span>
<span class="check"></span>
<span class="box"></span>
</label>
</div>
</div>
</div>
</div>
This formhelper config
[
'button' => '<button{{attrs}}>{{text}}</button>' ,
'checkbox' => '<input type="checkbox" name="{{name}}" value="{{value}}"{{attrs}}>' ,
'checkboxFormGroup' => '<label class="col-lg-2 control-label">{{label}}</label><div class="col-md-10"> <div class="md-checkbox-list"><div class="md-checkbox"><input id="{{id}}" class="md-check" type="checkbox">
<label for="{{id}}">
<span></span>
<span class="check"></span>
<span class="box"></span></label></div></div></div>' ,
'checkboxWrapper' => '<div class="">{{label}}</div>' ,
'dateWidget' => '{{year}}{{month}}{{day}}{{hour}}{{minute}}{{second}}{{meridian}}' ,
'error' => '<div class="error-message">{{content}}</div>' ,
'errorList' => '<ul>{{content}}</ul>' ,
'errorItem' => '<li>{{text}}</li>' ,
'file' => '<input type="file" name="{{name}}"{{attrs}}>' ,
'fieldset' => '<fieldset{{attrs}}>{{content}}</fieldset>' ,
'formStart' => '<form class="form-horizontal" {{attrs}}><div class="form-body">' ,
'formEnd' => '</div> </form>' ,
'formGroup' => '{{label}}<div class="col-md-10">{{input}}<div class="form-control-focus"> </div></div>' ,
'hiddenBlock' => '<div style="display:none;">{{content}}</div>' ,
'input' => '<input class="form-control" type="{{type}}" name="{{name}}"{{attrs}}/>' ,
'inputSubmit' => '<input type="{{type}}"{{attrs}}/>' ,
'inputContainer' => '<div class="form-group form-md-line-input">{{content}}</div>' ,
// 'inputContainer' => '<div class="input {{type}}{{required}}">{{content}}</div>' ,
'inputContainerError' => '<div class="input {{type}}{{required}} error">{{content}}{{error}}</div>' ,
'label' => '<label class="col-md-2 control-label" {{attrs}}>{{text}}</label>' ,
'nestingLabel' => '{{hidden}}<label{{attrs}}>{{input}}{{text}}</label>' ,
'legend' => '<legend>{{text}}</legend>' ,
'multicheckboxTitle' => '<legend>{{text}}</legend>' ,
'multicheckboxWrapper' => '<fieldset{{attrs}}>{{content}}</fieldset>' ,
'option' => '<option value="{{value}}"{{attrs}}>{{text}}</option>' ,
'optgroup' => '<optgroup label="{{label}}"{{attrs}}>{{content}}</optgroup>' ,
'select' => '<select class="form-control" name="{{name}}"{{attrs}}>{{content}}</select>' ,
'selectMultiple' => '<select name="{{name}}[]" multiple="multiple"{{attrs}}>{{content}}</select>' ,
'radio' => '<input type="radio" name="{{name}}" value="{{value}}"{{attrs}}>' ,
'radioWrapper' => '{{label}}' ,
'textarea' => '<textarea class="form-control" name="{{name}}"{{attrs}}>{{value}}</textarea>' ,
'submitContainer' => '<div class="">{{content}}</div>' ,
]
And currently it generate this
<div class="form-group form-md-line-input">
<label class="col-lg-2 control-label">
<input class="form-control"
name="active"
value="0"
type="hidden">
<label for="active">
<input name="active"
value="1"
id="active"
checked="checked"
type="checkbox">
Active
</label>
</label>
<div class="col-md-10">
<div class="md-checkbox-list">
<div class="md-checkbox">
<input id=""
class="md-check"
type="checkbox">
<label for="">
<span></span>
<span class="check"></span>
<span class="box"></span></label>
</div>
</div>
</div>
</div>
I'm wondering what should be my config to cakephp generate chekboxes as I want
in the theme I am using id="***this_part_should_be_match" and for="***this_part_should_be_match" should be the same to displays properly
I'm using cakephp 3.5 but I think it should be same in 3.*
I`ll appreciate any help
Add this to the config
'checkboxContainer' => '<div class="form-group form-md-line-input"><label class="col-md-2 control-label" for="form_control_1">{{title}}</label>
<div class="col-md-10">
<div class="md-checkbox-inline">
<div class="md-checkbox">
{{content}}{{label}}
<span></span>
<span class="check"></span>
<span class="box"></span>
</label>
</div>
</div>
</div>
</div>'
You'll have to set the title with the templateVars option when generating the checkbox
$this->Form->control('some_checkbox', ['type' => 'checkbox', 'templateVars' => ['title' => 'checkbox_title']);

How to properly customize CakePHP3 FormHelpers Radio buttons [duplicate]

Cakephp 3 create a radio container with label -> input like that
<div class="radio">
<label class="radio-acces-checked" for="condition-access-1">
<input id="condition-access-1" type="radio" value="1" name="condition_access">
Free access
</label>
</div>
...
I would like change structure but it does not work, it's always the same strucure... Do you have an idea about how to solve my problem ?
$myTemplates = [
'radioWrapper' => '<div class="radio">{{label}}{{input}}</div>'
];
echo $this->Form->radio('condition_access', [
['value' => 1, 'text' => __('Free Access')],
['value' => 2, 'text' => __('Payment Access')],
['value' => 3, 'text' => __('Reduce price')]
]);
You need to set the nestingLabel template:
echo $this->Form->input('condition_access', [
'type' => 'radio',
'options' => [
['value' => 1, 'text' => __('Free Access')],
['value' => 2, 'text' => __('Payment Access')],
['value' => 3, 'text' => __('Reduce price')]
],
'templates' => [
'nestingLabel' => '{{hidden}}<label{{attrs}}>{{text}}</label>{{input}}',
'radioWrapper' => '<div class="radio">{{label}}</div>'
]
]);
Output:
<div class="input radio">
<label>Condition Access</label>
<input name="condition_access" value="" type="hidden">
<div class="radio">
<label for="condition-access-1">Free Access</label>
<input name="condition_access" value="1" id="condition-access-1" type="radio">
</div>
<div class="radio">
<label for="condition-access-2">Payment Access</label>
<input name="condition_access" value="2" id="condition-access-2" type="radio">
</div>
<div class="radio">
<label for="condition-access-3">Reduce price</label>
<input name="condition_access" value="3" id="condition-access-3" type="radio">
</div>
</div>

CakePHP Form Error to add a class

Is there a way to test if a particular text field has an error so that i can add a Class to highlight the who text box
<div class="form-group">
<?php echo $this->Form->label('name', 'Name:', array('class' => 'col-sm-2 control-label')); ?>
<div class="col-sm-10">
<?php echo $this->Form->text('name', array('required' => false, 'class' => 'form-control input-lg')); ?>
<?php echo $this->Form->error('name', null, array('class' => 'label label-block label-danger text-left', 'wrap' => 'label')); ?>
</div>
</div>
i want to add has-error to <div class="form-group"> div if name has any errors
You can use
$this->Form->isFieldError('fieldname');
<div class="form-group <?= ($this->Form->isFieldError('name'))? 'has-error': '' ; ?>">
<?php echo $this->Form->label('name', 'Name:', array('class' => 'col-sm-2 control-label')); ?>
<div class="col-sm-10">
<?php echo $this->Form->text('name', array('required' => false, 'class' => 'form-control input-lg')); ?>
<?php echo $this->Form->error('name', null, array('class' => 'label label-block label-danger text-left', 'wrap' => 'label')); ?>
</div>
</div>

CakePHP & Twitter Bootstrap horizontal form with nested inline form

I am using the TwitterBootstrap Plugin for CakePHP2.x. And I can't get the combination of a horizontal form with a nested inline form to work.
part of my code:
<?php
echo $this->Form->create('Event', array('class' => 'form-horizontal'));
echo $this->Form->input('Event.short_name',array(
'label' => 'Short name',
'type' => 'text',
'class' => 'span5'
));
?>
<div class="control-group">
<div class="control-label">Date & Time</div>
<div class="controls form-inline">
<div class=" input-append">
<?php
echo $this->Form->input('Event.start_date', array(
'label' => false,
'type' => 'text',
'class' => 'span2 start_date',
'after' => '<span class="add-on datetime"><span class="icon-calendar"></span></span>'
));
echo $this->Form->input('Event.end_date', array(
'label' => false,
'type' => 'text',
'class' => 'span2 end_date',
'after' => '<span class="add-on"><span class="icon-calendar"></span></span>'
));
?>
</div>
</div>
</div>
In the above example this happens:
and the generated html
<div class="control-group">
<div class="control-label">Date & Time</div>
<div class="controls form-inline">
<div class=" input-append">
<div class="control-group">
<div class="controls">
<input name="data[Event][start_date]" class="span2 start_date" type="text" value="2013-06-15" id="EventStartDate" required="required"><span class="add-on"><span class="icon-calendar"></span></span>
</div>
</div>
<div class="control-group">
<div class="controls">
<input name="data[Event][end_date]" class="span2 end_date" type="text" value="2013-06-22" id="EventEndDate" required="required"><span class="add-on"><span class="icon-calendar"></span></span>
</div>
</div>
</div>
</div>
</div>
When I add 'div' -> false to the two date form field they move inline but the padding etc is gone.
and the generated html
<div class="control-group">
<div class="control-label">Date & Time</div>
<div class="controls form-inline">
<div class=" input-append">
<input name="data[Event][start_date]" class="span2 start_date" type="text" value="2013-06-15" id="EventStartDate" required="required"><span class="add-on"><span class="icon-calendar"></span></span>
<input name="data[Event][end_date]" class="span2 end_date" type="text" value="2013-06-22" id="EventEndDate" required="required"><span class="add-on"><span class="icon-calendar"></span></span>
</div>
</div>
</div>
I think this is due to the fact that all form fields are placed in controls divs... Does anyone know how to solve this?
I also posted this as an issue on the GitHub page, since I think it has to do with the plugin, but I hope someone knows a temp workarround.
Maybe this could work. I used it before and it looks like this:
<?php echo $this->Form->create('Event', array(
'class' => 'form-horizontal',
'inputDefaults' => array(
'format' => array('before', 'label', 'between', 'input', 'error', 'after'),
'div' => array('class' => 'control-group'),
'label' => array('class' => 'control-label'),
'between' => '<div class="controls">',
'after' => '</div>',
'error' => array('attributes' => array(
'wrap' => 'span', 'class' => 'help-inline'
)),
)));?>
<fieldset>
<?php echo $this->Form->input('Event.start_date', array(
'label' => array('class' => 'control-label',
'text' => 'start date'),
));?>
</fieldset>
<?php echo $this->Form->end();?>
The issue might be conflict between TB and Cake about float and clear, because cake.generic.css sets for form div clear:both which moves elements below instead of next to.
Try this:
div.form-inline div{
clear: none;
}

Resources