Wrox Programmer Forums

Need to download code?

View our list of code downloads.

| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read
BOOK: Professional JavaScript for Web Developers ISBN: 978-0-7645-7908-0
This is the forum to discuss the Wrox book Professional JavaScript for Web Developers by Nicholas C. Zakas; ISBN: 9780764579080
Welcome to the p2p.wrox.com Forums.

You are currently viewing the BOOK: Professional JavaScript for Web Developers ISBN: 978-0-7645-7908-0 section of the Wrox Programmer to Programmer discussions. This is a community of tens of thousands of software programmers and website developers including Wrox book authors and readers. As a guest, you can read any forum posting. By joining today you can post your own programming questions, respond to other developers’ questions, and eliminate the ads that are displayed to guests. Registration is fast, simple and absolutely free .
DRM-free e-books 300x50
Reply
 
Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old May 16th, 2005, 12:05 AM
Registered User
 
Join Date: May 2005
Location: Raleigh, NC, USA.
Posts: 1
Thanks: 0
Thanked 0 Times in 0 Posts
Default sorting tables enhancement

The final code for sorting tables (chapter 12) does not handle empty cells well. A couple minor changes make the code more forgiving.

I made a couple minor changes to the code you provided.
- the first change was to move the method of accessing the objects value into the convert function.
- the second change was to add checks to make sure that the object existed before the convert function accesses the value. In the case that the object is non-existant, the convert function returns an empty string.

The code snippets below can probably be cleaned up some, but I believe the basic functionality is now improved.

The only other enhancement that would be nice is the capability to sort a table entry that is hyperlinks ( a href's) by the link's text.
<a href="somelink">link text</a>



---- changed code below

   function convert(sCell, sDataType) {
      var sValue;

      if (sCell == null) return "";
      if (sCell.getAttribute("value")) sValue = sCell.getAttribute("value");
      if (sCell.firstChild == null) return "";
      if (sCell.firstChild.nodeValue) sValue = sCell.firstChild.nodeValue;
      if (sValue == "&nbsp;") return "";
      switch(sDataType) {
          case "int":
              return parseInt(sValue);
          case "float":
              return parseFloat(sValue);
          case "date":
              return new Date(Date.parse(sValue));
          default:
              return sValue.toString();

      }
  }

  function generateCompareTRs(iCol, sDataType) {

      return function compareTRs(oTR1, oTR2) {
                  var vValue1, vValue2;

                  vValue1 = convert(oTR1.cells[iCol], sDataType);
                  vValue2 = convert(oTR2.cells[iCol], sDataType);

                  if (vValue1 < vValue2) {
                      return -1;
                  } else if (vValue1 > vValue2) {
                      return 1;
                  } else {
                      return 0;
                  }
              };
  }


Reply With Quote
  #2 (permalink)  
Old May 16th, 2005, 08:56 AM
nzakas's Avatar
Wrox Author
 
Join Date: Dec 2004
Location: Peabody, MA, USA.
Posts: 217
Thanks: 0
Thanked 5 Times in 5 Posts
Default

Yes, the code in chapter 12 did make several assumptions about the format of the table, not the least of which was assuming that there wouldn't be any empty cells. Your code updates work well, if there's a second edition of the book, I'll try to incorporate your insights.

Thanks!

Nicholas C. Zakas
Author, Professional JavaScript for Web Developers (ISBN 0764579088)
http://www.nczonline.net/
Reply With Quote
  #3 (permalink)  
Old July 8th, 2006, 08:55 PM
Registered User
 
Join Date: Jul 2006
Location: Alpharetta, GA, .
Posts: 1
Thanks: 0
Thanked 0 Times in 0 Posts
Default

:)Chapter 12 sorting tables examples doesn't handle nested <input> boxes. If you create editable tables using <input type="text"> you need to go deeper into the dom. Additionally, the current sort routine only sorts a column once, subsequent column selections only REVERSE the current display order. If you enable changes to a given column and click the column expecting a new sort you will find that sorting will occur according to the first sorted positions and not the new values.

