[TYPO3-mvc] Filter plugin in different Controller / content element

typo3 at litedesigns.nl typo3 at litedesigns.nl
Fri Mar 2 11:25:07 CET 2012


Hi List,

This is my first post, so hello all :)

I’m building my first extbase / fluid plugin and with some trial and error
i’m progressing quite nicely. But unfortunately i’ve stumbled on a problem
i haven’t been able to find a solution for. Sorry for the long post, but i
hope to provide all the needed info right away.

I’m using Typo3 4.6.4 with Fluid, Extbase and Fed (from TER).

I have a frontend controller, model, repository and views for a Company
entity i have setup in the Extension Builder. I can list, show, edit,
update and delete my Companies in the frontend.

Based on the sjr_offers plugin and the extbase/fluid book
(http://docs.typo3incubator.org/ExtbaseFluidBook/_build/html/Index.html) i
have created a ‘Demand’ Model and created a findDemanded() function in my
Company repository. When i show the search form (for simplicity i’m only
using a searchWord field for now) in the List.html template above the
<f:for objects=”{companies}”> loop of my Company template i can search /
filter my companies when the form with searchWord is submitted. This works
like a charm! :)

But what i would like to do is separate the search form in a separate
content element. This way in a 2 column layout i can show my search form
in the sidebar and the list of companies in the main content column. (i
have matching frontend and backend Templates for this two column layout).
I have tried two approaches, but neither work:

-== ATTEMPT 1 ==-
I have created a FilterController with a showAction() function and a
Show.html template in Templates/Filter/ folder. The Show.html contains the
form. With configurePlugin() and registerPlugin() i can now insert a
plugin in my sidebar in the backend. But when i submit the search form, my
Company controller listAction never receives the $demand object (i.e. it
is always NULL). I have abbreviated my code for simplicity, but i have
setup all annotations, full class names etc. (since the search form works
when in the List.html of the Company controller template, i don’t think
annotations or something will be the problem)

Code:
class Tx_MyExt_Controller_CompanyController
function listAction(Tx_MyExt_Domain_Model_Demand $demand = NULL)
{
$this->view->assign('demand', $demand);
	$propertiesToSearch = array('field_1', 'field_2');
	$this->view->assign('companies',
$this->companyRepository->findDemanded($demand, $propertiesToSearch));
}

class Tx_MyExt_Domain_Repository_CompanyRepository
function findDemanded(Tx_MyExt_Domain_Model_Demand $demand = NULL, array
$propertiesToSearch = array())
{
	// custom query here by $this->createQuery(), $demand->getSearchWord(),
$query->matching() etc.
	// if $demand == NULL, a simple $this->findAll() is returned
	return $companies;
}

class Tx_MyExt_Domain_Model_Demand
{
	protected $searchWord;
	// getter and setter function for searchWord
}

class Tx_MyExt_Controller_FilterController
{
	/**
	 * action show
	 * @param Tx_MyExt_Domain_Model_Demand $demand A demand taken as a basis
for filtering the companies
	 *
	 * @return void
	 */
	public function showAction(Tx_ MyExt _Domain_Model_Demand $demand = NULL) {
		$this->view->assign('demand', $demand);
	}
}

Resources/Private/Templates/Filter/Show.html
{namespace fed=Tx_Fed_ViewHelpers}

<f:layout name="Default" />

<f:section name="main">
	<f:flashMessages />

	<h2>Filter companies</h2>

	<f:form class="tx-my-ext-companies" method="post" controller="Company"
action="list" name="demand" object="{demand}">
		<tr>
			<td valign="top" ><noscript><f:form.submit
value="Filter"/></noscript></td>
			<td valign="top" ><f:form.textbox id="searchWord" property="searchWord"
style="width: 200px;" additionalAttributes="{onChange :
'document.demand.submit();'}" /></td>
		</tr>
	</f:form>

</f:section>

Now when this form in Templates/Filter/Show.html is submitted, the $demand
object is NULL in my CompanyController listAction() and therefore the
findDemanded() can’t filter my companies on the searchWord. Without the
‘controller’ param in the form, extbase complains about the missing
function listAction() in my FilterController, which makes sense since the
FilterController does not have a listAction, nor is it setup in
configurePlugin(). This makes me believe the form is actually sent to the
CompanyController listAction(), but somehow the the $demand object is
still NULL.


-== ATTEMPT 2 ==-
Instead of creating a new frontend plugin to display my search form, i’ve
tried setting up a Fluid Content Element, a functionality offered by the
FED plugin. The CompanyController, CompanyRepository and DemandModel are
all unchanged.
As my FCE i have this file:

Resources/Elements/CompanyFilter.html
{namespace fed=Tx_Fed_ViewHelpers}

<f:layout name="FCE" />

<f:section name="Configuration">
	<fed:fce id="display-companies_filter" label="Display: Companies Filter"
enabled="TRUE">
		<fed:fce.field.input name="myvalue" label="My custom flexform value" />
	</fed:fce>
</f:section>

<f:section name="Preview">

</f:section>

<f:section name="Main">
	<f:form class="tx-my-ext-companies-filter" method="post" action="list"
controller="Company" name="demand" object="{demand}">
		<tr>
			<td valign="top" ><noscript><f:form.submit
value="Filteren"/></noscript></td>
			<td valign="top" ><f:form.textbox id="searchWord" property="searchWord"
style="width: 90%;" additionalAttributes="{onChange :
'document.demand.submit();'}" /></td>
		</tr>
	</f:form>
</f:section>

In the Backend i have added this FCE to my sidebar. But i don’t know how
to pass the {demand} object (see <f:form> param) to my view template since
there is no controller where i can do something like
$this->view->assign(‘demand’, $demand);.
So this attempt failed at getting the $demand object passed to my view.



-== WORKING CODE – BUT NOT THE DESIRED SOLUTION ==-
Again, all models, controllers etc are unchanged to listed above.

Resources/Private/Templates/Company/List.html
{namespace fed=Tx_Fed_ViewHelpers}

<f:layout name="Default" />

<f:section name="main">
	<f:flashMessages />

	<h1>Overview of Companies</h1>

	<!—search form -->
	<f:form class=" tx-my-ext-companies-filter " method="post" action="list"
name="demand" object="{demand}">
		<tr>
			<td valign="top" ><noscript><f:form.submit
value="Filteren"/></noscript></td>
			<td valign="top" ><f:form.textbox id="searchWord" property="searchWord"
style="200px;" additionalAttributes="{onChange :
'document.demand.submit();'}" /></td>
		</tr>
	</f:form>

	<!—list of companies -->
	<f:for each="{companies}" as="company">
		{company.name}
	</f:for>

</f:section>

When the search form is submitted, the CompanyController listAction()
receives the $demand object with the searchWord set and findDemanded() can
filter my companies


So after this very long post, my question is: how can i separate my search
form into another content element which i can then place in the backend in
any location wanted, even on other pages, since i can simply set the
pageUid=’x’ in my <f:form>.

Kind regads,
Tim








More information about the TYPO3-project-typo3v4mvc mailing list