Implement the add existing search button.

This commit is contained in:
Andrew Short 2012-12-23 22:37:59 +11:00
parent df6f793212
commit a8c586dfc0
7 changed files with 317 additions and 0 deletions

View File

@ -1,6 +1,10 @@
SilverStripe Grid Field Extensions Module
=========================================
This module provides a number of useful grid field components:
* `GridFieldAddExistingSearchButton` - a more advanced search form for adding items.
Maintainer Contacts
-------------------
* Andrew Short (<andrewjshort@gmail.com>)

View File

@ -0,0 +1,42 @@
<?php
/**
* A modal search dialog which uses search context to search for and add
* existing records to a grid field.
*/
class GridFieldAddExistingSearchButton implements
GridField_HTMLProvider,
GridField_URLHandler {
protected $fragment;
/**
* @param string $fragment
*/
public function __construct($fragment = 'before') {
$this->fragment = $fragment;
}
public function getHTMLFragments($grid) {
Requirements::css('gridfieldextensions/css/GridFieldExtensions.css');
Requirements::javascript('gridfieldextensions/javascript/GridFieldExtensions.js');
$data = new ArrayData(array(
'Link' => $grid->Link('add-existing-search')
));
return array(
$this->fragment => $data->renderWith('GridFieldAddExistingSearchButton'),
);
}
public function getURLHandlers($grid) {
return array(
'add-existing-search' => 'handleSearch'
);
}
public function handleSearch($grid, $request) {
return new GridFieldAddExistingSearchHandler($grid, $this);
}
}

View File

@ -0,0 +1,102 @@
<?php
/**
* Used by {@link GridFieldAddExistingSearchButton} to provide the searching
* functionality.
*/
class GridFieldAddExistingSearchHandler extends RequestHandler {
public static $allowed_actions = array(
'index',
'add',
'SearchForm'
);
/**
* @var GridField
*/
protected $grid;
/**
* @var GridFieldAddExistingSearchButton
*/
protected $button;
/**
* @var SearchContext
*/
protected $context;
public function __construct($grid, $button) {
$this->grid = $grid;
$this->button = $button;
$this->context = singleton($grid->getModelClass())->getDefaultSearchContext();
parent::__construct();
}
public function index() {
return $this->renderWith('GridFieldAddExistingSearchHandler');
}
public function add($request) {
if(!$id = $request->postVar('id')) {
$this->httpError(400);
}
$list = $this->grid->getList();
$item = DataList::create($list->dataClass())->byID($id);
if(!$item) {
$this->httpError(400);
}
$list->add($item);
}
/**
* @return Form
*/
public function SearchForm() {
$form = new Form(
$this,
'SearchForm',
$this->context->getFields(),
new FieldList(
FormAction::create('doSearch', _t('GridFieldExtensions.SEARCH', 'Search'))
->setUseButtonTag(true)
->addExtraClass('ss-ui-button')
->setAttribute('data-icon', 'magnifier')
)
);
$form->addExtraClass('stacked add-existing-search-form');
$form->setFormMethod('GET');
return $form;
}
public function doSearch($data, $form) {
$list = $this->context->getResults($data);
$list = $list->subtract($this->grid->getList());
$list = new PaginatedList($list, $this->request);
$data = $this->customise(array(
'SearchForm' => $form,
'Items' => $list
));
return $data->index();
}
public function Items() {
$list = DataList::create($this->grid->getList()->dataClass());
$list = $list->subtract($this->grid->getList());
$list = new PaginatedList($list, $this->request);
return $list;
}
public function Link($action = null) {
return Controller::join_links($this->grid->Link(), 'add-existing-search', $action);
}
}

View File

