Solution: Converting HTML Form Post Variables into URL View Parameters

About

A recommended feature within eZ Publish template language is the use of view parameters instead of ezhttp operators to access _GET or _POST variables. View parameters are eZ Publish cache friendly while ezhttp usage is not.

Example Problem

Often a problem arises during requirements analysis and development with eZ Publish is how to submit complex combinations of view parameters as _POST variables and transform those variables into view parameters and redirecting the browser.

An example of this might be a filter bar which limits the results of a fetch with a series of html form inputs and options.

This document should provide an example of turning the html form _POST variables into view parameters.

Solutions

At the end of the day this requires either using one of the following

  • javascript onSubmit/onClick solution (incompatible with text browsers to append parameters and redirect browser)
  • custom module view (compatible with all browsers and simple to create)
  • default '/content/action' module view in eZ Publish to provide this parameter type translation/redirection.

Default /content/action module view

This module view is provided in the default kernel but has some limitations

Variables

  • DestinationURL - This is the path to your view without starting slash. Don't use ezurl on this value as it would add a starting slash.
  • Parameter - Any input variable with the name ie, 'Example #1 In a custom template for the node uri, 'ez_publish_root_node/events'
  • Submit - This parameter is ignored and not translated. Apparently this includes multiple values with the same name.
  • All other parameters submitted within the html form elements be added with the /([name])/[value] view parameters format.

Example Form

<form action={"content/action"|ezurl} method="post">

<input type="hidden" name="DestinationURL" value="{$node.url_alias}" />

<input type="text" name="(keyword)" value="" size="12" /> <br />

<input type="checkbox" name="(year)" value="1999" /> <br />

<input type="checkbox" name="(month)" value="12" /> <br />

<input type="submit" name="Submit" value="Go" />

</form>

Result

Upon submit the user will be redirected to: 'ez_publish_root_node/events/(keyword)//(year)/1999/(month)/12' if both checkboxes are checked and no text is input.

Limitations and Problems

The primary problem with the default 'content/action' module solution is certain html form input _POST values are converted inconsistently due to the generic nature of the solution provided by default.

Checkboxes are only submitted if checked, textline could be optional and on submit send empty values and cause further user page loading / redirection problems.

These problems at any level require custom php to properly detect, evaluate and set reliable url + view parameters hence the recommendation to use the bcposttoview custom module solution if these limitations affect you and your code.

Custom module view

You could create a custom module view within an extension activated for your user siteaccess to provide custom redirection implementation (review the file kernel/content/action.php for the default example).

At some point I hope for someone to publish at least an example of such a solution for further modification as needed by the user / developer as a starting point for avoiding null values in url parameters in redirected url (a common short coming of using the default /content/action module method).

Example Solution

2009.09.20 Brookins Consulting published the bcposttoview module view extension which was an example (several in fact) self contained modules and module views within the bcposttoview extension. The name mirrored off of an old deprecated module view name ezposttoview mentioned online in conjunction as an older example of this functionality but not available to the public, while our bcposttoview is freely available example in response to the for mentioned need (above).

Javascript redirection

You could use javascript to convert html form variables into view parameters. This would be better when used in conjunction with ajax content request than simply html form variables to url variable conversion to avoid the need for a custom module view for redirection.

In the end we think a module view redirection provides better browser compatibility than javascript hands down. Although a javascript solution (or ajax solution) was used on top of the module view solution that would be just fine since it provides a reliable fallback for browsers without javascript.

Example Javascript Method #1

function defaultStaticFormToViewParameterUrlRedirect( suffixString = '' )
{
    var form=document.getElementById( 'form_search' + suffixString );
    var action=form.action;
    
    var todaySelect=document.getElementById( '(today)' + suffixString );
    var locationSelect=document.getElementById( '(location)' + suffixString );
    var keywordSelect=document.getElementById( '(keyword)' + suffixString );
    var eventTypeSelect=document.getElementById( '(eventType)' + suffixString );

    if (todaySelect.value)
    {
        action += '/(today)/' + escape( todaySelect.value ); 
    }
    if (locationSelect.value)
    {
        action += '/(location)/' + escape( locationSelect.value ); 
    }
    if (keywordSelect.value)
    {
        action += '/(keyword)/' + escape( keywordSelect.value ); 
    }
    if (eventTypeSelect.value)
    {
        action += '/(eventType)/' + escape( eventTypeSelect.value ); 
    }

    form.action=action;
}
Example Javascript Form (with fallback)
<form action={"content/action"|ezurl} method="post"  onsubmit="defaultStaticFormToViewParameterUrlRedirect( '' )">

<input type="hidden" name="DestinationURL" value="{$node.url_alias}" />

<input type="text" name="(keyword)" value="" size="12" /> <br />

<input type="checkbox" name="(year)" value="1999" /> <br />

<input type="checkbox" name="(month)" value="12" /> <br />

<input type="submit" name="Submit" value="Go" />

</form>

Example Javascript Method #2

function eventFilter( i )
{
   var filter=document.getElementById( 'EventFilter' );
   var filter_action=filter.action;

   var offset=document.getElementById( 'Offset' );
   var date=document.getElementById( 'Date' );
   var city=document.getElementById( 'City' );
   var state=document.getElementById( 'State' );
   var country=document.getElementById( 'Country' );
   var production=document.getElementById( 'Production' );
   var coordinator=document.getElementById( 'Coordinator' );

   if ( offset.value != '0' )
   {
   filter_action += '/(offset)/' + escape( offset.value ); 
   }
   if ( date.value != 'all' )
   {
   filter_action += '/(date)/' + escape( date.value ); 
   }
   if ( city.value != 'all' )
   {
   filter_action += '/(city)/' + escape( city.value ); 
   }
   if ( state.value != 'all' )
   {
   filter_action += '/(state)/' + escape( state.value ); 
   }
   if ( country.value != 'all' )
   {
   filter_action += '/(country)/' + escape( country.value ); 
   }
   if ( production.value != 'all' )
   {
   filter_action += '/(production)/' + escape( production.value ); 
   }
   if ( coordinator.value != 'all' )
   {
   filter_action += '/(coordinator)/' + escape( coordinator.value ); 
   }
   filter.action=filter_action;
}

Reference