Jump to content
  • Checkout
  • Login
  • Get in touch

osCommerce

The e-commerce.

Dr. Rolex

Pioneers
  • Posts

    321
  • Joined

  • Last visited

  • Days Won

    8

Dr. Rolex last won the day on July 30 2014

Dr. Rolex had the most liked content!

1 Follower

Profile Information

  • Real Name
    Jonas
  • Gender
    Male

Recent Profile Visitors

10,753 profile views

Dr. Rolex's Achievements

  1. Sorry but I had to disappear for a couple of months. :ph34r: I noticed a bunch of bugs when I upgraded my own store but didn't have the time to fix them for the Add-On. Will take a look at them and give some solutions when possible.
  2. No, me neither, my memory is not reliable and I'm too lazy to check (even if I would the forum layout doesn't exactly makes it easy...). I have an old PM however that mentions problems with printing envelopes. Are you using the old revision of the Add-On and if so, does it work?
  3. @@Tsimi If you have the time and willingness, I would love to here if the latest update to this Add-On solved the problems you were having. I don't remember what they were exactly, perhaps you resolved them yourself?
  4. I've played around with the new Clipboard API and made a new function that copies the content from all table columns to clipboard so that the data can easily be pasted into e.g. a spreadsheet or document. To add this feature, find this in 01_03_order_handler_rev3_module.js (Tested on Rev4, will probably work on Rev3 as well...) // iconCSS: 'fa fa-copyright', iconCSS: '', cssClass: 'copyrightModal', click: function() { $( "#copyright-modal-button" ).click(); }, }, { Replace With // iconCSS: 'fa fa-copyright', iconCSS: '', cssClass: 'copyrightModal', click: function() { $( "#copyright-modal-button" ).click(); }, }, { text: 'Copy Table', iconCSS: 'fa fa-copy', click: function() { // Copy jTable var tdIndex, copyDiv = $( "#jTable" ).clone(); // Find & Remove all columns with an empty heading var emptyColumns = []; copyDiv.find( ">thead th" ).each( function( tdIndex ) { if ( "" === $( this ).text() ) emptyColumns.push(tdIndex+1); }); // Reverese so that we can start from last empty column emptyColumns.reverse(); emptyColumns.forEach(function( tdIndex ) { copyDiv.find( "th:nth-child(" + tdIndex + "), td:nth-child(" + tdIndex + ")" ).remove(); }); // Show all hidden columns copyDiv.find( ":css(display=none)" ).show(); // Replace <select> with it's selected value // copyDiv.find( "select" ).each(function( index ) { // $( this ).closest( "td" ) // .html( $( this ).find( "option:selected" ).text() ); // }); // Nah.. Remove them instead since we have otherwise get duplicates copyDiv.find( "select" ).each( function() { tdIndex = $( this ).closest( "td" ).index() + 1; copyDiv.find( "th:nth-child(" + tdIndex + "), td:nth-child(" + tdIndex + ")" ).remove(); }); // Remove all inner elements copyDiv.find( "td" ).each( function() { $( this ).html( $( this ).text() ); }); // Remove all Columns with nothing in them var columns = {}; copyDiv.find( "tbody td" ).each(function() { tdIndex = $( this ).index() + 1; if ( undefined === columns[ tdIndex ] ) columns[ tdIndex ] = 0; if ( "" !== $( this ).text() ) columns[ tdIndex ] += 1; }); for ( tdIndex in columns ) { if ( 0 === columns[ tdIndex ] ) copyDiv.find( "th:nth-child(" + tdIndex + "), td:nth-child(" + tdIndex + ")" ).remove(); } // In order to copy to clipboard element must be visible in DOM $( "body" ).append( copyDiv ); selectText( copyDiv[0] ); // Copy Address and output success/error to console try { var successful = document.execCommand('copy'); log(successful); var msg = successful ? 'successful' : 'unsuccessful'; console.log('Copying text command was ' + msg); } catch (err) { console.log('Oops, unable to copy'); } // Remove Selection deSelectText(); // Remove copied element when done copyDiv.remove(); // Send Gritter Notification oHandler.gritter( "Table Copied to Clipboard", "", "fa-clipboard" ); }, }, { Find this range = doc.createRange(); range.selectNodeContents(text); selection.removeAllRanges(); selection.addRange(range); } }, Replace With range = doc.createRange(); range.selectNodeContents(text); selection.removeAllRanges(); selection.addRange(range); } }, /* DeSelect All Selections *************************************************************************/ deSelectText = function() { var range, selection, doc = document; if (doc.body.createTextRange) { //ms range = doc.body.createTextRange(); range.select(); } else if (window.getSelection) { //all others selection = window.getSelection(); range = doc.createRange(); selection.removeAllRanges(); selection.addRange(range); } }, Usage Click on the 'Copy Table' jTable Toolbar button (under the Order Handler Rev4 heading and to the left of the 'Configuration' button) and then paste to a spreadsheet or document. --- I also made a new context menu selection that copies the data from only the selected column, e.g. copying from the 'Order #' column will yield a list with one order number per row. To add this feature, find this in 01_03_order_handler_rev3_module.js (Tested on Rev4, will probably work on Rev3 as well...) items.delete = { cssIcon: "", icon: "delete", name: "Delete", } items.make_ellipsis = { name: "Show this Column as Ellipsis", cssIcon: "fa-ellipsis-h" }; Replace With items.delete = { cssIcon: "", icon: "delete", name: "Delete", } items.make_ellipsis = { name: "Show this Column as Ellipsis", cssIcon: "fa-ellipsis-h" }; items.copy_column_values = { name: "Copy all values from this column", cssIcon: "fa-clipboard" }; Find This } return true; } if ( "delete" === action ) action = "jtable-delete-command-button"; Replace With } return true; } if ( "delete" === action ) action = "jtable-delete-command-button"; if ( "copy_column_values" === action ) { var tdIndex = ( options.items[key].tdIndex + 1 ); var columns = $( "#jTable" ).find( "td:nth-child(" + tdIndex + ")" ); // Put column values to a div var copyDiv = $('<div />'); columns.each(function( index ) { copyDiv.append( $( this ).text() + "<br />\n" ); }); // In order to copy to clipboard element must be visible in DOM $( "body" ).append( copyDiv ); // Select newly created element with formatted address selectText( copyDiv[0] ); // Copy Address and output success/error to console try { var successful = document.execCommand('copy'); log(successful); var msg = successful ? 'successful' : 'unsuccessful'; console.log('Copying text command was ' + msg); } catch (err) { console.log('Oops, unable to copy'); } // Remove copied element when done copyDiv.remove(); // Send Gritter Notification oHandler.gritter( "Column '" + $( "#jTable" ).find( ">thead th:nth-child(" + tdIndex + ")" ).text() + "' Copied", "", "fa-clipboard" ); return true; } Find This in 02_02_jquery.contextMenu.js if ( undefined !== e.data.items.make_ellipsis ) { if ( -1 === e.target.className.indexOf( "comments" ) ) { var tdIndex = $( e.target ).closest( "td" ).index(); var tdName = $( "#jTable" ).find( "thead" ).eq(0).find( "th" ).eq( tdIndex ).text(); e.data.items.make_ellipsis.tdIndex = tdIndex; if ( true === $( e.target ).closest( "td" ).hasClass( "ellipsis" ) ) { e.data.items.make_ellipsis.name = "Remove Ellipsis for column '" + tdName + "'"; e.data.items.make_ellipsis.action = "remove"; } else { e.data.items.make_ellipsis.name = "Show Column '" + tdName + "' as Ellipsis"; e.data.items.make_ellipsis.action = "make"; } } else { e.data.items.make_ellipsis.disabled = true; } } var showMenu = false; Replace With var tdIndex = $( e.target ).closest( "td" ).index(); var tdName = $( "#jTable" ).find( "thead" ).eq(0).find( "th" ).eq( tdIndex ).text(); if ( undefined !== e.data.items.make_ellipsis ) { if ( -1 === e.target.className.indexOf( "comments" ) ) { e.data.items.make_ellipsis.tdIndex = tdIndex; if ( true === $( e.target ).closest( "td" ).hasClass( "ellipsis" ) ) { e.data.items.make_ellipsis.name = "Remove Ellipsis for column '" + tdName + "'"; e.data.items.make_ellipsis.action = "remove"; } else { e.data.items.make_ellipsis.name = "Show Column '" + tdName + "' as Ellipsis"; e.data.items.make_ellipsis.action = "make"; } } else { e.data.items.make_ellipsis.disabled = true; } } if ( undefined !== e.data.items.copy_column_values ) { e.data.items.copy_column_values.tdIndex = tdIndex; e.data.items.copy_column_values.name = "Copy all values from column '" + tdName + "'"; } var showMenu = false; Find This var i = 7; if ( true === opt.items.make_ellipsis.disabled ) Replace With var i = 8; opt.$menu.find( "li" ).eq(0).find( "span" ).text( opt.items.copy_column_values.name ); if ( true === opt.items.make_ellipsis.disabled ) Usage Make sure that the Right-Click Menu is activated (green button on top left navbar) => right click on any column and select 'Copy all values from column [name]' => Paste in text editor, spreadsheet or wherever you want the data.
  5. Glad you like and that you find use for it! It would be a real bummer if I put down all those hours on it and nobody used it, so I appreciate the response! :P
  6. jQuery/Ajax Advanced Order Handler Rev4 Download Add-On here: http://addons.oscommerce.com/info/9055 Since the package was so big and the maximum file upload is only 3 MB I had to make a multipart RAR archive and then zip each of the split RAR files to get files with .zip as file extension since that's the only one that osC allow to upload. So.. Download all 8 files, unzip them and you should get 8 new RAR files, jQuery Advanced Order Handler 2.3 Rev4.part01.rar ... jQuery Advanced Order Handler 2.3 Rev4.part08.rar. Unrar jQuery Advanced Order Handler 2.3 Rev4.part01.rar and you will get a directory called jQuery Advanced Order Handler 2.3 Rev4 which has all the installation files, screenshots etc.. Screenshots
  7. Hello Larry, I do remember something about that issue with DataTables warning: table id={id} - Requested unknown parameter '{parameter}' for row{row-index} I think it occurs when there is an unequal number of table columns vs. fields in the JSON response. Check the network tab in your browser developer tools and look for how many fields each row in the JSON response have, then check your table for how many columns it have or run this in your console $( "#dataTable" ).find( ">thead th" ).length They should match, if they doesn't match try with adding/removing one table column to see if that helps. Right now I'm working on my order handler Add-On, when I'm done with that one I'll see if I can give you some more help with this.
  8. I don't use the Discount Coupons Add-On myself so I don't know. But I would guess that no, you probably need to add comparability for them to work together. You can, of course, change price and add your own order total fields to the order but if the Coupon Add-On works by manually inserting something like a code then there's nowhere to do that so that's something that you have to add. This shouldn't be to much of a hassle, look on the original instructions for the Discount Add-On and find the same places to modify this Add-On.
  9. All right, for the past months I've been doing lots of updates and created many new features for this Add-On which I needed for my own shop and now I guess I might have some time to also make a new revision of this Add-On. I've worked on a lot of things but the main reason for me to update the order handler was because I needed it to work with a really wacko tax law on shipping costs that the regime has inflicted upon us [citizens]. The only sane way of doing this was to remake the function that updates order totals to do the same steps as a 'regular' checkout process would if a customer placed the order 'manually'. So long story short

 the order handler now make a (more or less) regular checkout routine on any update to an order that changes order totals. This should fix problems for anyone who get wrong calculations in the updating process and should make it compatible with all shipping & payment modules. There's (of course) much more, here's a selection of new features 'Hold Search' - New button which can be used if you want more than one filter to your search, e.g. searching for orders from customers named Adam that also has order status Pending. AmCharts and AmMaps are now both annotatable and can be exported to PNG, JPG, SVG and PDF. AmMap - Animated Javascript Maps with Geographical data from your orders where you can both check orders for individual postal codes/delivery cities or get the data as a heat map with stronger color for regions with more sales Autoresize - <textarea> will automatically grow/shrink when you write. Autosize.js - Comment field <textarea> will now automatically resize when you write Back/Forward buttons in browser will now take you to prev/next order filter/search term Barcode generation on invoices - Order number will be present as a scannable barcode. Comment field can now optionally be displayed in a collapsed jQuery Accordion to save space. Comments field - automatic positioning of cursor. Default comments with automatic positioning of cursor. Default template for textarea which adds 'Hello [Customers_name]' and Signature block Fixed Firefox CSS bug that prevents table cell borders to be displayed Improved Bootstrap style/look for order details jQuery-UI Theme (optional) Locale Support for 29 languages (jTable & AmCharts Translations) Many new ways to filter orders, e.g. search multiple order numbers, orders with specific product, specific customers_id More table fields New 'Advanced Statistics' - AmCharts generated Yearly/Monthly/Daily graphs withAverage Order Total per Order Average Orders per Customer Average Purchased Products per Order Customers Average Age Customers with 0 orders New Male/Female Customers Total New Customers New look for the Right Click Context Menu New Optional Compact Layout New Row/Order Tools - Get a modal with a list of all purchased products from customer New Row/Order Tools - Link to customers page of customer New Row/Order Tools - List all orders from selected customer New Row/Order Tools - Quick comments - Quickly get a tooltip with all order comments New Search Option - Configurable Min/Max Order Totals New Table Field - Customers Age and Date of Birth as Tooltip New Table Field - Number (%) of Returned Orders (or other order status) New Table Field - Number of Orders from Customer Order Management - Make Table Rows Sortable Order Management - Minimize Navbar Size Order Management - Unlock Top/Bottom Navbar Buttons for repositioning Pick list Generated on batch printing invoices Quick change Payment/Shipping Methods Quick Select Order Status from table Quick Select Payment Method from table Quick Select Shipping Method from table Quotable comments - Click the quote symbol next to the comment to automatically add it as a quote. Quotable comments - Right click on order comments to copy them as 'Quoted' Right Click Menu - Make ellipsis off columns with long text Right click on address field and automatically copy formatted to clipboard Only works in recently updated browsers Saved User Data - List and Delete Cookies and data saved in localStorage Search History - Previous searches will be saved to memory and accessible from a modal Smoother Animation when expanding Order Sortable Table Columns - both horizontally and vertically. Stock Update - Stock quantity will properly be updated on any modification to the order. Two new Add new Customer options - when creating new order - order fields from your create_account.php will automatically be fetched and incorporated to the form. Warning Filtration System - Highlight rows that satisfy filter rule, e.g. Customers Birthday within ± n days When changing shipping and/or payment method the order totals will be recalculated accordingly, just like it would be a new order made on catalog side. So, there you have it. I'll upload the new revision as soon as I have updated instructions etc..
  10. I'm sorry Lecarl, but I think that it's time for you to pay someone to look into this problem for you. I mean, I don't think there is anything wrong with the code and nobody else is getting the same or similar error that you're getting. It shouldn't be more than an hour for an experienced programmer to fix whatever weird problem you managed to entangle yourself in. And to be honest, if it was my shop that produced this kind of problem, I would make sure to get to the bottom of it ASAP so it doesn't produce any mysterious errors in the future. I had a minor bug that f*cked up my order totals a couple of years ago and it was a pain to correct retrospectively. Though, I think the American IRS are more friendly than my tax office, so perhaps it's nothing to worry about ...
  11. osC OpenSSL Encryption with jCryption - Support thread - Without a SSL certificate the data posted on your shop might be visible to third parties, e.g. your admin username and password. With this Add-On all form data will be encrypted using OpenSSL before it's posted to the server and then decrypted on your server, greatly enhancing the security for you and your customers. How does this work client requests RSA public key from server client encrypts a randomly generated key with the RSA public key server decrypts key with the RSA private key and stores it in the session server encrypts the decrypted key with AES and sends it back to the client client decrypts it with AES, if the key matches the client is in sync with the server and is ready to go everything else is encrypted using AES Source: http://www.jcryption.org/#howitworks Features for this Revision: Support for and tested on osCommerce 2.3.4 Should work for most osCommerce versions with minimum modification. Tested successfully on Google Chrome, Firefox and IE Encrypts all Form Data with OpenSSL Works on both catalog and admin side of shop Uses jCryption library. Screenshots included in package. Download Add-On here: http://addons.oscommerce.com/info/9333
  12. Did you check the Network tab like I suggested? You can, temporary for testing, find this code in ajaxManager.js $.fn.cartRemoveAction = function(productID) { $('input[value="' + productID + '"][name=\"cart_delete[]\"]').attr('checked', true) ; // If this is the last product in cart then refresh the entire page // var productsInCart = parseInt( $("#content-body input[name=products_in_cart]").val() ) ; var action = parseInt($('input[id="pl' + productID + '"]').val()); action = -1 * action; $.ajax({ type: 'POST', url: encodeURI($('form[name=cart_quantity]').attr('action')) + '&show_total=1', data: $('form[name=cart_quantity]').serialize(), async: false, success: function(data) { ajaxRefreshProducts(); ajaxPerformShippingRefresh(); }, complete: function() { if ( productsInCart + action <= 0 ) { $('form[name=cart_quantity]').submit(); } return($(this).update_cart(action)); } }); return(false); } Replace with $.fn.cartRemoveAction = function(productID) { $('input[value="' + productID + '"][name=\"cart_delete[]\"]').attr('checked', true) ; // If this is the last product in cart then refresh the entire page // var productsInCart = parseInt( $("#content-body input[name=products_in_cart]").val() ) ; var action = parseInt($('input[id="pl' + productID + '"]').val()); action = -1 * action; $.ajax({ type: 'POST', url: encodeURI($('form[name=cart_quantity]').attr('action')) + '&show_total=1', data: $('form[name=cart_quantity]').serialize(), async: false, success: function(data) { alert( 'URL:\n' + decodeURIComponent(this.url) + "\n\n" + 'Request Payload:\n' + decodeURIComponent(this.data) ); ajaxRefreshProducts(); ajaxPerformShippingRefresh(); }, complete: function() { if ( productsInCart + action <= 0 ) { $('form[name=cart_quantity]').submit(); } return($(this).update_cart(action)); } }); return(false); } Now, try deleting a product again. You should get a new prompt with info like this: URL: https://[your_server]/ajax_checkout.php?action=update_product&show_total=1 Request Payload: products_in_cart=1&cart_delete[]=28&cart_quantity[]=1&products_id[]=28 You'll find the delete product code in ./includes/application_top.php As you see in the request URL above, the $_GET (same as $HTTP_GET_VARS) parameter update_product is set. The code below is what removes the product from the cart: switch ($HTTP_GET_VARS['action']) { // customer wants to update the product quantity in their shopping cart case 'update_product' : for ($i=0, $n=sizeof($HTTP_POST_VARS['products_id']); $i<$n; $i++) { if (in_array($HTTP_POST_VARS['products_id'][$i], (is_array($HTTP_POST_VARS['cart_delete']) ? $HTTP_POST_VARS['cart_delete'] : array()))) { $cart->remove($HTTP_POST_VARS['products_id'][$i]); } else { $attributes = ($HTTP_POST_VARS['id'][$HTTP_POST_VARS['products_id'][$i]]) ? $HTTP_POST_VARS['id'][$HTTP_POST_VARS['products_id'][$i]] : ''; $cart->add_cart($HTTP_POST_VARS['products_id'][$i], $HTTP_POST_VARS['cart_quantity'][$i], $attributes, false); } } tep_redirect(tep_href_link($goto, tep_get_all_get_params($parameters))); break; Perhaps you have made some modification to application_top.php or includs/classes/shopping_cart.php? Also make sure that it's not just a cosmetic issue, after you have tried to remove a product, reload the page to see if the shopping cart still has the product or if it has been removed.
  13. You could start with replacing all these instances in ajax_update.php include DIR_WS_CLASSES . 'order.php'; require DIR_FS_DOCUMENT_ROOT . DIR_WS_CLASSES . 'order.php'; require DIR_WS_CLASSES . 'shipping.php'; require DIR_WS_CLASSES . 'order_total.php'; To these include_once DIR_WS_CLASSES . 'order.php'; require_once DIR_FS_DOCUMENT_ROOT . DIR_WS_CLASSES . 'order.php'; require_once DIR_WS_CLASSES . 'shipping.php'; require_once DIR_WS_CLASSES . 'order_total.php'; You can do the same thing if you find more instance of include and require. Change them to include_once and require_once
  14. Did you solve this, Ed or are you still having the same problem deleting products? I did not manage to reproduce this error. Check your console for error messages. You can try with replacing this code $('body').on('click', '.cart-delete', function(){ products_id = $(this).attr('rel') ; return($(this).cartRemoveAction(products_id)); return false; }); With this $('body').on('click', '.cart-delete', function(){ products_id = $(this).attr('rel') ; alert(products_id); return($(this).cartRemoveAction(products_id)); return false; }); Then try to delete a product, you should get a javascript prompt with the products_id. Also check the 'Network' tab in Chrome's Console, there should be 6 requests where the first one should be to shopping_cart.php?show_total=1
  15. Hello Ed, You can add this code to make it possible to change products quantity by manually entering a new number in the input field. In ajaxManager.js find this code: $('body').on('click', '.cart-delete', function(){ products_id = $(this).attr('rel') ; return($(this).cartRemoveAction(products_id)); return false; }); Add the following code below that code: $( "body" ).on( "focus", ".cart-qty input", function( event ) { // Save Old Input value to Data object. $( this ).data('oldVal', $( this ).val() ); }).on( "change", ".cart-qty input", function( event ) { // Get the value when input is changed var oldValue = $( this ).data( 'oldVal' ); var newValue = $( this ).val(); // Calculate difference between old and new value var action = newValue - oldValue; $.ajax({ type: "POST", url: encodeURI($('form[name=cart_quantity]').attr('action')) + '&show_total=1', data: $('form[name=cart_quantity]').serialize(), }).done(function( data ) { // Refresh Products, Totals & Shipping ajaxRefreshProducts(); ajaxPerformShippingRefresh(); // Refresh Shopping Cart $(this).update_cart( action ); var productsInCart = parseInt( $("#content-body input[name=products_in_cart]").val() ) ; // If Shopping Cart is Empty, Refresh Entire Page // if ( productsInCart <= 0 ) { $('form[name=cart_quantity]').submit(); } }); }); Find this code if ( typeof comments != 'undefined' ) Replace With if ( typeof comments != 'undefined' && $( "#comments" ).length > 0 )
×
×
  • Create New...