CakePHP 3 input type file design - php

I want to set span before input type file. Here is my existing code.
<?= $this->Form->input('logo', ['onchange'=>'onFileImage(this);',
'label' => false,
'type' => 'file',
'class'=>'']);?>
<lable class="inva_img"></lable>
I want the output to resemble the code below.
<span class="btn btn-default btn-file">
<span>Choose file</span>
<input type="file" name="logo" id="logo" onchange="onFileImage(this);" />
</span>

You can do it by below code
<?php
echo $this->Form->input('logo', [
'templates' => [
'inputContainer' => '<span class="input file required btn btn-default input {{type}}{{required}}"><span>Choose file</span>{{content}}</span>',
],
'onchange'=>'onFileImage(this);',
'class' => 'form-control',
'type' => 'file',
'label' => false
]);
?>
For details please see ndm ans.

<span class="btn btn-default btn-file">
<span>Choose file</span>
<input type="file" name="logo" id="logo" onchange="onFileImage(this);" />
</span>
Just replace <input> tag field with cakephp standard keeping others code unchanged. Here is the conversion:
<span class="btn btn-default btn-file">
<span>Choose file</span>
<?php
echo $this->Form->input(
'logo', array(
'id' => 'logo',
'type' => 'file',
'onchange' => 'onFileImage(this);'
)
);
?>
</span>

try the before/after options
echo $this->Form->input('field_name', array(
'before' => '-before-',
'after' => '-after-',
'between' => '-between-'
));
read more of this in cakephp book.

try this for cakephp2:
<?php
$this->Form->input('logo', ['onchange'=>'onFileImage(this);',
'label' => false,
'before' => '<span class="btn btn-default btn-file"><span>Choose file</span>',
'after' => '</span>',
'type' => 'file',
'class'=>'']);
I hope that there is similar concept for cakephp3
HTH.

Related

Difficult decorators for file input

I need this markup for file input:
<label class="col-sm-12">File upload</label>
<div class="col-sm-12">
<div class="fileinput fileinput-new input-group" data-provides="fileinput">
<div class="form-control" data-trigger="fileinput">
<i class="glyphicon glyphicon-file fileinput-exists"></i>
<span class="fileinput-filename"></span>
</div>
<span class="input-group-addon btn btn-default btn-file">
<span class="fileinput-new">Select file</span>
<span class="fileinput-exists">Change</span>
<input type="file" name="...">
</span>
<a href="#" class="input-group-addon btn btn-default fileinput-exists" data-dismiss="fileinput">Remove</a
</div>
<ul class="errors">
<li>Some error</li>
</ul>
</div>
I tried it like that:
<label class="col-sm-12">Attachment</label>
<div class="col-sm-12">
<?php echo $this->form->attachment; ?>
</div>
With very difficult decorator:
$this->fileDecorator = array(
array(
array('divOpen' => 'HtmlTag'), array('tag' => 'div', 'class' => 'form-control', 'data-trigger' => 'fileinput', 'openOnly' => true, 'placement' => Zend_Form_Decorator_Abstract::APPEND)
),
array(
array('i' => 'HtmlTag'), array('tag' => 'i', 'class' => 'glyphicon glyphicon-file fileinput-exists', 'placement' => Zend_Form_Decorator_Abstract::APPEND)
),
array(
array('span' => 'HtmlTag'), array('tag' => 'span', 'class' => 'fileinput-filename', 'placement' => Zend_Form_Decorator_Abstract::APPEND)
),
array(
array('divClose' => 'HtmlTag'), array('tag' => 'div', 'closeOnly' => true, 'placement' => Zend_Form_Decorator_Abstract::APPEND)
),
array(
array('spanOpen' => 'HtmlTag'), array('tag' => 'span', 'class' => 'input-group-addon btn btn-default btn-file', 'openOnly' => true, 'placement' => Zend_Form_Decorator_Abstract::APPEND)
),
array(
'Callback',
array('callback' =>
function($content, $element, $options) {
return "<span class=\"{$options['class']}\">{$options['text']}</span><span class=\"{$options['class2']}\">{$options['text2']}</span>";
},
'class' => 'fileinput-new',
'text' => $this->translator->_('_selectFile'),
'class2' => 'fileinput-exists',
'text2' => $this->translator->_('_change')
)
),
'File',
array(
array('spanClose' => 'HtmlTag'), array('tag' => 'span', 'closeOnly' => true, 'placement' => Zend_Form_Decorator_Abstract::APPEND)
),
array(
'Callback',
array('callback' =>
function($content, $element, $options) {
return "{$options['text']}";
},
'class' => 'input-group-addon btn btn-default fileinput-exists',
'text' => $this->translator->_('_remove'),
'data-dismiss' => 'fileinput'
)
),
array(
array('div' => 'HtmlTag'), array('tag' => 'div', 'class' => 'fileinput fileinput-new input-group', 'data-provides' => 'fileinput')
),
'Errors'
);
But problem is, that Callback can be only once in decorator (not like HtmlTag). And tag with content is not possible add without callback. It can be solved with more callbacks or differently?
Edit:
I have idea. Is possible to add File decoratror to Callback decorator?
It is simple like that:
<div class="form-group<?php echo count($this->form->attachment->getErrors()) ? ' has-error has-feedback' : null; ?>">
<label class="col-sm-12"><?php echo $this->form->attachment->renderLabel(); ?></label>
<div class="col-sm-12">
<div class="fileinput fileinput-new input-group" data-provides="fileinput">
<div class="form-control" data-trigger="fileinput">
<i class="glyphicon glyphicon-file fileinput-exists"></i>
<span class="fileinput-filename"></span>
</div>
<span class="input-group-addon btn btn-default btn-file">
<span class="fileinput-new">Select file</span>
<span class="fileinput-exists">Change</span>
<?php echo $this->form->attachment->renderFile(); ?>
</span>
Remove
</div>
<?php echo $this->formErrors($this->form->attachment->getMessages()); ?>
</div>
</div>

