SitePoint Sponsor

User Tag List

Results 1 to 2 of 2
  1. #1
    SitePoint Evangelist
    Join Date
    Nov 2005
    Posts
    496
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Cross-browser way of adding/deleting rows in table?

    Hello! I have tried looking around on the forum for a solution, but nothing that is too recent...

    I'm not too great at JavaScript, but I know it's possible... I have a table with lots of rows, and i need to know how to determine where a row is in the table and then add a row underneath (or above) that...

    Could anybody possible help me? I'm looking for a native solution really, can't use jQuery/MooTools/etc for this project...

    Thank you in advance for your time!

  2. #2
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,683
    Mentioned
    99 Post(s)
    Tagged
    4 Thread(s)
    Here's how to do it. I'm using buttons because this is a behaviour, rather than a destination that's occuring.

    I'm also using a function that I created today which makes it easier to add elements to the DOM. For example

    Code javascript:
    appendToEl(document.body, {
        table: {
            attr: {id: 'myTable'}, 
            tbody: {tr: {td: 'Some sample text'}}
        }
    });

    Code javascript:
    function appendToEl(el, args, isAttr) {
    	var newEl;
    	var arg;
    	var i;
    	if (typeOf(args) === "array") {
    		for (i = 0; i < args.length; i += 1) {
    			appendToEl(el, args[i], isAttr);
    		}
    	} else if (typeOf(args) === "object") {
    	    for (arg in args) if (args.hasOwnProperty(arg)) {
    			if (isAttr) {
    				el.setAttribute(arg, args[arg]);
    			} else if (arg === 'attr') {
    				appendToEl(el, args[arg], true);
    			} else {
    				newEl = document.createElement(arg);
    				appendToEl(newEl, args[arg]);
    				el.appendChild(newEl);
    			}
    		}
    	} else if (typeof args === "string") {
    		el.appendChild(document.createTextNode(args));
    		return;
    	}
    }
    // typeOf() function from Douglas Crockford's Remedial Javascript
    // [url]http://javascript.crockford.com/remedial.html[/url]
    function typeOf(value) {
        var s = typeof value;
        if (s === 'object') {
            if (value) {
                if (typeof value.length === 'number' &&
                        !(value.propertyIsEnumerable('length')) &&
                        typeof value.splice === 'function') {
                    s = 'array';
                }
            } else {
                s = 'null';
            }
        }
        return s;
    }

    Anyway, on with the answer.

    The test table looks like this:

    Code html4strict:
    <table id="myTable"><tbody>
        <tr><td>Line 0</td><td>
            <input value="+▲" name="addBefore" type="button">
            <input value="+▼" name="addAfter" type="button"></td></tr>
        <tr><td>Line 1</td><td>
            <input value="+▲" name="addBefore" type="button">
            <input value="+▼" name="addAfter" type="button"></td></tr>
        <tr><td>Line 2</td><td>
            <input value="+▲" name="addBefore" type="button">
            <input value="+▼" name="addAfter" type="button"></td></tr>
        <tr><td>Line 3</td><td>
            <input value="+▲" name="addBefore" type="button">
            <input value="Add After" name="addAfter" type="button"></td></tr>
        <tr><td>Line 4</td><td>
            <input value="+▲" name="addBefore" type="button">
            <input value="+▼" name="addAfter" type="button"></td></tr>
        <tr><td>Line 5</td><td>
            <input value="+▲" name="addBefore" type="button">
            <input value="+▼" name="addAfter" type="button"></td></tr>
        <tr><td>Line 6</td><td>
            <input value="+▲" name="addBefore" type="button">
            <input value="Add After" name="addAfter" type="button"></td></tr>
        <tr><td>Line 7</td><td>
            <input value="+▲" name="addBefore" type="button">
            <input value="+▼" name="addAfter" type="button"></td></tr>
        <tr><td>Line 8</td><td>
            <input value="+▲" name="addBefore" type="button">
            <input value="+▼" name="addAfter" type="button"></td></tr>
        <tr><td>Line 9</td><td>
            <input value="+▲" name="addBefore" type="button">
            <input value="+▼" name="addAfter" type="button"></td></tr>
        <tr><td>Line 10</td><td>
            <input value="+▲" name="addBefore" type="button">
            <input value="+▼" name="addAfter" type="button"></td></tr>
    </tbody></table>

    I cheated, and used a script to create the table for me.

    Code javascript:
    // create table
    appendToEl(document.body,
    	{table: {attr: {id: 'myTable'}, tbody: {}}}
    );
    var myTable = document.getElementById('myTable');
    var el = myTable.getElementsByTagName('tbody')[0];
    var i;
    for (i = 0; i < 11; i += 1) {
    	appendToEl(el, {tr: newTR('Line ' + i)});
    }
    function newTR(text) {
    	// \u25b2 = black up arrow
    	// \u25bc = black down arrow	
    	return [
    		{td : text},
    		{td: [
    			{input:
    				{attr: {type: 'button', name: 'addBefore', value: '+\u25b2'}}
    			},
    			{input:
    				{attr:{type: 'button', name: 'addAfter', value: '+\u25bc'}}
    			}
    		]}
    	];
    }

    The buttons are handled using the following script, and this is what you're wanting to find out how to achieve.

    Code javascript:
    // onclick event for buttons
    myTable.onclick = function (evt) {
    	evt = evt || window.event;
    	var targ = evt.target || evt.srcElement;
    	var rows = getParent(targ, 'tbody').getElementsByTagName('tr').length;
     
    	// create new row
    	el = document.createElement('tr');
    	appendToEl(el, newTR('New text ' + (rows + 1)));
    	// add new row
    	if (targ.getAttribute('name') === 'addBefore') {
    		targ = getParent(targ, 'tr');
    		targ.parentNode.insertBefore(el, targ);
    	} else if (targ.getAttribute('name') === 'addAfter') {
    		targ = getParent(targ, 'tr');
    		if (targ.nextSibling) {
    			targ.parentNode.insertBefore(el, targ.nextSibling);
    		} else {
    			targ.appendChild(el);
    		}
    	}
    }
    function getParent(el, tagName) {
    	tagName = tagName.toUpperCase();
    	do {
    		el = el.parentNode;
    	} while (el.nodeName !== tagName);
    	return el;
    }
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •