January 2006 - Posts

[DotNetNuke] Eagerly awaiting the release of the DotNetNuke Store Module...

UPDATE: DotNetNuke Store (BETA) has been released. Get it here.

Ah, I'm too excited to wait for the release to post about this. The DotNetNuke Store Module is due out any day now.

The DNN Store out of the box allows you to sell products using either Authorize.Net or PayPal.

Features include categories, products (list and details), mini cart (with integrated controls), full shopping cart (including multiple ship/bill to addresses/recipients), reviews (including a review admin for approving reviews), order history (customer and admin viewable), and provider based gateways.

This is good news to me. I've been helping my wife set up a store based on the ZenCart branch of OSCommerce to save a few bucks on PHP / mySQL hosting, and I'm done with printf debugging...  

Join me in the "Are we there yet? Are we there yet? Are we there yet?" forum...

Posted by Jon Galloway | 3 comment(s)
Filed under:

[tip] Test command line settings with EchoArgs 9.78 PRO

Occasionally, applications will allow you to call external helper programs via command line. That can get tricky when you're supplying a command line template and the application does some token replacement before running the commandline. For example, when I hooked up SourceGear Vault to WinMerge, the trick was in figuring out which tokens it was replacing and how those mapped to WinMerge's commandline arguments. So if my commandline setting is /dl "%WORKING_LABEL%" /dr "%OTHER_LABEL%" "%WORKING_PATH%" "%OTHER_PATH%" "%DEST_PATH%", what exactly is being passed for "WORKING_LABEL" and "OTHER_LABEL"?

Thus, I proudly release EchoArgs 9.78 PRO, the following (ahem) DOS Batch File:

TITLE EchoArgs 9.78 PRO
@echo off
echo Command Line: %*
echo Path :        %~dp0
echo .
echo Arguments 
echo 0: %0
echo 1: %1
echo 2: %2 
echo 3: %3
echo 4: %4
echo 5: %5
echo 6: %6
echo 7: %7
echo 8: %8
echo 9: %9
pause

Here's what it does:

C:\>echoargs test "inscrutable monkey" 5 geronimo

C
:\>TITLE EchoArgs 9.78 PRO
Command Line
: test "inscrutable monkey" 5 geronimo
Path 
:        C:\
.
Arguments
0: echoargs
1
: test
2
: "inscrutable monkey"
3
: 5
4
: geronimo
5
:
6
:
7
:
8
:
9
:
Press any key to continue 
. . .

 

Of course, that doesn't tell us anything we didn't already know. The point is that you'd use it to test the commandline settings by temporarily setting echoargs.bat as my external diff / merge tool (in this example) and seeing what's actually going to be passed to the real application when I've got my arguments straight.

 

Posted by Jon Galloway | 2 comment(s)
Filed under: ,

[tip] Use WinMerge for compare / merge in SourceGear Vault

I previously blogged about how to use WinMerge as the diff tool in StarTeam. Diff / Merge against source control is something I do very frequently, so I think it's worth the few minutes to use the best possible tool. I've been a fan of WinMerge for a while, so when I started using SourceGear Vault this post was pretty much inevitable.

So, here's how you set this up:

  1. Download WinMerge. I know it sounds kind of crazy to use experimental builds of a diff / merge tool, but these guys have been putting out very high quality releases for years and their betas are better than most finished products, so if you're feeling lucky go with the latest experimental build.
  2. In Vault: Tools > Options > Diff/Merge tab.
  3. Diff Program and Merge Program fields: Path to your WinMerge.exe (or WinMergeU.exe if you need Unicode support). Default is C:\Program Files\WinMerge\WinMerge.exe\
  4. Diff Arguments: /dl "%LEFT_LABEL%" /dr "%RIGHT_LABEL%"  "%LEFT_PATH%" "%RIGHT_PATH%"
  5. Merge Arguments: /dl "%WORKING_LABEL%" /dr "%OTHER_LABEL%" "%WORKING_PATH%" "%OTHER_PATH%" "%DEST_PATH%"

More info on the WinMerge commandline args here.
More info on the Vault Diff/Merge Options here.

Oh, and one other Vault tip - use CRC's to determine changed files when working in CVS mode. Otherwise I end up with tons of files that say they're changed, but aren't. You can set that via Tools > Options > Local Files > Check "Detect Modified Files using CRCs instead of modification times"

