1
votes

I want to show the default SilverStripe site search box in a modal and then upon submission of form want to show the search results in the same modal rather them showing on the page. default search on front end I was following the approach where I created a page type ...

AjaxFormPage extends Page {}
class AjaxFormPage_Controller extends Page_Controller {}

1) In here I did the init method to load jQuery.

2) Created Form (basically, the same search form from the ContentControllerSearchExtension class and pasted in here.

3) Also copied the results function from the ContentControllerSearchExtension as below:

public function resultsAjax($data, $form, $request) {
        //$this->request->isAjax()
        //Director::is_ajax()
        if (Director::is_ajax()) {
    $data = array(
        'Results' => $form->getResults(),
        'Query' => DBField::create_field('Text', $form->getSearchQuery()),
        'Title' => _t('SearchForm.SearchResults', 'Search Results')
    );
    return $this->owner->customise($data)->renderWith(array('Page_results', 'Page'));
        } else {
            return "Not Ajax";
        }
}

}

The Form is going to the following URL /new-ajax-form-page/SearchForm/?Search=asdasd&action_AjaxSubmit=Go

And I am getting the following waring 1, 2 and 3 for each argument to resultsAjax method

[Warning] Missing argument 1 for AjaxFormPage_Controller::resultsAjax(), called in /var/www/projects/xxxx/framework/view/ViewableData.php on line 466 and defined
GET /new-ajax-form-page/SearchForm/?Search=asdasd&action_AjaxSubmit=Go

Line 137 in /var/www/projects/xxxx/mysite/AjaxFormPage.php

[Warning] Missing argument 2 for AjaxFormPage_Controller::resultsAjax(), called in /var/www/projects/xxxx/framework/view/ViewableData.php on line 466 and defined
GET /new-ajax-form-page/SearchForm/?Search=asdasd&action_AjaxSubmit=Go

Line 137 in /var/www/projects/xxxx/mysite/AjaxFormPage.php

[Warning] Missing argument 3 for AjaxFormPage_Controller::resultsAjax(), called in /var/www/projects/xxxx/framework/view/ViewableData.php on line 466 and defined
GET /new-ajax-form-page/SearchForm/?Search=asdasd&action_AjaxSubmit=Go

Line 137 in /var/www/projects/xxxx/mysite/AjaxFormPage.php

Any help how to make it working will be highly appreciated.

1

1 Answers

2
votes

Generally speaking, you shouldn't inject too many concerns about ajax in your backend code. An ajax form should work fundamentally the same as any other form, except for the behaviours that are applied to it on the frontend. This helps with uniformity throughout your code and also allows your forms to degrade gracefully (i.e. they still work without ajax).

In your case, I think all you need is to make the results() function provided by ContentControllerSearchExtension ajax-aware.

Start by overloading results() in Page_Controller.

public function results($data, $form, $request) {
    $data = array(
        'Results' => $form->getResults(),
        'Query' => DBField::create_field('Text', $form->getSearchQuery()),
        'Title' => _t('SearchForm.SearchResults', 'Search Results')
    );
    return $this->owner->customise($data)->renderWith(array('Page_results', 'Page'));
}

Now, instead of returning a full template, check to see if the request is ajax, and if so, return a partial.

public function results($data, $form, $request) {
    // ...

    if ($this->getRequest()->isAjax()) {
      return $this->customise($data)->renderWith('AjaxSearchResults');
    }

    return $this->owner->customise($data)->renderWith(array('Page_results', 'Page'));
}

Where AjaxSearchResults.ss is a template containing only the snippet of HTML you want to inject into the modal window.

Your JS will look something like this (excuse my rusty jQuery):

$('.myForm').submit(e => {
  e.preventDefault();
  const data = $(this).serialize();
  const $form = $(this);
  $.ajax(
    $form.attr('action'),
    {    
      type: 'GET',
      data,
    } 
  })
  .done(response => {
    $('#some-div').html(response);
  });
);

Relevant: https://www.silverstripe.org/learn/lessons/ajax-behaviour-and-viewabledata

UPDATE: Gist: https://gist.github.com/unclecheese/dcb3777e929a429e906b8b5c9ffc9c0b