Create icon inside of input with bootstrap and cakePHP

I have this cakePHP code:
<?php
echo $this->Form->input('about_me',
array('label' => __l('About Me'),
'class' => 'form-control',
'before' => '<div class="form-group form-group-icon-left"><i class="fa fa-user input-icon input-icon-show"></i>',
'after' => '</div>',
array('escape' => false)
)
);
?>
I would like the output to be (indented for readability):
<div class="col-md-6">
<div class="form-group form-group-icon-right"><i class="fa fa-map-marker input-icon"></i>
<label>About me</label>
<input class="form-control" placeholder="Write something" type="text" />
</div>
Anyone can help?
My solution was like this:
<div class="form-group form-group-icon-right">
<i class="fa fa-map-marker input-icon"></i>
<?= $this->Form->input('about_me', [
'div' => false,
'label' => 'About me',
'placeholder' => 'Write something',
];?>
</div>
I usually set 'label' => false, used the CakePHP function only for the input field and customized the structure in pure HTML.
Skatch's answer is good, but you would need to modify it further to make sure it takes into account validation. If you don't use the form helper for the wrapping div you don't get the error and required classes generated for you where appropriate.
It looks like you're almost there with your example code. However, rather than set the <div> in the after and before properties use the div property to define the <div> class:-
<div class="col-md-6">
<?php
echo $this->Form->input('about_me',
array('label' => __l('About Me'),
'class' => 'form-control',
'before' => '<i class="fa fa-user input-icon input-icon-show"></i> ',
'div' => 'form-group form-group-icon-left',
'placeholder' => 'Write something'
)
);
?>
</div>
You can also define the placeholder as a property of the input as shown. You shouldn't need to use 'escape' => false.

How to load remote Modal content in yii2

I have been trying to load remote content for different bootstrap modal on same yii2 view
<?php
$label = $model->getAttributeLabel('educationId');
$addon = [
'prepend' => [
'content' => Html::icon('book')
],
'append' => [
'content' => Html::button(
Html::icon('plus'), [
'class' => 'btn btn-success',
'title' => 'Add New' . $label,
'onclick' => new JsExpression('showModal();'),
]
),
'asButton' => true
]
];
echo Html::tag('label',$model->getAttributeLabel('educationId'), ['class'=>'control-label']);
echo Select2::widget([
'model' => $model,
'attribute' => 'educationId',
'data' => ArrayHelper::map ( EducationLevel::find ()->all (), 'id', 'name' ),
'options' => ['placeholder' => 'Select Education Level ...','template' => 'label}\n{error}'],
'addon' => $addon,
'pluginOptions' => [
'maximumInputLength' => 10
],
]);
JS function
Function showModal(){
$('#addEducationModal').modal({
remote: 'modal.html',
show: true
});
}
So the user will click on the addon button of a text field and the modal will show up, and other text fields shall have same mechanism with different modal content.
However all what I get is faded background.
I was able to make it work and more than that.
The issue i had mainly because the yii cashes generated files so to resolve i deleted the generated files and made sure the content is generated fresh :)
and i havent used the JQuery load function.
see below code:
PHP View Code
$label = $model->getAttributeLabel('majorId');
$addon = [
'prepend' => [
'content' => Html::icon('book')
],
'append' => [
'content' => Html::button(Html::icon('plus'), [
'class' => 'btn btn-success',
'title' => 'Add New' . $label ,
'data-toggle' => 'modal',
'data-target' => '#addModal',
'href'=> 'addMajorModal.html',
]),
'asButton' => true
]
];
echo Html::tag('label',$model->getAttributeLabel('majorId'),['class'=>'control-label']);
echo Select2::widget([
'model' => $model,
'attribute' => 'majorId',
'data' =>ArrayHelper::map ( Major::find ()->all (), 'id', 'name' ),
'options' => ['placeholder' => 'Select Major ...','template' => 'label}\n{error}'],
'addon' => $addon,
'pluginOptions' => [
'maximumInputLength' => 10
],
]);
<div class="modal fade" id="addModal" >
<div class="modal-dialog" dir="rtl">
<div class="modal-content" dir="rtl">
<!-- Content will be loaded here from "addMajorModal.html" file -->
</div>
</div>
</div>
The Modal file content
<div class="modal-header panel-primary" dir="rtl" horizantal-aligned="">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">إضا�ة جديد</h4>
</div>
<div class="modal-body" dir="rtl">
<div id="login-boxs" class="login-popup>
<form id="newCat" method="post" class="signin" dir="rtl" action="#">
<div class="form-group">
<label for="certName" class="control-label">مسمى التخصص </label>
<input type="text" name="name" data-val="true" data-val-required="ErrMsg" data-rule-required="true" placeholder="مسمى الشهادة" class="form-control" id="certName">
</div>
<div class="form-group">
<label for="certShortDesc" class="control-label">وص� قصير </label>
<input type="text" name="shdesc" data-rule-required="true" placeholder="وص� قصير" class="form-control" id="certShortDesc" required>
</div>
</form>
</div>
</div>
<div class="modal-footer" dir="rtl">
<div class="col-lg-6" dir="rtl">
<div class="progress" >
<div class="progress-bar progress-bar-striped" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 100%;" id="progresBarUpload">
</div>
</div>
</div>
<div class="col-lg-6" dir="rtl">
<button type="button" class="btn btn-danger" dir="rtl" data-dismiss="modal"><i class="glyphicon glyphicon-remove"> </i>Close</button>
<button id="submitButton" type="button" dir="rtl" class="btn btn-primary" onclick="createCertificate()"><i class="glyphicon glyphicon-ok"> </i>Save changes</button>
</div>
</div>
Thats all, with this the modal will be loaded based on yii append generation of the HTML
As far as i know, this will be workable till Bootstrap 3.3 as remote content will be deprecated in version 4

