Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

All other Modules /

Discuss all other Modules here.

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

Generic Views Module - Problem with search results


Go to End


6 Posts   2502 Views

Avatar
ciaranhickey

Community Member, 17 Posts

7 January 2010 at 6:56am

Hi,

I recently installed the genericviews module (http://silverstripe.org/generic-views-module/) with the aim of using it for a scaffolded search.
I got it up and running fine (created new CollectionPage and selected CollectionController as the controller class and selected my DataObject class for the model class (I'm searching data object 'Authors'). All fine! And the search works fine....

However when it comes to the templates my CollectionController.ss (in Layout folder) has an include for the results (<% include CollectionController_results %>) and when I go to the search page initially ALL my dataobjects (Authors) are being listed below my search (ie. Results contains everything BEFORE I search) - However when I search it all works fine but the initial search form page shows the full list). Obviously if I remove the include above it shows nothing on the search results page (Which appears to be the same template).

Apologies if I'm not explaining correctly. But I guess I'm looking for a way of only showing results once search is carried out. I tried using a CollectionPage_results.ss similar to a regular searchcontext but I had no luck in telling the Search to use this template. (I even tried modifying the CollectionController.php to include a ->renderWith(CollectionPage_results) but had no luck!

Hope someone can help - been at this for ages now!

Thanks in advance.
Ciarán

Avatar
Euphemismus

Community Member, 82 Posts

7 January 2010 at 10:09am

Hi, I think I've come across the same problem. I'm dealing with it as follows:
I'm not showing the results initially.
Instead I've ajaxified the search form's call and added a method to render the search results with a separate template.
This way you can have a placeholder (e.g. a <div id="searchResult">&nbsp;</div>) on your main template where you show the search form and lateron fill it with your data. For Ajax I use jQuery from the jsparty directory with the plugin "form".
If you need, I can post some code examples.

Regards,
Marc

Avatar
ciaranhickey

Community Member, 17 Posts

8 January 2010 at 6:24am

Thanks for your help. Some code might be useful as I've not really gone near any AJAX in Silverstripe yet. For the moment I'll keep plugging away for a solution.

Thanks,
Ciaran

Avatar
Euphemismus

Community Member, 82 Posts

8 January 2010 at 8:14am

Hi Ciaran,

this is the code from my EntryCategory controller:

	/**
	 * create searchform based on CustomSearchContext fields
	 *
	 * @see Entry::getCustomSearchContext
	 * @return object form
	 */
	public function SearchForm()
	{
		$context = singleton( 'Entry' )->getCustomSearchContext();
		$fields = $context->getSearchFields();

		$form = new Form(
								$this,
								'SearchForm',
								$fields,
								new Fieldset(
									new FormAction( 'doSearch', _t( 'EntryCategory.DOSEARCH', 'Suchen' ) )
								)
							);

		return $form;
	}

	/**
	 * execute search
	 *
	 * @param $data
	 * @param $form
	 * @return string rendered content
	 */
	public function doSearch( $data, $form )
	{
		$context = singleton( 'Entry' )->getCustomSearchContext();

		...

		$results = $context->getResults( $data );

		return $this->customise( array(
					'Results' => $results,
					) )->renderWith( 'EntryCategory_Results' );
	}

Here I get a custom search context, but the crucial part is the "doSearch" method which has a renderWith() call chained. This I use to get a rendered template response.

In your /mysite/code/Page.php you'll need an init() method call to include the needed jQuery sources:

	function init()
	{
		Requirements::javascript( THIRDPARTY_DIR . '/jquery/jquery-packed.js' );
		Requirements::javascript( THIRDPARTY_DIR . '/jquery/plugins/livequery/jquery.livequery.js' );
		Requirements::javascript( THIRDPARTY_DIR . '/jquery/plugins/form/jquery.form.js' );

		...

		parent::init();
	}

Here you load the jQuery sources and plugins. So you're able to use the form plugin :-)
Now you need two templates: One for your searchform and one for the results. The easiest way is to use your existing one and strip the whole part with the control to iterate the resultset.

EntryCategory.ss:

<div id="entryCategory">
	<h2>
		<a href="$Link">$Title</a>
	</h2>

	$Content

	$SearchForm

	<div id="Form_SearchForm_Result">&nbsp;</div>
</div>

Now the results (EntryCategory_Results.ss):

	<% if Entries %>
		...
		<% control Entries %>
			...
		<% end_control %>
	<% else %>
		<h3>Sorry, no entries</h3>
	<% end_if %>

This result template needs to be placed in the code-folder where your controller is located. I haven't figured out why SS searches in there for the template in this special case...

Now the fun-part :-)
Since we use jQuery, this is quite easy: You'll have to place this code either in your main .js file (maybe use a try/catch) or within script tags in the controller's template (in my case EntryCategory.ss), so the stuff will be loaded with the page and finds the mentioned id to hook in.
JS in script-tag-style:

<script type="text/javascript">
/* <![CDATA[ */
jQuery( document ).ready( function()
{
	var options = {
			target:		'#Form_SearchForm_Result'
	};

	// bind to the form's submit event
	jQuery( '#Form_SearchForm' ).submit( function()
	{
		jQuery( this ).ajaxSubmit( options );
		return false;
	} );
}
/* ]]> */
</script>

Normally I'd place this at the bottom of the template file.
Some things to keep in mind about jQuery:

  • SS uses prototype for lots of things, so don't use "jQuery" instead of "$" as selector
  • use jQuery(document).ready(), so jQ will load and hook in directly after the DOM is ready (before the complete page is loaded)

I hope this helps :-)

Regards,
Marc

Avatar
ciaranhickey

Community Member, 17 Posts

9 January 2010 at 6:11am

Thanks Marc, this helped me out a lot!!

Thanks for taking the time to go through the code.
My main issues were with the Controller dosearch functionality - but I've solved my issue now.

Thanks again for your help.

Ciaran

Avatar
Euphemismus

Community Member, 82 Posts

9 January 2010 at 6:32am

You're welcome - Figuring this out took me quite some time (and a real pain in the ass), too :-(