home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2000 January / maximum-cd-2000-01.iso / Dreamweaver2 / data1.cab / Program_Files / Configuration / Commands / Sort Table.js < prev    next >
Encoding:
JavaScript  |  1999-02-23  |  11.4 KB  |  324 lines

  1. //*************** GLOBAL VARS  *****************
  2.  
  3. var HAVE_SORTED_BY = new Array(7);
  4.  
  5. //******************* API **********************
  6.  
  7. function commandButtons(){
  8.    var tableObj = findTable();
  9.    var retArr = new Array(BUTTON_OK,     "sortAndClose()",
  10.                          BUTTON_Apply,   "sortTable()",
  11.                          BUTTON_Cancel,  "window.close()",
  12.                          BUTTON_Help, "displayHelp()");
  13.                          
  14.    //display buttons that can only close the dialog if there are problems with table format
  15.    if (hasSpans(tableObj) || isInvalidTable(tableObj) || hasCaption(tableObj))  
  16.      retArr=new Array(BUTTON_OK,"window.close()",BUTTON_Cancel,"window.close()");
  17.  
  18.      return retArr;
  19. }
  20.  
  21. function canAcceptCommand(){
  22.   if (findTable())
  23.     return true;
  24.   else
  25.     return false;
  26. }
  27. //***************** LOCAL FUNCTIONS  ******************
  28.  
  29. function findTable(){
  30.   var tableObj="";
  31.   var selArr = dreamweaver.getSelection();
  32.   var selObj = dreamweaver.offsetsToNode(selArr[0],selArr[1]);
  33.  
  34.   while (tableObj=="" && selObj.parentNode){
  35.     if (selObj.nodeType == Node.ELEMENT_NODE && selObj.tagName=="TABLE")
  36.       tableObj=selObj;
  37.     else
  38.       selObj = selObj.parentNode;
  39.   }
  40.   return tableObj;
  41. }
  42.  
  43. function sortAndClose(){
  44.   //If the current sort has already been applied, close the dialog
  45.   //otherwise, sort
  46.   if (findObject("sortCol").selectedIndex==HAVE_SORTED_BY[0] &&
  47.       findObject("subsortCol").selectedIndex-1==HAVE_SORTED_BY[1] &&
  48.       findObject("sortType").selectedIndex==HAVE_SORTED_BY[2] &&
  49.       findObject("subsortType").selectedIndex==HAVE_SORTED_BY[3] &&
  50.       findObject("sortOrder").selectedIndex==HAVE_SORTED_BY[4] &&
  51.       findObject("subsortOrder").selectedIndex==HAVE_SORTED_BY[5]&&
  52.       findObject("sortFirstRow").checked==HAVE_SORTED_BY[6]){
  53.       window.close();
  54.       }
  55.    else{
  56.      sortTable();
  57.      window.close();
  58.    }
  59.  
  60. }
  61.  
  62. function sortTable(){
  63.     var tableObj, rowCount, rowIter, rowArray, tdIter;
  64.     var rowNode, colIter, sortCol,subsortCol,rowHTML,bSkipFirstRow;
  65.     var textString,startCount,currRow,bMoveRowAttrs;
  66.  
  67.     // Get the selected table
  68.     tableObj = findTable();
  69.  
  70.  
  71.     // Determine number of rows 
  72.     rowIter = tableObj.childNodes; //rowIter is array of TR tags in this table
  73.     rowCount = rowIter.length;
  74.     bSkipFirstRow = !findObject("sortFirstRow").checked;
  75.     bMoveRowAttrs = findObject("moveRowAttrs").checked;
  76.     rowCount = (bSkipFirstRow)?rowCount-1:rowCount;
  77.  
  78.     // Determine column and subsort column
  79.     sortCol = findObject("sortCol").selectedIndex;
  80.     subsortCol = findObject("subsortCol").selectedIndex-1;
  81.  
  82.     //Create a two-dimensional array containing rowCount rows and 3 columns.
  83.     //The first column contains the HTML text for the row,the second
  84.     //column contains the contents of column number sortCol for that row,
  85.     //and the third column contains the contents of column number subsortColumn
  86.     //for that row. 
  87.  
  88.     rowArray = new Array();
  89.     for (i=0;i<rowCount;i++) {
  90.  
  91.        // Copy row text into rowArray
  92.        rowArray[i] = new Array();
  93.        rowHTML = (bSkipFirstRow)?rowIter.item(i+1):rowIter.item(i);  
  94.        rowArray[i][0] = (bMoveRowAttrs)?rowHTML.outerHTML:rowHTML.innerHTML;
  95.  
  96.        // Copy sort key into rowArray
  97.        colIter = rowHTML.childNodes;
  98.        textString=getTextNode(colIter.item(sortCol));
  99.        rowArray[i][1] = findObject("sortType").selectedIndex==0 ?
  100.          gobbleWhiteSpace(textString.toLowerCase()):parseNumber(gobbleWhiteSpace(textString));
  101.        //copy subsort key into rowArray, if applicable
  102.        if (findObject("subsortCol").selectedIndex!=-1){
  103.          textString=getTextNode(colIter.item(subsortCol));
  104.          rowArray[i][2]= findObject("subsortType").selectedIndex==0 ?
  105.             gobbleWhiteSpace(textString.toLowerCase()):parseNumber(gobbleWhiteSpace(textString));
  106.  
  107.        }        
  108.     }
  109.  
  110.     // Sort the rowArray, based on sort key
  111.     rowArray.sort(compareCallback);
  112.  
  113.     // Copy the contents of the sorted rowArray back into the HTML document
  114.     for (i = 0; i < rowCount; i++) {
  115.       currRow=(bSkipFirstRow)?rowIter.item(i+1):rowIter.item(i);
  116.       if (bMoveRowAttrs)
  117.         currRow.outerHTML=rowArray[i][0];
  118.       else
  119.         currRow.innerHTML=rowArray[i][0];
  120.     }
  121.  
  122.     //plug sort information into global HAVE_SORTED_BY variable
  123.     HAVE_SORTED_BY[0]=sortCol;
  124.     HAVE_SORTED_BY[1]=subsortCol;
  125.     HAVE_SORTED_BY[2]=findObject("sortType").selectedIndex;
  126.     HAVE_SORTED_BY[3]=findObject("subsortType").selectedIndex;
  127.     HAVE_SORTED_BY[4]=findObject("sortOrder").selectedIndex;
  128.     HAVE_SORTED_BY[5]=findObject("subsortOrder").selectedIndex;
  129.     HAVE_SORTED_BY[6]=findObject("sortFirstRow").checked;
  130.     
  131.     //restore original selection
  132.     selArr = dreamweaver.nodeToOffsets(tableObj);
  133.     dreamweaver.setSelection(selArr[0],selArr[1]);
  134. }
  135.  
  136. function compareCallback(a,b){
  137.    var retVal=0;
  138.    //determine whether to switch a and b based on a and b values and specified sort order
  139.    //if -1 is returned: order stays the same, if 1: values are switched, if 0: values are equal
  140.  
  141.    if (a[1]!=b[1])
  142.      retVal=((a[1]<b[1])?-1:1)*(findObject("sortOrder").selectedIndex==0?1:-1);
  143.    else if(a[2]!=b[2])
  144.      retVal=((a[2]<b[2])?-1:1)*(findObject("subsortOrder").selectedIndex==0?1:-1);
  145.    return retVal;
  146. }
  147.  
  148. function initializeUI(){
  149.    var colCount;
  150.    var tableObj = findTable();
  151.  
  152.    if (hasSpans(tableObj)){ //if table has rowspans or colspans
  153.       findObject("ErrMsgLayer").innerHTML="<p> " + MSG_SpansArePresent;
  154.       findObject("formLayer").visibility = "hidden";
  155.       findObject("ErrMsgLayer").visibility="visible";
  156.     } else if (hasCaption(tableObj)){
  157.       findObject("ErrMsgLayer").innerHTML="<p> " + MSG_CaptionIsPresent;
  158.       findObject("formLayer").visibility = "hidden";
  159.       findObject("ErrMsgLayer").visibility="visible";
  160.      }else if (isInvalidTable(tableObj)){ //if table is invalid
  161.       findObject("ErrMsgLayer").innerHTML="<p> " + MSG_IsInvalidTable;
  162.       findObject("formLayer").visibility = "hidden";
  163.       findObject("ErrMsgLayer").visibility="visible";
  164.       } else { //if everything is okay
  165.  
  166.       //dynamically update all form elements
  167.       //dynamically update sort order and type
  168.       with (findObject("sortType")){
  169.         options[0]= new Option(MENU_TypeAlphabetical);
  170.         options[1]= new Option(MENU_TypeNumerical);
  171.       }
  172.       with (findObject("subsortType")){
  173.         options[0]= new Option(MENU_TypeAlphabetical);
  174.         options[1]= new Option(MENU_TypeNumerical);
  175.       }
  176.       with (findObject("sortOrder")){
  177.         options[0]= new Option(MENU_OrderAscending);
  178.         options[1]= new Option(MENU_OrderDescending);
  179.       }
  180.       with (findObject("subsortOrder")){
  181.         options[0]= new Option(MENU_OrderAscending);
  182.         options[1]= new Option(MENU_OrderDescending);
  183.       }
  184.       //dynamically update sortCol and subsortCol menus
  185.       colCount=tableObj.childNodes.item(0).childNodes.length;
  186.       for (i=0;i<colCount;i++)
  187.         findObject("sortCol").options[i]=new Option(MENU_Column + " " + (i+1)); 
  188.       findObject("subsortCol").options[0]=new Option(" ");
  189.       for (i=0;i<colCount;i++)
  190.         findObject("subsortCol").options[i+1]=new Option(MENU_Column + " " + (i+1)); 
  191.    }
  192. }
  193.  
  194. function parseNumber(value){
  195.  
  196.   var retVal=value;
  197.   var numLength = retVal.length;
  198.   var k=0;
  199.  
  200.   //before sorting as numbers, remove % and $ symbols 
  201.   if (retVal.charAt(0)=="$")
  202.     retVal=retVal.slice(1);
  203.   else if (retVal.charAt(numLength-1)=="%" || retVal.charAt(numLength-1)=="$")
  204.     retVal=retVal.slice(0,-1);
  205.   
  206.   //before sorting as numbers, remove spaces and turn commas into decimal points
  207.   while(retVal.charAt(k)!=""){ 
  208.     if (retVal.charAt(k)==" "){ 
  209.       retVal=retVal.substring(0,k) + retVal.substring(k+1);continue; 
  210.     }
  211.     if (retVal.charAt(k)==","){ 
  212.        retVal=retVal.substring(0,k) + retVal.substring(k+1);continue; 
  213.     }   
  214.     k++;
  215.   }
  216.    
  217.   //following lines exist to work around Netscape crash caused by comparing
  218.   //two values that are both NaN. Workaround: Non-numbers are treated as strings.
  219.   if (parseFloat(retVal) == retVal)
  220.     retVal = parseFloat(retVal);
  221.   return retVal;
  222. }
  223.  
  224.  
  225.  
  226. function hasSpans(theObj){ //checks for rowspans and colspans
  227.    var hasSpans=false;
  228.    var tdIter=theObj.getElementsByTagName("TD");
  229.    var iterLength=tdIter.length;
  230.    
  231.    for (i=0;i<iterLength;i++){  //if any rowspan or colspan attributes are found, return true
  232.       if(tdIter.item(i).getAttribute("ROWSPAN") || tdIter.item(i).getAttribute("COLSPAN")){
  233.         hasSpans=true;
  234.         break;
  235.       }
  236.    }
  237.    return hasSpans;
  238. }
  239.  
  240. function hasCaption(theObj){
  241.   if (theObj.childNodes.item(0).tagName && theObj.childNodes.item(0).tagName=="CAPTION")
  242.     return true;
  243.   return false;
  244. }
  245.  
  246. function isInvalidTable(theObj){
  247.  
  248.   var retVal=false;
  249.   var trIter=theObj.childNodes;
  250.   var trIterLen = trIter.length;
  251.   var widthOfFirstRow=trIter.item(0).childNodes.length;
  252.  
  253.   //check that each child node of table is TR tag
  254.   //and that each TR has same number of children
  255.   //note that we use the childNodes to check the children number
  256.   //instead of getElementsByTagName("TD").length, because the latter
  257.   //would give deceiving results in the case of nested tables
  258.   for (i=0;i<trIterLen;i++){
  259.     if (trIter.item(i).tagName != "TR" || trIter.item(i).childNodes.length==0
  260.             || trIter.item(i).childNodes.length!=widthOfFirstRow){
  261.       retVal=true; break;
  262.     }
  263.   }
  264.   return retVal;
  265. }
  266.  
  267.  
  268. function getTextNode(theObj){
  269.     var iter=theObj.childNodes;
  270.     var counter=0;
  271.     var child=iter.item(counter);
  272.     var retVal="";
  273.  
  274.    while (child) {
  275.       retVal+=getTextNode(child);
  276.       child=iter.item(++counter);
  277.    }
  278.      if (theObj.nodeType == Node.TEXT_NODE)
  279.      retVal+=theObj.data;
  280.    
  281.    return retVal;
  282. }
  283.  
  284. function gobbleWhiteSpace(textstring){
  285.   var lastChar,counter=0;
  286.   
  287.   //gobble whitespace from beginning of string
  288.   while (textstring.charAt(0)==" " || textstring.charAt(0)=="\n" || textstring.charAt(0)=="\r"
  289.             || textstring.charAt(0)=="\t")
  290.     textstring = textstring.substring(1);
  291.   //gobble whitespace from end of string
  292.   lastChar = textstring.length-1;
  293.   while (textstring.charAt(0)==" " || textstring.charAt(0)=="\n" || textstring.charAt(0)=="\r"
  294.             || textstring.charAt(0)=="\t"){
  295.     textstring = textstring.substring(0,textstring.length-1);
  296.     lastChar = textstring.length-1;
  297.   }        
  298.   return textstring;  
  299. }    
  300.  
  301. //**************** GENERIC FUNCTIONS ****************
  302.  
  303. function findObject(objName,  parentObj) {
  304.   var i,tempObj="",found=false,curObj = "";
  305.   var NS = (navigator.appName.indexOf("Netscape") != -1);
  306.   if (!NS && document.all) curObj = document.all[objName]; //IE4
  307.   else {
  308.     parentObj = (parentObj != null)? parentObj.document : document;
  309.     if (parentObj[objName] != null) curObj = parentObj[objName]; //at top level
  310.     else { //if in form
  311.       if (parentObj.forms) for (i=0; i<parentObj.forms.length; i++) {  //search level for form object
  312.         if (parentObj.forms[i][objName]) {
  313.           curObj = parentObj.forms[i][objName];
  314.           found = true; break;
  315.       } }
  316.       if (!found && NS && parentObj.layers && parentObj.layers.length > 0) {
  317.         parentObj = parentObj.layers;
  318.         for (i=0; i<parentObj.length; i++) { //else search for child layers
  319.           tempObj = findObject(objName,parentObj[i]); //recurse
  320.           if (tempObj) { curObj = tempObj; break;} //if found, done
  321.   } } } }
  322.   return curObj;
  323. }
  324.