Category Archives: Javascript

How-to for Javascript

Tomato Cart Second Variant Problem

Tomato Cart has a second problem in the Variant area. (See the first problem here.) It is possible to accidentally delete your variant content for a product with variants. There is a fix. I will first describe the problem, then the fix.

Normal/expected scenario: In the administration area …

  1. You create a variant (ex. states: Denver, California)
  2. You create a product with the variant states.
  3. You create variations for Denver and California, filling in the values for image, cost, SKU, etc.
  4. You go in to change a value for either variant of the product (perhaps the Denver variant).
  5. You press save and continue, and the following happens:
    1. Waiting message comes up on screen
    2. Waiting message goes away indicating the save is complete, your information is displaying
    3. Moments later your variant information clears and
    4. The system reprints your updated data from the database, it looks as before the clearing of the variant data.

That is the normal scenario. Now imagine, you do step 5, pressing step and continue. Your administration area reaches step 5b, the waiting message vanishes and you think everything is done. You accidentally or intentionally hit save and continue again about 2 seconds after the waiting message vanished … before the variant information vanishes. 80-90% of the time, your variant data will be deleted. (Note, the 2 second number can change as a result of your computer or internet activity. Sometimes this can be 10 or more seconds.) You may have hit the save and continue for a number of reasons (1) You are not sure there was a save, (2) You think things are done saving, you change something and hit save, or (3) other reasons. You may loose your data.

If this problem happens to you, you can fix this problem. Go to file /admin/includes/extmodules/products/products_dialog.php … line 198. Comment out the line as follows …

// this.pnlImages.grdImages.getStore().on(‘load’, onDsImagesLoad, this);

This should solve your problem in version 1.1.8.5 Tomato Cart. Hopefully, this problem will be corrected in the next revision of Tomato Cart.

 

 

Tomato Cart variant.js Correction

Pardon me for getting sidetracked. My last memo on Tomato Cart talked about Tomato Cart working well, but, that it needed a correction in the variants handling. I mentioned I created a fix and the answer would be in a following article, and then I got sidetracked and did not give the patch. Well, let me get around to it now.

Tomato Cart is a nice cart, but, it does have a bug in variants. When creating variants, it allows you to save prices, weights, SKU, images, etc for the variants. When your visit comes to the site, they can select the variants, and see the information change. However, when the information changes, the images do not change. Oops.

I do have a fix for the bug. It may not be the best answer that could be done by the original developers of the package, but, it will solve the problem for you short-term, until they fix the problem. The change is in the file /includes/javascript/variants.js.

The problem is on about line 139 of variants.js.



   The following line should be commented out:

        this.changeImage(product['image']);

    Replace it with:

        // this.changeImage(product['image']);
        //

        image = product['image'] ;
        $$('.mini').each(function(link) {
            var href = link.getProperty('href');
            if (href.indexOf(image) > -1) {
                $('product_image').src = image;
                $('product_image').fade('in');
                return ;
            }
        });

      

For some reason, the changeImage() call is not working. But the code specified is actually the code in changeImage(). Placed inline, everything works fine.

Don’t ask me why the code does not work as it existed (I don’t know), but, it is nice to know there is a work around.

 

 

Using SilverStripe – Part 2

How to Find the Administration Panel

SilverStripeFirst things first. Eventually, you will want to get to the SilverStripe administration panel. You might expect to see an admin directory in the root directory, as done on Joomla, Drupal and WordPress, but you will be surprised to see no corresponding directory in SilverStripe. The SilverStripe administration is virtual, no obvious login or index file for it in particular. To get to administration, enter

  • /admin

Voila, you have the login access to the administration area. If you are looking for the actual admin files, they are available in the /framework/admin directory.

Where to Load Add-ons

Curiously, unlike Drupal, Joomla or WordPress, SilverStripe likes to clutter the Document Root directory with all add-ons folders. Retrieve your add-on from Git and the add-on folder will be stored in the site’s root directory.

If you use a ZIP file retrieved from the GIT directory for the add-on:

  • Unpack the zip file, leaving content in their add-on directory
  • Rename the add-on directory. If the add-on directory name has “silverstripe” prepended, or “-master” incorporated in the directory name, remove the “silverstripe” and “-master,” leaving only the application name as the directory name.
  • Replace “-” with “_” if a dash has been used in the naming of the directory.
  • Copy the add-on to the site’s root directory.

