Advertisement
Uno-Dan

DBMagic

Jan 29th, 2021
1,408
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.    
  2. var log = console.log;
  3. var wpadminbar;
  4. var fadetime = 400;
  5. var sash_width = 5;
  6. var zoom = document.documentElement.clientWidth / window.innerWidth;
  7.    
  8. var mockup_data = {
  9.   keys: [
  10.     'status_id', 'customer_id', 'branch_id', 'agent_id', 'phone1',
  11.     'phone2', 'email_address', 'address', 'unit', 'postalcode', 'country_id',
  12.     'zone_id', 'location_id', 'notes'
  13.   ],
  14.   head: {
  15.     labels: [
  16.       'Status', 'Customer', 'Branch', 'Agent', 'Phone1', 'Phone2',
  17.       'Email Address', 'Address', 'Unit', 'Post Code', 'Country', 'State/Prov',
  18.       'City/Town', 'Notes'
  19.     ]
  20.   },
  21.   body: {
  22.     1: [
  23.       0, 'Whole Foods', 'Whole Foods Yorkville - YRK', 'xx', '123.456.7890',
  24.       '432.546.4325', '[email protected]', 'address', '#745', 'M5R-3R9',
  25.       'Canada', 'Ontario', 'Toronto',
  26.       'This is a test message...'
  27.     ],
  28.     3: [
  29.       1, 'Whole Foods', 'Whole Foods Yorkville - YRK', 'xx', '123.456.7890',
  30.       '432.546.4325', '[email protected]', 'address', '#745', 'M5R-3R9',
  31.       'Canada', 'Ontario', 'Toronto',
  32.       'This is a test message...'
  33.     ],
  34.     5: [
  35.       2, 'Whole Foods', 'Whole Foods Yorkville - YRK', 'xx', '123.456.7890',
  36.       '432.546.4325', '[email protected]', 'address', '#745', 'M5R-3R9',
  37.       'Canada', 'Ontario', 'Toronto',
  38.       'This is a test message...'
  39.     ],
  40.     25: [
  41.       3, 'Whole Foods', 'Whole Foods Yorkville - YRK', 'xx', '123.456.7890',
  42.       '432.546.4325', '[email protected]', 'address', '#745', 'M5R-3R9',
  43.       'Canada', 'Ontario', 'Toronto',
  44.       'This is a test message...'
  45.     ]
  46.   },
  47.   children: {
  48.     status_id: {
  49.       type: 'option',
  50.       children: { 0: '', 1: 'Active', 2: 'Prospect', 3: 'Pending', 4: 'On Hold' }
  51.     },
  52.     agent_id: {
  53.       type: 'option',
  54.       children: { 0: '', 1: 'Dan', 2: 'Danny', 3: 'Daniel', 4: 'Uno' }
  55.     }
  56.   }
  57. };
  58.    
  59. var mockup_data2 = {
  60.   keys2: [
  61.     'status_id2', 'customer_id2', 'branch_id2', 'agent_id2', 'phone1',
  62.     'phone2', 'email_address', 'address', 'unit', 'postalcode', 'country_id',
  63.     'zone_id', 'location_id', 'notes'
  64.   ],
  65.   head2: {
  66.     labels2: [
  67.       'Status2', 'Customer2', 'Branch2', 'Agent2', 'Phone12', 'Phone2',
  68.       'Email Address', 'Address', 'Unit', 'Post Code', 'Country', 'State/Prov',
  69.       'City/Town', 'Notes'
  70.     ]
  71.   },
  72.   body2: {
  73.     1: [
  74.       0, 'Whole Foods', 'Whole Foods Yorkville - YRK', 'xx', '123.456.7890',
  75.       '432.546.4325', '[email protected]', 'address', '#745', 'M5R-3R9',
  76.       'Canada', 'Ontario', 'Toronto',
  77.       'This is a test message...'
  78.     ],
  79.     3: [
  80.       1, 'Whole Foods', 'Whole Foods Yorkville - YRK', 'xx', '123.456.7890',
  81.       '432.546.4325', '[email protected]', 'address', '#745', 'M5R-3R9',
  82.       'Canada', 'Ontario', 'Toronto',
  83.       'This is a test message...'
  84.     ],
  85.     5: [
  86.       2, 'Whole Foods', 'Whole Foods Yorkville - YRK', 'xx', '123.456.7890',
  87.       '432.546.4325', '[email protected]', 'address', '#745', 'M5R-3R9',
  88.       'Canada', 'Ontario', 'Toronto',
  89.       'This is a test message...'
  90.     ],
  91.     25: [
  92.       3, 'Whole Foods', 'Whole Foods Yorkville - YRK', 'xx', '123.456.7890',
  93.       '432.546.4325', '[email protected]', 'address', '#745', 'M5R-3R9',
  94.       'Canada', 'Ontario', 'Toronto',
  95.       'This is a test message...'
  96.     ]
  97.   },
  98.   children2: {
  99.     status_id2: {
  100.       type2: 'option',
  101.       children2: { 0: '', 1: 'Active', 2: 'Prospect', 3: 'Pending', 4: 'On Hold' }
  102.     },
  103.     agent_id2: {
  104.       type2: 'option',
  105.       children2: { 0: '', 1: 'Dan', 2: 'Danny', 3: 'Daniel', 4: 'Uno' }
  106.     }
  107.   }
  108. };
  109.  
  110. var debug = false;
  111.  
  112. String.prototype.splice = function( idx, rem, str ) {
  113.     return this.slice( 0, idx ) + str + this.slice( idx + Math.abs( rem ) );
  114. };
  115.  
  116. class DBMagic {
  117.   constructor( db_name, db_version, stores ) {  
  118.     this.stores = stores;
  119.     this.db_name = db_name;
  120.     this.db_version = db_version;
  121.     var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
  122.     this.indexedDB = indexedDB;
  123.    
  124. //    this.db_delete();
  125.     this.db_create();
  126.   }
  127.    
  128.   add( name, items, callback ) {
  129.     const db_name = this.db_name;
  130.     let req = this.indexedDB.open( db_name, this.db_version );
  131.    
  132.     req.onsuccess = () => {
  133.       let db = req.result;
  134.       let tx = db.transaction ( [ name ], 'readwrite' );
  135.      
  136.       tx.oncomplete = () => {
  137.         if ( debug )
  138.           console.log( 'SUCCESS: Transaction [add] on database [' + db_name + '] store [' + name + '] completed successfully.' );
  139.       };
  140.      
  141.       tx.onerror = ( e ) => {
  142.         if ( debug )
  143.           console.log( 'ERROR: Transaction method add() has failed.\n', e.srcElement.error );
  144.       };
  145.      
  146.       items.forEach( item => {
  147.         let storeReq = tx.objectStore( name ).add( item );
  148.         storeReq.onsuccess = ( e ) => {
  149.           if ( debug )
  150.             console.log( 'SUCCESS: Added key ['+ item.id +'] to store [' + name + '] on database [' + db_name + '] successfully.' );
  151.             if ( callback ) callback( e );
  152.         };
  153.        
  154.         storeReq.onerror = ( e ) => {
  155.           if ( debug )
  156.             console.log( 'ERROR: Adding key ['+ item.id +'] to store [' + name + '] on database [' + db_name + '] failed.\n', e.srcElement.error );
  157.           if ( callback ) callback( e );  
  158.         };
  159.       });
  160.     };
  161.    
  162.     req.onerror = ( e ) => {
  163.       if ( debug )
  164.         console.log( 'ERROR: Could not connect to database [' + db_name + '].\n', e.srcElement.error );
  165.     };
  166.   }
  167.  
  168.   get( name, items, callback ) {
  169.     const db_name = this.db_name;
  170.     const req = this.indexedDB.open( db_name, this.db_version );
  171.    
  172.     req.onsuccess = () => {
  173.       let db = req.result;
  174.      
  175.       let tx = db.transaction ( [ name ], 'readonly' );
  176.       let store = tx.objectStore( name );
  177.  
  178.       tx.onerror = ( e ) => {
  179.         if ( debug )
  180.           console.log( 'ERROR: Transaction on database [' + db_name + '] failed.\n', e.srcElement.error );
  181.       };
  182.      
  183.       tx.oncomplete = () => {
  184.         if ( debug )
  185.           console.log( 'SUCCESS: Transaction [get] on database [' + db_name + '] store [' + name + '] completed successfully.' );
  186.       };
  187.      
  188.       items.forEach( item => {
  189.         let storeReq = store.get( item );
  190.        
  191.         storeReq.onerror = ( e ) => {
  192.           if ( debug )
  193.             console.log('ERROR: Could not connect to database ['+ db_name +'].\n', e.srcElement.error );
  194.          
  195.           if ( callback ) callback( e );
  196.         };
  197.        
  198.         storeReq.onsuccess = ( e ) => {
  199.           if ( debug )
  200.             console.log( 'SUCCESS: Retrieved key ['+ item +'] from store [' + name + '] on database ['+ db_name +'] successfully.' );
  201.           if ( callback ) callback( e.target.result );  
  202.         };
  203.       });  
  204.     };
  205.    
  206.     req.onerror = ( e ) => {
  207.       if ( debug )
  208.         console.log('ERROR: Could not connect to database ['+ db_name +'].\n', e.srcElement.error );
  209.     };
  210.   }
  211.  
  212.   getAll( name, callback ) {
  213.     const db_name = this.db_name;
  214.     const req = this.indexedDB.open( db_name, this.db_version );
  215.    
  216.     req.onsuccess = () => {
  217.       let db = req.result;
  218.       let tx = db.transaction ( [ name ], 'readonly' );
  219.       let store = tx.objectStore( name );
  220.      
  221.       tx.oncomplete = () => {
  222.         if ( debug )
  223.           console.log( 'SUCCESS: Transaction [getAll] on database [' + db_name + '] store [' + name + '] completed successfully.' );
  224.       };
  225.      
  226.       let storeReq = store.getAll();
  227.       storeReq.onsuccess = ( e ) => {
  228.         if ( callback ) callback( e.target.result );
  229.       };
  230.     };
  231.    
  232.     req.onerror = ( e ) => {
  233.       if ( debug )
  234.         console.log('ERROR: Could not connect to database ['+ db_name +'].\n', e.srcElement.error );
  235.     };
  236.    
  237.   }
  238.  
  239.   delete( name, items, callback ) {
  240.     const db_name = this.db_name;
  241.     const req = this.indexedDB.open( db_name, this.db_version );
  242.    
  243.     req.onsuccess = () => {
  244.       let db = req.result;
  245.       let tx = db.transaction ( [ name ], "readwrite" );
  246.       let store = tx.objectStore( name );
  247.      
  248.       tx.onerror = ( e ) => {
  249.         if ( debug )
  250.           console.log( 'ERROR: Transaction [delete] on database [' + db_name + '] failed.\n', e.srcElement.error );
  251.       };
  252.      
  253.       tx.oncomplete = () => {
  254.         if ( debug )
  255.           console.log( 'SUCCESS: Transaction [delete] on database [' + db_name + '] store [' + name + '] completed successfully.' );
  256.       };
  257.      
  258.       items.forEach( item => {
  259.         let storeReq = store.delete( item );
  260.        
  261.         storeReq.onerror = ( e ) => {
  262.           if ( debug )
  263.             console.log('ERROR: Deleted key ['+ item +'] from store ['+ name +'] failed.\n', e.srcElement.error );
  264.          
  265.           if ( callback ) callback( e );
  266.         };
  267.        
  268.         storeReq.onsuccess = ( e ) => {
  269.           if ( debug )
  270.             console.log('SUCCESS: Deleted key ['+ item +'] from store ['+ name +'] successfully.');
  271.           if ( callback ) callback( e );
  272.         };
  273.       });
  274.     };
  275.    
  276.     req.onerror = ( e ) => {
  277.       if ( debug )
  278.         console.log('ERROR: Could not connect to database ['+ db_name +'].\n', e.srcElement.error );
  279.     };
  280.    
  281.   }
  282.    
  283.   update( name, items, callback ) {
  284.     const db_name = this.db_name;
  285.     let req = this.indexedDB.open( db_name, this.db_version );
  286.    
  287.     req.onsuccess = () => {
  288.       let db = req.result;
  289.       let tx = db.transaction ( [ name ], 'readwrite' );
  290.      
  291.       tx.oncomplete = () => {
  292.         if ( debug )
  293.           console.log( 'SUCCESS: Transaction [update] on database [' + db_name + '] store [' + name + '] completed successfully.' );
  294.       };
  295.      
  296.       tx.onerror = ( e ) => {
  297.         if ( debug )
  298.           console.log( 'ERROR: Transaction method update() has failed.\n', e.srcElement.error );
  299.       };
  300.       items.forEach( item => {
  301.         let storeReq = tx.objectStore( name ).put( item );
  302.         storeReq.onsuccess = ( e ) => {
  303.           if ( debug )
  304.             console.log( 'SUCCESS: Updated key ['+ item.id +'] in store [' + name + '] on database [' + db_name + '] successfully.' );
  305.             if ( callback ) callback( e );
  306.         };
  307.        
  308.         storeReq.onerror = ( e ) => {
  309.           if ( debug )
  310.             console.log( 'ERROR: Updating key ['+ item.id +'] in store [' + name + '] on database [' + db_name + '] failed.\n', e.srcElement.error );
  311.           if ( callback ) callback( e );  
  312.         };
  313.       });
  314.     };
  315.    
  316.     req.onerror = ( e ) => {
  317.       if ( debug )
  318.         console.log( 'ERROR: Could not connect to database [' + db_name + '].\n', e.srcElement.error );
  319.     };
  320.   }
  321.  
  322.   db_create( callback ) {
  323.     const db_name = this.db_name;
  324.     const self = this;
  325.     const req = this.indexedDB.open( db_name, this.db_version );
  326.    
  327.     req.onsuccess = () => {
  328.       let db = req.result;
  329.       if ( debug )
  330.         console.log('SUCCESS: Database ['+ db_name +'] opened successfully, [ version = ' + db.version + ' ]');
  331.       if ( callback ) callback( true );  
  332.     };
  333.    
  334.     req.onerror = () => {
  335.       let db = req.result;
  336.       if ( debug )
  337.         console.log('ERROR: Database ['+ db_name +'] could not be opened successfully, [ version = ' + db.version + ' ]');
  338.       if ( callback ) callback( true );  
  339.     };
  340.    
  341.     req.onupgradeneeded = ( e ) => {
  342.       let db = req.result;
  343.      
  344.       switch( e.oldVersion ) {
  345.         case 0:
  346.           self.stores.forEach( name => {
  347.             db.createObjectStore( name, { keyPath: 'id' } );
  348.           } );
  349.         case 1:
  350.           let oldVersion = e.oldVersion;
  351.           let newVersion = e.newVersion;
  352.           if ( debug ) log( db.objectStoreNames );
  353.       }
  354.     };
  355.   }
  356.  
  357.   db_delete( callback ) {
  358.     const db_name = this.db_name;
  359.     this.indexedDB.deleteDatabase( db_name, this.db_version );
  360.    
  361.     if ( debug )
  362.       console.log('SUCCESS: Database ['+ db_name +'] deleted successfully.');
  363.     if ( callback ) callback( true );  
  364.   }
  365. }
  366.  
  367. class MenuMagic {
  368.   constructor( id, parent ) {
  369.     $ = jQuery;
  370.     var menu = $( '<div id="' + id + '" class="menu magic"><ul></ul></div>' );
  371.     this.parent = parent;
  372.     this.id = id;
  373.     this.elm = menu;
  374.     this.items = menu.find('>ul');
  375.     this.commands = [];
  376.     parent.append( menu );
  377.   }
  378.  
  379.   init() {
  380.     self = this;
  381.     $ = jQuery;
  382.    
  383.     this.parent.off( "contextmenu" ).on( "contextmenu", function( e ) {
  384.       e.preventDefault();
  385.       var elm = $( document.elementFromPoint( e.pageX, e.pageY ) );
  386.       self.show( elm, e.pageX, e.pageY );
  387.       return false;
  388.     } );
  389.    
  390.     $( document ).off( 'click' ).
  391.     on( 'click', function() { self.elm.hide(); }).
  392.     on( 'keyup', function( e ) {
  393.       if ( e.key === "Escape" ) { self.elm.hide(); }
  394.     });
  395.   }
  396.  
  397.   show( elm, x, y ) {
  398.     self = this;
  399.     if ( ! elm.is( ':input' ) ) return false;
  400.    
  401.     document.active_table = elm.closest( 'table' );
  402.  
  403.     $('.wrapper').find( '.menu:visible' ).hide();
  404.  
  405.     self.add_commands( elm );
  406.     self.elm[0].target = elm;
  407.     self.elm.css( { top: y, left: x, position: 'fixed' } );
  408.     self.elm.show();
  409.   }
  410.  
  411.   add_item( item ) {
  412.     this.commands.push( item );
  413.   }
  414.  
  415.   add_items( items ) {
  416.     this.commands = items;
  417.   }
  418.  
  419.   add_command( item, elm ) {
  420.     var ul = self.elm.find('ul');
  421.     var cls = item.label.replace( ' ' , '_' ).toLowerCase();
  422.     cls = cls !== '' ? cls : 'seperator';
  423.     var button = item.label.length ?
  424.     '<button class="none">' + item.label + '</button>' : '';
  425.     var li = $ ( '<li class="'+ cls +'">' + button + '</li>' );
  426.     ul.append( li );
  427.  
  428.     if ( item.command ) {
  429.       li.find('button').on( 'click', { elm: elm }, function( e ) {
  430.         item.command( e );
  431.         self.elm.fadeOut( fadetime / 2 );
  432.       });
  433.     }
  434.   }
  435.  
  436.   add_commands( elm ) {
  437.     self = this;
  438.     var ul = this.elm.find('>ul');
  439.     var items = this.commands;
  440.    
  441.     ul.find('>li').remove();
  442.     items.forEach( function( item, idx ) {
  443.       self.add_command( item, elm );
  444.     });
  445.   }
  446. }
  447.  
  448. class TableMagic {
  449.   constructor( elm, opts, data ) {
  450.     $ = jQuery;
  451.    
  452.     var tm = elm[0].obj = this;
  453.     elm.addClass( 'magic' );
  454.    
  455.     document.active_table = elm;
  456.     this.elm = elm;
  457.     this.opts = opts;
  458.     this.data = data;
  459.     this.menu = false;
  460.     this.copy_buffer = '';
  461.    
  462.     var body = $( 'body' );
  463.     var wrap = $( '<div class="wrap" />' );
  464.     var span = $( '<span class="measure lato" />' );
  465.    
  466.     if ( ! elm.find( '>thead' ).length ) elm.append( '<thead /><tr />' );
  467.     if ( ! elm.find( '>tbody' ).length ) elm.append( '<tbody />' );
  468.     body.append( span );
  469.    
  470.     if( span.css( 'font-size' ) !== '' )
  471.       document.font_width = parseInt( span.css( 'font-size') );
  472.    
  473.     elm.parent().append( wrap );
  474.     wrap.append( elm );
  475.    
  476.     tm.head_init().body_init().bindings_set( body );
  477.   }
  478.    
  479.   menu_add( id, opts = 0 ) {
  480.     var menu = this.menu = new
  481.     Menu( id, opts.parent ? opts.parent : this.elm );
  482.    
  483.     if ( opts.class ) menu.elm.addClass( opts.class );
  484.     menu.add_items( opts.items );
  485.    
  486.     return menu;
  487.   };
  488.    
  489.   head_init() {
  490.     var tm = this;
  491.     var tbl = this.elm;
  492.     var opts = this.opts;
  493.     var data = this.data;
  494.     var thead = tbl.find( '>thead' );  
  495.     var tr = thead.find( '>tr' );
  496.      
  497.     if ( opts.index === true ) {
  498.       tr.append( $(`
  499.         <th class="index"><div><button><span>&nbsp;</span></button></div></th>`
  500.       ) );
  501.     }
  502.    
  503.     data.keys.forEach( function( key, idx ) {
  504.       tr.append( $(`
  505.         <th data-key=" '` + key + `' ">
  506.           <div><button><span>` + data.head.labels[ idx ] + `</span></button></div>
  507.         </th>`
  508.       ) );
  509.     } );  
  510.    
  511.     thead.find( '>tr>th>div>button' ).css( {
  512.       minWidth: ( opts.column_sizing ? 5 : 0 ) + 'px',
  513.       paddingRight: ( opts.column_sizing ? 5 : 0 ) + 'px'
  514.     } );
  515.    
  516.     if ( opts.colorize ) tm.body_colorize( opts.colorize );
  517.    
  518.     return tm.bindings_set( thead );
  519.   }
  520.    
  521.   body_init() {
  522.     var tm = this;
  523.     var tbl = this.elm;
  524.     var opts = this.opts;
  525.    
  526.     tm.body_populate( tm.data );
  527.  
  528.     tbl.find( '>thead>tr>th' ).each( function( idx ) {
  529.       tm.column_set_width( idx );
  530.     });
  531.    
  532.     if ( opts.index ) tm.body_index();
  533.     if ( opts.colorize ) tm.body_colorize();
  534.     if ( opts.context_menu ) {
  535.       if ( typeof opts.context_menu === "boolean" ) {
  536.         opts.context_menu = [
  537.           { label: 'View Form', command: this.show_form },
  538.           { label: '' },
  539.           { label: 'Cut', command: this.input_cut },
  540.           { label: 'Copy', command: this.input_copy },
  541.           { label: 'Paste', command: this.input_paste },
  542.           { label: 'Undo' },
  543.           { label: '' },
  544.           { label: 'Select Cell', command: tm.cell_select },
  545.           { label: '' },
  546.           { label: 'Copy Row', command: this.copy_row },
  547.           { label: 'Paste Row', command: this.paste_row },
  548.           { label: 'Insert Row', command: this.new_row },
  549.           { label: 'Delete Row', command: this.delete_row }
  550.         ];
  551.       }
  552.      
  553.       var id = 'mm' + ( $( 'body .magic.menu' ).length + 1 );
  554.       tm.menu = new MenuMagic( id, tbl.find( '>tbody' ) );
  555.       tm.menu.add_items( opts.context_menu );
  556.     }
  557.    
  558.     tm.bindings_set( tbl.find( '>tbody' ) );
  559.    
  560.     return this;
  561.   }
  562.    
  563.   body_index() {      
  564.     this.elm.find( '>tbody>tr:not(.details)' ).each( function( idx ) {
  565.       $( this ).find( 'td.index input[type=text]' ).val( idx + 1 );
  566.     });
  567.   };
  568.    
  569.   body_colorize( args = 0 ) {
  570.     var elm = this.elm;
  571.     var raw = elm[ 0 ];
  572.    
  573.     var hdr_fg = args && args.th && args.th.color ? args.th.color : 0;
  574.     var hdr_bg = args && args.th && args.th.background ? args.th.background : 0;
  575.     var odd_fg = args && args.td && args.td.odd_fg ? args.td.odd_fg : 0;
  576.     var odd_bg = args && args.td && args.td.odd_bg ? args.td.odd_bg : 0;
  577.     var even_fg = args && args.td && args.td.even_fg ? args.td.even_fg : 0;
  578.     var even_bg = args && args.td && args.td.even_bg ? args.td.even_bg : 0;
  579.  
  580.     raw.hdr_fg = hdr_fg = hdr_fg ? hdr_fg : raw.hdr_fg ? raw.hdr_fg : '';
  581.     raw.hdr_bg = hdr_bg = hdr_bg ? hdr_bg : raw.hdr_bg ? raw.hdr_bg : '';
  582.     raw.odd_fg = odd_fg = odd_fg ? odd_fg : raw.odd_fg ? raw.odd_fg : '';
  583.     raw.odd_bg = odd_bg = odd_bg ? odd_bg : raw.odd_bg ? raw.odd_bg : '#d7d7d7';
  584.     raw.even_fg = even_fg = even_fg ? even_fg : raw.even_fg ? raw.even_fg : '';
  585.     raw.even_bg = even_bg = even_bg ? even_bg : raw.even_bg ? raw.even_bg : '#ffffff';
  586.  
  587.     elm.find( ">thead>tr *" ).css( { color: hdr_fg, background: hdr_bg } );
  588.  
  589.     var tr_odd = elm.find( ">tbody>tr:not(.details):odd *" );
  590.     var tr_even = elm.find( ">tbody>tr:not(.details):even *" );
  591.    
  592.     tr_odd.css( { color: odd_fg, backgroundColor: odd_bg } );
  593.     tr_odd.find( ">td" ).css( "border-color", odd_bg );
  594.     tr_even.css( { color: even_fg, backgroundColor: even_bg } );
  595.     tr_even.find( ">td" ).css( "border-color", even_bg );
  596.  
  597.     return this;
  598.   };
  599.  
  600.   body_populate( data ) {    
  601.     var tm = this;
  602.     var tbl = this.elm;
  603.     var tbody = tbl.find( '>tbody' );
  604.    
  605.     var html = '';
  606.     for ( var id in data.body ) {
  607.       html += '<tr data-id="' + id + '">';
  608.       data.body[ id ].forEach( function( value, idx ) {
  609.         var elms = data.children[ data.keys[ idx ] ];
  610.        
  611.         if ( elms ) {
  612.           var args = data.children[ data.keys[ idx ] ];
  613.           var elm_type = args.type;
  614.          
  615.           switch ( elm_type ) {
  616.             case 'option':
  617.               html += `
  618.               <td>
  619.                 <div>
  620.                   <select>`;
  621.                   var opts = data.children[ data.keys[ idx ] ];
  622.                   for ( var key in opts.children ) {
  623.                     html += '<option value="' + key +
  624.                     '">' + opts.children[ key ] + '</option>';
  625.                   }
  626.               html += `
  627.                   </select>
  628.                 </div>
  629.               </td>`;
  630.             break;
  631.           }
  632.         } else {
  633.           html +=
  634.           '<td><div><input type="text" value="' + value + '" /></div></td>';
  635.         }
  636.       } );
  637.       html += '</tr>';
  638.     };
  639.    
  640.     var html = $( html );
  641.     tbody.append( html );
  642.    
  643.     tbody.find( '>tr' ).each( function() {
  644.       tm.bindings_set( $( this ) );
  645.     });
  646.      
  647.     if ( tm.opts.index === true ) {
  648.       tbody.find( '>tr:not(.details)' ).prepend( $(  
  649.         '<td class="index"><div><input type="text" readonly="readonly"/></div></td>'
  650.       ) );
  651.     }
  652.    
  653.     return this;
  654.   }
  655.    
  656.   bindings_set( elm ) {
  657.     function move_up( e ) {
  658.       var input = $( e.target );
  659.      
  660.       var td = input.closest( 'td' );
  661.       var tr = td.closest( 'tr' ).prev();
  662.       if ( ! tr.length || tr.prop( 'tagName') !== 'TR' ) return false;
  663.      
  664.       td = tr.find( '>td' ).eq( td.index() );
  665.       td.find( '>div :input' ).focus();
  666.       if ( opts.selector ) tm.selector_set( td );
  667.     }
  668.    
  669.     function move_down( e ) {
  670.       var input = $( e.target );
  671.      
  672.       var td = input.closest( 'td' );
  673.       var tr = td.closest( 'tr' ).next();
  674.       if ( ! tr.length || tr.prop( 'tagName') !== 'TR' ) return false;
  675.      
  676.       td = tr.find( '>td' ).eq( td.index() );
  677.       td.find( '>div :input' ).focus();
  678.       if ( opts.selector ) tm.selector_set( td );
  679.     }
  680.    
  681.     function move_left( e ) {
  682.       var input = $( e.target );
  683.       var td = input.closest( 'td' ).prev();
  684.       if ( ! td.length || td.index() - opts.index < 0 ) return false;
  685.      
  686.       td.find( '>div :input' ).focus();
  687.       if ( opts.selector ) tm.selector_set( td );
  688.     }
  689.    
  690.     function move_right( e ) {
  691.       var input = $( e.target );
  692.       var td = input.closest( 'td' ).next();
  693.       if ( ! td.length || ! td.index() ) return false;
  694.      
  695.       td.find( '>div :input' ).focus();
  696.       if ( opts.selector ) tm.selector_set( td );
  697.     }
  698.    
  699.     function key_events() {
  700.       elm.off( 'keyup' ).on( 'keyup', function( e ) {
  701.         var input = $( ':focus' );
  702.         switch ( e.keyCode ) {
  703.           case 27: // ESC
  704.             input.removeAttr( 'readonly' );
  705.             if ( opts.selector ) tm.selector_set( input.closest( 'td' ) );
  706.             break;
  707.         }
  708.       });
  709.      
  710.       elm.off( 'keydown' ).on( 'keydown', function( e ) {
  711.         if ( ! $( 'table.magic .selected' ).length ) return;
  712.         var input = $( ':focus' );
  713.        
  714.         switch( e.keyCode )   {
  715.           case 37: if ( opts.selector ) move_left( e ); break;
  716.           case 39: if ( opts.selector ) move_right( e ); break;
  717.         }
  718.         if ( ! opts.selector ) return;
  719.        
  720.         e.preventDefault();
  721.        
  722.         switch( e.keyCode )   {
  723.           case 9: e.shiftKey ? move_left( e ) : move_right( e ); break; // Tab
  724.           case 13: e.shiftKey && opts.selector ? move_up( e ) : move_down( e ); break; //Enter
  725.           case 38: move_up( e ); break;
  726.           case 40: move_down( e ); break;
  727.          
  728.           case 113: // F2
  729.             tm.selection_remove();
  730.             input.removeAttr( 'readonly' );
  731.             break;
  732.         }
  733.       } );
  734.     }
  735.    
  736.     var tm = this;
  737.     var tbl = this.elm;
  738.     var opts = this.opts;
  739.     var id = tbl.attr( 'id' );
  740.     var thead = tbl.find( '>thead' );
  741.     var tbody = tbl.find( '>tbody' );
  742. //    var config = JSON.parse( localStorage.getItem( id ) ).config;
  743.    
  744.     switch ( elm.prop( 'tagName' ) ) {
  745.       case 'THEAD':
  746.         if ( tm.opts.sortable ) {
  747.           thead.find('>tr>th span').on( 'click', tm.column_sort );
  748.         }
  749.         if ( tm.opts.column_sizing ) {
  750.           thead.find( 'span' ).on( 'dblclick', false );
  751.           thead.find( 'span' ).on( 'mousedown', false );
  752.           thead.find( 'button' ).on( 'dblclick', function() {
  753.             tm.column_set_width( $( this ).closest( 'th').index() );
  754.           } );    
  755.           thead.find( '>tr>th button' ).
  756.           on( 'mousedown', { elm: false }, function( e ) {
  757.             e.data.elm = $( this );
  758.             tm.column_sizer( e );
  759.           } );
  760.         }
  761.         break;
  762.      
  763.       case 'TBODY':
  764.         tbody.find( ':input' ).on( 'contextmenu', function() {
  765.           tm.menu.init( tbody );
  766.         } );
  767.         break;
  768.      
  769.       case 'TR':
  770.         key_events();
  771.        
  772.         elm.find( 'td.index input' ).off( 'click' );  
  773.        
  774.         if( opts.column_sizing ) {
  775.           elm.find( ':input' ).on( 'dblclick', tm.cell_edit );
  776.           elm.find( ':input' ).on( 'click', tm.selector_set );
  777.           elm.find( 'select' ).on( 'focus', tm.selector_set );
  778.         }
  779.         break
  780.     }
  781.    
  782.     $( window ).on( 'load', function() {
  783.    
  784.     } ).
  785.     on( 'resize', function() { tbl.resize(); } );
  786.    
  787.     return this;
  788.   }  
  789.      
  790.   selector_set( e ) {
  791.     var input = e.target ? $( e.target ) : e.find( '>div :input' );
  792.     var tbl = input.closest( 'table' );
  793.     var thead = tbl.find( '>thead' );
  794.     var tm = tbl[0].obj;
  795.  
  796.     if ( ! tm.opts.selector ) return false;
  797.    
  798.     document.active_table = tbl;    
  799.     document.caret_position = input[0].selectionStart;
  800.    
  801.     if ( ! $( '.menu.magic' ).is( ':visible' ) )
  802.       tm.selection_remove();
  803.     else
  804.       $( 'table.magic div:not(.row).selected' ).removeClass( 'selected' );
  805.  
  806.     input.closest( 'div' ).addClass( 'selected' );
  807.     input.attr( 'readonly', 'readonly' );
  808.    
  809.    
  810.     tbl.find( '.selector' ).removeClass( 'selector' );
  811.    
  812.     thead.find( '>tr>th' ).eq(
  813.       input.closest( 'td' ).index() ).addClass( 'selector' );
  814.      
  815.     input.closest( 'tr' ).find( 'td:first-child' ).addClass( 'selector' );
  816.    
  817.     return false;
  818.   };
  819.    
  820.   selection_get() {
  821.     var input = this.elm.find( '>tbody>tr>td>div.selected :input' );
  822.     return input.val().substr(
  823.       input[0].selectionStart, input[0].selectionEnd - input[0].selectionStart );
  824.   };
  825.  
  826.   selection_remove() {
  827.     $( 'table.magic .selected' ).removeClass( 'selected row cells' );
  828.     return this;
  829.   };
  830.    
  831.   column_sort() {  
  832.     var tbl = $( this ).closest( 'table' );
  833.     var value = 0;
  834.     var table = tbl[0];
  835.     var idx = $(this).closest( 'th' ).index();
  836.     var selected = tbl.find( '>tbody>tr>td>div.selected' );
  837.    
  838.     var value = function( tr, idx ) {
  839.       var input = $( tr ).find( 'td' ).eq( idx ).find( ':input' );
  840.       switch ( input.prop('tagName') ) {
  841.         case 'INPUT':
  842.           return input.val();
  843.         case 'SELECT':
  844.           return input.find( 'option[value="' + input.val() + '"]' ).text();
  845.         default: return '';
  846.       }
  847.     };
  848.  
  849.     var column = ( idx, asc ) => ( a, b ) => ( ( v1, v2 ) =>
  850.       v1 !== '' && v2 !== '' && ! isNaN(v1) && ! isNaN( v2 ) ?
  851.       v1 - v2 : v1.toString().localeCompare( v2 )
  852.       ) ( value( asc ? a : b, idx ), value( asc ? b : a, idx ) );
  853.  
  854.     var tbl_rows = tbl.find( '>tbody>tr:not(.details)' );
  855.  
  856.     if ( typeof table.asc === 'undefined' ) table.asc = 1;
  857.  
  858.     Array.from( tbl_rows ).sort( column( idx, table.asc = ! table.asc ) )
  859.       .forEach( tr => tbl.find( '>tbody' )[0].appendChild( tr ) );
  860.  
  861.     tbl_rows.each( function() {
  862.       var elm = $( this );
  863.       var id = $( this ).attr( 'data-id' );
  864.       elm.parent().
  865.         find( 'tr.details[data-id=' + id + ']' ).insertAfter( elm );
  866.     });
  867.     tbl[0].obj.body_colorize();
  868.    
  869.     if ( selected.length ) { selected.find( ':input' ).focus(); }
  870.    
  871.     return table.obj;
  872.   };
  873.    
  874.   column_sizer( e ) {
  875.     function reset()  {
  876.       wrap.off( 'mousemove' );
  877.       thead.find( 'tr *' ).css( 'cursor', '' );
  878.       tbody.find( 'tr *' ).css( 'cursor', '' );
  879.      
  880.       localStorage.setItem( id, JSON.stringify( tm.cache ) );
  881.     }
  882.  
  883.     function set_size( e ) {
  884.       wrap.off( 'mousemove' );
  885.       deltaX = e.pageX - curX;
  886.       curX = e.pageX;
  887.       width = Math.round( button.width() ) + deltaX;
  888.      
  889.       button.width( width );
  890.       rows.each( function() {
  891.         var size = width + ( opts.column_sizing ? sash_width : 0 );
  892.         $( this ).find( 'td:nth-child(' + ( th.index() + 1 ) + ')' ) .
  893.         find( ':input' ).width( size );
  894.         tm.cache.config.columns.sizes[ idx ] = size;
  895.       });  
  896.    
  897.    
  898.       wrap.on( 'mousemove', set_size );
  899.     }
  900.    
  901.     var button = e.data.elm;
  902.     var th = button.closest('th');
  903.     if ( ! th.length ) return;
  904.    
  905.     var idx = th.index();
  906.     var tbl = this.elm;
  907.     var id = tbl.attr( 'id' );
  908.     var tm = this;
  909.     var opts = this.opts;
  910.     var width = 0;
  911.     var deltaX = 0;
  912.     var curX = e.pageX;
  913.     var thead = tbl.find( '>thead' );
  914.     var tbody = tbl.find( '>tbody' );
  915.     var rows = tbody.find( '>tr:not(.details)' );
  916.     var wrap = tbl.closest( '.wrap' );
  917.    
  918.     var json = localStorage.getItem( id ) ?
  919.       JSON.parse( localStorage.getItem( id ) ) : {};
  920.    
  921.     wrap.
  922.     on( 'mouseup', function() {
  923.       reset();
  924.     }).
  925.     on( 'mouseleave', function() {
  926.       reset();
  927.     }).
  928.     on( 'mousemove', function() {
  929.       thead.find( 'tr *' ).css( 'cursor', 'col-resize' );
  930.       tbody.find( 'tr *' ).css( 'cursor', 'col-resize' );
  931.       set_size( e );
  932.     });
  933.    
  934.     return this;
  935.   };
  936.    
  937.   column_set_width( idx, width = 0 ) {
  938.     var tbl = this.elm;
  939.     var opts = this.opts;
  940.     var id = tbl.attr( 'id' );
  941.     var thead = tbl.find( '>thead' );
  942.     var sizes = false;
  943.    
  944. //    if ( this.cache.config.columns.sizes ) {
  945. //      sizes = this.cache.config.columns.sizes;
  946. //    }
  947.    
  948.     if ( ! width ) width = this.cell_largest( idx );
  949.     thead.find( '>tr>th' ).eq( idx ).find( 'button' ).width( width + 4 );
  950.    
  951.     width = ( opts.column_sizing ? ( width + sash_width ) : width ) + 4;
  952.  
  953.     tbl.find( '>tbody>tr:not(.details)' ).each( function() {
  954.       var input = $( this ).find( '>td' ).eq( idx ).find( ':input' );
  955.       input.width( width );
  956.       if ( sizes ) sizes[ idx ] = width;
  957.     });
  958. //    localStorage.setItem( id, JSON.stringify( this.cache ) );
  959.     return this;
  960.   };
  961.      
  962.   cell_edit( e ) {
  963.     var elm = $( e.target );
  964.     var tm = elm.closest( 'table' )[0].obj;
  965.     var position = document.caret_position;
  966.    
  967.     tm.selection_remove();
  968.     if ( tm.opts.selector ) elm[0].setSelectionRange( position, position );
  969.     elm.removeAttr( 'readonly' );
  970.    
  971.     return false;
  972.   };
  973.      
  974.   cell_select( e ) {
  975.     var elm = e.data.elm;
  976.     elm.select();
  977.     elm.closest( 'div' ).addClass( 'selected' );
  978.   };
  979.  
  980.   cell_largest( idx ) {
  981.     var tbl = this.elm;
  982.     var opts = this.opts;
  983.     var tbody = tbl.find( '>tbody' );
  984.     var span = $( 'body>.measure' );
  985.     var rows = tbody.find( '>tr:not(.details)' );
  986.  
  987.     if ( ! idx && opts.index ) {
  988.       span.text( rows.length );
  989.       return Math.round( span.width() );
  990.     }
  991.  
  992.     var width = 0;
  993.     var largest = 0;
  994.     rows.each( function() {
  995.       var input = $( this ).find( '>td' ).eq( idx ).find( ':input' );
  996.      
  997.       switch ( input.prop( 'tagName' ) ) {
  998.         case 'SELECT':  
  999.           if ( opts.column_sizing ) {
  1000.             var option = input.find( 'option[value="' + input.val() + '"]' );
  1001.             if ( option.text() === '' ) {
  1002.               option = option.next();
  1003.             }
  1004.             span.text( option.text() + 'W' );
  1005.             width = span.width();
  1006.           } else {
  1007.             var widest = 0;
  1008.             input.find( 'option' ).each( function() {
  1009.               span.text( $( this ).text() + 'W ' );
  1010.               widest = span.width() > widest ? span.width() : widest;
  1011.             });      
  1012.             width = widest;
  1013.           }
  1014.           break;
  1015.         case 'INPUT':
  1016.           span.text( input.val().trim() );
  1017.           width = Math.round( span.width() - ( opts.column_sizing ? sash_width : 0 ) );
  1018.           break;
  1019.       }
  1020.       largest = width > largest ? width : largest;
  1021.     } );
  1022.     return largest;
  1023.   };
  1024.    
  1025.   input_cut() {
  1026.     var tbl = self.parent.closest( 'table' );
  1027.     var text = tbl[0].obj.selection_get();
  1028.    
  1029.     document.copy_buffer = text;
  1030.     document.execCommand( 'cut' );
  1031.   };
  1032.    
  1033.   input_copy( e ) {
  1034.    document.execCommand( 'copy' );
  1035.     var tbl = self.parent.closest( 'table' );
  1036.     var elm = e.data.elm;
  1037.     var text = tbl[0].obj.selection_get();
  1038.     if ( text === '' ) return;
  1039.  
  1040.     elm.focus();
  1041.     document.copy_buffer = text;
  1042.   };
  1043.    
  1044.   input_paste( e ) {
  1045.     var elm = e.data.elm;
  1046.     var text = document.copy_buffer;
  1047.     var start = elm[0].selectionStart;
  1048.    
  1049.     elm[0].value = elm.val().splice( elm[0].selectionStart, 0, text );
  1050.     elm.focus();
  1051.     elm[0].setSelectionRange( start + text.length, start + text.length );
  1052.   };
  1053.  
  1054.   new_row( e ) {
  1055.     var tbl = document.active_table;
  1056.     var tm = tbl[0].obj;
  1057.     var args = tm.data;
  1058.     var index = tm.opts.index;
  1059.     tm.selection_remove();
  1060.    
  1061.     var tbody = tbl.find( 'tbody' );
  1062.     var new_id = tbody.find( 'tr:not(details).new' ).length;
  1063.     var html = '<tr data-id="' + new_id + '~" class="new">';
  1064.    
  1065.     if ( index ) {
  1066.       html +=
  1067.       '<td class="index"><div><input type="text" readonly="readonly"/></div></td>';
  1068.     }
  1069.    
  1070.     args.keys.forEach( function( key ) {
  1071.       if ( key in args.children ) {
  1072.         switch ( args.children[ key ].type ) {
  1073.           case 'option':
  1074.             html += '<td><div><select>';
  1075.             var nodes = args.children[ key ].children;
  1076.             for( var idx in nodes ) {
  1077.               html += '<option value="' + idx + '">' + nodes[ idx ] + '</option>';
  1078.             };
  1079.             html += '</select></div></td>';
  1080.           break;
  1081.         }
  1082.       } else {
  1083.         html += '<td><div><input type="text" /></div></td>';
  1084.       }
  1085.     } );
  1086.     html += '</tr>';
  1087.    
  1088.     var row = $( html );
  1089.     if ( typeof e === 'undefined' ) {
  1090.       tbody.prepend( row );
  1091.     } else {
  1092.       var tr = e.data.elm.closest( 'tr' );
  1093.       tbl.find( 'tr' ).eq( tr.index() + 1 ).after( row );
  1094.     }
  1095.    
  1096.     tm.bindings_set( row );
  1097.    
  1098.     var idx = tm.opts.index ? 1 : 0;
  1099.     var td = row.find( 'td' ).eq( idx );
  1100.    
  1101.     td.find( ':input' ).focus();
  1102.     td.find( 'div' ).addClass( 'selected' );
  1103.     tbl.find( '>thead>tr>th' ).each( function( idx ) {
  1104.       tm.column_set_width( idx, $( this ).width() - 7.5 );
  1105.     });
  1106.    
  1107.     tm.body_index();
  1108.     tm.body_colorize();
  1109.   };
  1110.      
  1111.   copy_row( e ) {
  1112.     var elm = e.data.elm;
  1113.     var tr = elm.closest( 'tr' );
  1114.     tr.find( '>td>div' ).addClass( 'selected row' );
  1115.     tr.addClass( 'selected' );
  1116.     document.selected_rows = [ tr ];
  1117.   }
  1118.      
  1119.   paste_row( e ) {
  1120.     var elm = e.data.elm;
  1121.     var tr = elm.closest( 'tr' );
  1122.     var tbl = elm.closest( 'table' );
  1123.     var thead = tbl.find( '>thead' );
  1124.     var tm = tbl[0].obj;
  1125.    
  1126.     var rows = document.selected_rows;
  1127.     var new_row = false;
  1128.    
  1129.     rows.forEach( function( row, idx ) {
  1130.       var clone = row.clone();
  1131.       tr.eq( idx - 1).after( clone );
  1132.       new_row = row = tr.next().not( '.details' );
  1133.      
  1134.       tm.bindings_set( row );  
  1135.       tm.column_set_width( idx );
  1136.     } );
  1137.    
  1138.     tm.body_index();
  1139.     tm.body_colorize();
  1140.     tm.selection_remove();
  1141.     if ( new_row ) {
  1142.       new_row.addClass( 'selected' );
  1143.       new_row.find( '>td>div' ).addClass( 'selected cells' );
  1144.       new_row.find( '>td :input' ).each( function( idx ) {
  1145.         $( this ).width( thead.find( '>tr>th' ).eq( idx ).width() - 3 );
  1146.       } );
  1147.     }
  1148.   }
  1149.    
  1150.   delete_row( e ) {
  1151.     var tbl = document.active_table;
  1152.     var tm = tbl[0].obj;
  1153.     var tbody = tbl.find( 'tbody' );
  1154.     var focus = $( ':focus' );
  1155.    
  1156.     var tr = e.data.elm.closest( 'tr' );
  1157.     var widths = [];
  1158.     tbl.find( '>thead>tr>th' ).each( function() {
  1159.       widths.push( $( this ).width() );
  1160.     });
  1161.    
  1162.     if ( tr.next().hasClass( 'details' ) ) {
  1163.       tr.next().find( '.wrap' ).slideUp( fadetime, function() {
  1164.         tr.next().remove();
  1165.         tr.remove();
  1166.         tm.body_index();
  1167.         tm.body_colorize();
  1168.       });
  1169.     } else {
  1170.       tr.remove();
  1171.       tm.body_index();
  1172.       tm.body_colorize();
  1173.     }
  1174.     if ( ! tbody.find( 'tr' ).length ) {
  1175.       tm.new_row();
  1176.       widths.forEach( function( width, idx ) {
  1177.         tm.column_set_width( idx, width - 7.5 );
  1178.       });
  1179.     }
  1180.     focus.focus();
  1181.   };
  1182. }
  1183.  
  1184.  
  1185. //  -------------------------------------------------------
  1186.  
  1187. jQuery(document).ready( function( $ ) {
  1188.   wpadminbar = $( '#wpadminbar' ).length ? set_top() : false;
  1189.  
  1190.   var tables = [ 'tables', 'tables1' ];
  1191.   var tbl1 = tables[0];
  1192.   var tbl2 = tables[1];
  1193.  
  1194.   let items = [];
  1195.   for ( var i = 1; i < 6; i++ )
  1196.     items.push( { id: 'test'+i, data: mockup_data, created: new Date() } );
  1197.  
  1198.   let items2 = [];
  1199.   for ( var i = 1; i < 6; i++ )
  1200.     items2.push( { id: 'test'+i, data: mockup_data2, created: new Date() } );
  1201.  
  1202.   db1 = new DBMagic( 'TableMagic', 1, tables );
  1203.    
  1204.   db1.add( tbl1, items, function( result ) {
  1205. //    log( 'TEST 1:', result );
  1206.   } );
  1207.  
  1208.   db1.get( tbl1, [ 'test1', 'test2' ], function( result ) {
  1209. //    log( 'TEST 2:', result );
  1210.   } );
  1211.  
  1212.   db1.update( tbl1, items2, function( result ) {
  1213. //    log( 'TEST 3:', result );
  1214.   } );
  1215.  
  1216.   db1.add( tbl2, items, function( result ) {
  1217. //    log( 'TEST 4:', result);
  1218.   } );
  1219.  
  1220.   db1.get( tbl1, [ 'test1', 'test2' ], function( result ) {
  1221. //    log( 'TEST 5:', result );
  1222.   } );
  1223.  
  1224.   db1.get( tbl2, [ 'test1', 'test2' ], function( result ) {
  1225. //    log( 'TEST 6:', result );
  1226.   } );
  1227.  
  1228.   db1.getAll( tbl1, function( result ) {
  1229. //    log( 'TEST 7:', result );
  1230.   } );
  1231.  
  1232.   db1.delete( tbl1, [ 'test3', 'test4' ], function( result ) {
  1233. //    log( 'TEST 8:', result );
  1234.   } );
  1235.  
  1236.   db1.getAll( tbl1, function( result ) {
  1237. //    log( 'TEST 9:', result);
  1238.   } );  
  1239.  
  1240. //  db1.db_delete();
  1241.  
  1242.   items = [
  1243.     { label: 'View Form', command: false },
  1244.     { label: '' },
  1245.     { label: 'Cut', command: false },
  1246. //    { label: 'Copy', command: false },
  1247. //    { label: 'Paste', command: false },
  1248.     { label: 'Undo' },
  1249.     { label: '' },
  1250.     { label: 'Select Cell', command: false },
  1251.     { label: '' },
  1252.     { label: 'Insert Row', command: false },
  1253.     { label: 'Delete Row', command: false }
  1254.   ];  
  1255.  
  1256.   colorize1 = {
  1257.     th: {
  1258.       color: 'white',
  1259.       background: 'blue'
  1260.     }
  1261.   };
  1262.  
  1263.   colorize2 = {
  1264.     th: {
  1265.       color: 'white',
  1266.       background: 'teal',
  1267.       backgroundColor: 'teal'
  1268.     },
  1269. //    td: {
  1270. //      odd_fg: 'blue',
  1271. //      odd_bg: 'cyan',
  1272. //      even_fg: 'white',
  1273. //      even_bg: 'green'
  1274. //    }
  1275.   };
  1276.  
  1277.   tm1 = new TableMagic( $( 'table#test1' ), {
  1278.     index: true,
  1279.     selector: true,
  1280.     colorize: true,
  1281.     sortable: true,
  1282.     context_menu: true,
  1283.     column_sizing: true
  1284.   }, mockup_data  );  
  1285.  
  1286.   tm1.elm.find( '>tbody>tr:first-child>td:nth-child(2) :input' ).trigger( 'focus' );
  1287.  
  1288.   tm2 = new TableMagic( $( 'table#test2' ), {
  1289.     index: false,
  1290.     selector: false,
  1291.     colorize: colorize2,
  1292.     sortable: false,
  1293.     context_menu: true,
  1294.     column_sizing: false
  1295.   }, mockup_data  );
  1296.  
  1297. //  tm2.elm.find( '>tbody>tr:first-child>td:nth-child(2) :input' ).trigger( 'focus' );
  1298.  
  1299. });  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement