#!/usr/bin/perl use strict; use warnings; use JSON; use Data::Dumper; use CGI::Lazy; #our $q = CGI::Lazy->new('/var/cache/apache2/cgi-conf/lazydemo.conf'); our $q = CGI::Lazy->new({ tmplDir => "/var/www/templates", jsDir => "/lazydocs/js", # dbhVar => "DBH", plugins => { mod_perl => { # PerlHandler => "ModPerl::PerlRun" PerlHandler => "ModPerl::Registry", saveOnCleanup => "1", }, dbh => { dbDatasource => "dbi:mysql:lazydemo:localhost", dbUser => "luser", dbPasswd => "letmein", dbArgs => {"RaiseError" => 1}, }, # session => { # sessionTable => "SessionData", # sessionCookie => "frobnostication", # saveOnDestroy => "1", # expires => "+15m" # }, } }); our $var = undef; our $id = \$var; our $stuff = $q->widget->composite({ id => 'stuff', type => 'parentChild', relationship => { parent => { name => 'invoiceBlock', # searchLike => '%?%', searchDiv => 1, }, children => { detailBlock => { parentKey => 'id', childKey => 'invoiceid', }, }, }, members => [ $q->widget->dataset({ id => 'invoiceBlock', type => 'single', multiType => 'sequential', template => "invoiceBlock.tmpl", multipleTemplate => 'invoiceBlockMultiple.tmpl', lookups => { countryLookup => { sql => 'select ID, country from countryCodeLookup', preload => 1, orderby => ['ID'], output => 'hash', primarykey => 'ID', }, }, recordset => $q->db->recordset({ table => 'invoice', fieldlist => [ {name => 'id', hidden => 1}, {name => 'merchant', label => 'Merchant', multi => 1}, {name => 'batch', label => 'Bat', multi => 1}, {name => 'post_date', label => 'Post Date', multi => 1}, {name => 'cardnum', label => 'Card Number', multi => 1}, {name => 'tailno', label => 'Tail Number',}, {name => 'authCode', label => 'Auth Code',}, {name => 'icao', label => 'ICAO',}, {name => 'invoicenum', label => 'Invoice Number', multi => 1}, {name => 'invtotal', label => 'Invoice Total', validator => {rules => ['/\d+/'], msg => 'number only, and is required'}, }, {name => 'trandate', label => 'Invoice Date', }, {name => 'country', label => 'Country',}, {name => 'card_type', hidden => 1,}, ], basewhere => '', orderby => 'id', primarykey => 'id', insertdefaults => { card_type => {#field name value => 'frobnitz', }, }, }), }), $q->widget->dataset({ id => 'detailBlock', template => "detailBlock.tmpl", # nodelete => 1, lookups => { prodcodeLookup => { sql => 'select ID, description from prodCodeLookup', preload => 1, orderby => ['ID'], output => 'hash', primarykey => 'ID', }, }, recordset => $q->db->recordset({ table => 'detail', fieldlist => [ {name => 'detail.ID', hidden => 1}, {name => 'invoiceid', hidden => 1}, {name => 'prodCode', label => 'Product Code', validator => {rules => ['/\d+/'], msg => 'number only, and is required'}}, {name => 'quantity', label => 'Quantity', validator => {rules => ['/\d+/'], msg => 'number only, and is required'}}, {name => 'unitPrice', label => 'Unit Price' , validator => {rules => ['/\d+/'], msg => 'number only, and is required'}}, {name => 'productGross', label => 'Product Gross' , validator => {rules => ['/\d+/'], msg => 'number only, and is required'}}, {name => 'prodCodeLookup.description', label => 'Product Description', readOnly => 1, }, ], basewhere => '', joins => [ {type => 'inner', table => 'prodCodeLookup', field1 => 'prodCode', field2 => 'prodCodeLookup.ID',}, ], orderby => 'detail.ID', primarykey => 'detail.ID', }), }), ] }); my %nav = ( dbwrite => \&dbwrite, ); if ($q->param('nav')) { $nav{$q->param('nav')}->(); } elsif ($q->param('POSTDATA')) { ajaxHandler(); } else { display(); } #---------------------------------------------------------------------------------------- sub ajaxHandler { my $incoming = from_json($q->param('POSTDATA')); if ($incoming->{delete}) { doFullDelete($incoming); return; } print $q->header, $stuff->ajaxSelect(incoming => $incoming); } #---------------------------------------------------------------------------------------- sub display { my $recordnum; if (!defined $q->param('recordnum')) { $recordnum = 0; } else { $recordnum = $q->param('recordnum'); $recordnum++; } print $q->header, #standard http header $q->start_html({-style => {src => '/css/topbanner.css'}}), # $q->start_html({-style => {src => '/css/lazydemo.css'}}), #refactor to use composite methods, then can use standard css $q->javascript->modules($stuff); #javascript functions needed by widget #header section print $q->template('header.tmpl')->process({ mainTitle => 'CGI::Lazy Demo', secondaryTitle => 'Composite Sequential Edit', versionTitle => $q->lazyversion, messageTitle => 'Nik rocks', }); #help block section print $q->template('helpBlock.tmpl')->process({ helpMessage1 => ' ', helpMessage2 => ' ', }); #composite widget section print $q->start_form(), $q->hidden({-name => 'nav', -value => 'dbwrite'}), $q->hidden({-name => 'recordnum', -value => $recordnum, -override => 1}); my $invoiceBlock = $stuff->members->{invoiceBlock}; my $detailBlock = $stuff->members->{detailBlock}; print $invoiceBlock->displaySelect(vars => {id => {handle => $id}, -recordnum => $recordnum}), $detailBlock->displaySelect(invoiceid =>$id); print $q->javascript->load('lazydemo.js'); print $q->template('submit.tmpl')->process({url => $q->url}); print $q->end_form; print $q->template('footer.tmpl')->process({version => $q->lazyversion}); return; } #---------------------------------------------------------------------------------------- sub doFullDelete { my $incoming = shift; my $invoiceid = $incoming->{delete}->{invoiceid}; $q->db->do('delete from detail where invoiceid = ?', $invoiceid); $q->db->do('delete from invoice where invoiceid = ?', $invoiceid); print $q->header, $stuff->ajaxBlank; return; } #---------------------------------------------------------------------------------------- sub dbwrite { $stuff->dbwrite; display('blank'); }