Skip to content

Commit

Permalink
FEATURE added GridFieldPrintButton compoonent
Browse files Browse the repository at this point in the history
  • Loading branch information
normann committed Apr 3, 2012
1 parent 00b904b commit ba02e50
Show file tree
Hide file tree
Showing 4 changed files with 231 additions and 0 deletions.
169 changes: 169 additions & 0 deletions forms/gridfield/GridFieldPrintButton.php
@@ -0,0 +1,169 @@
<?php
/**
* @package sapphire
* @subpackage gridfield
*/

/**
* Adds an "Print" button to the bottom or top of a GridField.
*
* WARNING: This is experimental and its API is subject to change. Feel free to use it as long as you are happy of
* refactoring your code in the future.
*/
class GridFieldPrintButton implements GridField_HTMLProvider, GridField_ActionProvider, GridField_URLHandler {

/**
* @var array Map of a property name on the printed objects, with values being the column title in the CSV file.
* Note that titles are only used when {@link $csvHasHeader} is set to TRUE.
*/
protected $printColumns;

/**
* @var boolean
*/
protected $printHasHeader = true;

/**
* Fragment to write the button to
*/
protected $targetFragment;

/**
* @param string $targetFragment The HTML fragment to write the button into
* @param array $printColumns The columns to include in the print view
*/
public function __construct($targetFragment = "after", $printColumns = null) {
$this->targetFragment = $targetFragment;
$this->printColumns = $printColumns;
}

/**
* Place the print button in a <p> tag below the field
*/
public function getHTMLFragments($gridField) {
$button = new GridField_FormAction(
$gridField,
'print',
_t('TableListField.Print', 'Print'),
'print',
null
);
$button->setAttribute('data-icon', 'grid_print');
$button->addExtraClass('gridfield-button-print');
//$button->addExtraClass('no-ajax');
return array(
$this->targetFragment => '<p>' . $button->Field() . '</p>',
);
}

/**
* print is an action button
*/
public function getActions($gridField) {
return array('print');
}

function handleAction(GridField $gridField, $actionName, $arguments, $data) {
if($actionName == 'print') {
return $this->handlePrint($gridField);
}
}

/**
* it is also a URL
*/
function getURLHandlers($gridField) {
return array(
'print' => 'handlePrint',
);
}

/**
* Handle the print, for both the action button and the URL
*/
public function handlePrint($gridField, $request = null) {
set_time_limit(60);
Requirements::clear();
Requirements::css(SAPPHIRE_DIR . '/css/GridField_print.css');
if($data = $this->generatePrintData($gridField)){
return $data->renderWith("GridField_print");
}
}

/**
* Export core.
*/
function generatePrintData($gridField) {
$printColumns = ($this->printColumns) ? $this->printColumns : $gridField->getDisplayFields();
if($this->printHasHeader){
$header = new ArrayList();
foreach($printColumns as $field => $label){
$header->push(
new ArrayData(array(
"CellString" => $label,
))
);
}
}

$items = $gridField->getList();
$itemRows = new ArrayList();
foreach($items as $item) {
$itemRow = new ArrayList();
foreach($printColumns as $field => $label) {
$value = $item->relField($field);
$itemRow->push(
new ArrayData(array(
"CellString" => $value,
))
);
}
$itemRows->push(new ArrayData(
array(
"ItemRow" => $itemRow
)
));
}
$ret = new ArrayData(
array(
"Header" => $header,
"ItemRows" => $itemRows,
)
);


$item->destroy();

return $ret;
}

/**
* @return array
*/
function getPrintColumns() {
return $this->printColumns;
}

/**
* @param array
*/
function setPrintColumns($cols) {
$this->printColumns = $cols;
return $this;
}

/**
* @return boolean
*/
function getPrintHasHeader() {
return $this->printHasHeader;
}

/**
* @param boolean
*/
function setPrintHasHeader($bool) {
$this->printHasHeader = $bool;
return $this;
}
}
42 changes: 42 additions & 0 deletions javascript/GridField.js
Expand Up @@ -111,7 +111,49 @@
}
}
});

$('.ss-gridfield .action.gridfield-button-print').entwine({
UUID: null,
onmatch: function() {
this._super();
this.setUUID(new Date().getTime());
},
onclick: function(e){
var self = this, iframeID = 'gridfield-print-iframe' + this.getUUID();
var printIframe = $('#' + iframeID);

if(!printIframe.length){
printIframe = $('<IFRAME id="'+iframeID+'" class="ss-gridfield-print-iframe">');
$(document.body).append(printIframe);
}

var self = this, btn = this.closest(':button'), grid = this.getGridField(),
form = this.closest('form'), data = form.find(':input').serialize();

// Add current button
data += '&' + encodeURIComponent(btn.attr('name')) + '=' + encodeURIComponent(btn.val());

// Include any GET parameters from the current URL, as the view state might depend on it.
// For example, a list prefiltered through external search criteria might be passed to GridField.
if(window.location.search) data = window.location.search.replace(/^\?/, '') + '&' + data;

var url = $.path.makeUrlAbsolute(grid.data('url') + '?' + data, $('base').attr('href'));
printIframe.attr('src', url);
return false;
}
});

$('.ss-gridfield-print-iframe').entwine({
onmatch: function(){
this.hide().bind('load', function()
{
this.focus();
var ifWin = this.contentWindow || this;
ifWin.print();
});;
}
});

/**
* Prevents actions from causing an ajax reload of the field.
* Useful e.g. for actions which rely on HTTP response headers being interpreted nativel
Expand Down
3 changes: 3 additions & 0 deletions scss/GridField_print.scss
@@ -0,0 +1,3 @@
table td{
border: 1px solid black;
}
17 changes: 17 additions & 0 deletions templates/Includes/GridField_print.ss
@@ -0,0 +1,17 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//MI" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="mi" lang="mi">
<head>
</head>
<body>
<table>
<thead>
<tr><% control Header %><td>$CellString</td><% end_control %></tr>
</thead>
<tbody>
<% control ItemRows %>
<tr><% control ItemRow %><td>$CellString</td><% end_control %></tr>
<% end_control %>
</tbody>
</table>
</body>
</html>

0 comments on commit ba02e50

Please sign in to comment.