Uno-Dan

Untitled

Jan 23rd, 2021
972
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. function get_scrollbar_width( $ ) {
  3.     $('body').append( $(`
  4.     <div id="scrollbar" style="width: 40px; overflow-y: scroll; display: none;">
  5.       <div id="scrollbar_inner" style="height: 20px;"></div>
  6.     </div>`) );
  7.    
  8.     var scrollbarWidth = 0;
  9.     var scrollbar = $( '#scrollbar' );
  10.     var scrollbar_inner = $( '#scrollbar_inner' );
  11.    
  12.     scrollbar.show();
  13.     scrollbarWidth = scrollbar[0].offsetWidth - scrollbar_inner[0].offsetWidth;
  14.     scrollbar.remove();
  15.    
  16.     return Math.round( scrollbarWidth );
  17. }
  18.    
  19. var log = console.log;
  20. var fadetime = 400;
  21. var user;
  22. var wpadminbar;
  23. var scrollbarWidth = get_scrollbar_width( jQuery );
  24. var zoom = document.documentElement.clientWidth / window.innerWidth;
  25. var sash_width = 5;
  26.    
  27. var mockup_data = {
  28.   keys: [
  29.     'status_id', 'customer_id', 'branch_id', 'agent_id', 'phone1',
  30.     'phone2', 'email_address', 'address', 'unit', 'postalcode', 'country_id',
  31.     'zone_id', 'location_id', 'notes'
  32.   ],
  33.   head: {
  34.     labels: [
  35.       'Status', 'Customer', 'Branch', 'Agent', 'Phone1', 'Phone2',
  36.       'Email Address', 'Address', 'Unit', 'Post Code', 'Country', 'State/Prov',
  37.       'City/Town', 'Notes'
  38.     ]
  39.   },
  40.   body: {
  41.     1: [
  42.       0, 'Whole Foods', 'Whole Foods Yorkville - YRK', 'xx', '123.456.7890',
  43.       '432.546.4325', 'sam@abc.com', 'address', '#745', 'M5R-3R9',
  44.       'Canada', 'Ontario', 'Toronto',
  45.       'This is a test message...'
  46.     ],
  47.     3: [
  48.       1, 'Whole Foods', 'Whole Foods Yorkville - YRK', 'xx', '123.456.7890',
  49.       '432.546.4325', 'sam@abc.com', 'address', '#745', 'M5R-3R9',
  50.       'Canada', 'Ontario', 'Toronto',
  51.       'This is a test message...'
  52.     ],
  53.     5: [
  54.       2, 'Whole Foods', 'Whole Foods Yorkville - YRK', 'xx', '123.456.7890',
  55.       '432.546.4325', 'sam@abc.com', 'address', '#745', 'M5R-3R9',
  56.       'Canada', 'Ontario', 'Toronto',
  57.       'This is a test message...'
  58.     ],
  59.     25: [
  60.       3, 'Whole Foods', 'Whole Foods Yorkville - YRK', 'xx', '123.456.7890',
  61.       '432.546.4325', 'sam@abc.com', 'address', '#745', 'M5R-3R9',
  62.       'Canada', 'Ontario', 'Toronto',
  63.       'This is a test message...'
  64.     ]
  65.   },
  66.   children: {
  67.     status_id: {
  68.       type: 'option',
  69.       children: { 0: '', 1: 'Active', 2: 'Prospect', 3: 'Pending', 4: 'On Hold' }
  70.     },
  71.     agent_id: {
  72.       type: 'option',
  73.       children: { 0: '', 1: 'Dan', 2: 'Danny', 3: 'Daniel', 4: 'Uno' }
  74.     }
  75.   }
  76. };
  77.  
  78. String.prototype.splice = function(idx, rem, str) {
  79.     return this.slice(0, idx) + str + this.slice(idx + Math.abs(rem));
  80. };
  81.  
  82. class MenuMagic {
  83.   constructor( id, parent ) {
  84.     $ = jQuery;
  85.     var menu = $( '<div id="' + id + '" class="menu magic"><ul></ul></div>' );
  86.     this.parent = parent;
  87.     this.id = id;
  88.     this.elm = menu;
  89.     this.items = menu.find('>ul');
  90.     this.commands = [];
  91.     parent.append( menu );
  92.   }
  93.  
  94.   show( elm, x, y ) {
  95.     self = this;
  96.     document.active_table = elm.closest( 'table' );
  97.  
  98.     if ( ! elm.is( ':input' ) ) return false;
  99.     $('.wrapper').find( '.menu:visible' ).hide();
  100.  
  101.     self.add_commands( elm );
  102.     self.elm[0].target = elm;
  103.     self.elm.css( { top: y, left: x, position: 'fixed' } );
  104.     self.elm.show();
  105.   }
  106.  
  107.   init() {
  108.     self = this;
  109.     $ = jQuery;
  110.    
  111.     this.parent.on("contextmenu", function( e ) {
  112.       e.preventDefault();
  113.       var elm = $( document.elementFromPoint( e.pageX, e.pageY ) );
  114.       self.show( elm, e.pageX, e.pageY );
  115.       return false;
  116.      
  117.     } );
  118.    
  119.     $( document ).
  120.       on('click', function() { self.elm.hide(); }).
  121.       keyup( function( e ) { if ( e.key === "Escape" ) { self.elm.hide(); }
  122.     });
  123.   }
  124.  
  125.   add_item( item ) {
  126.     this.commands.push( item );
  127.   }
  128.  
  129.   add_items( items ) {
  130.     this.commands = items;
  131.   }
  132.  
  133.   add_command( item, elm ) {
  134.     var ul = self.elm.find('ul');
  135.     var cls = item.label.replace( ' ' , '_' ).toLowerCase();
  136.     cls = cls !== '' ? cls : 'seperator';
  137.     var button = item.label.length ?
  138.     '<button class="none">' + item.label + '</button>' : '';
  139.     var li = $ ( '<li class="'+ cls +'">' + button + '</li>' );
  140.     ul.append( li );
  141.  
  142.     if ( item.command ) {
  143.       li.find('button').on( 'click', { elm: elm }, function( e ) {
  144.         item.command( e );
  145.         self.elm.fadeOut( fadetime / 2 );
  146.       });
  147.     }
  148.   }
  149.  
  150.   add_commands( elm ) {
  151.     self = this;
  152.     var ul = this.elm.find('>ul');
  153.     var items = this.commands;
  154.    
  155.     ul.find('>li').remove();
  156.     items.forEach( function( item, idx ) {
  157.       self.add_command( item, elm );
  158.     });
  159.   }
  160. }
  161.  
  162. class TableMagic {
  163.   constructor( elm, opts, data ) {
  164.     $ = jQuery;
  165.     elm[0].obj = this;
  166.     elm.addClass( 'magic' );
  167.     var tm = this;
  168.     var self = this;
  169.     document.active_table = elm;
  170.    
  171.    
  172.     this.elm = elm;
  173.     this.opts = opts;
  174.     this.data = data;
  175.     this.menu = false;
  176.     this.copy_buffer = '';
  177.    
  178.     if( ! $( 'body>.measure' ).length )
  179.       $('body').append( $( '<span class="measure lato" />' ) );
  180.    
  181.     var wrap = $( '<div class="wrap" />' );
  182.     elm.parent().append( wrap );
  183.     if ( ! elm.find('>thead' ).length ) elm.append( '<thead /><tr />' );
  184.     if ( ! elm.find('>tbody' ).length ) elm.append( '<tbody />' );
  185.     wrap.append( elm );
  186.    
  187.     this.init_head();
  188.     this.init_body();
  189.    
  190.     elm.find( ':input' ).on( 'focus', function() {
  191.       self.menu.init( self.menu.parent );
  192.     } );
  193.    
  194.     elm.find( '>tbody>tr' ).on( 'contextmenu', function( e ) {
  195.       e.preventDefault();
  196.       var elm = $( document.elementFromPoint( e.pageX, e.pageY ) ).find( ':input' );
  197.      
  198.       self.menu.show( elm, e.pageX, e.pageY );
  199.     } );
  200.   }
  201.    
  202.   sort() {  
  203.     var tbl = $( this ).closest( 'table' );
  204.     var value = 0;
  205.     var table = tbl[0];
  206.     var idx = $(this).closest('th').index();
  207.  
  208.     var value = ( tr, idx ) => $( tr ).find('td').eq( idx ).
  209.       find( 'input' ).val();
  210.  
  211.     var column = (idx, asc) => (a, b) => ((v1, v2) =>
  212.       v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v2) ? v1 - v2 : v1.toString().localeCompare(v2)
  213.       ) ( value(asc ? a : b, idx), value(asc ? b : a, idx) );
  214.  
  215.     var tbl_rows = tbl.find('>tbody>tr:not(.details)');
  216.  
  217.     if (typeof table.asc === 'undefined') {
  218.       table.asc = 1;
  219.     }
  220.  
  221.     Array.from(tbl_rows).sort( column(idx, table.asc = !table.asc) )
  222.       .forEach(tr => tbl.find('>tbody')[0].appendChild(tr) );
  223.  
  224.     tbl_rows.each(function() {
  225.       var elm = $(this);
  226.       var id = $(this).attr('data-id');
  227.       elm.parent().
  228.         find('tr.details[data-id=' + id + ']').insertAfter(elm);
  229.     });
  230.     tbl[0].obj.colorize();
  231.   };
  232.    
  233.   index() {      
  234.     var elm = this.elm;
  235.     var rows = elm.find('>tbody>tr:not(.details)');
  236.  
  237.     rows.each( function( idx ) {
  238.       var input = $(this).find('td.index input[type=text]');
  239.       input.val( idx + 1 );
  240.     });
  241.  
  242.     rows.find('>td.index').css('text-align', 'right !important');
  243.     rows.find('>td.index input').css('text-align', 'right');
  244.   };
  245.    
  246.   colorize( args = 0 ) {
  247.     var elm = this.elm;
  248.     var raw = elm[ 0 ];
  249.    
  250.     var hdr_fg = args && args.th && args.th.color ? args.th.color : 0;
  251.     var hdr_bg = args && args.th && args.th.background ? args.th.background : 0;
  252.     var odd_fg = args && args.td && args.td.odd_fg ? args.td.odd_fg : 0;
  253.     var odd_bg = args && args.td && args.td.odd_bg ? args.td.odd_bg : 0;
  254.     var even_fg = args && args.td && args.td.even_fg ? args.td.even_fg : 0;
  255.     var even_bg = args && args.td && args.td.even_bg ? args.td.even_bg : 0;
  256.  
  257.     raw.hdr_fg = hdr_fg = hdr_fg ? hdr_fg : raw.hdr_fg ? raw.hdr_fg : '';
  258.     raw.hdr_bg = hdr_bg = hdr_bg ? hdr_bg : raw.hdr_bg ? raw.hdr_bg : '';
  259.     raw.odd_fg = odd_fg = odd_fg ? odd_fg : raw.odd_fg ? raw.odd_fg : '';
  260.     raw.odd_bg = odd_bg = odd_bg ? odd_bg : raw.odd_bg ? raw.odd_bg : '#d7d7d7';
  261.     raw.even_fg = even_fg = even_fg ? even_fg : raw.even_fg ? raw.even_fg : '';
  262.     raw.even_bg = even_bg = even_bg ? even_bg : raw.even_bg ? raw.even_bg : '#ffffff';
  263.  
  264.     elm.find( ">thead>tr *" ).css( { color: hdr_fg, background: hdr_bg } );
  265.  
  266.     elm.find( ">tbody>tr:not(.details):odd *" ).css( "color", odd_fg );
  267.     elm.find( ">tbody>tr:not(.details):odd *" ).css( "background-color", odd_bg );
  268.     elm.find( ">tbody>tr:not(.details):odd>td div" ).css( "border-color", odd_bg );
  269.  
  270.     elm.find( ">tbody>tr:not(.details):even *" ).css( "color", even_fg );
  271.     elm.find( ">tbody>tr:not(.details):even *" ).css( "background-color", even_bg );
  272.     elm.find( ">tbody>tr:not(.details):even>td div" ).css( "border-color", even_bg );
  273.  
  274.     return $( this );
  275.   };
  276.    
  277.   sortable() {
  278.     this.elm.
  279.     find('>thead>tr>th span').on('click', { call: this.colorize }, this.sort).
  280.     find('>tbody>tr.details .wrap').css( { 'position': 'static' } );
  281.     return this.elm;
  282.   };
  283.    
  284.   init_head() {
  285.     var self = this;
  286.     var tbl = this.elm;
  287.     var opts = this.opts;
  288.     var data = this.data;
  289.     var thead = tbl.find('>thead');  
  290.     var tr = thead.find('>tr');
  291.      
  292.    
  293.     if ( opts.index === true ) {
  294.       tr.append( $(`
  295.         <th class="index"><div><button><span>&nbsp;</span></button></div></th>`
  296.       ) );
  297.     }
  298.     data.keys.forEach( function( key, idx ) {
  299.       tr.append( $(`
  300.         <th data-key=" '` + key + `' ">
  301.           <div><button><span>` + data.head.labels[ idx ] + `</span></button></div>
  302.         </th>`
  303.       ) );
  304.     } );  
  305.    
  306.     if (opts.column_sizing === true ) {
  307.       thead.find( 'span' ).on( 'dblclick', false );
  308.       thead.find( 'button' ).on( 'dblclick', function() {
  309.         self.set_column_width( $( this ).closest( 'th' ).index() );
  310.       } );
  311.       thead.find( 'span' ).on( 'mousedown', false );
  312.     }
  313.  
  314.     if ( opts.sortable ) this.sortable();
  315.     if ( opts.column_sizing ) this.column_sizing();
  316.     return tbl;
  317.   }
  318.    
  319.   init_body() {
  320.     var tbl = this.elm;
  321.     var self = this;
  322.     var opts = this.opts;
  323.     var data = this.data;
  324.     var thead = tbl.find('>thead');
  325.     var tbody = tbl.find('>tbody');
  326.    
  327.     var html = '';
  328.     for (var id in data.body ) {
  329.       html += '<tr data-id="' + id + '">';
  330.       data.body[ id ].forEach( function( value, idx ) {
  331.         var elms = data.children[ data.keys[ idx ] ];
  332.        
  333.         if ( elms ) {
  334.           var args = data.children[ data.keys[ idx ] ];
  335.           var elm_type = args.type;
  336.          
  337.           switch ( elm_type ) {
  338.             case 'option':
  339.               html += `
  340.               <td>
  341.                 <div>
  342.                   <select>`;
  343.                   var opts = data.children[ data.keys[ idx ] ];
  344.                   for ( var key in opts.children ) {
  345.                     html += '<option value="' + key +
  346.                     '">' + opts.children[ key ] + '</option>';
  347.                   }
  348.               html += `
  349.                   </select>
  350.                 </div>
  351.               </td>`;
  352.             break;
  353.           }
  354.         } else {
  355.           html +=
  356.           '<td><div><input type="text" value="' + value + '" /></div></td>';
  357.         }
  358.       } );
  359.       html += '</tr>';
  360.     };
  361.     var tr = $( html );
  362.    
  363.     tbody.append( tr );
  364.     tr.find( ':input' ).on( 'focus', function() {
  365.       $( '.menu' ).hide();
  366.       document.active_table = tbl;
  367.       self.remove_selected();
  368.       $( this ).closest( 'div' ).addClass( 'selected' );
  369.     } );
  370.    
  371.     tr.find( 'td.index :input' ).off( 'focus' );  
  372.     if ( opts.index === true ) {
  373.       tbl.find( '>tbody>tr:not(.details)' ).prepend( $(  
  374.         '<td class="index"><div><input type="text" readonly="readonly"/></div></td>'
  375.       ) );
  376.     }
  377.  
  378.     thead.find( '>tr>th' ).each( function( idx ) {
  379.       var th = $( this );
  380.       var width = th.width();
  381.       self.set_column_width( idx, width );
  382.     });
  383.     if ( opts.index ) this.index();
  384.     if ( opts.colorize ) this.colorize();
  385.    
  386.     if ( opts.context_menu ) {
  387.       if ( typeof opts.context_menu === "boolean") {
  388.         opts.context_menu = [
  389.           { label: 'View Form', command: this.show_form },
  390.           { label: '' },
  391.           { label: 'Cut', command: this.input_cut },
  392.           { label: 'Copy', command: this.input_copy },
  393.           { label: 'Paste', command: this.input_paste },
  394.           { label: 'Undo' },
  395.           { label: '' },
  396.           { label: 'Select Cell', command: this.select_cell },
  397.           { label: '' },
  398.           { label: 'Copy Row', command: this.copy_row },
  399.           { label: 'Paste Row', command: this.paste_row },
  400.           { label: 'Insert Row', command: this.new_row },
  401.           { label: 'Delete Row', command: this.delete_row }
  402.         ];
  403.       }
  404.      
  405.       this.menu = new MenuMagic( 'mm1', this.elm.find( '>tbody' ) );
  406.       this.menu.add_items( opts.context_menu );
  407.     }
  408.    
  409.     $( 'body>.cover' ).hide();  
  410.   }
  411.    
  412.   size_column( e ) {
  413.     function reset()  {
  414.       wrap.off( 'mousemove' );
  415.       thead.find( '*' ).css( 'cursor', '' );
  416.       tbody.find( '*' ).css( 'cursor', '' );
  417.       tbody.find( '>tr>td>div.selected :input' ).focus();
  418.     }
  419.  
  420.     function set_size( e ) {
  421.       wrap.off( 'mousemove' );
  422.       deltaX = e.pageX - curX;
  423.       curX = e.pageX;
  424.       width = Math.round( button.width() ) + deltaX;
  425.  
  426.       button.width( width );
  427.       rows.each( function() {
  428.         $(this).find( 'td:nth-child(' + ( th.index() + 1 ) + ')' ) .
  429.         find( ':input' ).width( width + sash_width );
  430.       });  
  431.       wrap.on( 'mousemove', set_size );
  432.     }
  433.    
  434.     var button = e.data.elm;
  435.     var th = button.closest('th');
  436.     if ( ! th.length ) return;
  437.    
  438.     var tbl = this.elm;
  439.     var width = 0;
  440.     var deltaX = 0;
  441.     var curX = e.pageX;
  442.     var thead = tbl.find( '>thead' );
  443.     var tbody = tbl.find( '>tbody' );
  444.     var rows = tbody.find( '>tr:not(.details)' );
  445.     var wrap = tbl.closest( '.wrap' );
  446.  
  447.     wrap.
  448.     on( 'mouseup', function() { reset(); }).
  449.     on( 'mouseleave', function() { reset(); }).
  450.     on( 'mousemove', function() {
  451.       thead.find( '*' ).css( 'cursor', 'col-resize' );
  452.       tbody.find( '*' ).css( 'cursor', 'col-resize' );
  453.       set_size( e );
  454.     });
  455.  
  456.     return tbl;
  457.   };
  458.    
  459.   column_sizing() {
  460.     var self = this;
  461.    
  462.     document.active_table.find('>thead>tr>th button').
  463.     on('mousedown', { elm: false }, function( e ) {
  464.       e.data.elm = $( this );
  465.       self.size_column( e );
  466.     } );
  467.   };
  468.  
  469.   largest_cell( idx ) {
  470.     var tbl = this.elm;
  471.     var opts = this.opts;
  472.     var tbody = tbl.find('>tbody');
  473.     var span = $( 'body>.measure' );
  474.     var rows = tbody.find('>tr:not(.details)');
  475.  
  476.     if ( ! idx && opts.index ) {
  477.       span.text( rows.length );
  478.       return Math.round( span.width() );
  479.     }
  480.  
  481.     var width = 0;
  482.     var largest = 0;
  483.     rows.each( function() {
  484.       var elm = $(this).find( '>td' ).eq( idx ).find( ':input' );
  485.       switch ( elm.prop('tagName') ) {
  486.         case 'SELECT':          
  487.           span.text(
  488.           elm.find( 'option[value="' + elm.val() + '"]' ).text().trim() );
  489.           width = Math.round( span.width() - sash_width );
  490.           break;
  491.         case 'INPUT':
  492.           span.text( elm.val().trim() );
  493.           width = Math.round( span.width() - sash_width );
  494.           break;
  495.       }
  496.       largest = width > largest ? width : largest;
  497.     });
  498.     return largest;
  499.   };
  500.    
  501.   set_column_width( idx, width = 0 ) {    
  502.     var tbl = this.elm;
  503.     var thead = tbl.find('>thead');
  504.    
  505.     if ( ! width ) width = this.largest_cell( idx ) + 1;
  506.  
  507.     tbl.find('>tbody>tr:not(.details)').each( function() {
  508.       $( this ).find( '>td' ).eq( idx ).
  509.       find(':input').width( width + sash_width );
  510.  
  511.       thead.find('>tr>th').eq( idx ).find('button').width( width );
  512.     });
  513.   };
  514.  
  515.   set_column_widths() {  
  516.     var self = this;
  517.     this.elm.find('>thead>tr>th').each( function( idx ) {
  518.       self.set_column_width( idx );
  519.     } );
  520.   };
  521.    
  522.   add_menu( id, opts = 0 ) {
  523.     this.menu = new Menu( id, opts.parent ? opts.parent : this.elm );
  524.     var menu = this.menu;
  525.    
  526.     if ( opts.class )
  527.       menu.elm.addClass( opts.class );
  528.    
  529.     menu.add_items( opts.items );
  530.    
  531.     return menu;
  532.  
  533.   };
  534.  
  535.   show_form( e ) {
  536.   }
  537.    
  538.   get_selected() {
  539.     return this.elm.find('>tbody>tr>td>div.selected :input');
  540.   };
  541.    
  542.   get_selection() {
  543.     var input = this.elm.find('>tbody>tr>td>div.selected :input');
  544.  
  545.     var text = input.val().substr(
  546.       input[0].selectionStart, input[0].selectionEnd - input[0].selectionStart);
  547.  
  548.     return text;
  549.   };
  550.  
  551.   remove_selected() {
  552.     $( 'table.magic .selected' ).removeClass( 'selected row' );
  553.   };
  554.    
  555.   input_cut() {
  556.     var tbl = self.parent.closest( 'table' );
  557.     var text = tbl[0].obj.get_selection();
  558.    
  559.     document.copy_buffer = text;
  560.     document.execCommand( "cut" );
  561.   };
  562.    
  563.   input_copy( e ) {
  564.    document.execCommand( "copy" );
  565.     var tbl = self.parent.closest( 'table' );
  566.     var elm = e.data.elm;
  567.     var text = tbl[0].obj.get_selection();
  568.     if ( text === '' ) return;
  569.  
  570.     elm.focus();
  571.     document.copy_buffer = text;
  572.   };
  573.    
  574.   input_paste( e ) {
  575.     var elm = e.data.elm;
  576.     var text = document.copy_buffer;
  577.     var start = elm[0].selectionStart;
  578.    
  579.     elm[0].value = elm.val().splice(elm[0].selectionStart, 0, text);
  580.     elm.focus();
  581.     elm[0].setSelectionRange( start + text.length, start + text.length );
  582.     document.execCommand( "paste" );
  583.   };
  584.      
  585.   select_cell( e ) {
  586.     var elm = e.data.elm;
  587.     elm.select();
  588. //    elm.closest('div').addClass( 'selected' );
  589.   };
  590.  
  591.   new_row( e ) {
  592.     var tbl = document.active_table;
  593.     var tm = tbl[0].obj;
  594.     var tr = tm.get_selected().closest( 'tr' );
  595.     var args = tm.data;
  596.     var index = tm.opts.index;
  597.     tm.remove_selected();
  598.    
  599.     var tbody = tbl.find('tbody');
  600.     var new_id = tbody.find( 'tr:not(details).new' ).length;
  601.     var html = '<tr data-id="' + new_id + '~" class="new">';
  602.    
  603.     if ( index ) {
  604.       html += '<td class="index"><div><input type="text" readonly="readonly"/></div></td>';
  605.     }
  606.    
  607.     args.keys.forEach( function( key ) {
  608.       if ( key in args.children ) {
  609.         switch ( args.children[ key ].type ) {
  610.           case 'option':
  611.             html += '<td><div><select>';
  612.             var nodes = args.children[ key ].children;
  613.             for( var idx in nodes ) {
  614.               html += '<option value="' + idx + '">' + nodes[ idx ] + '</option>';
  615.             };
  616.             html += '</select></div></td>';
  617.           break;
  618.         }
  619.       } else {
  620.         html += '<td><div><input type="text" /></div></td>';
  621.       }
  622.     } );
  623.     html += '</tr>';
  624.    
  625.     var row = $( html );
  626.     if ( ! e ) {
  627.       tbody.prepend( row );
  628.     } else {
  629.       tbl.find( 'tr' ).eq( tr.index() + 1 ).after( row );
  630.     }
  631.    
  632.     row.find( ':input' ).on( 'focus', function() {
  633.       tm.remove_selected();
  634.       $( this ).closest( 'div' ).addClass( 'selected' );
  635.     } );
  636.     row.find( 'td.index :input' ).off( 'focus' );  
  637.    
  638.     var idx = tm.opts.index ? 1 : 0;
  639.     row.find('td').eq( idx ).find( 'div' ).addClass( 'selected' );
  640.     tbl.find('>thead>tr>th' ).each( function( idx ) {
  641.       tm.set_column_width( idx, $( this ).width() - 7.5 );
  642.     });
  643.    
  644.     tm.index();
  645.     tm.colorize();
  646.   };
  647.      
  648.   copy_row( e ) {
  649.     var elm = e.data.elm;
  650.     var tr = elm.closest( 'tr' );
  651.     tr.find( '>td div' ).addClass( 'selected row' );
  652.     tr.addClass( 'selected' );
  653.     document.copied_row = tr;
  654.   }
  655.      
  656.   paste_row( e ) {
  657.     var tr = document.copied_row;
  658.   }
  659.    
  660.   delete_row( e ) {
  661.     var tbl = document.active_table;
  662.     var tm = tbl[0].obj;
  663.     var tbody = tbl.find( 'tbody' );
  664.    
  665.     var tr = tm.get_selected().closest( 'tr' );
  666.     var widths = [];
  667.     tbl.find('>thead>tr>th' ).each( function() {
  668.       widths.push( $( this ).width() );
  669.     });
  670.    
  671.     if ( tr.next().hasClass( 'details' ) ) {
  672.       tr.next().find('.wrap').slideUp( fadetime, function() {
  673.         tr.next().remove();
  674.         tr.remove();
  675.         tm.index();
  676.         tm.colorize();
  677.       });
  678.     } else {
  679.       tr.remove();
  680.       tm.index();
  681.       tm.colorize();
  682.     }
  683.     if ( ! tbody.find('tr').length ) {
  684.       tm.new_row();
  685.       widths.forEach( function( width, idx ) {
  686.         tm.set_column_width( idx, width - 7.5 );
  687.       });
  688.     }
  689.   };
  690.    
  691. }
  692.  
  693. (function( $ ) {
  694.   var cnt = 0;
  695.   var methods = {
  696.     init: function( opts = 0 ) {
  697.       var tbl = $( this );
  698.       if ( tbl.prop('tagName') !== 'TABLE' ) return false;
  699.      
  700.       var obj = new TableMagic( tbl, opts, mockup_data );
  701.      
  702.       if ( opts.index ) obj.index();
  703.       if ( opts.colorize ) obj.colorize();
  704.       if ( opts.sortable ) obj.sortable();
  705.       if ( opts.column_sizing ) obj.column_sizing();
  706.       if ( opts.context_menu )
  707.         obj.context_menu( 'menu' + ( ++cnt ), opts.context_menu );
  708.     }
  709.   };
  710.  
  711.   $.fn.table_magic = function( method ) {
  712.     if ( methods[method] ) {
  713.       return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
  714.     } else if ( typeof method === 'object' || ! method ) {
  715.       return methods.init.apply( this, arguments );
  716.     } else {
  717.       $.error( 'Method ' +  method + ' does not exist on jQuery.menu' );
  718.     }  
  719.   };
  720. }) ( jQuery );
  721.  
  722. //  -------------------------------------------------------
  723.  
  724.  
  725. jQuery(document).ready( function( $ ) {
  726.  
  727.   function set_top() {
  728.     var offset = Math.round( $( '#wpadminbar' ).height() );
  729.     $('#branding, #nav-primary').css( 'top', offset + 'px' );
  730.     offset += Math.round( $('#branding').height() );
  731.     $('#primary').css('top', offset + 'px' );
  732.     return true;
  733.   }
  734.  
  735.   function test() {
  736.     alert(876)
  737.   }
  738.  
  739.   wpadminbar = $( '#wpadminbar' ).length ? set_top() : false;
  740.  
  741.   var items = [
  742.     { label: 'View Form', command: test },
  743.     { label: '' },
  744.     { label: 'Cut', command: false },
  745. //    { label: 'Copy', command: false },
  746. //    { label: 'Paste', command: false },
  747.     { label: 'Undo' },
  748.     { label: '' },
  749.     { label: 'Select Cell', command: false },
  750.     { label: '' },
  751.     { label: 'Insert Row', command: false },
  752.     { label: 'Delete Row', command: false }
  753.   ];  
  754.  
  755.   tm1 = new TableMagic( $( 'table#test1' ), {
  756.     index: true,
  757.     colorize: true,
  758.     sortable: true,
  759.     context_menu: true,
  760.     column_sizing: true,
  761.   }, mockup_data  );  
  762.  
  763.   tm2 = new TableMagic( $( 'table#test2' ), {
  764.     index: true,
  765.     colorize: true,
  766.     sortable: true,
  767.     context_menu: true,
  768.     column_sizing: true
  769.   }, mockup_data  );
  770.  
  771. });  
RAW Paste Data