CakePHP form submit not working

I've just started working with CakePHP and I want to create a form that when it is submitted it calls a function in the controller. I'm using CakePHP version 2.6
The Code I currently have is:
view:
<div class="modal-body">
<?php echo $this->Form->create('Tweet', array('url' => array('controller' => 'posts', 'action' => 'postTweet'))); ?>
<?php echo $this->Form->textarea('Tweet', array('class' => 'form-control','rows' => '3', 'placeholder' => "what's happening?", 'maxlength' => '140', 'label' => false)); ?>
<?php echo $this->Form->button('Close', array('class' => 'btn btn-default', 'data-dismiss' => 'modal', 'type' => 'button'));?>
<?php echo $this->Form->submit('Tweet', array('class' => 'btn btn-primary', 'type' => 'submit', 'div' => false)); ?>
<?php echo $this->Form->end(); ?>
</div>
PostsController:
public function postTweet(){
//check if post is being made
if ($this->request->is('post')) {
//do something
}
}
HTML on page:
<form action="/posts/postTweet" id="TweetIndexForm" method="post" accept-charset="utf-8">
<div style="display:none;">
<input name="_method" value="POST" type="hidden">
</div>
<textarea name="data[Tweet][Tweet]" class="form-control" rows="3" placeholder="what's happening?" maxlength="140" id="TweetTweet"></textarea>
<button class="btn btn-default" data-dismiss="modal" type="button">Close</button>
<input class="btn btn-primary" value="Tweet" type="submit">
</form>
The problem is when I click the submit button nothing happens, I've checked in Firebug and no errors are in the console tab, no POST is made in the network tab and there are also no errors logged to the error log. Any help will be great thanks.
EDIT:
Solved I had JavaScript preventing the form from being submitted Thanks for the help!
Use submit like ->
echo $this->Form->submit('Tweet', array('label' => false, 'name' => 'submit', 'class' => 'grayBTN', 'title' => '', 'alt' => 'Submit', 'error' => false));
It works I use it all the time .
The issue with your submit is 'type' => 'submit' is used in your code and you also specify $this->Form->submit too .
If you are specifying Button with type submit then its ok like ->
echo $this->Form->button('Submit Form', array('type' => 'submit'));
But in your case you have $this->Form->submit.. So you dont need to specify it explicitely.
try this
echo $this->Form->end(array('label' => 'Tweet','div' => false,'class' => 'btn btn-primary'));

