Skip to content
This repository
Browse code

FEATURE added GridFieldPrintButton compoonent

  • Loading branch information...
commit ba02e500e7145516b63d5b915cbaf35844c33846 1 parent 00b904b
Normann Lou authored April 03, 2012
169  forms/gridfield/GridFieldPrintButton.php
... ...
@@ -0,0 +1,169 @@
  1
+<?php
  2
+/**
  3
+ * @package sapphire
  4
+ * @subpackage gridfield
  5
+ */
  6
+
  7
+/**
  8
+ * Adds an "Print" button to the bottom or top of a GridField.
  9
+ * 
  10
+ * WARNING: This is experimental and its API is subject to change.  Feel free to use it as long as you are happy of
  11
+ * refactoring your code in the future.
  12
+ */
  13
+class GridFieldPrintButton implements GridField_HTMLProvider, GridField_ActionProvider, GridField_URLHandler {
  14
+
  15
+	/**
  16
+	 * @var array Map of a property name on the printed objects, with values being the column title in the CSV file.
  17
+	 * Note that titles are only used when {@link $csvHasHeader} is set to TRUE.
  18
+	 */
  19
+	protected $printColumns;
  20
+
  21
+	/**
  22
+	 * @var boolean
  23
+	 */
  24
+	protected $printHasHeader = true;
  25
+	
  26
+	/**
  27
+	 * Fragment to write the button to
  28
+	 */
  29
+	protected $targetFragment;
  30
+
  31
+	/**
  32
+	 * @param string $targetFragment The HTML fragment to write the button into
  33
+	 * @param array $printColumns The columns to include in the print view
  34
+	 */
  35
+	public function __construct($targetFragment = "after", $printColumns = null) {
  36
+		$this->targetFragment = $targetFragment;
  37
+		$this->printColumns = $printColumns;
  38
+	}
  39
+
  40
+	/**
  41
+	 * Place the print button in a <p> tag below the field
  42
+	 */
  43
+	public function getHTMLFragments($gridField) {
  44
+		$button = new GridField_FormAction(
  45
+			$gridField, 
  46
+			'print', 
  47
+			_t('TableListField.Print', 'Print'),
  48
+			'print', 
  49
+			null
  50
+		);
  51
+		$button->setAttribute('data-icon', 'grid_print');
  52
+		$button->addExtraClass('gridfield-button-print');
  53
+		//$button->addExtraClass('no-ajax');
  54
+		return array(
  55
+			$this->targetFragment => '<p>' . $button->Field() . '</p>',
  56
+		);
  57
+	}
  58
+
  59
+	/**
  60
+	 * print is an action button
  61
+	 */
  62
+	public function getActions($gridField) {
  63
+		return array('print');
  64
+	}
  65
+
  66
+	function handleAction(GridField $gridField, $actionName, $arguments, $data) {
  67
+		if($actionName == 'print') {
  68
+			return $this->handlePrint($gridField);
  69
+		}
  70
+	}
  71
+
  72
+	/**
  73
+	 * it is also a URL
  74
+	 */
  75
+	function getURLHandlers($gridField) {
  76
+		return array(
  77
+			'print' => 'handlePrint',
  78
+		);
  79
+	}
  80
+
  81
+	/**
  82
+	 * Handle the print, for both the action button and the URL
  83
+ 	 */
  84
+	public function handlePrint($gridField, $request = null) {
  85
+		set_time_limit(60);
  86
+		Requirements::clear();
  87
+		Requirements::css(SAPPHIRE_DIR . '/css/GridField_print.css');
  88
+		if($data = $this->generatePrintData($gridField)){
  89
+			return $data->renderWith("GridField_print");
  90
+		}
  91
+	}
  92
+
  93
+	/**
  94
+	 * Export core.
  95
+ 	 */
  96
+	function generatePrintData($gridField) {
  97
+		$printColumns = ($this->printColumns) ? $this->printColumns : $gridField->getDisplayFields();
  98
+		if($this->printHasHeader){
  99
+			$header = new ArrayList();
  100
+			foreach($printColumns as $field => $label){
  101
+				$header->push(
  102
+					new ArrayData(array(
  103
+						"CellString" => $label,
  104
+					))
  105
+				);
  106
+			}
  107
+		}
  108
+		
  109
+		$items = $gridField->getList();
  110
+		$itemRows = new ArrayList();
  111
+		foreach($items as $item) {
  112
+			$itemRow = new ArrayList();
  113
+			foreach($printColumns as $field => $label) {
  114
+				$value = $item->relField($field);
  115
+				$itemRow->push(
  116
+					new ArrayData(array(
  117
+						"CellString" => $value,
  118
+					))
  119
+				);
  120
+			}
  121
+			$itemRows->push(new ArrayData(
  122
+				array(
  123
+					"ItemRow" => $itemRow
  124
+				)
  125
+			));
  126
+		}
  127
+		$ret = new ArrayData(
  128
+			array(
  129
+				"Header" => $header,
  130
+				"ItemRows" => $itemRows,
  131
+			)
  132
+		);
  133
+		
  134
+		
  135
+		$item->destroy();
  136
+		
  137
+		return $ret;
  138
+	}
  139
+
  140
+	/**
  141
+	 * @return array
  142
+	 */
  143
+	function getPrintColumns() {
  144
+		return $this->printColumns;
  145
+	}
  146
+
  147
+	/**
  148
+	 * @param array
  149
+	 */
  150
+	function setPrintColumns($cols) {
  151
+		$this->printColumns = $cols;
  152
+		return $this;
  153
+	}
  154
+
  155
+	/**
  156
+	 * @return boolean
  157
+	 */
  158
+	function getPrintHasHeader() {
  159
+		return $this->printHasHeader;
  160
+	}
  161
+
  162
+	/**
  163
+	 * @param boolean
  164
+	 */
  165
+	function setPrintHasHeader($bool) {
  166
+		$this->printHasHeader = $bool;
  167
+		return $this;
  168
+	}
  169
+}
42  javascript/GridField.js
@@ -111,7 +111,49 @@
111 111
 			}