Posted by Jon Galloway | 10 comment(s)
Filed under:

[fix] DotNetNuke SolPart menu positioning fix for Firefox

The admin dropdown menus in our DNN 3.1.1 sites haven't been working in FireFox - they show up in the upper left hand corner of the screen (absolutely positioned at 0,0). A javascript change (in spmenu.js) fixed it for us.

I'm not sure if this somehow works for everyone else, or if DNN people don't use FireFox, or what. I checked the latest release (3.2 / 4.2) and they don't appear to have this fix, so here it is. I'm going to submit it as a bug and suggested fix to the DNN forums, too.

The problem is setting positions via javascript DOM manipulation without specifying the units:

oMenu.style.top = 100; //bad - no units specified
oMenu.style.top = 100 + 'px'//good - units specified

The best I can tell, the units should be required, so FireFox is being correct in ignoring the improper settings. Anyhow, here's my altered spmenu.js. Of course, the original copyright applies, this is just a patch fix.

//------------------------------------------------------//
// Solution Partner's ASP.NET Hierarchical Menu Control //
// Copyright (c) 2002-2005                              //
// Jon Henning - Solution Partner's Inc                 //  
// jhenning@solpart.com   -   http://www.solpart.com    //
// Compatible Menu Version:  <Min: 1400>             //
//                           <Max: 1.6.1.0>             //
// <Script Version: 1610>                               //
//------------------------------------------------------//
var m_oSolpartMenu;
if (m_oSolpartMenu == null)
    m_oSolpartMenu = 
new Array(); //stores all menu objects (SolpartMenu) in array 
var m_spm_sBrowser;
var m_spm_sVersion;
function spm_initMyMenu(oXML, oCtl)   
//Creates SolpartMenu object and calls generate method
{

  m_oSolpartMenu[oCtl.id] = 
new SolpartMenu(oCtl);
  m_oSolpartMenu[oCtl.id].GenerateMenuHTML(oXML);
 
}
  
