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'));
Related
This code in pic below:
Image:
Actually it deppends on form_submit($data);. But you can make data like this, so you can insert the $data['html'] inside the botton.
$data = array(
'class' => 'btn btn-primary btn-lg btn-myblock',
'name' => 'signin',
'value' => 'Sign In',
'html'=>'<span class="glyphicon glyphicon-user"></span>'
);
?>
<?php echo form_submit($data); ?>
I've seen a strange behavior for a custom plugin. It's skin generates some html and it works fine. As soon as i drop the widget onto the page it is only visible after a page refresh. Same is true when i try to drag the widget to another position.
Has anybody experienced the same issue? I am not sure whether its a bug or i might miss something in my code.
[edit] There is an issue with ipContent()->getCurrentPage()->getId() which is NULL after performing any drag and drop action [edit]
This is my skin file:
<div>
<div class="form-group">
<div class="checkbox">
<label>
<input id="auth-email-check-nutzung" type="checkbox"><?php echo ipSlot('text', array(
'id' => 'nutzungsbedingungen_' . ipContent()->getCurrentPage()->getId(),
'default' => 'Ich stimme den Nutzungebedingungen zu.',
'attributes' => array(
'id' => 'auth-email-check-nutzung-text'
)
)); ?>
</label>
</div>
<div class="checkbox">
<label>
<input id="auth-email-check-daten" type="checkbox"><?php echo ipSlot('text', array(
'id' => 'datenschutz' . ipContent()->getCurrentPage()->getId(),
'default' => 'Ich stimme der Datenschutzerklärung zu.',
'attributes' => array(
'id' => 'auth-email-check-daten-text'
)
)); ?>
</label>
</div>
</div>
<form class="form" role="form">
<div class="form-group">
<label for="inputEmail1" class="control-label">Email</label>
<input type="email" class="form-control" id="inputEmail1" placeholder="Email">
</div>
<div class="form-group">
<?php if ((ipIsManagementState())) :?>
<?php
// Use a simulated Button to edit text and prevent any default button event
// for user friendly inline editing
echo ipSlot('text', array(
'id' => 'button' . ipContent()->getCurrentPage()->getId(),
'default' => 'senden',
'tag' => "div",
'class' => 'btn btn-danger auth-button btn-block',
'attributes' => array(
'data-target' => 'bs-button',
'id' => 'auth-email-button-div'
)
)); ?>
<?php endif; ?>
<?php if (!(ipIsManagementState())) :?>
<?php
// Display real Button only on the live page with the contents of ipSlot :
// 'id' => 'button' . ipContent()->getCurrentPage()->getId()
echo ipSlot('text',array(
'id' => 'button' . ipContent()->getCurrentPage()->getId(),
'tag' => "button",
'class' => 'btn btn-danger btn-block',
'attributes' => array(
'data-target' => 'bs-button',
'id' => 'auth-email-button',
'disabled' => 'disabled'
)
)); ?>
<?php endif; ?>
</div>
</form>
</div>
Thanks in advance.
When you reload the page, "currentPage" really exists. That's why the code works. But when you drag a new widget or move the widget, it's content is loaded using AJAX. AJAX request has no real page. So getting current page id in widget's skin is not possible at some points.
I have a foreach that show many forms with the same action ending with diferente id's.
But, the tag <form> just appears in the first form. All others, the fields appears, but don't the <form>
I tried to put the id for the form different in the loop. But doesn't work.
The code:
<?php echo $this->Form->create(null, array(
'url' => array('controller' => 'menus', 'action' => 'aprovar', $procuracao['Attorney']['id']), 'id' => $procuracao['Attorney']['id']
)); ?>
<div class="control-group">
<label class="control-label">Alçada:</label>
<div class="controls">
<?php echo $this->Form->input ('alcada', array('type' => 'select', 'label' => FALSE, 'options' => array(
'Até 10.000' => 'Até 10.000',
'Até 50.000' => 'Até 50.000',
'Acima de 100.000' => 'Acima de 100.000',
'Acima de 500.000' => 'Até 500.000',),
'empty' => 'Selecione')); ?>
</div>
</div>
<div class="control-group">
<label class="control-label">Validade:</label>
<div class="controls">
<?php echo $this->Form->input('validade', array('label' => FALSE, 'type' => 'text')); ?>
</div>
</div>
<?php echo $this->Form->submit('Ok', array('class' =>'btn btn-success pull-left', 'div' => false)); ?>
</div>
The field "Alçada" and "Validade" appears correctly. But the tag <form> just appears in the first element.
You are not ending the form.
echo $this->Form->create(null, array(
'id' => 'your-form-'.$i, //that $i is the index of the foreach, for example
'url' => array('controller' => 'menus', 'action' => 'aprovar', $procuracao['Attorney']['id']), 'id' => $procuracao['Attorney']['id']
));
//all inputs and other stuff
echo $this->Form->end(array('label'=>'Ok', 'class' =>'btn btn-success pull-left', 'div' => false));
all that inside the foreach you're using.
Here is the reference of that function in the docs. But basically, it does this
Closes an HTML form, cleans up values set by FormHelper::create(), and
writes hidden input fields where appropriate
I am trying to pass data from a button within a gridview to a modal window. I need to pass the ID of the record in order to be able to reference it after submitting the form within the modal window.
I am struggling with this quite a bit. First I need to be able to pass the ID variable to the modal, and then upon clicking the submit button make an ajax call to create a new record within the DB.
The Gridview
if(isset($results)){
$this->widget('bootstrap.widgets.TbExtendedGridView', array(
'id'=>'searchgrid',
'fixedHeader' => true,
'headerOffset' => 40, // 40px is the height of the main navigation at bootstrap
'type'=>'condensed',
'dataProvider'=>$results,
'responsiveTable' => true,
'template'=>"{items}",
'columns'=>array(
array('name'=>'title', 'header'=>'Name'),
array('name'=>'city', 'header'=>'City'),
array('name'=>'state', 'header'=>'State'),
array('name'=>'leads', 'header'=>'Leads', 'value'=>'Parkslist::model()->leadRange($data["leads"])'),
array('name'=>'pastbid', 'header'=>'Previous', 'value'=>'Parkslist::model()->pastBid($data["pasthighbid"])'),
array('name'=>'currentbid', 'header'=>'Current', 'value'=>'Parkslist::model()->highBid($data["currenthighbid"], $data["secondhighbid"], $data["countcurrenthighbid"])'),
array('name'=>'minimumbid', 'header'=>'Minimum', 'value'=>'Parkslist::model()->minimumBid($data["currenthighbid"], $data["secondhighbid"], $data["countcurrenthighbid"])'),
array('name'=>'userhighbid', 'header'=>'Your Bid'),
array('name'=>'placebid', 'header'=>'Bid', 'value'=>'CHtml::textField("bid" . $data["id"])', 'type'=>'raw'),
array('name'=>'report', 'header'=>'Report',
'value'=>function($data){
$this->widget('bootstrap.widgets.TbButton', array(
'label' => 'Click me',
'type' => 'primary',
'htmlOptions' => array(
'data-toggle' => 'modal',
'data-target' => '#myModal',
'data-id' => '$data["id"]',
),
));
}
),
),
));
}
The Modal
<?php
$this->beginWidget('bootstrap.widgets.TbModal', array('id' => 'myModal')); ?>
<div class="modal-header">
<a class="close" data-dismiss="modal">×</a>
<h4>Why should this park be removed?</h4>
</div>
<form>
<div class="modal-body">
<select>
<option>Duplicate</option>
<option>Closed</option>
</select>
</div>
<div class="modal-footer">
<?php $this->widget('bootstrap.widgets.TbButton', array(
'type' => 'primary',
'buttonType'=>'submit',
'label' => 'Save changes',
'url' => '#',
'htmlOptions' => array('data-dismiss' => 'modal'),
)); ?>
<?php $this->widget('bootstrap.widgets.TbButton', array(
'label' => 'Close',
'url' => '#',
'htmlOptions' => array('data-dismiss' => 'modal'),
)); ?>
</div>
</form>
<?php $this->endWidget(); ?>
I was able to get this working. I would assume there might be a better solution but this seems to work.
First, inside of the button in the gridview I made the button ID = to the id of the record. Next, I created a javascript function called includeData and included the button ID.
Button Code
array('name'=>'report', 'header'=>'Report',
'value'=>function($data){
$this->widget('bootstrap.widgets.TbButton', array(
'label' => 'Click me',
'type' => 'primary',
'htmlOptions' => array(
'id'=>$data["id"],
'data-toggle' => 'modal',
'data-target' => '#myModal',
'data-id' => '$data["id"]',
'onClick' => 'includeData(this.id);'
),
));
}
),
JS Code
<script type='text/javascript'>
function includeData(parkid){
$('#reportparkid').val(parkid);
}
</script>
The JS function just sets the value of a hidden field equal to the buttonid. I would love to see some better ways to handle this.
Thanks
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!