Reputation: 185
I have added a widget to a Page with a class of Page. The widget php code returns a PaginatedList and it is successfully rendering in my Page.ss template using the $SidebarView tag.
How can I hijack the pagination click to have the widget rendered with a new template? I assume that testing for is_ajax on the index method and doing a $this->renderWith('myTemplate') is not going to work since I only want to render the widget with the new template, not the whole page.
Here is my current Page.php code drawing from Zauberfisch's original answer:
public function index( SS_HTTPRequest $request ) {
$page = $this->data();
if ( $request->isAjax() ) {
$widgetArea = $page->Sidebar();
$widget = $widgetArea->Widgets()->filter( 'ClassName', 'ScbWidget' );
return $widget->renderWith( 'ScbTemplate' );
} else {
return array();
}
}
and here is my widget php code that returns the paginated list to my template:
public function ScbList() {
$list = new PaginatedList( CatalogItem::get()->filter( array( 'SchoolChoirRelease' => 1 ) ), Controller::curr()->getRequest() );
$list->setPageLength( $this->ShowPerPage );
return $list;
}
When the paginated list is returned to the template without ajax, everything works as expected - ?start=2 returns the list offset by 2 items. When I hijack the link and render the widget using the new template, my list is not being rendered in the new template. Here is my js:
ajaxify = function( href, callback ) {
$.ajax( {
url: href,
success: function( data ) {
callback( data );
}
});
};
hijackSubmit = function() {
jqueryMap.$pagination.on( 'click', 'a', function( e ) {
e.preventDefault();
var href = $( this ).attr( 'href' );
ajaxify( href, function( data ) {
jqueryMap.$container.html( data );
} );
});
};
Upvotes: 0
Views: 554
Reputation: 4015
In SilverStripe any object of type ViewableData
can be rendered. Page is a subclass of ViewableData
, but so is Widget
. A lot of objects in SilverStripe extend ViewableData
.
This means you are already on the right track. I am assuming you have 2 variables:
$request
a request object of type SS_HTTPRequest
$request = $this->getRequest()
)$page
a page object of type Page
or subclass.$page = $this->data()
)now you should be able to do:
if ($request->isAjax()) {
$widgetArea = $page->SideBar();
$widget = $widgetArea->Widgets()->filter('ClassName', 'MyWidget')->First();
return $widget->renderWith('MyWidgetTemplate');
}
// do something else
NOTE: if $request->isAjax()
is never true, add ?ajax=1
to the URL when you call it in javascript. ?ajax=1
will let SilverStripe know that this is an ajax request.
Upvotes: 1