112 112
 		}
113 113
 	});
  114
+	
  115
+	$('.ss-gridfield .action.gridfield-button-print').entwine({
  116
+		UUID: null,
  117
+		onmatch: function() {
  118
+			this._super();
  119
+			this.setUUID(new Date().getTime());
  120
+		},
  121
+		onclick: function(e){
  122
+			var self = this, iframeID = 'gridfield-print-iframe' + this.getUUID();
  123
+			var printIframe = $('#' + iframeID);
  124
+			
  125
+			if(!printIframe.length){
  126
+				printIframe = $('<IFRAME id="'+iframeID+'" class="ss-gridfield-print-iframe">');
  127
+				$(document.body).append(printIframe);
  128
+			}
  129
+			
  130
+			var self = this, btn = this.closest(':button'), grid = this.getGridField(), 
  131
+				form = this.closest('form'), data = form.find(':input').serialize();
  132
+
  133
+			// Add current button
  134
+			data += '&' + encodeURIComponent(btn.attr('name')) + '=' + encodeURIComponent(btn.val());
114 135
 
  136
+			// Include any GET parameters from the current URL, as the view state might depend on it.
  137
+			// For example, a list prefiltered through external search criteria might be passed to GridField.
  138
+			if(window.location.search) data = window.location.search.replace(/^\?/, '') + '&' + data;
  139
+
  140
+			var url = $.path.makeUrlAbsolute(grid.data('url') + '?' + data, $('base').attr('href'));
  141
+			printIframe.attr('src', url);
  142
+			return false;
  143
+		}
  144
+	});
  145
+	
  146
+	$('.ss-gridfield-print-iframe').entwine({
  147
+		onmatch: function(){
  148
+			this.hide().bind('load', function() 
  149
+		    {	
  150
+				this.focus();
  151
+				var ifWin = this.contentWindow || this;
  152
+				ifWin.print();
  153
+		    });;
  154
+		}
  155
+	});
  156
+	
115 157
 	/**
116 158
 	 * Prevents actions from causing an ajax reload of the field.
117 159
 	 * Useful e.g. for actions which rely on HTTP response headers being interpreted nativel
3  scss/GridField_print.scss
... ...
@@ -0,0 +1,3 @@
  1
+table td{
  2
+	border: 1px solid black;
  3
+}
17  templates/Includes/GridField_print.ss
... ...
@@ -0,0 +1,17 @@
  1
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//MI" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  2
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="mi" lang="mi">
  3
+	<head>
  4
+	</head>
  5
+	<body>
  6
+		<table>
  7
+			<thead>
  8
+				<tr><% control Header %><td>$CellString</td><% end_control %></tr>
  9
+			</thead>
  10
+			<tbody>
  11
+				<% control ItemRows %>
  12
+					<tr><% control ItemRow %><td>$CellString</td><% end_control %></tr>
  13
+				<% end_control %>
  14
+			</tbody>
  15
+		</table>
  16
+	</body>
  17
+</html>

0 notes on commit ba02e50

Please sign in to comment.
Something went wrong with that request. Please try again.