473,461 Members | 1,493 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Ordering rows in a table

Hi

I have a javascript problem that has been annoying me for two days now
and thought that a javascript expert might have the magic solution.

I am populating a table dynamically from the database and I am trying
to allow the user to order the rows in the table using up and down
arrows.

The function I am using is:

function moveContactRow(direction)
{
var tempVal; //stores temporary value while swapping hidden values
rowIndex =
parseInt(window.event.srcElement.parentElement.par entElement.index);
if((rowIndex == 0 && direction > 0) || (rowIndex ==
id_listTable.rows.length - 1 && direction < 0) || (rowIndex > 0 &&
rowIndex < id_listTable.rows.length - 1))
{
if(id_listTable.rows[rowIndex].cells[0].swapNode)
{
id_listTable.rows[rowIndex +
direction].cells[0].swapNode(id_listTable.rows[rowIndex].cells[0]);
id_listTable.rows[rowIndex +
direction].cells[1].swapNode(id_listTable.rows[rowIndex].cells[1]);
id_listTable.rows[rowIndex +
direction].cells[2].swapNode(id_listTable.rows[rowIndex].cells[2]);
tempVal = document.all('hidID' + rowIndex).value;
document.all('hidID' + rowIndex).value = document.all('hidID' +
[rowIndex + direction]).value;
document.all('hidID' + [rowIndex + direction]).value = tempVal;
document.all('hid' + rowIndex).value = rowIndex + direction;
document.all('hid' + [rowIndex + direction]).value = rowIndex;
}
}
}
To call the function the arrows have the following code:

upArrow - onclick="moveContactRow(-1)
DownArrow - onclick="moveContactRow(1)

The good thing is that the table rows move correctly, but the values
written to the hidden fields (prefixed with hid or hidID) aren't always
correct.

Any ideas on whats happening?

Any help is greatly appreciated.

Thanks

Brendan

Sep 6 '05 #1
6 6454
Br*************@Singularity.co.uk wrote:
Hi

I have a javascript problem that has been annoying me for two days now
and thought that a javascript expert might have the magic solution.

I am populating a table dynamically from the database and I am trying
to allow the user to order the rows in the table using up and down
arrows.

The function I am using is:

function moveContactRow(direction)
{
var tempVal; //stores temporary value while swapping hidden values
rowIndex =
parseInt(window.event.srcElement.parentElement.par entElement.index);
if((rowIndex == 0 && direction > 0) || (rowIndex ==
id_listTable.rows.length - 1 && direction < 0) || (rowIndex > 0 &&
rowIndex < id_listTable.rows.length - 1))
{
if(id_listTable.rows[rowIndex].cells[0].swapNode)
{
id_listTable.rows[rowIndex +
direction].cells[0].swapNode(id_listTable.rows[rowIndex].cells[0]);
id_listTable.rows[rowIndex +
direction].cells[1].swapNode(id_listTable.rows[rowIndex].cells[1]);
id_listTable.rows[rowIndex +
direction].cells[2].swapNode(id_listTable.rows[rowIndex].cells[2]);
tempVal = document.all('hidID' + rowIndex).value;
document.all('hidID' + rowIndex).value = document.all('hidID' +
[rowIndex + direction]).value;
document.all('hidID' + [rowIndex + direction]).value = tempVal;
document.all('hid' + rowIndex).value = rowIndex + direction;
document.all('hid' + [rowIndex + direction]).value = rowIndex;
}
}
}
To call the function the arrows have the following code:

upArrow - onclick="moveContactRow(-1)
DownArrow - onclick="moveContactRow(1)

The good thing is that the table rows move correctly, but the values
written to the hidden fields (prefixed with hid or hidID) aren't always
correct.

Any ideas on whats happening?

Any help is greatly appreciated.

Thanks

Brendan

Hi Brendan,

I wouldn't have used swapNodes to handle the re-ordering, instead I
would have an array that represents the table and then used the "sort"
function of array to re index the array and then redraw the table from
the array.
Consider this javascript:

------------------------ JAVASCRIPT ---------------------------
// An Array of data.
var aTable = {
{"1", "First Name", "First Address", "First Phone" },
{"2", "Second Name", "Second Address", "Second Phone" },
{"3", "Third Name", "Third Address", "Third Phone" }};

// A var to define which column is ordered
var nCurrentColumn = 0;