Below are changes to the example code that allow changes to the displayed values via nested <input> tags and a new sort for every column selection , still preserving the ascending / descending toggle.

I added an additional function call to pull the value from any given column and row in the array. This allows for a quick test to determine if the column is currently in ascending or descending order
(most of the time, the exception being that an initial random ordering may produce an ascending or descending initial sort.).

The following code was tested only on IE6, but meets my needs for inclusion in autogenerated header/detail tables directly from a database using Cold Fusion or .Net2.0.





================ Modified Code =====================


<html>
    <head>
    <title>Table Sort Example</title>
        <script type="text/javascript">

            function convert(sValue, sDataType) {
                switch(sDataType) {
                    case "int":
                        return parseInt(sValue);
                    case "float":
                        return parseFloat(sValue);
                 case "number":
                        return parseFloat(sValue);
                     case "num":
                        return parseFloat(sValue);
                    case "date":
                        return new Date(Date.parse(sValue));
                    default:
                        return sValue.toString();

                }
            }

            function generateCompareTRs(iCol, sDataType) {

                return function compareTRs(oTR1, oTR2) {
                            var vValue1, vValue2;

                            if (oTR1.cells[iCol].getAttribute("value")) {
                                vValue1 = convert(oTR1.cells[iCol].getAttribute("value"),
                                              sDataType);
                                vValue2 = convert(oTR2.cells[iCol].getAttribute("value"),
                                              sDataType);
                            }
                            else if(oTR1.cells[iCol].firstChild.nodeValue) {
                                vValue1 = convert(oTR1.cells[iCol].firstChild.nodeValue,
                                              sDataType);
                                vValue2 = convert(oTR2.cells[iCol].firstChild.nodeValue,
                                              sDataType);
                            }
                            else {
                                vValue1 = convert(oTR1.cells[iCol].firstChild.getAttribute("value"),
                                              sDataType);
                                vValue2 = convert(oTR2.cells[iCol].firstChild.getAttribute("value"),
                                              sDataType);
                            }



                            if (vValue1 < vValue2) {
                                return -1;
                            } else if (vValue1 > vValue2) {
                                return 1;
                            } else {
                                return 0;
                            }
                        };
            }

            function sortTable(sTableID, iCol, sDataType) {
                var oTable = document.getElementById(sTableID);
                var oTBody = oTable.tBodies[0];
                var colDataRows = oTBody.rows;
                var aTRs = new Array;

                for (var i=0; i < colDataRows.length; i++) {
                    aTRs[i] = colDataRows[i];
                }

                //rVal = aTRs.cells[2].firstChild.getAttribute("value");
                //alert(rVal + " Datatype = " + sDataType);

                if (oTable.sortCol == iCol) {
                // We need to sort always and then set to the reverse order
                // that the column is in. So get the first value then sort so that
                // the new value does not equal the incoming first. this preserves the
                // toggle action

                    curVal = getValByColumn(aTRs, 0, iCol);

                    // Perform the sort and test for ordering
                     aTRs.sort(generateCompareTRs(iCol, sDataType));
                    if (getValByColumn(aTRs, 0, iCol) == curVal){
                        aTRs.reverse();}

                    }
                 else {
                    aTRs.sort(generateCompareTRs(iCol, sDataType));
                }


                var oFragment = document.createDocumentFragment();
                for (var i=0; i < aTRs.length; i++) {
                    oFragment.appendChild(aTRs[i]);
                }

                oTBody.appendChild(oFragment);
                oTable.sortCol = iCol;
            }

            function getValByColumn(aR, iRow, iCol)
            {
            var colVal = "";
                            if (aR[iRow].cells[iCol].getAttribute("value")) {
                                colVal = aR[iRow].cells[iCol].getAttribute("value");

                            }
                            else if(aR[iRow].cells[iCol].firstChild.nodeValue) {
                                colVal = aR[iRow].cells[iCol].firstChild.nodeValue;

                            }

                            else {
                                colVal = aR[iRow].cells[iCol].firstChild.getAttribute("value");

                            }


            return colVal;
            }

        </script>
    </head>
    <body>
        <p>Click on the table header to sort.</p>
        <table border="1" id="tblSort">
            <thead>
                <tr>
                    <th onClick="sortTable('tblSort', 0)" style="cursor:pointer">Type</th>
                    <th onClick="sortTable('tblSort', 1)" style="cursor:pointer">Filename</th> <th onClick="sortTable('tblSort', 2, 'int')" style="cursor:pointer">Seq Num</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td value="doc"><img src="images/wordicon.gif"/></td>
                    <td>My Resume.doc</td>
                    <td><input type="text" value="1"
                         onDblClick="javascript:alert(this.value);"></input></td>
                </tr>
                <tr>
                    <td value="xls"><img src="images/excelicon.gif"/></td>
                    <td>Fall Budget.xls</td>
                    <td><input type="text" value="2"
                         onDblClick="javascript:alert(this.value);"></input></td>
                </tr>
                <tr>
                    <td value="pdf"><img src="images/acrobaticon.gif"/></td>
                    <td>How to be a better programmer.pdf</td>
                    <td><input type="text" value="3"
                         onDblClick="javascript:alert(this.value);"></input></td>
                                    </tr>
                <tr>
                    <td value="doc"><img src="images/wordicon.gif"/></td>
                    <td>My Old Resume.doc</td>
                    <td><input type="text" value="4"
                         onDblClick="javascript:alert(this.value);"></input></td>
                </tr>
                <tr>
                    <td value="txt"><img src="images/notepadicon.gif"/></td>
                    <td>Notes from Meeting.txt</td>
                    <td><input type="text" value="5"
                         onDblClick="javascript:alert(this.value);"></input></td>
                </tr>
                <tr>
                    <td value="zip"><img src="images/zippedfoldericon.gif"/></td>
                    <td>Backups.zip</td>
                    <td><input type="text" value="6"
                         onDblClick="javascript:alert(this.value);"></input></td>
                </tr>
                <tr>
                    <td value="xls"><img src="images/excelicon.gif"/></td>
                    <td>Spring Budget.xls</td>
                    <td><input type="text" value="7"
                         onDblClick="javascript:alert(this.value);"></input></td>
                </tr>
                <tr>
                    <td value="doc"><img src="images/wordicon.gif"/></td>
                    <td>Job Description - Web Designer.doc</td>
                    <td><input type="text" value="8"
                         onDblClick="javascript:alert(this.value);"></input></td>
                </tr>
                <tr>
                    <td value="pdf"><img src="images/acrobaticon.gif"/></td>
                    <td>Saved Web Page.pdf</td>
                    <td><input type="text" value="16"
                         onDblClick="javascript:alert(this.value);"></input></td>
                </tr>
                <tr>
                    <td value="doc"><img src="images/wordicon.gif"/></td>
                    <td>Chapter 1.doc</td>
                    <td><input type="text" value="9"
                         onDblClick="javascript:alert(this.value);"></input></td>
                </tr>
            </tbody>
        </table>
    </body>
