Jump to content

Dr. Rolex

  • Content count

  • Joined

  • Last visited

  • Days Won


Everything posted by Dr. Rolex

  1. jQuery/Ajax Mini Cart for osCommerce 2.3.3 - Support thread - Download Add-On here: http://addons.oscommerce.com/info/8908
  2. Hello and Welcome, all osCommerce idiots! No one will tell you to "Read the manual" here, everybody is equal dumb so dumb questions are somewhat advocated. :thumbsup: This is the support thread for jQuery/Ajax Fast checkout 2.3.3 With Login/Create account/Shopping Cart/Bootstrap MATC and more! Everything squeezed together on One Single Page. This contribution / Add-On (which one is it; Contrib or Add-On, I'm confused?) was originally created by advancewebsoft.com/solutions/oscommerce/oscommerce-contributions.html, but has now, under the knife with surgical precision, transformed to work with osCommerce 2.3.3. Advance Software deserve all the credit they can get and make sure to check their website as they offer more free contributions for osCommerce as well as creating custom made, for a cost of course. In my very amateurish opinion, I believe that their cotribs & code are very elaborate and nicely designed. I'm not affiliated with them in any way but I have contacted them about publishing my modified version of their Add-On and they responded: My hope is that, finally, we can get a One page/Single page checkout that works for everybody and the way this Add-On work should be the best way to do it since it uses the modules you already have as well as using the language files for each section (E.g. information found in the create account section uses the defined constants from ./includes/languages/english/create_account.php. This also makes this Add-On automatically Multilingual! :beers: Now, enough with the drabble! Here is the features for this Add-On, starting with the original specs: Full support for ALL OsCommerce shipping modules Standard OsCommerce features like FREE SHIPPING, STOCK CHECK, ALLOW STOCK CHECKOUT are supported Virtual downloadable products are supported Basic Payment modules like Cash on Delivery, Bank Transfer and PayPal are supported Authorize.Net payment module is supported AJAX checkout interface - no more whole page reloading New customers instant registration is available and existing customers will be able to login and checkout Instant shipping and payment modules selection using AJAX Instant delivery and billing address selection and adding a new address is available using AJAX All javascript form validation scripts (creating account, shipping & billing addresses, modules etc) are available Dynamic shopping cart restoration for registered users using AJAX All order total modules from OsCommerce are supported Features added by Dr. Rolex: Support for and tested on osCommerce 2.3.3 Tested successfully on Google Chrome, Firefox, Safari and Internet Explorer 9 Since the original Add-On was made for the old oSc 2.2 I have made several modification to the code so it will work with newer versions of PHP and of course changed the entire layout to fit in the oSc 2.3.3 grid. Compatible with jQuery 2.0.2 Added so shopping cart is included on checkout - now the customer can add/remove products on checkout and interactively see what the shipping cost will be. Customer must accept Conditions and terms of use when both creating an account and before confirming order. Your Conditions and Terms of use will be dropped down with a very nice Bootstrap modal! Added a comment box similar to the regular one on normal checkout. Added a nice modal that grays out screen on confirming order to prevent double orders from any trigger happy customers with ADHD. Automatic capitalization of first letter when updating Customers Details. Shopping Cart Infobox will update when changing product quantities. Header cart counter refresh I might add a "Guest checkout" Feature in the Future, assuming that someone want it. I'll upload the package and include the link later today. Please report all, eventual bugs you may find or improvements that you would like. I will add support for the jQuery/Ajax Shopping Cart 2.3.3 Add-On later when I'm done testing. Best regards, Dr. Rolex
  3. Hello and welcome! jQuery/Ajax Advanced Order Handler for osCommerce 2.3.3 - Support thread - Have you noticed how frustrating order management in osCommerce can be? Especially if you display 100 orders at a time and every single time you need to look at another order you have to reload the entire page thus querying the database for each and every order again and again and again... It can be quite annoying, at least I thought so and it definitely isn't very effective. It's as bad/slow as it gets and we don't like slow, do we?. In addition to this most (if not all) who uses osCommerce have probably run into the problem of not being able to manually create new orders. Doing this natively requires one to actually login to an account and creating the order as if you were a customer. Even more problematic is modifying an existing order, doing this natively requires the admin to either delete & create a new order with correct details or manually editing the database directly. Both of which are, to say the least, very unattractive solutions. Having used a combination of Order Editors / Batch Printing Add-Ons myself I felt it was warranted to create a new Order Management solution that incorporates all of them in an easy to use & effective way. The goal was also to completely get rid of the need to refresh/reload the order page to see new orders. Order Refresh The solution was to use Comet: Comet is a web application model in which a long-held HTTP request allows a web server to push data to a browser, without the browser explicitly requesting it. The Comet Technique used is Ajax with long polling with jQuery.ajax. This is how it works: A GET request is sent to stream.php in which it includes the current last order displayed together with a Timeout in seconds which you can set to any number you want in the order handler Bootstrap Fixed-bottom Navbar. So, if set to e.g. 20, stream.php will every 20 seconds check the order number of the newest order in the database. If the database has a newer order than the one displayed in the order table, then the script will break the loop and return a json response with the order number. This will be parsed by jQuery, which then sends another GET request to order_poller.php asking for the new order/orders, the new rows will be returned which will be added to your displayed order table by jQuery. It will only add new information, NOTmessing up your selections in the order handler. A Growl Notification will be displayed with information from the new order. Ajax Polling will automatically be enabled when the 'Pending' selection is selected from the 'Status' dropdown, but it can also be toggled in the Navbar. Order Handling To be able to display even the long order comments, I have added a feature to display them as Bootstrap Tooltips when hovered over. I have removed the menu selection box and instead used that space to display more information in columns. A feature to sort the orders by how many products are in them have been added. Clicking on a table row will not make any requests to the server but instead use jQuery to move the highlighting. The Navbar I have used a Bootstrap Navbar with a Fixed Bottom position. This means it will always be displayed at the bottom of the screen which helps a lot when seeking through orders or when updating them. I have used the Bootstrap Multiselect Add-On to get the menu items like I wanted and I have also used Font-Awesome to get some nice looking Icons. The Action field The action field is the rightmost column on the orders table, containing the five action icons. Hover mouse over them to see what each action does. Note that there will be no Dialog asking for confirmation on Order Duplication or E-Mail Order Confirmation, pressing any of those icons will instantly proceed with their action. From left to right; the first Icon will Mail a new Order Confirmation E-Mail to the customer (and the shop owner if configured) for that order; the second icon will duplicate the order; the third icon will open a Dialog for Quick Editing the order; the forth icon will open a dialog for creating a new order; the fifth icon will go to the "normal" edit order mode. Export I use Mail Merge in Pages for Mac OS X to create Envelopes. This is very easy and fast. To do this, you first need to create a Envelope template in Pages 4.3 (version 5.0 doesn't support this feature anymore for some reason). Look at what names the data-fields have and then change the code in print_batch_process_2.php around line 56 that looks something like this: echo "Name;Street address;Postcode;City;Country\n"; So it has the same names in the heading as your envelope data-fields. Then simply open the CSV created by selecting 'Envelope' in Numbers and convert the top row to a heading. Save and then open in Pages by selecting 'Mail Merge'. This will automatically create a new envelope for every address which you easily can print. Since I don't use Excel I don't know how this is done with that software, google it, I'm sure it has some similar functionality. There is also an alternative to export to XML, a format commonly used by shipping providers to import addresses to shipping labels. Ask your shipping provider how the XML file should be designed and then make the appropriate modifications to print_batch_process_2.php around line 79 to 106. Order Editing Having a dedicated page for editing orders isn't my first choice as a solution. Instead I found ledave's Add-On, the AJAX Orders Editor. The Order Editor enables you to edit the order directly on the Order page. I really liked this solution, however it still required some editing to get it to work (for me) with taxes etc. I also added the possibility to edit the Telephone and E-Mail fields*.Moreover, I added a feature to select available taxes when adding additional fields (note that the tax is overwritten if a product is added after adding the field) and adding jQuery code to automatically refresh the fields when they have been edited so that you don't have to refresh/reload the page to see the changes. Hopefully, this will work for everyone now without need to modify any code, but no promises.. Order Creation To create new orders I have used the Manual Order Maker Add-On. Used together with the Ajax Orders Editor, new orders can be created in just a couple of seconds, no matter whether it is from a new or an existing customer.I might* have added extra search functionality - search customer by E-Mail Address or Name and also added jQuery autocomplete to suggest customers from typed name. The Order Creator can be reached both from the menu and as a Modal Quick Open by clicking it's icon in the order handler, it will then automatically pre-select the customer that made the order from the same row. I have also added dropdown selections where you can select payment & shipping method for the new order. Order Duplication If you have a customer that want to place the same order as he/she has done before, then simply search for his order and press the Duplicate Order Icon. One click and a new order has been created for this customer with the same products & shipping/payment methods. This makes creating new orders really easy and if you need to change something, then just edit the order. Deleting Orders Just check the checkboxes for the orders you want to delete and then press the red 'Delete' button on the Navbar. You will get a confirmation modal where you can select to optionally restock the products and confirm/cancel the deletion. You can also delete specific order when your at "Editing mode". * I don't want to take credit for stuff I didn't do and I have used these Add-Ons for so long that I can't remember how they originally worked. Features for this Revision: Support for and tested on osCommerce 2.3.3 Tested successfully on Google Chrome and Firefox Compatible with jQuery 2.1.0 Complete Order Creator/Editor/Handler Edit any field on an order by simply clicking on it and change the value - Code used from the 'AJAX Orders Editor' Add-On by ledave. Edited fields will instantly be refreshed when edited or a product has been added/removed (including Order Total, if affected). Quickly Add/Remove products to a order by searching in a javascript window. Edit Name/Price on products. Add/Remove 'Extra' Fields like shipping/payment costs (adding tax is selectable). One-Click-Duplication of any order - E-Mail will be sent as if the order was created by a customer. Order Creator, both as a jQuery Dialog or as a whole page with added Autocomplete support for searching customers - Code used from the 'Manual Order Maker' Add-On Quickly Create New order for existing customer by either searching for customer by Name/E-Mail/Customer Nr. or clicking the quick add icon next to existing order. Quickly Create New order for new customer - Optionally Creating New account jQuery/Ajax Handling of Orders - No need for those costly page reloads every time you select a new order or want to update for new orders. Togglable Comet/Ajax Long-Polling for new orders - When a customer creates a new order, the Order Table will automatically update and add the new order to the list without messing with your selections. Never do a page refresh again! Growl like Notifications with jQuery Gritter http://boedesign.com/blog/2009/07/11/growl-for-jquery-gritter/ Order Comments will be displayable as a Bootstrap Tooltip - No need to open the order just to check what a comment says. Batch Delete of Orders - Simply toggle the checkbox for the orders you would like to Delete and then review & confirm the selections in a nice Bootstrap Modal. - Code used from one of the Batch Print Add-Ons, can't find which one. ;=( Batch Handling of Orders - Batch Print Invoices (one order = one A4) for the selected orders, without need for PDF, in one click. Code used is from 'Batch Printing without Frames or PDF v.2.3.1' Add-On by 0ethos0 (Originally made by PandA.nl) Batch Handling of Orders - Batch Update Order Status / Send E-Mail for selected orders. Batch Handling of Orders - Export CSV to be used for automatically creating Envelopes with Excel/Numbers/Pages. Batch Handling of Orders - Export XML to be used to automatically create Shipping Labels for your shipping provider. Added an 'Order by products quantity' sorting feature to simplify order processing by handling orders with just one product first. Search Orders by E-Mail, Name or Order Number. Simple Tab management - Batch Invoices will open/refresh in same tab, meaning you only need to tabs open to handle both orders and invoices. CSS3 Loading Spinner displayed while orders are updating preventing editing orders while they're being updated. HTML5 pushState with history.js - Enables Ajax support for Back/Forward button in browser. Fixed-Bottom Bootstrap Navbar with Bootstrap Multiselect - Sliding down automatically when editing orders. Quick Send New Order Confirmation E-Mail to customer
  4. This Add-On isn't completet for distribution yet, but I have created a DEMO site which you can look at if you're interested. Please report all bugs/problems or features you would like to have as I plan to continue develop this Add-On far beyond it's release. So What does it do? It upgrades your shop to an Ajax shop where only the boxes/areas of the page that needs updating will update and by this eliminating the otherwise necessary page reload. Two great things come with this; 1: The ugly reload of everything á la 1995 is now history and 2: It makes your page MUCH fast (as you will see in the DEMO) since it doesn't require the queries made for all the boxes. It also include an advanced Caching Engine who primary uses PHP_APC (if you have it, it's rare on shared hosting I think, look it up) or otherwise fall back to the native file caching of oscommerce. PHP_APC is free and very easy to install: http://php.net/manual/en/book.apc.php In the admin section you will be able to select which pages that should be cached (standard is index.php (ignoring front page), product_info.php and product_reviews.php). You can also select the cache expiry time in seconds. Look at these page transition, you can use any of them for the bodyContent <div> (main content page) when browsing including CSS3 3D-cube animations: http://tympanus.net/Development/PageTransitions/ On the demo I have used a CSS Loading Spinner. Don't forget to use the "back/forward" buttons in your browser. All pages will be cached in the browser with jQuery.data, so if the customer have visited the page before, not a single request will be made! There is of course an exclusion setting for some pages. I'm working on making the installation as smooth as possible. You will not need to modify every page. Pages affected will be application_top.php, template_top.php, template_bottom.php, cache.php, general.php and probably some more. I have also upgraded the admin section so that the configuration will be cached like in many other Add-Ons, but now you can see it in the "Cache Control" in Admin and also modify what you want to cache. If you have PHP_APC, then I have included a modified php_apc.php file that uses osCommerce login security and also automatically rebuilds configuration cache on removal. I have added a "Parse time window" using information from KISS, showing some benchmarking info. More functions is on the way! I hope you like it! ;) Enjoy! DEMO: http://jholmster.com
  5. 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.
  6. Advanced Statistics Rev1 for osCommerce 2.3 - Compatible Without mysqlnd - - Support thread - Having made another module for handling products/categories which utilize DataTables, I realized that my store needed a new reporting "engine" to produce statistics/sales data for me so that I don't have to make a new spreadsheet every time I want some statistics. As of Revision 1 there's still a lot to work on but the the module has come to a point of being useful so I thought I share it with the rest of the osC community as an Add-On. If you think you have a good idea on new features/stats that could be useful, please share them here on the support forum. DataTables DataTables requests the sales data from your server with Ajax and then builds you a table with a action bar and selectable rows. You can Drag & Drop Column Headers to reorder the table the way you like it. It’s also possible to toggle column visibility. Clicking on the columns will sort the column ascending/descending. Clicking on the leftmost plus (+) sign will expand the column to detailed day-by-day per month sales & tax data. Performance The former Reporting Add-On I used was very slow, it queried each row in table orders_products and the amount of queries done to calculate sales & tax for a period was massive! Data will be loaded from JSON source which also helps improve Performance, especially on slow connections. Make very sure if you are going to use this Add-On that it calculates your data correctly! You have to both double and triple check the reports with another reporting system so you know for sure that everything works. This is how the Advanced Statistics Add-On calculates your sales data, it’s quite simple: If you have a tax rate set to 20% and the summary for this tax for 1 day is $200 then it will calculate generated sales with 20% tax this way: [Total Tax] / [Tax Rate] * 100 = Sold Goods with 20% Tax 200 / 20 * 100 = 1000. So Sales 20% will be $1000. As of Rev1, order_totals classes that will be counted are ot_total, ot_tax & ot_shipping. TableTools The TableTools Extension comes with a swf (flash) file which helps e.g. to copy table data to clipboard. Unfortunately, flash is the only way to do this right now.. Copying Data and then Pasting it in your spreadsheet editor is a neat way to quickly create custom reports. TableTools also comes with buttons to automatically create CSV files. You might need to configure the CSV field separator in advanced_statistics.js. Search for the sFieldSeperator option and set correct separator if you can’t get the CSV to import correctly. Print View Using a CSS with media="print”, a print view is automatically created when you select to print the page. If you have selected to filter orders by status, then there will be an added heading with Status Information, as of Rev1 however, you need to reload the page to get it to display. I’ll fix this later.. You can also use the TableTools ”Print” Button which essentially makes the same thing. You can also have TableTools create a PDF for you, but it looks like sh*t if you ask me. Check DataTables homepage on how to configure the layout for this PDF, I will not work on this as I don’t need it (will use CMD/CTRL + P instead..). Note also that some of the themes probably needs some CSS styling fixes if you want to print e.g. background colors of header. Make sure to add these to advanced_statistics_print_view.css. Menus & Navigation I always wanted one of those Slide-In menus so I finally got one; jQuery mmenu. It’s still rather empty, but should fill up with more filtering options and other knobs, buttons & of course whistles soon enough. To open it; click on the top left icon on the top navigation, it will randomly pick one out of 37 icons on each load but shouldn’t be hard to find as long as you’re not completely ”challenged” by the world around you… :P There’s a couple of more buttons in the Bootstrap top navigation which will toggle the admin menu and header and also a button to clear all currently applied filters. To the right on the top navigation you’ll have two dropdowns which will switch theme and filter by orders status. Theming jQuery DataTables comes with some options to implement themes, so I fixed support for five different layouts: jTable - Looks a bit like the Advanced Order Handler and uses Bootstrap buttons for the seven leftmost buttons. Original - DataTables as it comes out of the box (more or less) Bootstrap - Like Original but with the DataTables Bootstrap css & js jQuery UI - Will adapt to your jQuery-UI Admin Theme (default is Redmond) jQuery UI Smoothness - Uses Smoothness theme instead of Redmond Screenshots of all Themes can be found at the bottom of the ReadMe file in the package. Theme-creator https://www.datatables.net/manual/styling/theme-creator Internationalization Both amCharts and DataTables comes with many language definitions which is included and should automatically load the same language as the one you have set in your admin (assuming the definition exist). amCharts I plan to make a lot of use of amCharts to get easy to interpret charts from store sales etc.. As of Revision 1, you can get a line, area, column, bar, step line, smoothed line, candlestick and OHLC graph for each of the visible columns and for either the specific rows that you have selected (OS style selection, shift/control/CMD click to select multiple rows) or for the entire table(s). The chart modal is movable (only one move per page load) and also resizable. Click on the Graph Names at the bottom of the modal to hide/show different line graphs. Security & Compatability All querying with parameters/input variables to your database will be made with MySQLi Prepared Statements. Preferably you should use the MySQL Native Driver (mysqlnd), but I have added support and tested the Add-On without mysqlnd and everything should work. Prepared Statements removes the threat of MySQL Injections. Not that it matters that much on the admin side of the shop since only authorized users have access, but you can never be too secure, right? ;) For simple installation I have not messed with more native osC files than necessary and instead included necessary functions in general_functions.php. If you have any of my previous Add-Ons installed then you might run into a problem under certain conditions when the mysqli_prepared_query and tep_db_fetch_all functions will fail. If so, then try with replacing the current database functions that you have in ./admin/includes/functions/database.php with the ones that you find in general_functions.php from this Add-on. Features for Revision 1 Sales/Tax Statistics/Report Generator for osC 2.3.x Only tested on osC 2.3.4 but should work on any version Simple five step Installation - Only three files needs to be modified! Automatically creates HTML table and loads orders from server using AJAX. Export Options: CSV, Copy/Paste, XLS, PDF "Automatic" Print View amCharts Graphs over sales & taxes Very Fast Operation, a shop with 30 000 orders loads in under 2 seconds. jQuery DataTables - https://datatables.net/ Drag & Drop Columns Automatic Column Sorting Toggle Column Visibility Detailed day-to-day sales Slide-In Menu with mmenu - http://mmenu.frebsite.nl/ Fixed Bootstrap Top Navigation Themes jTable Original Bootstrap jQuery UI jQuery UI Smoothness DataTables Internationalization - 63 Language Definitions Included amCharts Internationalization - 29 Language Definitions Included 100% MySQLi Prepared Statements Bootstrap Tooltips Toggleable Visibility of both your store header and Admin menu using CSS3 classes OS style selection, shift/control/CMD click to select multiple rows - Plenty of screenshots in package! -
  7. 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?
  8. @@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?
  9. 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.
  10. 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
  11. 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
  12. 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.
  13. 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.
  14. 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..
  15. 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 ...
  16. 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
  17. 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.
  18. 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
  19. 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
  20. 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 )
  21. @@discxpress So, did you solve your problem, Mr. Butler?
  22. Hello interbiolab, Could you be a little more specific to what your problem is? What happens when you browse to advanced_statistics.php; empty page, no stats even though there should be?
  23. Okay, this is a quick fix to escape special characters when changing address or creating a new account. Find this +'&email_address='+email_address +'&gender='+gender +'&firstname='+firstname +'&lastname='+lastname +'&dob='+dob +'&company='+company +'&street_address='+street_address +'&suburb='+suburb +'&postcode='+postcode +'&city='+city +'&state='+state +'&country='+country +'&telephone='+telephone +'&fax='+fax +'&newsletter='+newsletter +'&password='+password +'&confirmation='+confirmation +'&guest='+guest Replace with +'&email_address='+ escape( email_address ) +'&gender='+ escape( gender ) +'&firstname='+ escape( firstname ) +'&lastname='+ escape( lastname ) +'&dob='+ escape( dob ) +'&company='+ escape( company ) +'&street_address='+ escape( street_address ) +'&suburb='+ escape( suburb ) +'&postcode='+ escape( postcode ) +'&city='+ escape( city ) +'&state='+ escape( state ) +'&country='+ escape( country ) +'&telephone='+ escape( telephone ) +'&fax='+ escape( fax ) +'&newsletter='+ escape( newsletter ) +'&password='+ escape( password ) +'&confirmation='+ escape( confirmation ) +'&guest='+ escape( guest ) Find This +'&gender='+gender +'&firstname='+firstname +'&lastname='+lastname +'&company='+company +'&street_address='+street_address +'&suburb='+suburb +'&postcode='+postcode +'&city='+city +'&state='+state +'&country='+country Replace With +'&gender='+ escape( gender ) +'&firstname='+ escape( firstname ) +'&lastname='+ escape( lastname ) +'&company='+ escape( company ) +'&street_address='+ escape( street_address ) +'&suburb='+ escape( suburb ) +'&postcode='+ escape( postcode ) +'&city='+ escape( city ) +'&state='+ escape( state ) +'&country='+ escape( country ) Find this +'&gender='+gender +'&firstname='+firstname +'&lastname='+lastname +'&company='+company +'&street_address='+street_address +'&suburb='+suburb +'&postcode='+postcode +'&city='+city +'&state='+state +'&country='+country Replace with +'&gender='+ escape( gender ) +'&firstname='+ escape( firstname ) +'&lastname='+ escape( lastname ) +'&company='+ escape( company ) +'&street_address='+ escape( street_address ) +'&suburb='+ escape( suburb ) +'&postcode='+ escape( postcode ) +'&city='+ escape( city ) +'&state='+ escape( state ) +'&country='+ escape( country )
  24. @@discxpress You might as well check so that you have the correct timezone configured, Find this $json_array = array(); $row = 0; Replace with $json_array = array(); $row = 0; prettify( date_default_timezone_get(), '0 Timezone: ' );
  25. Ok, try with this mod and try again. Find this $month_name = strftime( "%B", strtotime( $total_sales[ $i ]['year'] . '-' . $total_sales[ $i ]['month'] ) ); Replace With //$month_name = strftime( "%B", strtotime( $total_sales[ $i ]['year'] . '-' . $total_sales[ $i ]['month'] ) ); $datetime = (string)$total_sales[ $i ]['year'] . '-' . $total_sales[ $i ]['month'] . '-01'; $timestamp = strtotime( $datetime ); $month_name = date( "F", $timestamp ); $month_name_gm = gmdate( "F", $timestamp ); var_dump($total_sales[ $i ]['year'] . '-' . $total_sales[ $i ]['month']); echo "<br>"; var_dump($month_name); echo "<br>"; var_dump($month_name_gm); echo "<hr>"; Check if any of the two month names are the correct month (compare to the first numeric date). I.e.: string '2015-01' (length=7) string 'January' (length=7) <-- Correct string 'December' (length=8)