// A function the wrap the sorting and rendering;
function OrderCol( nCol ){
// @nCol defines what index the Array is to be index on.
nCurrentColumn = nCol;
aTable.sort(sortTable);
RenderTable();
}
// The Function to the array.
function sortTable (a,b){
if (a[nCurrentColumn]<b[nCurrentColumn]) return -1
if (a[nCurrentColumn]>b[nCurrentColumn]) return 1
return 0;
}

// A function to step through the array to render a table
function RenderTable(){
eTableBody = document.getElementById("tableBody");
eTableBody.innerHTML="";
for( var i=0;i<aTable.length;i++ ){
var eRow = document.createElement( "tr" );
for( var j=0; j<aTable[i].length;j++ ){
var eCell = document.createElement( "td" );
eCell.appendChild( document.createTextNode( aTable[i][j] ) );
eRow.appendChild(eCell);
}
eTableBody.appendChild( eRow );
}
}

// Using the onload event to start the table rendering
window.onload = function(){ OrderCol(0); }

---------------------------------------------------------
And this HTML :
------------------------ HTML ---------------------------

<table>
<thead>
<tr>
<td onclick="OrderCol(0);">KEY</td>
<td onclick="OrderCol(1);">Name</td>
<td onclick="OrderCol(2);">Address</td>
<td onclick="OrderCol(3);">Phone</td>
</tr>
</thead>
<tbody id="tableBody"></tbody>
</table>

---------------------------------------------------------

You will probably want to handle the control of direction so if a column
has been clicked twice for indexing you invert the direction of the
ordering. All you need to do to achive this is to have an indicator set
either to 1 or -1 and then in the sortTable function return the value
multiplied by this indicator.

For Example
if (a[nCurrentColumn]<b[nCurrentColumn]) return ( -1 * nDirection );
if (a[nCurrentColumn]>b[nCurrentColumn]) return ( 1 * nDirection );
return 0;

Hope this helps

Andy

----------------------------------------------------------------------
http://km0ti0n.blunted.co.uk/blog
http://km0ti0n.blunted.co.uk/mozXPath
http://km0ti0n.blunted.co.uk
----------------------------------------------------------------------

Sep 6 '05 #2

"Andrew Scott" <An****@compan.net> wrote in message
news:11*************@corp.supernews.com...
Br*************@Singularity.co.uk wrote:

Hi Brendan,

I wouldn't have used swapNodes to handle the re-ordering, instead I would
have an array that represents the table and then used the "sort" function
of array to re index the array and then redraw the table from the array.


I agree - getting into the DOM for this is nasty work. ;^)

Instead load your data into an abstracted element (like an array) and
rewrite the table each time - it's very fast on the client and sooo much
simpler.

Andrews code will work just fine (and a lot of people may prefer it) but if
you're interested I've got an abstraction component that might help. It
maintains an ordered set of objects (essentially abstracting Andrews array
into an object and providing management and sorting methods). Sorry, long
URL coming:

<
http://www.depressedpress.com/depres...ered/Index.cfm >

There's an example on that page of sorting a table using the component.

Using this Andrews original code might look like this:

// This creates a new ordered collection and makes the "ID" field the
key
MyData = new DP_ObCollectionOrdered("id", Object);
// Add the data - you need to name the properties if you want to sort
them here (Andrew's is less verbose in that respect).
MyData.add( {id: "1", name:"First Name", address:"First Address",
phone:"First Phone" } );
MyData.add( {id: "2", name:"Second Name", address:"Second Address",
phone:"Second Phone" } );
MyData.add( {id: "3", name:"Third Name", address:"Third Address",
phone:"Third Phone" } );

You could then sort the data by any property like this:

MyData.sortByProp('id', 'Numeric', 'asc');

MyData.sortByProp('address', 'AlphaNoCase', 'asc');

MyData.sortByProp('name', 'Alpha', 'desc');

And so forth.

You also get all sorts of "rank" (position in the collection) methods - you
can swap elements, move them up or down one or more steps or just move them
around using only a method call.

Also, before you pull your hair out: IE won't let you write into a tbody
tag... it's a damn pain in that respect. It doesn't even give a good error
(just an "unknown exception" or some such). Andrew's code will work
perfectly fine in FireFox but will error in IE on the
eTableBody.innerHTML=""; (well... at least it does for me).

Because of this it's usually simpler to just write the whole table (with the
header) into a <div> (the example on my site does this and works in both IE
and FireFox). It's not elegant, but it works.

