I check for data below and if data is there in the form field it updates the table. Problem is that if I click the button twice (its ajax) it wll insert a second row. How can I prevent it.
thanks
function update() {
if (!empty($this->data)) {
$this->Test->saveAll($this->data['Test'])
}
}
The problem is the form doesn't have the id field so cakephp insert a new row.
The easy way is check if exists another record with the same values before save.
You can check in function beforeSave() of the Model instead of the Controller action.
http://book.cakephp.org/#!/view/1052/beforeSave
You should take a two-pronged approach to preventing this:
First, Disable the submit button on submit. For example in jQuery:
$('#form_id').submit(function(event) {
event.preventDefault();
$('input[type=submit]', this).attr('disabled', 'disabled');
// submit form via ajax...
}
Secondly, perform rational check server-side to prevent duplicate saves. For example, two identical records submitted within a minute or so would be considered an error. I'd probably do this by creating a custom validation rule on one of the fields that's always required. In your model:
var $validate = array(
'myfield' => array(
'rule' => 'duplicateCheck',
'message' => 'Duplicate record'
)
);
function duplicateCheck() {
$conditions = array(
'Model.field1' => $this->data['Model']['field1'],
...
'Model.created >' => date("Y-m-d H:i:s", time() - 60)
);
return !$this->hasAny($conditions);
}
Then in your controller, I would redirect the user to the existing record if the save fails and it was because of that specific validation rule. This let's the user move along without caring that anything went wrong.
function add() {
if(isset($this->data)) {
if($this->Model->save($this->data)) {
...
} else {
if(isset($this->Model->validationErrors['myfield'])) {
// find the existing record and redirect user to view it
}
}
}
}
Related
I'm trying to detect when the date has changed inside a regular "date" field
Have seen a few forum posts about how this can be done with text fields and dropdown, but it doesn't work for date fields.
Also tried:
'displayParams' =>
array (
'javascript' => 'onchange="checkStatusOption(this)"',
),
In the editviewdefs.php, but it didn't work (works for text fields though)
The closest I've got it actually just tracking every click on on the screen and then checking the before and after state of the date field, but it's obviously not a very elegant solution
Here's the code from the extended editview
function display() {
parent::display();
$js = <<<EOT
<script type="text/javascript" language="JavaScript">
// Capture initial state
calendar_before = document.getElementById("contract_date_c").value;
// Wait for any click to take place anywhere on the screen
$(document).click(function() {
// Capture state after we clicked somewhere
calendar_after = document.getElementById("contract_date_c").value;
// Compare the before and after
if(calendar_before != calendar_after) {
// Change detected
alert("Something's changed eh?" + calendar_before +" "+ calendar_after);
}
// Set the new state of the before_calendar
calendar_before = document.getElementById("contract_date_c").value;
});
}
</script>
EOT;
// now I output the javascript
echo $js;
}
UPDATE:
I also tried the suggested solution
1) Created a file custom/modules/un_inventory/contract_date_c_change.js and put the following inside:
function yourCustomFunction(formElement){
console.log(formElement);
}
2) Included a reference to that file in the metadata file (made sure it loads it):
array (
'file' => 'custom/modules/un_inventory/contract_date_c_change.js',
),
3) Attached the updateCallback to the field:
array (
'name' => 'contract_date_c',
'label' => 'LBL_CONTRACT_DATE',
// Checks if this field got filled up and shows hidden form field
'displayParams' =>
array (
'updateCallback' => 'yourCustomFunction();',
),
),
But nothing happens when I change that date field
Check this out (just tested in SuiteCRM 7.11) for a datetime field, for other fields take a look at this answer to another SO question
First, include your custom JS in the editviewdefs.php (example for Accounts module)
'includes' =>
array (
0 =>
array (
'file' => 'modules/Accounts/Account.js',
'file' => 'custom/modules/Accounts/myCustomFile.js',
),
),
Create the custom JS file custom/modules/Accounts/myCustomFile.js .
function yourCustomFunction(formElement){
console.log(formElement);
}
Then update the field you want to monitor for changes (contractsigned_c in the example) using the following code in the editviewdefs.php:
array (
'name' => 'contractsigned_c',
'label' => 'LBL_CONTRACTSIGNED',
'displayParams' =>
array (
'updateCallback' => 'yourCustomFunction(this)',
),
),
Now do a Repair and Rebuild inside the Admin/Repair section and voilĂ it should work :)
You can add the JS function on the function display() if you want, its the samething, the function will be called right after native combo update. It will look like this combo_contractsigned_c.update(); yourCustomFunction(this)
use this . it is working
YAHOO.util.Event.addListener('your_field_name', 'change', function(){
// your code here
});
I have created a custom module that I need to collect info and run a function when a form is filled out and submitted.
It has two text areas and a button.
This is what I have which shows up fine on the page:
File: myFunction.admin.inc
function myFunction_form($form)
{
$form['pages'] = array(
'#type' => 'fieldset',
'#title' => t('Data'),
'#collapsible' => FALSE,
'#collapsed' => FALSE,
);
$form['pages']['title'] = array(
'#type' => 'textarea',
'#title' => t('Title'),
'#rows' => 5,
'#resizable' => FALSE,
);
$form['pages']['body'] = array(
'#type' => 'text_format',
'#title' => t('Body'),
'#rows' => 5,
'#resizable' => FALSE,
'#format' => 'full_html',
);
$form['submit'] = array('#type' => 'submit', '#value' => t('Run Function'));
myFunction($form);
return $form;
}
function myFunction()
{
//This is where I use the data collected from my form and do what I need to do.
}
So the things I missing form this (and please tell me if i'm going the wrong way about this) is I need to validate the form was filled out and return error message if not.
if the form was filled out then correctly pass the field data to my function which I did simply by adding function myFunction() before return $form; but this seems like the wrong way to do it. I don;t want the myFunction() to run if there is and errors with the form.
Could someone please help me with this last part of my custom module.
Please not that this module does NOT add anythig to the database.
Again, please tell me if i'm going the wrong way about this.
You should follow the standard naming structure used by the form API. If you function is:
myFunction_form(),
then
myFunction_form_validate() will be called when submitted to perform any validation. If everything passes, then
myFunction_form_submit() will be called. You should place your submit logic (or a call to your custom function) in the submit.
This is the preferred behavior over setting $form['#submit'][] and $form['#validate'][].
See the Examples Module for simple examples of how this works.
Yes you propably go the wrong way.
You will have to add your custom validator and submit functions like
<?php
$form['#submit'][] = my_submit_callback
$form['#validate'][] = my_validator_callback
function my_submit_callback($form, &$form_state) {
// form_state array contains the submitted values
}
function my_validator_callback($form, &$form_state) {
// form_state array contains the submitted values
if ($form_state['values']['body'] == '') {
form_set_error(...)
}
}
and ofcourse remove the myFunction() call from your form_builder function
Approach it this way:
$form['#validate'][] = 'myCustomValidateFunction';
$form['#submit'][] = 'myCustomSubmitFunction';
function myCustomValidateFunction($form, &$form_state) {
\\if validation was not passed use form_set_error()
}
function myCustomSubmitFunction($form, &$form_state) {
//submit logic, $form_state includes the values
}
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.
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
}
Drupal 7
I'm having a similar problem to one that's been presented previously but so far I've not been able to make any of the suggestions work.
I have 'Product' pages of content type 'Software Products'. I want to place a link on the product pages pointing to a Webform 'Request Information' I want to populate a (hidden) field on the form with the product name which is also the title of the referring product page.
I have tried the following but this just results in the title of the form being shown - not the referring page.
<?php
/**
* Implementation of hook_form_alter().
*/
function AddNodeInfoToForm_form_alter(&$form, $form_state, $form_id) {
switch($form_id) {
case 'webform_client_form_10': // the id of the form
{$current_object = menu_get_object();
$product_title = $current_object->title;
$form['submitted']['product']['#default_value'] = $product_title; }
return $form;
}
}
I would appreciate any pointers - I'm new to Drupal
That's quite a messy way round of doing what you need to, you should just put the product nid in the URL as part of the query string in the link from your product page and then load it up from the webform.
In your node template/preprocess:
$webform_path = 'node/10'; // Or whatever the webform's nid is
$link = l('Request Information', $webform_path, array(
'query' => array(
'product_nid' => $product_node->nid
)
));
echo $link;
Then in your form alter:
function AddNodeInfoToForm_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'webform_client_form_10' && isset($_GET['product_nid']) && is_numeric($_GET['product_nid'])) {
$product_node = node_load($_GET['product_nid']);
if ($product_node) {
$product_title = $product_node->title;
$form['submitted']['product']['#default_value'] = $product_title;
}
}
}
Note that you don't return the form from the hook_form_alter function, the $form variable is passed in by reference so changes are stored that way.