1: <?php
2:
3: class ListFieldSet {
4:
5: 6: 7: 8:
9: private $fieldsetData;
10:
11: 12: 13: 14:
15: private $parent;
16:
17: public function __construct(ExtendedFormHelper $parent, \FieldSetDefinition $fieldsetData) {
18: $this->parent = $parent;
19: $this->fieldsetData = $fieldsetData;
20: $this->javascriptVariable = 'ExtendedFormHelper_ListFieldset_' . $this->parent->createNewDomId();
21: $this->tableId = $this->parent->createNewDomId();
22: $this->newRowPrototypeId = $this->parent->createNewDomId();
23: }
24:
25: public function output() {
26:
27: $b = $this->_legend();
28: $b .= $this->_newRowPrototype();
29:
30: $b .= '<div class="actions">';
31: $b .= $this->parent->Html->link(
32: __d('extended_scaffold', 'New', true), '#', array(
33: 'onclick' => <<<EOT
34: {$this->javascriptVariable}.addRow();
35: return false;
36: EOT
37: )
38: );
39: $b .= '</div>';
40:
41: $b .= $this->parent->Lists->rowsTable(
42: $this->_columns()
43: , $this->_rows()
44: , $this->_tableOptions()
45: );
46:
47: $b .= $this->parent->javascriptTag(<<<EOT
48: {$this->javascriptVariable} = new ExtendedFormHelper.ListFieldSet(
49: '{$this->tableId}',
50: '{$this->newRowPrototypeId}',
51: {$this->_lastRowIndex()}
52: );
53: EOT
54: );
55:
56: return $b;
57: }
58:
59: private function _tableOptions() {
60: return array(
61: 'model' => $this->_model()
62: , 'showActions' => false,
63: 'htmlAttributes' => array(
64: 'id' => $this->tableId,
65: )
66: );
67: }
68:
69: private function _legend() {
70: return $this->fieldsetData->getLabel() ?
71: "<h3>{$this->fieldsetData->getLabel()}</h3>" :
72: '';
73: }
74:
75: private function _instances() {
76: $instances = array();
77:
78: if (!empty($this->parent->data[$this->_listAssociation()])) {
79: if (is_array($this->parent->data[$this->_listAssociation()])) {
80: foreach ($this->parent->data[$this->_listAssociation()] as $rowIndex => $instance) {
81: $instances[$rowIndex][$this->_listAssociation()] = $instance;
82: }
83: }
84: }
85:
86: return $instances;
87: }
88:
89: private function _rows() {
90: $rows = array();
91: foreach ($this->_instances() as $rowIndex => $instance) {
92: $rows[] = array_merge(array(
93: '_rowIndex' => $rowIndex
94: ), $instance);
95: }
96: return $rows;
97: }
98:
99: private function _lastRowIndex() {
100: $last = -1;
101: foreach ($this->_rows() as $row) {
102: if ($row['_rowIndex'] > $last) {
103: $last = $row['_rowIndex'];
104: }
105: }
106: return $last;
107: }
108:
109: private function _model() {
110: return $this->parent->CakeLayers->modelAssociationModel(
111: $this->_parentModel()
112: , $this->_listAssociation()
113: , true
114: );
115: }
116:
117: private function _listAssociation() {
118: return $this->fieldsetData->getListAssociation();
119: }
120:
121: private function _parentModel() {
122: return $this->parent->model();
123: }
124:
125: private function _fields() {
126: $fields = array();
127: foreach ($this->fieldsetData->getLines() as $line) {
128: foreach ($line->getFields() as $field) {
129: $fields[] = $field;
130: }
131: }
132: return $fields;
133: }
134:
135: private function _columns() {
136: $columns = array();
137: foreach ($this->_fields() as $field) {
138: $options = array(
139: 'valueFunction' => array($this, '_fieldColumnCallback'),
140: 'escapeHtml' => false,
141: 'extraData' => array(
142: 'fieldOptions' => $field->getOptions()
143: )
144: );
145: if (!empty($options['extraData']['fieldOptions']['label'])) {
146: $options['label'] = $options['extraData']['fieldOptions']['label'];
147: }
148:
149: $columns[$field->getName()] = $options;
150: }
151:
152: $columns['_deleteButton'] = array(
153: 'label' => __d('extended_scaffold','Actions', true),
154: 'valueFunction' => array($this, '_actionsColumnValueFunction'),
155: );
156:
157: return $columns;
158: }
159:
160: public function _fieldColumnCallback($view, $instance, $fieldData) {
161: unset($fieldData['extraData']['fieldOptions']['label']);
162: return $this->parent->input(
163: $this->_fieldName($instance, $fieldData['path'])
164: , array_merge(
165: array('label' => false), $fieldData['extraData']['fieldOptions']
166: )
167: );
168: }
169:
170: public function _actionsColumnValueFunction($view, $instance, $fieldData) {
171: $b = '<div class="actions">';
172: $b .= $this->parent->Html->link(
173: __d('extended_scaffold','Delete', true), '#', array(
174: 'onclick' => <<<EOT
175: {$this->javascriptVariable}.removeRow(this);
176: return false;
177: EOT
178: )
179: );
180: $b .= '</div>';
181:
182: $b .= $this->parent->hidden(
183: $this->_fieldName(
184: $instance, array(
185: $this->_model()->alias,
186: $this->_model()->primaryKey
187: )
188: )
189: );
190:
191: return $b;
192: }
193:
194: private function _fieldName($instance, $fieldPath) {
195: $name = $fieldPath[0] . '.' . $instance['_rowIndex'];
196: for ($i = 1; $i < count($fieldPath); ++$i) {
197: $name .= '.' . $fieldPath[$i];
198: }
199:
200: return $name;
201: }
202:
203: private function _newRowPrototype() {
204: $tableId = $this->parent->createNewDomId();
205: $b = "<table id='$tableId' style='display: none'>";
206: $b .= $this->parent->Lists->rowLine($this->_columns(), array(
207: '_rowIndex' => '%rowIndex%',
208: ), 0, $this->_tableOptions(), array(
209: 'htmlAttributes' => array(
210: 'id' => $this->newRowPrototypeId,
211: )
212: ));
213: $b .= '</table>';
214:
215: $b .= $this->parent->javascriptTag(<<<EOT
216: $(document).ready(function(){
217: {$this->javascriptVariable}.removeElementFromForm('#$tableId');
218: });
219: EOT
220: );
221:
222: return $b;
223: }
224:
225: }
226:
227: ?>
228: