In Drupal 7, I have this code.
It defines the hard-coded string my_module_custom_route_form as the form ID and use drupal_get_form to initialize a form. And there is one submit button.
Visit this route /custom_route, the output is
initialize form
If you submit the form, the output is
initialize form
submitted
The problem is this: The submission of this form will call my_module_custom_route_form again.
How can I prevent it from being called again on submission? If you know why Drupal does this, I would also like to know.
function my_module_menu() {
$items = array();
$items['custom_route'] = array(
"page arguments" => array("my_module_custom_route_form"),
"page callback" => "drupal_get_form",
"access callback" => TRUE,
);
return $items;
}
function my_module_custom_route_form($form, &$form_state){
print_r("initialize form");
$form = array();
$form["button"] = array(
"#type" => "submit",
"#value" => "submit"
);
return $form;
}
function my_module_custom_route_form_submit($form, &$form_state){
print_r("<br />submitted");
exit;
}
I think what you need is this:
Set $form_state['redirect'] = false in the submit handler.
See https://drupal.stackexchange.com/questions/26347/prevent-redirect-after-form-submit
Hope that helps!
I know that this is an old question, but the question is still relevant - I ran into the same problem. In my case it is definitely a problem, since the form in the block claims a queue item for processing, but when the form builder is called a second time, of course the item is blocked in the queue.
Clicking the button on a non-ajaxified form causes the page to reload. In the case of the block, this calls the block_view function, which rebuilds the form from 0.
I solved this by ajaxifying the submit button. Then the submission is called without re-viewing the block (and rebuilding the form, as is the case here). There is a nice ajax_example in the examples module, for those who are new to ajax forms.
Related
I manually set the CakePHP Pagination values in my Usergals Controller like so, so as to Paginate a related Model (TreasuresUsergal) on the view of Usergal. Here is a simplified snippet from the UsergalController:
public function view($id = null) {
$this->loadModel('TreasuresUsergal');
$options['joins'] = array(
array('table' => 'treasures',
'alias' => 'Treasure2',
'type' => 'LEFT',
'conditions' => array(
'Treasure2.id = TreasuresUsergal.treasure_id',
)
)
);
$options['conditions']=array('TreasuresUsergal.usergal_id'=>$id);
$options['fields']=array('Treasure2.*','TreasuresUsergal.ord','TreasuresUsergal.comments');
$options['order']=array('TreasuresUsergal.ord'=>'asc');
$options['limit']=$limit;
$this->Paginator->settings = $options;
$treasures=$this->Paginator->paginate('TreasuresUsergal');
$this->set('treasures',$treasures);
}
So in the above example, $id is the value passed to the view function from the URL. There is a live example of this here:
http://collections.centerofthewest.org/usergals/view/20
As you can see, it works just fine for a single page. However, today I tested the Paginator in the view and discovered the "next" button does not work. The Counter, sorting, and Page numbers all load correctly - but anytime the actual named parameter "page:n" is passed (when n is greater than 1) I get a Not Found page with the following error:
Not Found
Error: The requested address '/usergals/view/20/page:2?url=%2Fusergals%2Fview%2F20' was not found on this server.
I must be missing something simple - I have experimented with the routes a little, but haven't been able to figure it out. Or perhaps I am missing some Paginator options? Or does it think its OutOfBounds when its not?
UPDATE / WORKAROUND
After some messing around, I have devised this workaround. Not as nice as I'd like, but here is the basic idea (error handling, etc can be added)
First, I added a check in beforeFilter to see if page paramter was set. If so, I change it to 'p' parameter and redirect.
I did this here because otherwise I had problems with the Not Found exception (see notes at bottom). So, in beforeFilter:
if (isset($this->params['named']['page'])){
$newurl=$this->params['named'];
$pg=$newurl['page'];
unset($newurl['page']);
$newurl['p']=$pg;
$this->redirect(array('action' => 'view/'.$this->params['pass'][0])+$newurl);
}
Then, in the 'view' function of the same controller, I added this along with the other Paginator options:
if (isset($this->params['named']['p'])) $options['page']=$this->params['named']['p'];
With this, the standard Paginator behavior seems to work fine in the view. Prev, next, etc.
If anyone has a better suggestion, I would love to hear it. I don't like the idea of having to redirect, but it works for now.
It's worth noting that adding this code (even just to experiment) - caused all of my pagination counts to stop working. The query in debug was correct, but the displayed counts were wrong:
try {
$this->Paginator->paginate();
} catch (NotFoundException $e) {
}
I have a module, which includes multistep form. I decided to make one of these steps work like this: free times per employee are rendered as html elements, and when element is clicked, Javascript will apply the value to hidden input field.
So I found this tutorial: http://drupal.org/node/1092122 but it didn't work for me, maybe I made a error, maybe not.
My module name is reservation. My template file is named reservation_select_time_week_page.tpl.php and its in the reservation/theme folder.
I have these functions:
function reservation_theme() {
// basic things
$module_path = drupal_get_path('module', 'reservation');
$base = array(
'path' => "$module_path/theme",
);
// define themes
return array(
'reservation_select_time_form' => $base + array(
'render element' => 'form',
'template' => 'reservation_select_time_week_page',
),
);
}
function template_preprocess_reservation_select_time_week_page(&$variables) {
echo "this works!";
}
function template_preprocess_select_time_form(&$variables) {
echo "this works!";
}
I dont know which of those preprocess functions is right (should it be named based on template name or form id?
Anyhow, custom template is not applying.
I also have tried using the:
$form['start_time'] => array('#theme' => 'reservation_select_time_week_page');
I got it working, so that the static html is rendered in template file, but I dont know how I can render the form elements in template file. Using:
drupal_render($form)
caused the form to go infinite loop I think.
Is Drupal even able to handle complex forms and form layouts?
I created relation Post hasMany Photos, Photos actsAs ImageBehavior.
How put to $data['Photo']['model'] = 'Post'? Automated?
I'm not sure what you are asking about but when you have a form, you can simply add to your $this->data['Photo']['model'] any value you want with hidden fields.
// photo/add.ctp:
$this->Form->create('Photo');
$this->Form->input('model', array('type' => 'hidden', 'value' =>'yourvalue'));
$this->Form->end('Submit');
Update
You can set this value after the form was submitted, so even if someone will replace the hidden field value you can just check it.
function add(){
if(!empty($this->data['Photo']['model']){
$this->data['Photo']['model'] = "yourvalue";
$this->Photo->save($this->data));
}
else
rest of the code...
}
rest of the code
I'm trying show on views (each row) my custom form. It works, but the form doesn't work proper. I need to give to each form different ids.
hook_forms should help me, but I cannot manage how to use it. If I put print $form into it, I still cannot see my forms.
I'm calling my form like this from the template file:
$form1 = drupal_get_form('votingform_create_decision_form_' . $node->nid, $node->nid);
print drupal_render($form1);
Now I got it working:
function hook_forms($form_id, $args) {
if ($args[0] == 'mymodule_form_') {
$forms['mymodule_form_' . $args[1]] = array(
'callback' => 'mymodule_form',
'callback arguments' => array($args[1]),
);
}
return $forms;
}
hi to all i am using cakephp framework for my project. in on of my form i take a checkbox on click on this two other text box are shown.
by using cakephp validates method i validate the form data but i want that when the checkbox is not checked then it avoid the validation for that text box. it check only when the checkbox is checked.
so plz help me.
thanks in advance
You can use your models beforeValidate servicecall for that and add extra validation criteria for this model.
For example:
function beforeValidate($options = array())
{
if(!empty($this->data['Model']['fieldOne']))
$this->validate['fieldTwo'] = array(/*normal validation rules*/);
return true; // Needed or validation fails
}
You can use custom validation methods:
var $validate = array(
'checkbox1' => 'checkboxRule'
);
// If checkbox1 is checked, requires checkbox2 to be checked as well
function checkboxRule() {
if (!empty($this->data[$this->alias]['checkbox1'])) {
return !empty($this->data[$this->alias]['checkbox2']);
}
return true;
}
You can also invalidate other fields, like checkbox2, at the same time by calling $this->invalidate('checkbox2') in your custom method.
Also, you can unset the validation in your controller like this:
unset($this->Model->validate);