From a8c586dfc021010835e427477868bc7fdb1b04f7 Mon Sep 17 00:00:00 2001 From: Andrew Short Date: Sun, 23 Dec 2012 22:37:59 +1100 Subject: [PATCH] Implement the add existing search button. --- README.md | 4 + code/GridFieldAddExistingSearchButton.php | 42 ++++++++ code/GridFieldAddExistingSearchHandler.php | 102 ++++++++++++++++++ css/GridFieldExtensions.css | 55 ++++++++++ javascript/GridFieldExtensions.js | 75 +++++++++++++ templates/GridFieldAddExistingSearchButton.ss | 3 + .../GridFieldAddExistingSearchHandler.ss | 36 +++++++ 7 files changed, 317 insertions(+) create mode 100644 code/GridFieldAddExistingSearchButton.php create mode 100644 code/GridFieldAddExistingSearchHandler.php create mode 100644 css/GridFieldExtensions.css create mode 100644 javascript/GridFieldExtensions.js create mode 100644 templates/GridFieldAddExistingSearchButton.ss create mode 100644 templates/GridFieldAddExistingSearchHandler.ss diff --git a/README.md b/README.md index 19e25459..3f7bbfad 100644 --- a/README.md +++ b/README.md @@ -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 () diff --git a/code/GridFieldAddExistingSearchButton.php b/code/GridFieldAddExistingSearchButton.php new file mode 100644 index 00000000..6a2f45a4 --- /dev/null +++ b/code/GridFieldAddExistingSearchButton.php @@ -0,0 +1,42 @@ +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); + } + +} diff --git a/code/GridFieldAddExistingSearchHandler.php b/code/GridFieldAddExistingSearchHandler.php new file mode 100644 index 00000000..0faed89b --- /dev/null +++ b/code/GridFieldAddExistingSearchHandler.php @@ -0,0 +1,102 @@ +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); + } + +} diff --git a/css/GridFieldExtensions.css b/css/GridFieldExtensions.css new file mode 100644 index 00000000..010b6c4b --- /dev/null +++ b/css/GridFieldExtensions.css @@ -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; +} diff --git a/javascript/GridFieldExtensions.js b/javascript/GridFieldExtensions.js new file mode 100644 index 00000000..ccd6c6bc --- /dev/null +++ b/javascript/GridFieldExtensions.js @@ -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 = $("
").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); diff --git a/templates/GridFieldAddExistingSearchButton.ss b/templates/GridFieldAddExistingSearchButton.ss new file mode 100644 index 00000000..c06cb01a --- /dev/null +++ b/templates/GridFieldAddExistingSearchButton.ss @@ -0,0 +1,3 @@ + + <% _t("ADDEXISTING", "Add Existing") %> + diff --git a/templates/GridFieldAddExistingSearchHandler.ss b/templates/GridFieldAddExistingSearchHandler.ss new file mode 100644 index 00000000..eaa531a3 --- /dev/null +++ b/templates/GridFieldAddExistingSearchHandler.ss @@ -0,0 +1,36 @@ +$SearchForm + +

<% _t("RESULTS", "Results") %>

+
+ <% if $Items %> +
    + <% loop $Items %> +
  • $Title
  • + <% end_loop %> +
+ <% else %> +

<% _t("NOITEMS", "There are no items.") %>

+ <% end_if %> + + <% if $Items.MoreThanOnePage %> +
    + <% if $Items.NotFirstPage %> +
  • «
  • + <% end_if %> + + <% loop $Items.PaginationSummary(4) %> + <% if $CurrentBool %> +
  • $PageNum
  • + <% else_if $Link %> +
  • $PageNum
  • + <% else %> +
  • + <% end_if %> + <% end_loop %> + + <% if $Items.NotLastPage %> +
  • »
  • + <%end_if %> +
+ <% end_if %> +