Drupal form redirect to fragment - php

I have a poll block in the bottom of my front page, and I'd like to redirect the poll form to the block after submit. I use Drupal 6.x.
As usual, I use form_alter for this.
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
switch ($form_id) {
case 'poll_view_voting':
// not worked also
//$form['#redirect'] = url('', array('fragment' => 'poll-block'));
$form['#redirect'] = '#poll-block';
break;
}
}
After submit, I'm redirected to /%2523poll_block (this is a 404 page).
In a preprocess_page function I wrote the $_REQUEST['q'] using drupal_set_message(), and it shows the good redirect (#poll-block), but the URL in browser is encoded.
Can anybody help me?
Thanks in advance.

As per FAPI reference, you can enter an array to be passed to drupal_goto(). Ultimately this goes through url() so use your url() function's ninja tricks here.
Basically you can have 3 types of data here.
a string, Boolean FALSE, or an array.
If it's a string, it will redirect to the correct location after a url encode (what happens in your case). FALSE will disable redirects, and if you enter an array, it will be passed to drupal_goto().
So for your case, it would be:
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
switch ($form_id) {
case 'poll_view_voting':
// not worked also
//$form['#redirect'] = url('', array('fragment' => 'poll-block'));
//$form['#redirect'] = array('node/54', array('page' => '2'), 'poll-block'); // No "#" in fragment. This will work.
$form['#redirect'] = array('', array(), 'poll-block');
break;
}
}
However, drupal_goto() usually happens with absolute URL so probably your effort would be useless unless you use javascript.

Related

Zend Framework 1 pass parameters using get to the route