Using CakePHP FormHelper with Bootstrap Forms

CakePHP's FormHelper is how you generate forms when making CakePHP applications. As one might assume, this includes generating input elements, like so:
$this->Form->input('abc');
Which will produce HTML something like this:
<div class="input text">
<label for="ModelAbc">Abc</label>
<input name="data[Model][Abc]" class="" maxlength="250" type="text" id="ModelAbc">
</div>
Now, sadly, Bootstrap wants something like the following:
<div class="control-group">
<label for="ModelAbc" class="control-label">Abc</label>
<div class="controls">
<input name="data[Model][Abc]" class="" maxlength="250" type="text" id="ModelAbc">
</div>
</div>
How do I make CakePHP produce this output?
Inspired by lericson's answer, this is my final solution for CakePHP 2.x:
<?php echo $this->Form->create('ModelName', 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('Fieldname', array(
'label' => array('class' => 'control-label'), // the preset in Form->create() doesn't work for me
)); ?>
</fieldset>
<?php echo $this->Form->end();?>
Which produces:
<form...>
<fieldset>
<div class="control-group required error">
<label for="Fieldname" class="control-label">Fieldname</label>
<div class="controls">
<input name="data[Fieldname]" class="form-error" maxlength="255" type="text" value="" id="Fieldname"/>
<span class="help-inline">Error message</span>
</div>
</div>
</fieldset>
</form>
I basically added the 'format' and 'error' keys, and added the control-label class to the label element.
Here's a solution for Bootstrap 3
<?php echo $this->Form->create('User', array(
'class' => 'form-horizontal',
'role' => 'form',
'inputDefaults' => array(
'format' => array('before', 'label', 'between', 'input', 'error', 'after'),
'div' => array('class' => 'form-group'),
'class' => array('form-control'),
'label' => array('class' => 'col-lg-2 control-label'),
'between' => '<div class="col-lg-3">',
'after' => '</div>',
'error' => array('attributes' => array('wrap' => 'span', 'class' => 'help-inline')),
))); ?>
<fieldset>
<legend><?php echo __('Username and password'); ?></legend>
<?php echo $this->Form->input('username'); ?>
<?php echo $this->Form->input('password'); ?>
</fieldset>
<?php echo $this->Form->end(__('Login')); ?>
In case a field needs its own label:
<?php echo $this->Form->input('username', array('label' => array('text' => 'Your username', 'class' => 'col-lg-2 control-label'))); ?>
Here's one way:
<?php echo $this->Form->create(null, array(
'inputDefaults' => array(
'div' => array('class' => 'control-group'),
'label' => array('class' => 'control-label'),
'between' => '<div class="controls">',
'after' => '</div>',
'class' => '')
)); ?>
Your answer is correct, but for the benefit of other users there's some other tweaks you can do to take advantage of the error/help text:
Add form-horizontal to class in the Form->create() for more compact forms (labels on the left of the input, rather than on top)
Here's how to put help text underneath a field (has to be done for each field), not forgetting to close the </div>.
echo $this->Form->input('field_name', array(
'after'=>'<span class="help-block">This text appears
underneath the input.</span></div>'));
and to correctly display errors:
// cake 2.0
echo $this->Form->input('abc', array(
'error' => array('attributes' => array('class' => 'controls help-block'))
));
Outputs:
<div class="control-group required error">
<label for="ModelAbc" class="control-label">Abc</label>
<div class="controls">
<input name="data[Model][Abc]" class="" maxlength="250" type="text" id="ModelAbc">
</div>
<!-- error message -->
<div class="controls help-block">This is the error validation message.</div>
<!-- error message -->
</div>
It's extra mark-up and not as neat as bootstrap but it's a quick fix. The alternative is to do each error message individually.
and it lines up nicely. I haven't discovered an easy way to make use of inline messages yet however.
Applying the same principle as above to the form->end function as follows:
<?php echo $this->Form->end(array(
'label' => __('Submit'),
'class' => 'btn',
'div' => array(
'class' => 'control-group',
),
'before' => '<div class="controls">',
'after' => '</div>'
));?>
To produce:
<div class="control-group">
<div class="controls">
<input class="btn" type="submit" value="Submit">
</div>
</div>
small add for another comments:
if you whant add class and change label base text, you can write next
<?php echo $this->Form->input('Fieldname', array(
'label' => array('class' => 'control-label','text'=>'HERE YOU LABEL TEXT')
)); ?>
I had the same problem using slywalker / cakephp-plugin-boost_cake, I open a ticket and he had it fix in a few hours, he updated to 1,03 and told me to use it like this
<?php echo $this->Form->input('email', array(
'label' => array(
'text' => __('Email:'),
),
'beforeInput' => '<div class="input-append">',
'afterInput' => '<span class="add-on"><i class="icon-envelope"></i></span></div>'
)); ?>
I hope it helps some one else too
To get it working with a horizontal form in bootstrap with bootswatch I had to use:
echo $this->Form->create(
'User',
array(
'action' => 'add',
'admin' => 'false',
'class' => 'form-horizontal',
'inputDefaults' => array(
'format' => array( 'before', 'label', 'between',
'input', 'error', 'after' ),
'class' => 'form-control',
'div' => array( 'class' => 'form-group' ),
'label' => array( 'class' => 'col-lg-2 control-label' ),
'between' => '<div class="col-lg-10">',
'after' => '</div>',
'error' => array( 'attributes' => array( 'wrap' => 'span',
'class' => 'text-danger' ) ),
)
)
);
Then you can just use it as normal:
echo $this->Form->input( 'User.username' );
Luc Franken posted this link in his comment: http://github.com/slywalker/cakephp-plugin-boost_cake
It took me a while to notice it, so for those who are still looking for the simplest solution:
Simply add the CakePHP Bootstrap plugin from GitHub and let the helper do the job for you!

Categories