//------- Constructor -------//
function SolpartMenu(o)
{
__db(o.id + 
' - constructor');
//  var me = this;  //allow attached events to reference this
  //--- Data Properties ---//
  
this.systemImagesPath=spm_getAttr(o, 'SysImgPath''');  
  
this.iconImagesPath=spm_getAttr(o, 'IconImgPath'this.systemImagesPath);
  
  
this.xml = spm_getAttr(o, 'XML''');
  
this.xmlFileName = spm_getAttr(o, 'XMLFileName''');

  
//--- Appearance Properties ---//
  
this.fontStyle=spm_getAttr(o, 'FontStyle''font-family: arial;');
  
this.backColor=spm_getAttr(o, 'BackColor');  
  
this.foreColor=spm_getAttr(o, 'ForeColor');
  
this.iconBackColor=spm_getAttr(o, 'IconBackColor');
  
this.hlColor=spm_getAttr(o, 'HlColor''');
  
this.shColor=spm_getAttr(o, 'ShColor'''); 
  
this.selColor=spm_getAttr(o, 'SelColor');
  
this.selForeColor=spm_getAttr(o, 'SelForeColor');
  
this.selBorderColor=spm_getAttr(o, 'SelBorderColor');
  
this.menuAlignment = spm_getAttr(o, 'MenuAlignment''Left');
  
this.display=spm_getAttr(o, 'Display''horizontal');
  
this.MBLeftHTML=spm_getAttr(o, 'MBLHTML''');
  
this.MBRightHTML=spm_getAttr(o, 'MBRHTML''');

  
this.rootArrow = spm_getAttr(o, 'RootArrow''0');
  
this.rootArrowImage = spm_getAttr(o, 'RootArrowImage''');
  
this.arrowImage = spm_getAttr(o, 'ArrowImage''');
  
this.backImage=spm_getAttr(o, 'BackImage''');

    
this.supportsTransitions = spm_getAttr(o, 'SupportsTrans''0');

  
//--- Transition Properteis ---//
  //this.menuEffectsStyle=spm_getAttr(o, 'MenuEffectsStyle', '');
  
this.menuTransitionLength=spm_getAttr(o, 'MenuTransitionLength', .3);
  
this.menuTransition=spm_getAttr(o, 'MenuTransition''None');
  
this.menuTransitionStyle=spm_getAttr(o, 'MenuTransitionStyle''');
  
this.SolpartMenuTransitionObject = new SolpartMenuTransitionObject();
  
  
//--- Behavior Properteis ---//
  
this.moveable = spm_getAttr(o, 'Moveable''0');
  
this.moDisplay=spm_getAttr(o, 'MODisplay''HighLight');
  
this.moExpand=spm_getAttr(o, 'MOExpand', "-1");
  
this.moutDelay=spm_getAttr(o, 'MOutDelay', "0");
  
this.minDelay=spm_getAttr(o, 'MInDelay', "0");
  
this.minDelayType=null;
    
this.minDelayTimer=null;
    
this.minDelayObj=null;
      
  
if (spm_browserType() == 'safari')    //safari has issues with mouseoutdelay...
        
this.moutDelay = 5000;
        
  
this.target=spm_getAttr(o, 'target', "");
  
this.moScroll=spm_getAttr(o, 'MOScroll', "-1");

  
//--- Sizing Properties ---//
  
this.menuBarHeight=spm_fixUnit(spm_getAttr(o, 'MenuBarHeight''0'));
  
this.menuItemHeight=spm_fixUnit(spm_getAttr(o, 'MenuItemHeight''0'));
  
this.iconWidth=spm_fixUnit(spm_getAttr(o, 'IconWidth''0'));
  
this.borderWidth=spm_getAttr(o, 'BorderWidth''1');

  
//--- CSS Properties ---//
  
this.cssMenuContainer=spm_getAttr(o, 'CSSMenuContainer''');
  
this.cssMenuBar=spm_getAttr(o, 'CSSMenuBar''');
  
this.cssMenuItem=spm_getAttr(o, 'CSSMenuItem''');
  
this.cssMenuIcon=spm_getAttr(o, 'CSSMenuIcon''');
  
this.cssSubMenu=spm_getAttr(o, 'CSSSubMenu''');
  
this.cssMenuBreak=spm_getAttr(o, 'CSSMenuBreak''');
  
this.cssMenuItemSel=spm_getAttr(o, 'CSSMenuItemSel''');
  
this.cssMenuArrow=spm_getAttr(o, 'CSSMenuArrow''');
  
this.cssMenuRootArrow=spm_getAttr(o, 'CSSRootMenuArw''');
  
this.cssMenuScrollItem=spm_getAttr(o, 'CSSScrollItem''');

    
//for right to left (rtl) menus
    
this.direction = spm_getCurrentStyle(document.body, 'direction');

    
this.useIFrames=(spm_getAttr(o, 'useIFrames''1') != '0' && spm_supportsIFrameTrick());    
    
    
this.delaySubmenuLoad=(spm_getAttr(o, 'delaySubmenuLoad''0') != '0' && spm_needsSubMenuDelay());    
    
  
  
//---- methods ---//
  //this.GenerateMenuHTML=__GenerateMenuHTML;

  //----- private ----//
  
this._m_sNSpace = o.id;               //stores namespace for menu
  
this._m_sOuterTables = '';            //stores HTML for sub menus
  
this._m_oDOM;                         //stores XML DOM object
    
this._m_oMenu = o;                    //stores container
  
this._m_oMenuMove;                    //stores control that is used for moving menu
  
  
this._m_oTblMenuBar;                  //stores menu container
    
this._m_aOpenMenuID = new Array();      //stores list of menus that are currently displayed
    
this._m_bMoving=false;                //flag to determine menu is being dragged
  
this._m_dHideTimer = null;            //used to time when mouse out occured to auto hide menu based on mouseoutdelay
  
this._m_oScrollingMenu = null;                //used in scrolling menu on mouse over

    //--- Exposed Events ---//
/*
    this.onMenuComplete=spm_getAttr(o, 'OnMenuComplete', null);                        //fires once menu is done loading
    this.onMenuBarClick=spm_getAttr(o, 'OnMenuBarClick', null);                        //fires once menu bar is clicked
    this.onMenuItemClick=spm_getAttr(o, 'OnMenuItemClick', null);         //fires once menu item is clicked
    this.onMenuBarMouseOver=spm_getAttr(o, 'OnMenuBarMouseOver', null);        //fires once mouse moves over menu bar
    this.onMenuBarMouseOut=spm_getAttr(o, 'OnMenuBarMouseOut', null);            //fires once mouse moves out of menu bar
    this.onMenuItemMouseOver=spm_getAttr(o, 'OnMenuItemMouseOver', null);    //fires once mouse moves over menu item
    this.onMenuItemMouseOut=spm_getAttr(o, 'OnMenuItemMouseOut', null);        //fires once mouse moves out of menu bar
*/

//--- Menu Moving currently disabled ---//
/*
  this._menuhook_MouseMove=__menuhook_MouseMove;
  this._menuhook_MouseDown=__menuhook_MouseDown;
  this._menuhook_MouseUp=__menuhook_MouseUp;
  this._document_MouseMove=__document_MouseMove;
  this._document_MouseDown=__document_MouseDown;
  this._document_MouseUp=__document_MouseUp;
  this._bodyclick=__bodyclick;

  this.menuhook_MouseMove=function(e) {me._menuhook_MouseMove(e);};
  this.menuhook_MouseDown=function(e) {me._menuhook_MouseDown(e);};
  this.menuhook_MouseUp=function(e) {me._menuhook_MouseUp(e);};
  this.document_MouseMove=function(e) {me._document_MouseMove(e);};
  this.document_MouseDown=function(e) {me._document_MouseDown(e);};
  this.menuhook_MouseUp=function(e) {me._menuhook_MouseUp(e);};
  this.bodyclick=function() {me._bodyclick();};
*/ 
__db(this._m_oMenu.id + ' - constructor end');

}