</html>








Reply With Quote
  #4 (permalink)  
Old July 9th, 2006, 09:24 AM
nzakas's Avatar
Wrox Author
 
Join Date: Dec 2004
Location: Peabody, MA, USA.
Posts: 217
Thanks: 0
Thanked 5 Times in 5 Posts
Default

You are correct, the first sorder is kept in the example in the book. That is because the example was based around a table with static values. For your case, using input text boxes, you are correct that the code won't serve your purposes.

As a note, when generating the table you can put whatever you want in the value attribute and the code should work appropriately.

Nicholas C. Zakas
Author, Professional JavaScript for Web Developers (ISBN 0764579088)
http://www.nczonline.net/
Reply With Quote
  #5 (permalink)  
Old August 6th, 2006, 05:15 PM
Registered User
 
Join Date: Aug 2006
Location: Bellingham, MA, USA.
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Default

I can not get this to work on OSC with Safari

seem Safari does not like return function, any ideas

Thanks

Reply With Quote
  #6 (permalink)  
Old August 6th, 2006, 06:47 PM
nzakas's Avatar
Wrox Author
 
Join Date: Dec 2004
Location: Peabody, MA, USA.
Posts: 217
Thanks: 0
Thanked 5 Times in 5 Posts
Default

If you could explain the error you're getting, perhaps we can figure it out. What are you doing?