I hope the title does not sound too confusing, but I had no idea how to name my problem.
Brief intro:
I'm using Zend 1.1X.
At the moment I've been working with a search form sending few parameters via POST.
Now I have to change it to use GET, I have a route created looking similar to that:
"search/what/:what/shape/:shape"
and so on, I also have 2 optional parameters which takes null as default.
I'm trying to generate an URL (using Zend View Helper Url) at form's action, but it throws an exception:
Uncaught exception 'Zend_Controller_Router_Exception' with message what is not specified
I Now don't have idea what should I do. If I change my route to "search" only, it then sends the form correctly, but I end up with "search?what=XXXX&shape=YYYY" instead of "search/what/XXXX/shape/YYYY".
Is there any way that could be handled the way I like??? :>
#EDIT
I think this should also be mentioned - I have a different form, similar one, pointing to a route without parameters specified as well and the uri gets "translated" to the form of "key/value" pairs. The only difference between them is that the first one does not use Url helper, instead has the method part hard-coded and my form is being submitted programatically (button => jQuery stuff => submit). Would that make a difference here, as I believe it should not? :>
I hope any possible source of this behaviour will come up to you, because I'm really stuck at the moment and I simply can't find what's wrong..
Thanks in advance!
With the GET method a form generates an url like this: action?param1=val1&param2=val2&....
I see two solutions:
The first is to regenerate the URL by javacsript, we can imagine something like this:
<form method="get" id="id_form">
....
</form>
<script>
var objet_form = document.getElementById('id_form');
function gestionclic(event){
var url = objet_form.action;
for(var i = 0; i < objet_form.length; i++){
url += "/" + objet_form[i].name + "/" + objet_form[i].value;
}
objet_form.action = url;
}
if (objet_form.addEventListener){
objet_form.addEventListener("submit", gestionclic, false);
} else{
objet_form.attachEvent("onsubmit", gestionclic, false);
}
</script>
But I don't think this is a good solution.
The second is to manage it with a plugin:
For the plugin, it must be declared in the bootstrap.
For example:
public function _initPlugins(){
$front = Zend_Controller_Front::getInstance();
$front->registerPlugin(new Application_Plugin_PRoutage());
}
with this example, the application/plugins folder, create the PRoutage.php plugin like this:
class Application_Plugin_PRoutage extends Zend_Controller_Plugin_Abstract
{
public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
{
...
}
}
and with the variable $request you have access to your data as an array with $request->getParams().
We can imagine something like this:
public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
{
$param = $request->getParams();
$what = "";
$shape = "";
if (isset($param['what']) $what = $param['what'];
if (isset($param['shape']) $shape = $param['shape'];
if ($what == "XXXX" && $shape == "YYYY"){
$request->setControllerName('other_controler')
->setActionName('other_action')
->setDispatched(true) ;
}
}
I hope it will help you

Gravity Forms - Get Current Page Number

I have a multi-page form.
I would like to execute some custom JavaScript on the last page of this form. Theoretically, all I have to do is retrieve the current page number and write a conditional.
Simple, right? Apparently not.
My original workaround was like this:
if ($('gform_page').last().css('display') !== 'none') {
// perform custom scripts now that the last
// Gravity Form page is being shown
}
but $('...').css('display') returns undefined on every element I've tried this on within the form. Custom scripts were being fired every time the user hit the "Next" button. No cigar.
Then, after reviewing the Gravity Forms documentation, I found two useful-looking events: gform_post_render and gform_page_loaded.
However, the documentation gives no instruction on how to access the parameters.
jQuery(document).bind('gform_page_loaded', function(event, form_id, current_page){
console.log(current_page);
// returns nothing when loaded in the footer
// returns [Object, object] when placed in an HTML field in the form
});
In addition to not having the correct code, I also suspect I don't have the code in the correct place as I have also fruitlessly tried the following in functions.php and in header.php (as the documentation suggests):
<?php
function enqueue_custom_script($form, $is_ajax){
if ($is_ajax) :
echo '<script>console.log(current_page);</script>';
endif;
}
add_action("gform_enqueue_scripts", "enqueue_custom_script", 10, 2);
?>
Question:
What code do I need to retrieve the current page number, and more importantly, where do I place that code?
I got it.
The function rgpost is, apparently, crucial in accessing the current page number. After some muddling around on my own, I was able to get the following code working in both functions.php and just before the wp_head() function in header.php.
function run_script_on_last_page($form) {
if (!is_admin()) {
$current_page = rgpost('gform_source_page_number_' . $form['id']) ? rgpost('gform_source_page_number_' . $form['id']) : 1;
if ($current_page == 10) {
wp_enqueue_script('custom_script', get_template_directory_uri() . '/js/custom_script.js', array('jquery'), null, true);
}
}
}
add_action('gform_enqueue_scripts_63', 'run_script_on_last_page');
If you're copy/pasting the code above, make sure to:
replace 10 with the page you want to check
ensure your parameters are correct in wp_enqueue_script
replace 63 with your form ID
Some resources I found useful:
this section of the documentation for the gform_validation filter
the documentation for gform_enqueue_scripts.
The OPs accepted answer might well work but it doesn't work if you have the form setup to paginate using Ajax.
In that case I could only get it working using Javascript and the following method;
http://www.gravityhelp.com/documentation/page/Gform_post_render
jQuery(document).bind('gform_post_render', function (event, formId, current_page) {
if (current_page == 2) {
// do something
}
});
You could of course use the formId parameter to limit this to a specific form
The currently accepted answer only works if the user never goes to a previous page in the form, if they do, then gform_sourge_page_number always lags by one. I found a better solution (using this hook for an example, but you should be able to use it within any hook that has the $form passed to it):
function run_script_on_last_page( $form) {
if ( !is_admin() ) {
if ( \GFFormDisplay::get_current_page( $form['id'] ) == 10) {
wp_enqueue_script( 'custom_script', get_template_directory_uri() . '/js/custom_script.js', array( 'jquery' ), null, true );
}
}
}
add_action( 'gform_enqueue_scripts_63', 'run_script_on_last_page' );
GFFormDisplay::get_current_page( $form_id ) is one of many handy undocumented functions.
I wrote a little function that returns the current page:
// Get Gravity Forms Current Page
// Syntax: gf_current_page()
function gf_get_current_page()
{
return rgpost('gform_source_page_number_' . $_POST['gform_submit']) ? rgpost('gform_target_page_number_' . $_POST['gform_submit']) : 1;
}
Further to the accepted answer, here is an example of finding the current page, and dynamically finding how many pages are in the form. This example changes button text based on whether it is the last page of the form, instead of enqueueing a script.
// Change the text of the 'Next' form button to 'Submit' when
// the current page is the final page of the form
add_filter( 'gform_next_button', 'next_to_submit', 10, 2 );
function next_to_submit( $next_button, $form ) {
$replacement_next_button = $next_button;
$last_page_number = 1;
foreach ($form['fields'] as $field) {
$is_hidden = RGFormsModel::is_field_hidden( $form, $field, array() );
if ($field['pageNumber'] > $last_page_number && !$is_hidden) {
$last_page_number = $field['pageNumber'];
}
}
$current_page_number = rgpost('gform_source_page_number_' . $form['id']) ? rgpost('gform_source_page_number_' . $form['id']) : 1;
if ($last_page_number === $current_page_number) {
// If the current page is the final page
$replacement_next_button = str_replace( 'Next', 'Submit', $next_button );
}
return $replacement_next_button;
}
Following code works for me in JavaScript:
$('.gf_step_active .gf_step_number').html()
It will give you the page number of the current page in multi-page form.
Using Jquery
var current_page_ = 1+parseInt(jQuery('.gform_page:visible').index());
Try using this one:
var current_visible_page = jQuery('.gf_step_active .gf_step_number').html();
console.log(current_visible_page);
Use the above method in the console to check how it's working.

Using Hook_form_alter on webform submitted values

Drupal 7. Webforms 3.x.
I am trying to modify a webform component value on submit. I made a custom module called 'mos' and added this code to it.
function mos_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'webform_client_form_43') {
dsm($form['#node']->{'webform'}['components']['1']);
$form['#submit'][] = 'mos_contact_us_submit';
}
}
function mos_contact_us_submit($form, &$form_state) {
$form['#node']->{'webform'}['components']['1'] = 'working#mos.com';
}
However when I look at the results in the database the regular, non-overridden value is stored. Can you help let me know what I am doing wrong?
Eventually I want to take the input value and output an email address based on what was provided (for example. 24 turns into bob#somewhere.com) But I think I can figure this part out myself.
You should to place your submit first.
array_unshift(
$form['actions']['submit']['#submit'],
'mos_contact_us_submit'
);
However, if you want to change some variables in form_state, you should to using custom _valadate function.
I got it! BIG Thanks to #dobeerman for pointing me in the right direction. Here is the code that ended up working:
function mos_form_alter(&$form, &$form_state, $form_id) {
if ('webform_client_form_43' == $form_id) {
//dsm($form);
$form['#validate'][] = 'mos_check_email';
}
}
function mos_check_email(&$form, &$form_state, $form_id) {
$emailVal = $form_state['values']['submitted']['to'];
switch($emailVal) {
case 1: $emailVal = 'email#test.com'; break;
case 2: $emailVal = 'email2#test.com'; break;
case 3: $emailVal = 'email3#test.com'; break;
......
}
$form_state['values']['submitted']['to']=$emailVal;
//dpm($form_state);
}
This way I can keep email address private, but still pass variables to the form with _GET. Kind of a weird situation... but we are trying to keep some existing code intact, so it seemed like the best route.
I accidentally messed up my account creation, so I can't give you the credit dobeerman but I emailed the admins and hopefully I will get it straightened out to get you some rep!

custom drupal search module's form losing all post data when submitted

I am modifying an already contributed drupal module (Inline Ajax Search) to handle searching of a specific content type with some search filters (i.e. when searching for help documentation, you filter out your search results by selecting for which product and version of the product you want help with).
I have modified the module some what to handle all the search filters.
I also added in similar functionality from the standard core search module to handle the presenting of the search form and search results on the actual search page ( not the block form ).
The problem is that when i submit the form, i discovered that I'd lose all my post data on that submit because somewhere, and i don't know where, drupal is either redirecting me or something else is happening that is causing me to lose everything in the $_POST array.
here's the hook_menu() implementation:
<?php
function inline_ajax_search_menu() {
$items = array();
$items['search/inline_ajax_search'] = array(
'title' => t('Learning Center Search'),
'description' => t(''),
'page callback' => 'inline_ajax_search_view',
'access arguments' => array('search with inline_ajax_search'),
'type' => MENU_LOCAL_TASK,
'file' => 'inline_ajax_search.pages.inc',
);
}
?>
the page callback is defined as such (very similar to the core search module's search_view function):
<?php
function inline_ajax_search_view() {
drupal_add_css(drupal_get_path('module', 'inline_ajax_search') . '/css/inline_ajax_search.css', 'module', 'all', FALSE );
if (isset($_POST['form_id'])) {
$keys = $_POST['keys'];
// Only perform search if there is non-whitespace search term:
$results = '';
if(trim($keys)) {
require_once( drupal_get_path( 'module', 'inline_ajax_search' ) . '/includes/inline_ajax_search.inc' );
// Collect the search results:
$results = _inline_ajax_search($keys, inline_ajax_search_get_filters(), "page" );
if ($results) {
$results = theme('box', t('Search results'), $results);
}
else {
$results = theme('box', t('Your search yielded no results'), inline_ajax_search_help('inline_ajax_search#noresults', drupal_help_arg()));
}
}
// Construct the search form.
$output = drupal_get_form('inline_ajax_search_search_form', inline_ajax_search_build_filters( variable_get( 'inline_ajax_search_filters', array() ) ) );
$output .= $results;
return $output;
}
return drupal_get_form('inline_ajax_search_search_form', inline_ajax_search_build_filters( variable_get( 'inline_ajax_search_filters', array() ) ) );
}
?>
from my understanding, things should work like this: A user goes to www.mysite.com/search/inline_ajax_search and drupal will process the path given in my url and provide me with a page that holds the themed form for my search module. When i submit the form, whose action is the same url (www.mysite.com/search/inline_ajax_search), then we go thru the same function calls, but we now have data in the $_POST array and one of them is indeed $_POST['form_id'] which is the name of the form "inline_ajax_search_search_form". so we should be able to enter into that if block and put out the search results.
but that's not what happens...somewhere from when i submit the form and get my results and theme it all up, i get redirected some how and lose all my post data.
if anybody can help me, it'd make me so happy lol.
drupal_get_form actually wipes out the $_POST array and so that's why I lose all my post data.
according to this: http://drupal.org/node/748830 $_POST should really be ignored when doing things in drupal. It's better to find a way around using it. One way is the way described in the link, making ur form data persist using the $_SESSION array. I'm sure there are various other and better ways to do this, but yeah, drupal_get_form was the culprit here...

Using FlashMessenger with PartialLoop in ZF view scripts

I have two questions related to the FlashMessenger view helper. Both questions are to do this code:
My action method:
private $_messages; // set to $this->_helper->FlashMessenger; in init()
public function loginAction() {
// > login validation <
// Switch based on the result code
switch ($result->getCode()) {
// > snip several cases <
case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
$this->_messages->addMessage("That wasn't the right password.");
break;
case Zend_Auth_Result::SUCCESS:
$this->_messages->addMessage('Logged you in successfully. Welcome back!');
$this->_helper->Redirector('index', 'home');
break;
}
// >snip<
$this->view->messages = $this->_messages->getMessages();
$this->render();
}
My layout (Zend_Layout) view script:
<?php if (isset($this->messages) && count($this->messages) > 0) {
print_r($this->messages);
//$this->partialLoop('partials/messages.phtml', $this->messages);
} ?>
Why is the message not output the first time it is set?
I have a feeling this is to do with the messenger being stored in sessions but I'm sure it's to do with my implementation.
When I submit a bad value to my form I don't get a message until I either send the form again or refresh.
What is a good way of sending this to the PartialLoop helper?
The output of the messenger is something like:
Array(
[0] => 'Message',
[1] => 'Second message' //etc.
)
But this is no good for a PartialLoop as I need to get the message (which needs each message to be an array, containing a 'message' => 'Message string' key/value pair).
Is there a better method instead of rewriting the array before submitting it to the view?
Referring to OIS I'd like to add that you can retrieve the flash-messages within the same request in which they where added to the FlashMessenger. In this case you'd have to use Zend_Controller_Action_Helper_FlashMessenger::getCurrentMessages().
In your case you'd have to change the line
$this->view->messages = $this->_messages->getMessages();
to
$this->view->messages = $this->_messages->getCurrentMessages();
Hope that helps.
Ill quote from the documentation.
10.8.4.4.1. Introduction
The FlashMessenger helper allows you
to pass messages that the user may
need to see on the next request. To
accomplish this, FlashMessenger uses
Zend_Session_Namespace to store
messages for future or next request
retrieval.
Basically, this means that yes you have to refresh the page to see the messages.
Edit for PartialLoop:
You could try this:
foreach ($array as $message) {
$newArray[]['message'] = $message;
}
But you dont have to use PartialLoop. You could send it to Partial and loop it there. Or even loop it right there in your view.

Categories