@ -0,0 +1,55 @@
/**
* GridFieldAddExistingSearchButton
*/
.add-existing-search-dialog {
min-width: inherit !important;
}
.add-existing-search-dialog .add-existing-search-form .field {
border: none;
box-shadow: none;
margin-bottom: 0;
padding-bottom: 0;
}
.add-existing-search-dialog .add-existing-search-form .field label {
padding-bottom: 4px;
}
.add-existing-search-dialog .add-existing-search-form .Actions {
margin-top: 10px;
}
.add-existing-search-dialog .add-existing-search-items li a {
background: #FFF;
border-bottom-width: 1px;
border-color: #CCC;
border-left-width: 1px;
border-right-width: 1px;
border-style: solid;
display: block;
padding: 6px;
}
.add-existing-search-dialog .add-existing-search-items li:first-child a {
border-radius: 4px 4px 0 0;
border-top-width: 1px;
}
.add-existing-search-dialog .add-existing-search-items li:last-child a {
border-radius: 0 0 4px 4px;
}
.add-existing-search-dialog .add-existing-search-items li a:hover {
background: #F4F4F4;
}
.add-existing-search-dialog .add-existing-search-pagination li {
background: #FFF;
display: block;
float: left;
margin-right: 2px;
margin-top: 12px;
padding: 6px;
}

View File

@ -0,0 +1,75 @@
(function($) {
$.entwine("ss", function($) {
/**
* GridFieldAddExistingSearchButton
*/
$(".add-existing-search-dialog").entwine({
loadDialog: function(deferred) {
var dialog = this.addClass("loading").children(".ui-dialog-content").empty();
deferred.done(function(data) {
dialog.html(data).parent().removeClass("loading");
});
}
});
$(".ss-gridfield .add-existing-search").entwine({
onclick: function() {
var dialog = $("<div></div>").appendTo("body").dialog({
modal: true,
resizable: false,
width: 500,
height: 600,
close: function() {
$(this).dialog("destroy").remove();
}
});
dialog.parent().addClass("add-existing-search-dialog").loadDialog(
$.get(this.prop("href"))
);
dialog.data("grid", this.closest(".ss-gridfield"));
return false;
}
});
$(".add-existing-search-dialog .add-existing-search-form").entwine({
onsubmit: function() {
this.closest(".add-existing-search-dialog").loadDialog($.get(
this.prop("action"), this.serialize()
));
return false;
}
});
$(".add-existing-search-dialog .add-existing-search-items a").entwine({
onclick: function() {
var link = this.closest(".add-existing-search-items").data("add-link");
var id = this.data("id");
var dialog = this.closest(".add-existing-search-dialog")
.addClass("loading")
.children(".ui-dialog-content")
.empty()
$.post(link, { id: id }, function() {
dialog.data("grid").reload();
dialog.dialog("close");
});
return false;
}
});
$(".add-existing-search-dialog .add-existing-search-pagination a").entwine({
onclick: function() {
this.closest(".add-existing-search-dialog").loadDialog($.get(
this.prop("href")
));
return false;
}
});
});
})(jQuery);

View File

@ -0,0 +1,3 @@
<a href="$Link" class="ss-ui-button ui-button add-existing-search" data-icon="magnifier">
<% _t("ADDEXISTING", "Add Existing") %>
</a>

View File

@ -0,0 +1,36 @@
$SearchForm
<h3><% _t("RESULTS", "Results") %></h3>
<div class="add-existing-search-results">
<% if $Items %>
<ul class="add-existing-search-items" data-add-link="$Link('add')">
<% loop $Items %>
<li class="$EvenOdd"><a href="#" data-id="$ID">$Title</a></li>
<% end_loop %>
</ul>
<% else %>
<p><% _t("NOITEMS", "There are no items.") %></p>
<% end_if %>
<% if $Items.MoreThanOnePage %>
<ul class="add-existing-search-pagination">
<% if $Items.NotFirstPage %>
<li><a href="$Items.PrevLink">&laquo;</a></li>
<% end_if %>
<% loop $Items.PaginationSummary(4) %>
<% if $CurrentBool %>
<li class="current">$PageNum</li>
<% else_if $Link %>
<li><a href="$Link">$PageNum</a></li>
<% else %>
<li>&hellip;</li>
<% end_if %>
<% end_loop %>
<% if $Items.NotLastPage %>
<li><a href="$Items.NextLink">&raquo;</a></li>
<%end_if %>
</ul>
<% end_if %>
</div>