2 /**********************************************************************
3 Copyright (C) FrontAccounting, LLC.
4 Released under the terms of the GNU General Public License, GPL,
5 as published by the Free Software Foundation, either version 3
6 of the License, or (at your option) any later version.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
11 ***********************************************************************/
13 // Template for simple table editors
19 var $_none = ''; // selector value when no item is selected
20 var $pre_handlers; // control buttons and related methods called before view display
29 function simple_crud($name, $fields = null)
32 $this->pre_handlers = array(
34 'Delete' => '_delete',
37 'UPDATE' => '_update',
42 '' => 'list_view', // default view
43 'Edit' => 'editor_view',
44 'Delete' => 'list_view',
45 'NEW' => 'editor_view',
46 'ADD' => 'editor_view',
47 'UPDATE' => 'editor_view',
48 'RESET' => 'list_view',
49 'CLONE' => 'editor_view'
51 $this->tool_buttons['Edit'] =
52 array(_('Edit'), _('Edit document line'), ICON_EDIT, '');
53 $this->tool_buttons['Delete'] =
54 array(_('Delete'), _('Remove line from document'), ICON_DELETE, '');
55 $this->tool_buttons['UPDATE'] =
56 array(_('Update'), _('Confirm changes'), ICON_UPDATE, '');
57 $this->tool_buttons['RESET'] =
58 array(_('Cancel'), _('Cancel changes'), ICON_CANCEL, '');
60 $this->fields = $fields;
61 $this->selected_id = $this->_none;
64 Input/output formatters - convert values between php/user domains.
66 function _format_input($value, $fmt)
70 $this->dec = get_qty_dec($value);
75 return user_numeric($value);
77 return user_numeric($value)/100;
85 function _format_output($value, $fmt)
89 return price_format($value);
91 return number_format2($value, $this->dec);
93 return number_format2($value);
95 return percent_format($value*100);
97 $this->dec = get_qty_dec($value); // retrieve dec for use in later qty fields
105 function _check_mode()
109 $sel_name = $this->name.'_id';
111 // list controls lookup
112 foreach (array_keys($this->pre_handlers) as $m) {
113 if (isset($_POST[$this->name.$m])) {
114 unset($_POST['_focus']); // focus on first form entry
115 $Ajax->activate($this->name.'_div');
116 $val = @key($_POST[$this->name.$m]);
117 $this->selected_id = $val!==null ? @quoted_printable_decode($val) : $this->_none;
121 $mod = get_post($this->name.'Mode', '');
124 $this->selected_id = $val!==null ? @quoted_printable_decode($val) : $this->_none;
131 // Set record for edition
133 function _edit($mode)
135 if ($this->Mode != $mode) {
136 if ($this->selected_id != $this->_none) {
137 $this->data = $this->db_read();
139 $this->set_posts($this->data);
144 // Update record after edition
146 function _update($mode)
149 if ($this->update_check()) {
150 if ($this->db_update()) {
151 $this->selected_id = $this->_none;
164 if ($this->insert_check()) {
172 // Delete selected record
176 if ($this->delete_check())
181 // Return to listing view
185 $this->selected_id = $this->_none;
190 // Clone record for new edition
195 $this->_edit('Edit');
196 $this->selected_id = $this->_none;
199 Generate form controls
201 function _bottom_controls()
203 $clone = $this->selected_id != $this->_none;
211 if ($async === 'both') {
212 $async = 'default'; $cancel = 'cancel';
214 else if ($async === 'default')
216 else if ($async === 'cancel')
220 if ($this->Mode == '' || $this->Mode == 'RESET')
221 submit("{$base}NEW", _("Add new"), true, $title, $async);
223 if ($this->Mode == 'NEW' || $this->selected_id==$this->_none)
225 submit("{$base}ADD", _("Add"), true, $title, $async);
227 submit("{$base}UPDATE[{$this->selected_id}]", _("Update"), true, _('Submit changes'), $async);
229 submit("{$base}CLONE[{$this->selected_id}]", _("Clone"), true, _('Edit new record with current data'), $async);
231 submit("{$base}RESET", _("Cancel"), true, _('Cancel edition'), $cancel);
235 //===========================================================================
239 function tool_button($name, $selected_id=null, $params='')
241 $b = $this->tool_buttons[$name];
243 return "<td align='center' $params>"
244 .button( "{$this->name}$name"
245 .($selected_id === null || $selected_id === $this->_none ? '': "[$selected_id]"),
246 $b[0], $b[1], $b[2], $b[3])."</td>";
251 foreach($this->fields as $name => $fmt) {
256 $post = isset($fmt['post']) ? $fmt['post'] : $name;
257 $fld = isset($fmt['fld']) ? $fmt['fld'] : $name;
259 $value = $this->selected_id == $this->_none ? @$fmt['dflt'] :
260 (is_array($this->data) ? $this->data[$fld]: $this->data->$fld);
262 $_POST[$post] = $this->_format_output($value, @$fmt['fmt']);
265 //--------------------------
267 // Get editor POST variables.
269 function get_posts() {
270 foreach ($this->fields as $name => $fmt) {
275 $post = isset($fmt['post']) ? $fmt['post'] : $name;
276 $fld = isset($fmt['fld']) ? $fmt['fld'] : $name;
278 $value = $this->_format_input(@$_POST[$post], @$fmt['fmt']);
279 if (is_array($this->data))
280 $this->data[$fld] = $value;
282 $this->data->$fld = $value;
285 // Main function - display current CRUD editor content
289 if (!isset($_POST[$this->name.'Mode']))
292 $Mode = $this->_check_mode(true);
293 div_start($this->name.'_div');
295 if (array_key_exists($Mode, $this->pre_handlers)) {
296 $fun = $this->pre_handlers[$Mode];
300 if (isset($this->views[$this->Mode]))
301 $this->{$this->views[$this->Mode]}();
303 $this->{$this->views['']}(); // default view
305 $this->_bottom_controls();
306 // this is needed only when we use temporary crud object together with ajax screen updates
307 hidden($this->name.'Mode'.'['.$this->selected_id.']', $this->Mode);
311 //===========================================================================
312 // Database functions placeholders
315 // Read record from db for edition
318 display_notification(__FUNCTION__. ' is not defined...');
322 // Update record in db after edition
331 function db_delete() {
332 display_notification(__FUNCTION__. ' is not defined...');
339 display_notification(__FUNCTION__. ' is not defined...');
343 // Optional things like focus set.
350 function delete_check() {
351 display_notification(__FUNCTION__. ' is not defined...');
355 function insert_check() {
359 function update_check()
361 return $this->insert_check();
365 // Show database content in pager/table
367 function list_view() {
368 display_notification(__FUNCTION__. ' is not defined...');
372 // Show record editor screen content
374 function editor_view() {
375 display_notification(__FUNCTION__. ' is not defined...');