forked from lazymofo/datagrid
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
675 lines (486 loc) · 25.5 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Lazy Mofo Datagrid for PHP & MySQL CRUD</title>
<meta name="keywords" content="PHPGrid Free, PHP DataGrid, Automatic CRUD, PHP CRUD" />
<meta name="description" content="Lazy Mofo is a SQL meta driven form and grid generator for PHP and MySQL." />
<meta name="robots" content="noindex,nofollow">
<style>
* { font-family: sans-serif; }
body { margin: 40px; }
pre { font-family: monospace, courier; color: blue; margin-left: 10px; padding: 10px; border: 1px solid #999; border-radius: 2px; border-right: 0; background-color: #ffd; width: 100%; font-size: 70%; }
li { margin: 6px; }
.gray { color: #555; }
</style>
</head>
<body>
<img src='https://i.imgur.com/CGDTkQL.png' alt='logo' align='left' style='margin: 10px; clear: both;' />
<h1 style='clear:left;'>Lazy Mofo (LM) PHP Datagrid</h1>
<div>
<a href='https://github.com/lazymofo/datagrid'>github</a> |
<a href='http://lmdatagrid.hopto.org/'>live demo</a> |
<a href='mailto:iansoko@gmail.com'>email</a>
</div>
<p>LM is a single PHP class for performing CRUD (create, read, update and delete) operations on a MySQL database table.</p>
<ul>
<li>Define grids and forms by SQL statements or table name</li>
<li>Populate select, radio, and checkbox inputs with data from SQL statements</li>
<li>Upload documents, resize or crop images</li>
<li>Grid features include pagination, sorting, and inline editing. Searching can be added.</li>
<li>Grid uses SQL_CALC_FOUND_ROWS, limit + offset for efficiency and low memory usage on large datasets</li>
<li>Built-in validation, error reported next to input</li>
<li>i18n/internationalization enabled. See i18n/template.php to submit your county-language file.</li>
<li>Lightweight; a single class</li>
</ul>
<h1>Contents</h1>
<ul>
<li><a href='#whats_new'>What's New</a></li>
<li><a href='#requirements'>Requirements</a></li>
<li><a href='#example_1'>Example 1 - Basic Usage</a></li>
<li><a href='#example_2'>Example 2 - Advanced Usage</a></li>
<li><a href='#hiding_or_altering_links_and_buttons'>Hiding or Altering Links and Buttons</a></li>
<li><a href='#redirect_to_edit_screen_after_update_and_insert'>Redirect to Grid Screen After Update and Insert</a></li>
<li><a href='#input_and_output_controls'>Input and Output Controls - define how a field is rendered</a></li>
<ul>
<li><a href='#native_input_controls'>Native Input Controls</a></li>
<li><a href='#native_output_controls'>Native Output Control</a></li>
<li><a href='#defining_custom_input_and_output_controls'>Defining Custom Input and Output Controls</li>
<li><a href='#Automatically Populated Controls'>Automatically Populated Controls</li>
</ul>
<li><a href='#adding_search'>Adding Search</a></li>
<li><a href='#customizing_the_search_form'>Customizing the Search Form</a></li>
<li><a href='#defining_separate_add_and_edit_forms'>Defining Separate Add and Edit Forms</a></li>
<li><a href='#validation'>Validation</a></li>
<li><a href='#on_insert_update_delete_events'>On Insert/Update/Delete Events</a></li>
<li><a href='#cross_site_request_forgery_protection_token'>Cross Site Request Forgery Protection Token</a></li>
<li><a href='#i18n'>i18n/Internationalization</a></li>
<li><a href='#date_formats'>Date Formats</a></li>
<li><a href='#adding_jquery_ui_datepicker'>Adding JQuery UI Datepicker</a></li>
<li><a href='#export_to_csv'>Export to CSV</a></li>
<li><a href='#more_features_and_settings'>More Features and Settings</a></li>
</ul>
<h1 style='clear:left;'><a name='whats_new'>What's New</a></h1>
<ul>
<li>New syntax for input/output controls and validation; backward compatible, no worries.</li>
<li>Online demo is back, running on my Raspberry PI.</li>
<li>Header redirect are now relative. This will breaks ancient web browsers but helps in the modern world where port forwarding is common.</li>
<li>Added i18n/internationalization. See i18n/template.php if want to submit your county + language file.</li>
<li>Switched default mysql charset from utf8 to utf8mb4</li>
<li>Replaced preg_match_all with one that works properly with multibyte</li>
</ul>
<h1><a name='requirements'>Requirements</a></h1>
<ul>
<li>PHP 5+ and MySQL 5</li>
<li>Magic Quotes should be turned off</li>
<li>PDO MySQL module installed for PHP</li>
<li>Database table must have a primary key identity</li>
<li>Multibyte Support / mbstring must be enabled</li>
</ul>
<h1><a name='example_1'>Example 1 - Basic Usage</a></h1>
<pre>
include('lazy_mofo.php');
// required for csv export
ob_start();
// connect to database with pdo
$dbh = new PDO("mysql:host=localhost;dbname=test;", 'user', 'password');
// create LM object, pass in PDO connection, see i18n folder for language + country options
$lm = new lazy_mofo($dbh, 'en-us');
// table name for updates, inserts and deletes
$lm->table = 'market';
// identity / primary key column name
$lm->identity_name = 'market_id';
// use the lm controller
$lm->run();
</pre>
<h1><a name='example_2'>Example 2 - Advanced Usage</a></h1>
<pre>
include('lazy_mofo.php');
// enter your database host, name, username, and password
$db_host = 'localhost';
$db_name = 'test';
$db_user = 'root';
$db_pass = '';
// connect with pdo
try {
$dbh = new PDO("mysql:host=$db_host;dbname=$db_name;", $db_user, $db_pass);
}
catch(PDOException $e) {
die('pdo connection error: ' . $e->getMessage());
}
// create LM object, pass in PDO connection, see i18n folder for country + language options
$lm = new lazy_mofo($dbh, 'en-us');
// table name for updates, inserts and deletes
$lm->table = 'market';
// identity / primary key for table
$lm->identity_name = 'market_id';
// optional, make friendly names for fields
$lm->rename['country_id'] = 'Country';
// optional, define input controls on the form
$lm->form_input_control['photo'] = array('type' => 'image');
$lm->form_input_control['is_active'] = array('type' => 'radio', 'sql' => "select 1, 'Yes' union select 0, 'No'");
$lm->form_input_control['country_id'] = array('type' => 'select', 'sql' => 'select country_id, country_name from country');
// optional, define editable input controls on the grid
$lm->grid_input_control['is_active'] = array('type' => 'checkbox');
// optional, define output control on the grid
$lm->grid_output_control['contact_email'] = array('type' => 'email'); // make email clickable
$lm->grid_output_control['photo'] = array('type' => 'image'); // make image clickable
// show search box, but _search parameter still needs to be passed to query below
$lm->grid_show_search_box = true;
// query to define grid view
// IMPORTANT - last column must be the identity/key for [edit] and [delete] links to appear
// include an 'order by' to prevent potential parsing issues
$lm->grid_sql = "
select
m.market_id
, m.market_name
, m.photo
, m.contact_email
, c.country_name
, m.is_active
, m.create_date
, m.market_id
from market m
left
join country c
on m.country_id = c.country_id
where coalesce(m.market_name, '') like :_search
or coalesce(m.contact_email, '') like :_search
or coalesce(c.country_name, '') like :_search
order by m.market_id desc
";
// bind parameter for grid query
$lm->grid_sql_param[':_search'] = '%' . trim(@$_REQUEST['_search']) . '%';
// optional, define what is displayed on edit form. identity id must be passed in also.
$lm->form_sql = "
select
market_id
, market_name
, country_id
, photo
, contact_email
, is_active
, create_date
, notes
from market
where market_id = :market_id
";
// bind parameter for form query
$lm->form_sql_param[':market_id'] = @$_REQUEST['market_id'];
// optional, validation - regexp, 'email' or a user defined function, all other parameters optional
$lm->on_insert_validate['market_name'] = array('regexp' => '/.+/', 'error_msg' => 'Missing Market Name', 'placeholder' => 'this is required', 'optional' => false);
$lm->on_insert_validate['contact_email'] = array('regexp' => 'email', 'error_msg' => 'Invalid Email', 'placeholder' => 'this is optional', 'optional' => true);
// copy validation rules, same rules when updating
$lm->on_update_validate = $lm->on_insert_validate;
// run the controller
$lm->run();
</pre>
<h1><a name='hiding_or_altering_links_and_buttons'>Hiding or Altering Links and Buttons</a></h1>
Most links, buttons, and messages can be hidden or altered. View the class source code to see all the member variables.<br>
i18n/internationalization are in the process of being added. Check the i18n folder for your language + country. Set the i18n by passing the language + country code into the constructor.
<pre>
Example:
// change back button to read "Cancel"
$lm->form_back_button = "<input type='button' value='Cancel' class='lm_button dull' onclick='_back();'>";
// alter link text
$lm->grid_add_link = str_replace('Add a Record', 'Add New', $lm->grid_add_link);
$lm->grid_edit_link = str_replace('[edit]', 'Edit', $lm->grid_edit_link);
// hide delete and export links
$lm->grid_delete_link = "";
$lm->grid_export_link = "";
// change success message
$lm->form_text_record_added = "New Record Added";
$lm->grid_text_record_added = "New Record Added";
</pre>
<h1><a name='redirect_to_edit_screen_after_update_and_insert'>Redirect to Grid Screen After Update and Insert</a></h1>
<p>By default the user is redirected back to the edit form after making updates or inserting a record. Redirect users to the opening grid screen by setting the following variables to false:</p>
<pre>
$lm->return_to_edit_after_insert = false;
$lm->return_to_edit_after_update = false;
</pre>
<h1><a name='input_and_output_controls'>Input and Output Controls - define how a field is rendered</a></h1>
<p>Input and Output Controls are associative arrays used to define how to render input or output for a field.</p>
<p><b>Inputs</b> render form inputs such as textarea, select, or checkbox. </p>
<p><b>Outputs</b> render text, links, and images. Output controls only apply to the grid view and are defined in grid_output_control.</p>
For inputs where sql statements are used, the first column in the sql statement corresponds to the select/checkbox/radio value, the second column is the displayed text.
<pre>
Define Inputs on edit form()
$lm->form_input_control["field_name"] = array("type" => string [, "sql" => string [, "sql_param" => array]]);
Define Inputs on grid()
$lm->grid_input_control["field_name"] = array("type" => string [, "sql" => string [, "sql_param" => array]]);
Define Output on grid()
$lm->grid_output_control["field_name"] = array("type" => string);
</pre>
<pre class="gray">
// legacy syntax still supported (changed in version 2019-01-10)
// optional sql string depending on control, type is prefixed with --
$lm->form_input_control["field_name"] = "[sql]--type";
// legacy examples
$lm->form_input_control["country_id"] = "select country_id as val, country_name as opt from country;--select";
$lm->form_input_control["is_active"] = "--checkbox";
</pre>
<pre>
Examples:
$lm->form_input_control['client_pic'] = array("type" => "image");
$lm->form_input_control['pdf'] = array("type" => "document");
$lm->form_input_control['is_active'] = array("type" => "checkbox");
$lm->form_input_control['will_you_attend'] = array("type" => "radio", "sql" => "select 1 as key, 'Yes' as val union select 0, 'No'");
$lm->form_input_control['country_id'] = array("type" => "select", sql => "select country_id as val, country_name as opt from country");
</pre>
<h2><a name='native_input_controls'>Native Input Controls</a></h2>
<p>For use with form_input_control and grid_input_control arrays.</p>
<table border='1'>
<tr><th>type</th><th>description</th></tr>
<tr><td>text</td><td>text input (default)</td></tr>
<tr><td>password</td><td>password input</td></tr>
<tr><td>number</td><td>text input for number, when cast numbers are filtered through restricted_numeric_input pattern.</td></tr>
<tr><td>date</td><td>text input, date is formatted according to public $date_format variable</td></tr>
<tr><td>datetime</td><td>text input, date is formatted according to public $date_format variable</td></tr>
<tr><td>textarea</td><td>textarea input</td></tr>
<tr><td>readonly</td><td>plain text (not an input, just displays data)</td></tr>
<tr><td>readonly_date</td><td>plain text formatted with date settings (not an input, just displays data)</td></tr>
<tr><td>readonly_datetime</td><td>plain text formatted with datetime settings (not an input, just displays data)</td></tr>
<tr><td>image</td><td>file input for uploading, if image exists then image is displayed with 'delete' checkbox.</td></tr>
<tr><td>document</td><td>file input for uploading, if document exists then display link with 'delete' checkbox.</td></tr>
<tr><td>select</td><td>select dropdown, sql statement is optional.</td></tr>
<tr><td>selectmultiple</td><td>select dropdown with multiple options. values are stored in a delimited list. sql is optional. sql_param is optional.</td></tr>
<tr><td>checkbox</td><td>input checkboxes. values are stored in a delimited list. sql is optional. sql_param is optional. </td></tr>
<tr><td>radio</td><td>radio buttons. sql is optional. sql_param is optional.</td></tr>
</table>
<h2><a name='native_output_controls'>Native Output Controls</a></h2>
<p>For use with form_output_control and grid_output_control arrays.</p>
<table border='1'>
<tr><th>type</th><th>description</th></tr>
<tr><td>text</td><td>outputs plain text (default)</td></tr>
<tr><td>date</td><td>outputs date according to date_out setting</td></tr>
<tr><td>datetime</td><td>outputs datetime according to datetime_out setting</td></tr>
<tr><td>email</td><td>outputs a clickable email link</td></tr>
<tr><td>image</td><td>outputs a clickable link to the image, or display image if grid_show_images = true</td></tr>
<tr><td>document</td><td>outputs a clickable link to the document</td></tr>
<tr><td>html</td><td>outputs text without escaping</td></tr>
</table>
<h2><a name='defining_custom_input_and_output_controls'>Defining Custom Input and Output Controls</h2>
<p>User defined functions can be defined to render an input or output control. </p>
<pre>
Example:
$lm->form_input_control['weird_data'] = array("type" => "my_user_function");
function my_user_function($column_name, $value, $command, $called_from){
// $column_name: field name
// $value: field value
// $command: array defined in the control, or string with legacy syntax; rarely needed
// $called_from: orgin of call; 'form', or 'grid'; rarely needed
global $lm;
$val = $lm->clean_out($value);
return "<input type='text' name='$column_name' value='$val' size='100'>";
}
</pre>
<h2><a name='Automatically Populated Controls'>Automatically Populated Controls</h2>
<p>By default form_input_control and grid_output_control will populate with date, datetime, number and textarea according to meta data. To disable this behavior set auto_populate_controls = false.</p>
<h1><a name='adding_search'>Adding Search</a></h1>
In versions <= 2015-02-27 search was automatic. Now search requires grid_sql and grid_sql_param to be defined.
<pre>
Example:
$lm->grid_show_search_box = true;
$lm->grid_sql = "select m.market_id, m.market_name, m.photo, m.contact_email, c.country_name, m.is_active, m.create_date, market_id from market m left join country c on m.country_id = c.country_id where coalesce(m.market_name, '') like :_search or coalesce(m.contact_email, '') like :_search or coalesce(c.country_name, '') like :_search order by m.market_id desc";
$lm->grid_sql_param = array(':_search' => '%' . trim(@$_REQUEST['_search']) . '%');
</pre>
<h1><a name='customizing_the_search_form'>Customizing the Search Form</a></h1>
Sample of custom search form with <b>two</b> search boxes.
<pre>
Example:
$lm->grid_show_search_box = true; // show html defined in grid_search_box
$new_search_1 = $lm->clean_out(@$_REQUEST['new_search_1']);
$new_search_2 = $lm->clean_out(@$_REQUEST['new_search_2']);
// redefine our own search form with two inputs instead of the default one
$lm->grid_search_box = "
<form class='lm_search_box'>
<input type='text' name='new_search_1' value='$new_search_1' size='20' class='lm_search_input' placeholder='market'>
<input type='text' name='new_search_2' value='$new_search_2' size='20' class='lm_search_input' placeholder='email'>
<input type='submit' value='Search' class='lm_button'>
<input type='hidden' name='action' value='search'>
</form>
";
$lm->query_string_list = "new_search_1,new_search_2"; // add variable names to querystring so search is saved while paging, sorting, and editing
// set name parameters
$lm->grid_sql_param[':new_search_1'] = '%' . @$_REQUEST['new_search_1'] . '%';
$lm->grid_sql_param[':new_search_2'] = '%' . @$_REQUEST['new_search_2'] . '%';
// define sql
$lm->grid_sql = "
select
m.market_id
, m.market_name
, m.photo
, m.contact_email
, c.country_name
, m.is_active
, m.create_date
, m.market_id
from market m
left
join country c
on m.country_id = c.country_id
where coalesce(m.market_name, '') like :new_search_1
and coalesce(m.contact_email, '') like :new_search_2
order by m.market_id desc
";
</pre>
<h1><a name='defining_separate_add_and_edit_forms'>Defining Separate Add and Edit Forms</a></h1>
<p>Different forms may be defined for adding records versus editing records.</p>
<pre>
Example:
if(!isset($_REQUEST['market_id'])){
// form for adding records
$lm->form_sql = 'select * from market where market_id = :market_id';
}
else{
// form for editing records
$lm->form_sql = 'select market_id, market_name, country_id, photo, is_active, create_date, notes from market where market_id = :market_id';
}
$lm->form_sql_param = array(":market_id" => @$_REQUEST['market_id']);
</pre>
<h1><a name='validation'>Validation</a></h1>
<p>Server-side validation displays an error message next to the form input. <br>A general error message is displayed at the top and can be defined with the $lm->validate_text_general string setting. </p>
<p>Separate arrays are used for inserts and updates. If the validate needs are the same for both inserts and updates then just copy the existing array to duplicate the rules.</p>
<p>Alternatively, validation can be handled in On Insert/Update/Delete events <a href='#on_insert_update_delete_events'>(see below)</a>.</p>
<pre>
$lm-gt;on_insert_validate["field_name"] = array("regexp" => string, "error_msg" => string [, "placeholder" => string [, "optional" => boolean]]);
$lm-gt;on_update_validate["field_name"] = array("regexp" => string, "error_msg" => string [, "placeholder" => string [, "optional" => boolean]]);
</pre>
<pre class="gray">
// old style syntax still supported (changed in version 2019-01-10)
// same values, without keys
$lm-gt;on_insert_validate["field_name"] = array(string regexp, string error_msg, string placeholder, boolean optional);
</pre>
<ul>
<li><b>regexp</b> regular expression /slashes required/, 'email', or user defined function name.</li>
<li><b>error_msg</b> Error message to be displayed next to the element.</li>
<li><b>placeholder</b> Populate placeholder attribute of input with a tip. If placeholder is not applicable, text is displayed along side input. </li>
<li><b>optional</b> Is this input optional? Default is false. </li>
</ul>
<pre>
Example:
// validation using regular expression, slashes required
$lm->on_insert_validate["market_name"] = array("regexp" => "/.+/", "error_msg" => "Missing Market Name", "placeholder" => "This is Required");
// built-in "email" validation
$lm->on_insert_validate["contact_email"] = array("regexp" => "email", "error_msg" => "Missing or invalid Email", "placeholder" => "Optional Email", "optional" => true);
// user defined validation
$lm->on_insert_validate["country_id"] = array("regexp" => "my_validate", "error_msg" => "Missing or invalid country", "placeholder" => "Required");
// copy array - same setting for updates
$lm->on_update_validate = $lm->on_insert_validate;
// user defined validation example
function my_validate(){
if(empty($_POST['country_id'])
return false; // fail
else
return true; // success
}
</pre>
<h1><a name='on_insert_update_delete_events'>On Insert/Update/Delete Events</a></h1>
<p>On Insert/Update/Delete functions are useful for validation and data manipulation.</p>
<p>These functions can be also be used for validation. Strings returned by the user defined functions are displayed at the top as error messages and the insert/update/delete action is halted.</p>
<ul>
<li>on_insert_user_function</li>
<li>on_update_user_function</li>
<li>on_delete_user_function</li>
<li>on_update_grid_user_function</li>
</ul>
<pre>
Example:
$lm->on_update_user_function = 'my_hash';
function my_hash(){
if(isset($_POST['password_reset']))
$_POST['password'] = password_hash($_POST['password_reset']);
// returned string will be displayed as an error message
if(mb_strlen($_POST['password_reset']) > 100)
return "Password too long";
}
</pre>
<a name='after_insert_update_delete_events'></a>
<h1>After Insert/Update/Delete Events</h1>
<p>User define functions can be defined in the properties listed below.</p>
<p>after_ events are useful for running trigger-like actions. The after_insert_user_function event uniquely receives the identity id of the newly added record.</p>
<ul>
<li>after_insert_user_function</li>
<li>after_update_user_function</li>
<li>after_delete_user_function</li>
<li>after_update_grid_user_function</li>
</ul>
<pre>
Example:
$lm->after_insert_user_function = 'my_after_insert';
function my_after_insert($id){
// after_insert_user_function is the only action to get the identity id
// now that the record is added we can do anything we need to
global $lm;
$sql_param = array(':market_id' => $id);
$sql = "insert into related_table(field1, market_id) values (now(), :market_id)";
$lm->query($sql, $sql_param);
}
</pre>
<a name='cast_user_function'></a>
<h1>Cast Data Based on Colunm Name</h1>
<p>The cast_user_function array is used for storing column names and their corresponding cast function.</p>
<pre>
Example:
// when using the checkbox input maybe we'd want unchecked to be 0 instead of null
$lm->cast_user_function['is_active'] = 'my_cast';
function my_cast($val){
return intval($val);
}
</pre>
<h1><a name='cross_site_request_forgery_protection_token'>Cross Site Request Forgery Protection Token</a></h1>
<p>This script does not validate csrf itself but has a placeholder csrf variable from loaded from $_SESSION['_csrf']. To protect from csrf, place your nonce token in $_SESSION['_csrf'] and validate the csrf on POST commands.</p>
<pre>
Example:
// in your login script give the user a random string token
$_SESSION['_csrf'] = base64_encode(openssl_random_pseudo_bytes(15));
// somewhere else, before the page is processed, run some code like this
if($_SERVER['REQUEST_METHOD'] === 'POST' && $_SESSION['_csrf'] != $_POST['_csrf'])
die('Invalid csrf token');
</pre>
<h1><a name='i18n'>i18n/Internationalization</a></h1>
<p>By default LM datagrid is us-en (United States - English).
At this time very few country-language files are available. Check the i18n folder to see what is available.
If your coutry-language is not available consider making an open source contribution using i18n/template.php</p>
<pre>
Example:
// create LM object, pass in PDO connection, see i18n folder for language + country options
$lm = new lazy_mofo($dbh, 'en-us');
</pre>
<h1><a name='date_formats'>Date Formats</a></h1>
<p>Lazy Mofo will automatically identify date and datetime fields. All output of dates and datetimes are output in the format defined by member variables date_out and datetime_out.</p>
<pre>
Example:
// default US format
$lm->date_out = 'm/d/Y';
$lm->datetime_out = 'm/d/Y h:i A';
// or set non US date format
$lm->date_out = 'd/m/Y';
$lm->datetime_out = 'd/m/Y h:i A';
// or use a ISO-ish date format for html5 date inputs
$lm->date_out = 'Y-m-d';
$lm->datetime_out = 'Y-m-d H:i';
</pre>
<h1><a name='adding_jquery_ui_datepicker'>Adding JQuery UI Datepicker</a></h1>
<pre>
Example:
<link rel='stylesheet' href='//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css'>
<script src='//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js'></script>
<script src='//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js'></script>
<script>
$(function() {
// note how field class names are prefixed with 'lm_'
$('input.lm_create_date').datepicker();
// non US date example dd/mm/yy and week starting on monday(1) instead of sunday(0)
// make sure lazy mofo class members for date_out and datetime_out correspond with your local date format
//$('input.lm_create_date').datepicker({ dateFormat: 'dd/mm/yy', firstDay: 1 });
});
</script>
</pre>
<h1><a name='export_to_csv'>Export to CSV</a></h1>
<p>Clicking the Export link will convert the grid output to a CSV file for downloading.
Output buffering (ob_start) must be used at the beginning of the script for the export to CSV feature to function properly.</p>
<h1><a name='more_features_and_settings'>More Features and Settings</a></h1>
<p>View class source code to see all the property settings.</p>
</body>
</html>