Jim Davis
Sep 6 '05 #3
Br*************@Singularity.co.uk wrote:
Hi

I have a javascript problem that has been annoying me for two days now
and thought that a javascript expert might have the magic solution.

I am populating a table dynamically from the database and I am trying
to allow the user to order the rows in the table using up and down
arrows.


If all you are doing is moving rows up or down based on whether the up
or down arrow is clicked, I think you can do this much more easily.

Your use of document.all will prevent your code from working in a good
number of browsers. Use of window.event will restrict usage almost
entirely to IE.

Solutions for the document.all issue are on the group FAQ:

<URL:http://jibbering.com/faq/#FAQ4_15>

Solutions for window.event are here:

<URL:http://www.quirksmode.org/js/introevents.html>

Here is a simple script for moving rows up or down. The buttons could be
added using an onload function to reduce code bloat and users without
JavaScript would not see the buttons at all.

<script type="text/javascript">

function moveR( el, x )
{
while ( el.parentNode && 'tr' != el.nodeName.toLowerCase() ){
el = el.parentNode;
}
var t = el.parentNode;
var i = el.rowIndex + x;

if ( i < 0 ) i += t.rows.length;
if ( i == t.rows.length ) i = 0;

t.removeChild(el);
var nRow = t.insertRow( i );
t.replaceChild(el, nRow);
}

</script>

<table>
<tr>
<td>
<input type="button" value="Move up" onclick="moveR(this, -1);">
<input type="button" value="Move down" onclick="moveR(this, 1);">
</td>
<td>row 0</td>
</tr>
<tr>
<td>
<input type="button" value="Move up" onclick="moveR(this, -1);">
<input type="button" value="Move down" onclick="moveR(this, 1);">
</td>
<td>row 1</td>
</tr>
<tr>
<td>
<input type="button" value="Move up" onclick="moveR(this, -1);">
<input type="button" value="Move down" onclick="moveR(this, 1);">
</td>
<td>row 2</td>
</tr>
</table>

[...]

--
Rob
Sep 7 '05 #4
RobG wrote:
[...]
Here is a simple script for moving rows up or down. The buttons could be
added using an onload function to reduce code bloat and users without
JavaScript would not see the buttons at all.


Had a bit more of a play, the following is more concise but maybe more
difficult to maintain as a result:

function moveR( el, x )
{
while ( el.parentNode && 'tr' != el.nodeName.toLowerCase() ){
el = el.parentNode;
}
var t = el.parentNode;
var i = (el.rowIndex + +x)% t.rows.length;
t.replaceChild(t.removeChild(el), t.insertRow(i));
}

The extra '+' in '(el.rowIndex + +x)' ensures that x is a number even if
passed as a string.
[...]

--
Rob
Sep 7 '05 #5
Jim Davis wrote:
"Andrew Scott" <An****@compan.net> wrote in message
news:11*************@corp.supernews.com...
Br*************@Singularity.co.uk wrote:

Hi Brendan,

I wouldn't have used swapNodes to handle the re-ordering, instead I would
have an array that represents the table and then used the "sort" function
of array to re index the array and then redraw the table from the array.

I agree - getting into the DOM for this is nasty work. ;^)

Instead load your data into an abstracted element (like an array) and
rewrite the table each time - it's very fast on the client and sooo much
simpler.

Andrews code will work just fine (and a lot of people may prefer it) but if
you're interested I've got an abstraction component that might help. It
maintains an ordered set of objects (essentially abstracting Andrews array
into an object and providing management and sorting methods). Sorry, long
URL coming:

<
http://www.depressedpress.com/depres...ered/Index.cfm >

There's an example on that page of sorting a table using the component.

Using this Andrews original code might look like this:

// This creates a new ordered collection and makes the "ID" field the
key
MyData = new DP_ObCollectionOrdered("id", Object);
// Add the data - you need to name the properties if you want to sort
them here (Andrew's is less verbose in that respect).
MyData.add( {id: "1", name:"First Name", address:"First Address",
phone:"First Phone" } );
MyData.add( {id: "2", name:"Second Name", address:"Second Address",
phone:"Second Phone" } );
MyData.add( {id: "3", name:"Third Name", address:"Third Address",
phone:"Third Phone" } );

You could then sort the data by any property like this:

MyData.sortByProp('id', 'Numeric', 'asc');

MyData.sortByProp('address', 'AlphaNoCase', 'asc');

MyData.sortByProp('name', 'Alpha', 'desc');

And so forth.

You also get all sorts of "rank" (position in the collection) methods - you
can swap elements, move them up or down one or more steps or just move them
around using only a method call.

Also, before you pull your hair out: IE won't let you write into a tbody
tag... it's a damn pain in that respect. It doesn't even give a good error
(just an "unknown exception" or some such). Andrew's code will work
perfectly fine in FireFox but will error in IE on the
eTableBody.innerHTML=""; (well... at least it does for me).

Because of this it's usually simpler to just write the whole table (with the
header) into a <div> (the example on my site does this and works in both IE
and FireFox). It's not elegant, but it works.

Jim Davis

I'd have to agree that rewriting the whole table is better. And the use
of literal object over arrays is deffinatly more benifical. I'd
normally populate a table like this from an xml file, which would also
define the column data too. But with the xml data source I'd still have
to generate an array as the the XMLDOM doesn't have a sort method. Jim,
your ObCollectionOrdered script has some nice features.

I have to Admit I've never actually tried writing to innerHTML of a
tbody element. I try to avoid innerHTML as much as possible (just out
of habit). I probably would have done this :

while( eTableBody.firstChild ) { eTableBody.removeNode(
eTableBody.firstChild ); }

or

eTableBody = eTableBody.replaceNode( eTableBody.cloneNode( false ) );

Though there are many many ways to archive this. using innerHTML is
very fast. But from a users point rewriting the whole table or just a
section of the table doesn't matter it just preference of what you would
prefer to do.


Sep 7 '05 #6
Andrew Scott wrote:
[...]
I have to Admit I've never actually tried writing to innerHTML of a
tbody element.
Don't, it will fail in IE. Microsoft say don't use innerHTML on tables.

tbody element. I try to avoid innerHTML as much as possible (just out
of habit). I probably would have done this :

while( eTableBody.firstChild ) { eTableBody.removeNode(
eTableBody.firstChild ); }

or

eTableBody = eTableBody.replaceNode( eTableBody.cloneNode( false ) );


That's cool, the above iterative method will slow as the number of rows
increases, but this method should not.

[...]
--
Rob
Sep 7 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Matt Fletcher | last post by:
Hi guys, I am trying to allow the models in a mysql database to be ordered by the site owner. I was thinking along the lines of a <SELECT> list containing the model names and Up and Down...
6
by: Ken Fine | last post by:
(originally posted to one of macromedia's groups; no help, so hopefully someone here can help me out. I'm using VBScript ASP.) When designing administrative interfaces to websites, we often need...
5
by: Mike Nolan | last post by:
I notice that 7.4 doesn't do default ordering on a 'group by', so you have to throw in an 'order by' clause to get the output in ascending group order. Is this something that most RDB's have...
2
by: D. Dante Lorenso | last post by:
First I created a function that selected the next available pin code from a table of pre-defined pin codes: CREATE FUNCTION "public"."get_next_pin_code" () RETURNS varchar AS' DECLARE...
4
by: Jim | last post by:
I'm having trouble doing multiple counts with groups, ordering, and joins. Can someone help me out? Below is two table samples and what I'm trying to get my output to be: TABLEA ID ...
4
by: Chris | last post by:
Any good routines or suggestions to assist me in re-ordering my records in my datagrid? i.e. I have a field in each record that is used for ordering (i.e. 1,2,3,4). I would like to implement a...
1
by: Paramveer.Singh | last post by:
Hi! I created a table in postgres with varchar values in it, and I noticed that postgres lexicographical ordering is weird in the sense that it ignores whitespaces. please look at the result I...
20
by: Brian Tkatch | last post by:
An ORDER BY a simple-integer inside a FUNCTION, results in SQL0440N, unless the FUNCTION expects an INTEGER as its parameter. For example: DECLARE GLOBAL TEMPORARY TABLE A(A CHAR(1)) INSERT INTO...
0
by: DDE | last post by:
Hello, I have a table as follows: Branch_ID Branch_Name 8861 Puebla 8862 Vosges 8863 Maryland 8864 Delaware 8865 Veracruz-Llave 8866 Jarvis Island
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.