//--- Destroys interrnal object references ---//
SolpartMenu.prototype.destroy = function ()
{
  
this.systemImagesPath = null;  
  
this.iconImagesPath = null;
  
this.xml = null;
  
this.xmlFileName = null;

  
//--- Appearance Properties ---//
  
this.fontStyle = null;
  
this.backColor = null;  
  
this.foreColor = null;
  
this.iconBackColor = null;
  
this.hlColor = null;
  
this.shColor = null
  
this.selColor = null;
  
this.selForeColor = null;
  
this.selBorderColor = null;
  
this.menuAlignment = null;
  
this.display = null;

  
this.rootArrow = null;
  
this.rootArrowImage = null;
  
this.arrowImage = null;
  
this.backImage = null;

  
//--- Transition Properteis ---//
  //this.menuEffectsStyle = null;
  
this.menuTransitionLength = null;
  
this.menuTransition = null;
  
this.SolpartMenuTransitionObject = null;
  
  
//--- Behavior Properteis ---//
  
this.moveable = null;
  
this.moDisplay = null;
  
this.moExpand = null;
  
this.moutDelay = null;

  
//--- Sizing Properties ---//
  
this.menuBarHeight = null;
  
this.menuItemHeight = null;
  
this.iconWidth = null;
  
this.borderWidth = null;

  
//--- CSS Properties ---//
  
this.cssMenuContainer = null;
  
this.cssMenuBar = null;
  
this.cssMenuItem = null;
  
this.cssMenuIcon = null;
  
this.cssSubMenu = null;
  
this.cssMenuBreak = null;
  
this.cssMenuItemSel = null;
  
this.cssMenuArrow = null;
  
this.cssMenuRootArrow = null;
  
  
//---- methods ---//
  //this.GenerateMenuHTML=__GenerateMenuHTML = null;

  //----- private ----//
  
m_oSolpartMenu[this._m_sNSpace] = null;

  
this._m_sNSpace = null;                 //stores namespace for menu
  
this._m_sOuterTables = null;            //stores HTML for sub menus
  
this._m_oDOM = null;                    //stores XML DOM object
    
this._m_oMenu = null;                   //stores container
  
this._m_oMenuMove = null;               //stores control that is used for moving menu
  
  
this._m_oTblMenuBar = null;             //stores menu container
    
this._m_aOpenMenuID = null;                //stores list of menus that are currently displayed
    
this._m_bMoving = null;                 //flag to determine menu is being dragged
  
this._m_dHideTimer = null;              //used to time when mouse out occured to auto hide menu based on mouseoutdelay
  
this._m_oScrollingMenu = null;                    //used in scrolling menu on mouse over
  
}