If you fail to remove the prepended or appended labels, the loading of the files will fail.

If you fail to replace “-” with “_”, the content will load, but, will load incorrectly and fail to function.

How to Rebuild the CMS Control Database

If you load an add-on or make changes to the database, you must rebuild the SilverStipe site. To rebuild, enter:

  • /dev/build

How to Clear Cache

To speed site display, SilverStripe caches page content. Anytime you make changes to template files and data base, clear the cache. Clear the cache every time you add a new add-on, anytime you create a new page type (explained later), or make any change affecting database or available php or ss files. Clear cache by entering:

  • /index.php?flush=1

Where to Load Images

SilverStripe design suggests that specific content belongs in specific directories. Templates will be placed in /themes subdirectory, you images belong in the /assets. As you load content via SilverStripe, images will be loaded to /assets/upload and subdirectories you request. You may want to arrange to use /assets as the area to store all files you ftp onto your site for consistency. Expect your images stored in subdirectories of:

  • /assets/upload

Summary

  • /admin – access to the administration panel
  • / – location to store add-on directories
  • /dev/build – command to rebuild the site database
  • /index.php?flush=1 – command to flush the cache
  • /assets/upload – appropriate directory for storage of images

The next article will discuss creation of a template

 

 

HTML5 Placeholder

The new HTML5 attribute placeholder for the input tag could be wonderful if implemented correctly. Unfortunately, at the moment we have a problem on Firefox. When using placeholder on firefox, when focusing on the input field, the placeholder does not vanish. This gives the user the erroneous feel that the text is really there and attempts to “erase” it doesn’t work … it is in the background. The appearance is a bit confusing.

The following code can be used to create the “placeholder” behavior. Place a default value in an attribute called data-default, and that value will act as the placeholder.



    <script type="text/javascript">
      $(function() {
        $('input[type="text"]').focus(function() {
            if (!$(this).attr('data-default')) $(this).attr('data-default', $(this).val());
            if ($(this).val()==$(this).attr('data-default')) $(this).val('');
        });
        $('input[type="text"]').blur(function() {
            if ($(this).val()=='') $(this).val($(this).attr('data-default')); 
        });
        $( 'input[type="text"]' ).each(function( index ) {
            if ($(this).val()=='') {
			    $(this).val($(this).attr('data-default'));
			} 
        });
      }) ;
	</script>

jQuery is used, rather than simple javascript because the javascript getAttribute(‘data-function’) may not work correctly and new HTML5 data() may not work on all browsers. It is currently safest to use jQuery until HTML5 is a bit more mature.

 

JavaScript Regular Expressions and Exec()

JavaScript’s regular expressions method exec() is a great way to break apart a string into components you may need.

Given an expression, such as /(\([\d]{3}\)) ([\d]{3})-([\d]{4})/, you can use this for more than verifying that a string contains the pattern that matches a pattern like (xxx) xxx-xxxx where x is a number. You can use exec() to determine what the contents are for each of the 3 grouped elements of the screen. The () in the pattern identifies the grouping. Notice that grouping of \([\d]{3}\), [\d]{3} and [\d]{4} in the previous pattern. This pattern could be used to identify the contents of each group by using the following code:


    /* given a string */
    var str = "(408) 555-1212" ;

    /* given a pattern */
    var re = /(\([\d]{3}\)) ([\d]{3})-([\d]{4})/ ; 

    /* execute the pattern against the str */
    var match = str.exec(re) ;

    /* retrieve the values in each of the pattern positions */
    /* match[1]  is the first group  and returns (408) */
    /* match[2]  is the second group and returns 555  */
    /* match[3]  is the third group  and returns 1212 */
    /* match.index gives the 0-based index into the input string, identifying 
       where the pattern starts ... since it may not always start at the 
       beginning of the string */
    /* match.input returns the original string being examined  */

You may have as many groups as you like in the pattern, and the returned array will have one entry for each of the groups. If you pattern indicates that one group may have zero characters returned and there are zero characters found for that position, the match will return a “” string.

This works well in place of str.indexOf(), str.search(), str.contains(), str.substr() and many of there JavaScript methods you might otherwise use.