Nicholas C. Zakas
Author, Professional JavaScript for Web Developers (ISBN 0764579088)
http://www.nczonline.net/
Reply With Quote
  #7 (permalink)  
Old August 6th, 2006, 07:34 PM
Registered User
 
Join Date: Aug 2006
Location: Bellingham, MA, USA.
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Default

function generateCompareTRs(iCol, sDataType) {

    return function compareTRs(oTR1, oTR2) {
                var vValue1, vValue2;

                if (oTR1.cells[iCol].getAttribute("value")) {
                    vValue1 = convert(oTR1.cells[iCol].getAttribute("value"),
                                  sDataType);
                    vValue2 = convert(oTR2.cells[iCol].getAttribute("value"),
                                  sDataType);
                } else {
                    vValue1 = convert(oTR1.cells[iCol].firstChild.nodeValue,
                                  sDataType);
                    vValue2 = convert(oTR2.cells[iCol].firstChild.nodeValue,
                                  sDataType);
                }

                if (vValue1 < vValue2) {
                    return -1;
                } else if (vValue1 > vValue2) {
                    return 1;
                } else {
                    return 0;
                }
            };
}
I'm sorting tables, the code works correctly in OSX firefox but does not under Safari. Safari sees the "return function" as a syntax error and none of the javascript on that pages works, if I remove this function then the rest of my Javascript works as it should but of course the sort table does not. is there a way of writting this for safari.

Thanks

Reply With Quote
  #8 (permalink)  
Old August 8th, 2006, 07:39 PM
Registered User
 
Join Date: Aug 2006
Location: , , .
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via AIM to albeik Send a message via MSN to albeik Send a message via Yahoo to albeik
Default

@Dean Holmes

just replace "return" with var result = ...
then at the end "return result" --- that should make Safari happy... :)

function generateCompareTRs(iCol, sDataType) {
    var result = function compareTRs(oTR1, oTR2) {
        ...
    };
    return result;
}

hope that helps.

Reply With Quote
  #9 (permalink)  
Old August 9th, 2006, 03:08 PM
Registered User
 
Join Date: Aug 2006
Location: Bellingham, MA, USA.
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Default

HI Nicholas

Great thanks for that, it works just fine. Great book, looking forward for more like this from you

Thanks
Dean

Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Opinion Polls enhancement void BOOK: ASP.NET 2.0 Website Programming Problem Design Solution ISBN: 978-0-7645-8464-0 2 July 12th, 2006 10:42 PM
Sorting Tables and Safari HomersGhost BOOK: Professional JavaScript for Web Developers ISBN: 978-0-7645-7908-0 4 March 18th, 2006 07:09 PM
Mysql Sorting results from multiple tables dcb22 SQL Language 8 October 25th, 2004 10:57 AM
Enhancement Request Ben Horne Forum and Wrox.com Feedback 4 March 30th, 2004 08:13 PM
Enhancement Request Imar Forum and Wrox.com Feedback 8 March 16th, 2004 01:43 PM



All times are GMT -4. The time now is 09:49 AM.


Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.