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.
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'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.
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.
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
}
}
}
}