//--- static/shared members ---//
/*
SolpartMenu.prototype.menuhook_MouseMove=__menuhook_MouseMove;
SolpartMenu.prototype.menuhook_MouseDown=__menuhook_MouseDown;
SolpartMenu.prototype.menuhook_MouseUp=__menuhook_MouseUp;

SolpartMenu.prototype.document_MouseMove=__document_MouseMove;
SolpartMenu.prototype.document_MouseDown=__document_MouseDown;
SolpartMenu.prototype.document_MouseUp=__document_MouseUp;
*/

//--- xml document loaded (non-dataisland) ---//
SolpartMenu.prototype.onXMLLoad = function ()
{
  
this.GenerateMenuHTML(this._m_oDOM);
}

//--- Generates menu HTML through passed in XML DOM ---//
SolpartMenu.prototype.GenerateMenuHTML = function (oXML) 
{
__db(
this._m_oMenu.id + ' - GenerateMenuHTML');
    
//'Generates the main menu bar
  
var sHTML = '';
  
this._m_sOuterTables = '';
  
//this._m_oMenu.insertAdjacentElement('beforeBegin', );

  
    //if (oXML.readyState != 'complete')
    //    return;

    
if (oXML == null)
    {
      
if (this._m_oDOM == null)
      {
        oXML = spm_createDOMDoc();
//document.implementation.createDocument("", "", null);
        
this._m_oDOM = oXML;
              
        
if (this.xml.length)
          oXML.loadXML(
this.xml);
        
        
if (this.xmlFileName.length)
        {
          oXML.onload = eval(
'onxmlload' this._m_sNSpace); //'m_oSolpartMenu["' + this._m_sNSpace + '"].onXMLLoad'; this.onXMLLoad;
          
oXML.load(this.xmlFileName);
          
return//async load
        
}
    }
    }
    
else
      this
._m_oDOM = oXML;

  
if (this.display == "vertical")
  {
      sHTML += 
'<table ID="tbl' this._m_sNSpace + 'MenuBar" CELLPADDING=\'0\' CELLSPACING=\'0\' BORDER="0" CLASS="' + spm_fixCSSForMac(this.getIntCSSName('spmbctr') + this.cssMenuContainer) + '" HEIGHT="100%" STYLE="vertical-align: center;">\n';    //removed position: relative;  for IE and display: block; for Opera
      
sHTML += MyIIf(this.MBLeftHTML.length, '<tr>\n       <td>' this.MBLeftHTML + '</td>\n</tr>\n''');
      sHTML += MyIIf(Number(
this.moveable), '<tr>\n       <td ID="td' this._m_sNSpace + 'MenuMove" height=\'3px\' style=\'cursor: move; ' + spm_getMenuBorderStyle(this) + '\'>' + spm_getSpacer(this) + '</td>\n</tr>\n''');
      sHTML +=         
this.GetMenuItems(this._m_oDOM.documentElement);
      sHTML += 
'       <tr><td HEIGHT="100%">' + spm_getSpacer(this) + '</td>\n' ;
      sHTML += 
'   </tr>\n';
      sHTML += MyIIf(
this.MBRightHTML.length, '<tr>\n       <td>' this.MBRightHTML + '</td>\n</tr>\n''');
      sHTML += 
'</table>\n';
  }
  
else
  
{
      sHTML += 
'<table ID="tbl' this._m_sNSpace + 'MenuBar" CELLPADDING=\'0\' CELLSPACING=\'0\' BORDER="0" CLASS="' + spm_fixCSSForMac(this.getIntCSSName('spmbctr') + this.cssMenuContainer) + '" WIDTH="100%" STYLE="vertical-align: center; ">\n';    //removed position: relative;  for IE and display: block; for Opera
      
sHTML += '    <tr>\n';
      sHTML += MyIIf(
this.MBLeftHTML.length, '<td>' this.MBLeftHTML + '</td>\n''');
      sHTML += MyIIf(Number(
this.moveable), '       <td ID="td' this._m_sNSpace + 'MenuMove" width=\'3px\' style=\'cursor: move; ' + spm_getMenuBorderStyle(this) + '\'>' + spm_getSpacer(this) + '</td>\n''');
      sHTML += spm_getMenuSpacingImage(
'left'this);
      sHTML +=         
this.GetMenuItems(this._m_oDOM.documentElement);
      sHTML += spm_getMenuSpacingImage(
'right'this);
      sHTML += MyIIf(
this.MBRightHTML.length, '<td>' this.MBRightHTML + '</td>\n'