Which Submit Button was Clicked in CakePHP?
** what is solution for 2 buttons on same form with only 1 action in cakephp? **
i have following code,1 form contain 2 buttons print & ship,if i click
print button,page is redirected on printorder page but problem is , if i click ship
button it is not working & page is redirected on printorder.
==========================================================================
<?php // in index.ctp file
echo $this->Form->create('User',array('action'=>'orders','type' =>'post'));
echo $this->Form->submit('Ship',array('name'=>'user','value'=>'Ship','id'=>'1'));
echo $this->Form->submit('Print',array('name'=>'user','value'=>'Print','id'=>'2'));
echo $this->Form->end();
?>
<?php // in UserController
public function orders()
{
if($this->params->data['form']['user'] = "Print" )
{
$this->redirect(array('action'=>'printorder'));
}
if($this->params->data['form']['user'] = "Ship")
{
$this->redirect(array('action'=>'shiporder'));
}
}
?>
It's because you have created one form and you are submitting 2 different values on the "USER" form.
so it will redirected because action of the form is common.
To avoid it.. Using of 2 different forms are the best way.
Another way is to use javascript but I suggest to use 2 different forms.
Typical solution to two submit buttons situation is to create a submit button (default action) and a regular button to handle another action. Than you can use the JavaScript to implement the behaviour of the second button, e.g. to set a value of a hidden field which contains the actual 'action' string:
echo $this->Form->create('User',array('action'=>'orders','type' =>'post'));
echo $this->Form->hidden('submit_action', array(id='submit_action')); ?>
echo $this->Form->submit('Ship',array('value'=>'Ship','id'=>'ship_button'));
echo $this->Form->button('Print',array('value'=>'Print','id'=>'print_button'));
echo $this->Form->end();
And the js:
<script>
var form = <get your form here>
var print_button = document.getElementById('print_button');
print_button.onclick = function() {
// Set value of print button to the #submit_action hidden field
document.getElementById('submit_action').value = print_button.value;
// Submit the form
form.submit();
}
</script>
I followed the top voted (not selected solution) from Two submit buttons in one form, which suggested applying different values to each submit button, and checking those on submit.
However, CakePHP didn't easily play with this technique, as despite setting 'value' key in the $options array of $this->Form->submit, no value was set on the generated element. So, I followed the suggestions from here, and used the 'name' value key.
view.ctp
$this->Form->submit('Submit 1', array('name' => 'action1'));
$this->Form->submit('Submit 2', array('name' => 'anotherAction'));
controller.php
if (array_key_exists('action1', $this->request->data)) {
/** setup any data you want to retain after redirect
* in Session, Model, or add to redirect URL below
*/
// redirect to another action
$this->redirect(array('action' => 'myOtherAction'));
} else if (array_key_exists('anotherAction', $this->request->data)) {
// do something with anotherAction submit
}
Related
I'm calling a function with URL http://mywebsite.org/param/ajax?ID=2 which will return a form in html for which i use the following functions in the corresponfin callback function in my custom module.
$form_state = array(
'ajax' => TRUE,
'title' => t("Edit : $ID"),
);
$output = ctools_modal_form_wrapper('form_fn', $form_state);
print ajax_render($output);
drupal_exit();
I use this output to create a form inside a twitter bootstrap modal. The problem is when I'm submitting I get an ajax output again which I'm not able to handle. I would like to show a success message or failure based on the form_submit function. Is there any way I can show the output using the modal or on the original page which called the modal.
call to ctools modal should look like this:
$output = ctools_modal_form_wrapper($form_name, $form_state);
if(!empty($form_state['executed'])) {
$output = array();
$output[] = ctools_modal_command_display(t('Successful message title'), 'Successful message body');
$output[] = ctools_ajax_command_reload();
}
print ajax_render($output);
exit;
Don't forget to check for $form_state['executed'].
Also if you use a ctools_ajax_command_reload() this will reload a content of a modal and should fix the problem with another ajax output.
Would upvote sirBlond but my reputation isn't up there yet. I used this in the case where my modal window was not closing in IE8 on successful form submission. I needed to add this right before my redirect.
$commands[] = ctools_ajax_command_reload()
$commands[] = ctools_ajax_command_redirect($path, 0, $options);
Was exactly what I needed. Thanks.
I am new in CakePHP. This is the navigation part I am using in 1 of my CakePHP websites :
<?php
$list=array(
$this->Html->link('Home',array('controller'=>'pages','action'=>'index')),
$this->Html->link('About',array('controller'=>'pages','action'=>'about')),array(
$this->Html->tag('span',null,array('class'=>'top')),
$this->Html->tag('span',null,array('class'=>'bottom')),
$this->Html->link('Sub Menu 1',array('controller'=>'','action'=>'')),
$this->Html->link('Sub Menu 2',array('controller'=>'','action'=>'')),
$this->Html->link('Sub Menu 3',array('controller'=>'','action'=>'')),
),
$this->Html->link('Gallery',array('controller'=>'pages','action'=>'gallery')),array(
$this->Html->tag('span',null,array('class'=>'top')),
$this->Html->tag('span',null,array('class'=>'bottom')),
$this->Html->link('Sub Menu 1',array('controller'=>'','action'=>'')),
$this->Html->link('Sub Menu 2',array('controller'=>'','action'=>'')),
$this->Html->link('Sub Menu 3',array('controller'=>'','action'=>'')),
),
$this->Html->link('My Posts',array('controller'=>'pages','action'=>'myPosts/1')),
$this->Html->link('Blog',array('controller'=>'pages','action'=>'blog')),
$this->Html->link('Contact',array('controller'=>'pages','action'=>'contact')),
$this->Html->link('Logout',array('controller'=>'users','action'=>'logout'))
);
echo $this->Html->nestedList($list);
?>
What I want, "My Posts" and "Logout" menus will be shown if and only a user is logged in, otherwise not. How to do it ? And, do you have any better idea to make a navigation bar in CakePHP ?
Here span tags are used only for design issue.
1st Solution
You have to create a separate array for logged in user and this can be done via auth functions like
In Controller
$this->set('authUser', $this->Auth->user());
OR
$this->set( 'authUser', $this->Auth->loggedIn());
In View
If($authUser){
$list = array(/*without Post and Logout*/);
} else{
$list = array(/*same complete array*/);
}
2nd Solution
if ($this->Session->read('Auth.User')){
$list = array(/*without Post and Logout*/);
} else{
$list = array(/*same complete array*/);
}
in cakephp 2.3:
Suppose I have a form generated by controllerX. I start filling in data, and somewhere there is a button for performing some task which will open a new form (modal window) generated by controllerY for ModelY.
Whenever I am finishing with the second form I am losing all what I have filled in the 1st form.
I tried several things, including redirecting to $this->referrer(), but all not working.
Thanks
Update 1)
I am adding a snippet of the code:
Note: I am using twitter bootstrap. Below code is from "violations" add view. Inside this form, I want to enable the user to add a new Organization.
<script type="text/javascript">
/****** helper functions *******/
function onClickAddOrgLink() {
$('#myModal').modal();
}
</script>
<?php
echo $this->Form->create();
echo $this->Form->input('number');
echo $this->Form->input('organization_id');
//Add new organization button
echo '<a id="addOrgLink" href="#myModal" role="button" class="btn" data-toggle="modal">Add new Org</a>';
$this->Js->get('#addOrgLink')->event('click', 'onClickAddOrgLink()');
echo $this->Form->input('remarks', array('type'=>'textarea','rows'=>'6'));
echo $this->Form->end(array('class'=>'btn btn-primary', 'div'=>false,'name'=>'submit', 'label' => 'add'));
?>
<!-- Modal -->
<div id="myModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">adding a new org</h3>
</div>
<div class="modal-body">
<p>
<?php
echo $this->Form->create('Organization', array('controller'=>'organizations', 'action'=>'add'));
echo $this->Form->input('company_name', array('div'=>false));
echo $this->Form->input('address1', array('div'=>false));
echo ' <div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">cancel</button> ';
echo $this->Form->end(array('class'=>'btn btn-primary', 'div'=>false, 'name'=>'submit', 'label' => 'ADD'));
echo '</div>';
?>
</p>
</div>
</div>
Here is add new organization action:
var $helpers=array('Session', 'Js', 'Html');
public function add() {
$this->autoRender=false;
$this->Organization->create();
$this->Organization->save($this->request->data);
$this->redirect($this->referer());
}
Not a 'full' answer, but some suggestions that may assist in implementing a solution;
option 1 - Autosave (draft)
Implement autosave; on any page containing a form, add a JavaScript that submits the form (via AJAX) to a server-side autosave handler at a specific interval (e.g. Every xx seconds) or when the user navigates away for the page.
The server-side handler stores the submitted data inside the session, using the URL of the page as 'identifier' (e.g. /Users/edit/123). When returning to the page, check if a draft(autosave) is present in the session, and use that information to fill the request data;
public function beforeRender() {
if (!$this->request->is('post')) {
// restore autosave data for the current url if no form is posted
$this->request->data = $this->AutosaveComponent->restore($this->request->here);
} else {
// form is posted; flush the autosave data for the current URL
$this->AutosaveComponent->flush($this->request->here);
}
}
Option 2 - light box
Another option is to open the 'interrupting' form in a light box; the form that is currently worked on will stay open, and submitting the light box form will not interrupt this.
update - some suggestions
Basically, what you're trying to achieve is;
the user picks an organisation, enters the remarks and submits the form
if the organization does not yet exist, allow the user to add a new organization via a modal/popup. Select that organization after adding it via the Modal, enter the remarks and complete the form.
Use AJAX to submit the Modal box
Currently, your Modal-windows will be submitted via a 'regular' submit, not via AJAX, therefore the page will be reloaded after submitting the modal box.
You should submit the Modal box via AJAX and afterwards, append the newly created organization to the dropdown using a AJAX 'complete' handler.
However, because you'll also have to show validation-errors for the organization inside the Modal box, it may be better to load the 'add organization form' via AJAX as well.
All these will require quite some changes to your code and additional JavaScript to perform the AJAX handling.
Create the new Organization and submit the remark at the same time
Basically, combine both forms into a single form;
By default, the input-fields for the 'Organization' are hidden
If the user picks an existing organization from the dropdown, the 'Organization' fields remain hidden
If the user picks 'other organization...' from the dropdown, the 'Organization' fields become visible and the user can enter the details for the new organization
After submitting the form:
if the user selected 'other organization...', insert the new organization and insert the 'remark', using the 'id' of the new organization.
if the user selected an existing organization, only insert the remark.
I've customized the edit profile view using template.php and user-profile-form.php
All shows up correctly but the Submit (and Delete) button..
I'm using Adaptive Theme and I've modified like this :
template.php
function adaptivetheme_theme(&$existing, $type, $theme, $path) {
return array(
'user_profile_form' => array(
'template' => 'templates/user-profile-form',
'render element' => 'form',
),
);
}
function adaptivetheme_preprocess_user_profile_form(&$vars) {
$vars['form']['account']['name']['#description'] = t('blabla');
$vars['form']['submit']['#value'] = t('Save profile');
$vars['form']['delete']['#value'] = t('Delete account');
$vars['account'] = drupal_render($vars['form']['account']);
$vars['theme_select'] = drupal_render($vars['form']['theme_select']);
$vars['picture'] = drupal_render($vars['form']['picture']);
$vars['signature_settings'] = drupal_render($vars['form']['signature_settings']);
$vars['contact'] = drupal_render($vars['form']['contact']);
$vars['timezone'] = drupal_render($vars['form']['timezone']);
$vars['submit'] = drupal_render($vars['form']['submit']);
$vars['delete'] = drupal_render($vars['form']['delete']);
}
then in the user-profile-form.tpl.php :
<div id="user-profile-form">
<?php echo $account; ?>
<?php echo $timezone; ?>
<?php echo $submit; ?>
<?php echo $delete; ?>
</div>
The edit form of the account shows correctly. I've tried adding/removing variables successfully (ie the $timezone) but the submit/delete are missing.
I don't know what's wrong..
I've tried to change the name of the variables 'submit' and 'delete' but still no button shows up. Of course I've cleared the cache every times needed (and not).
I have no JS hiding the buttons neither..
I render this form through a custom block in a Panel :
<?
module_load_include('inc', 'user', 'user.pages');
global $user;
print drupal_render(drupal_get_form('user_profile_form', $user));
?>
Maybe a problem with Panels ???
Any idea is appreciated :)
Thx for reading
Erwan
I forgot the "[action]".. :
$vars['submit'] = drupal_render($vars['form']['actions']['submit']);
$vars['cancel'] = drupal_render($vars['form']['actions']['cancel']);
And 'Delete' button didn't show up at first because it's called "cancel", and its #access param was sent to FALSE. Thx DPM ;)
Now, the problem is that when I trigger the submit button, the form is not sent, it justs reload he page. I will update if I manage to solve that too.
The page is only reloading because you forget to render the hidden form elements. To do so in your template preprocess you can use something like that :
function THEME_preprocess_user_profile_form(&$variables) {
$hidden = array();
foreach(element_children($variables['form']) as $key)
{
$type = $variables['form'][$key]['#type'];
if($type == "hidden" || $type == "token"){
$hidden[] = $variables['form'][$key];
}
}
$variables['hidden'] = $hidden;
//Dont forget to report your variables like you already did ...
}
Then when it s done render the $hidden variable in your template file
<?php print render($hidden);?>
And there you go !
I am developing a custom module and used hook_form_FORM_ID_alter method. I have provided option same as in block's configuration visibility settings for specific pages. I have also created a database table for my module. I am not getting any idea how the options selected by user should be stored in my table when submitted and also how the option selected for a particular menu link should be retained. I have added this functionality on menu item edit form.
Something like this is what you're looking for:
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
$form['my_val'] = array(
'#type' => 'textfield',
'#title' => 'Some Text'
);
$form['#submit'][] = 'MYMODULE_my_form_submit';
}
function MYMODULE_my_form_submit(&$form, &$form_state) {
$val = $form_state['values']['my_val'];
db_insert('my_table')->fields(array('val' => $val))->execute();
}
That's obviously a very basic example but it shows you how to add a submit handler to an existing form, how to add an extra field, and how to then get the data for that field in the submit handler.