Advanced Search

Results 1 to 10 of 10

Thread: Auto Form (Dynamic)

  1. #1
    Join Date
    Sep 2006
    Posts
    6
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Cool Auto Form (Dynamic)

    Hey all,
    I have stumbled across a block here, and I was hoping that someone has seen or maybe even done this code.

    Overall it seems pretty simple, but with numerous attempts and searches, I seem unable to find it.

    Basically I have a friend of mine who competes in Horse Reining, she has a website that basically she would like to have a table where she can easily enter data into it.

    Date, City, State, Event, Type, Place, Horse, Rider

    My brainiac idea was to create this really cool idea that somewhat like in Access when you start typing in a new table a row would pop in and you can just continue entering data as long as you like.

    Then when you click on submit it would then place all of these items into a database. I understand that this would be an array and I would be able to loop through them for the database inserts.

    Has anyone seen or thought of this idea. I have seen similar things in Javascript, DHTML, and ASP.Net but nothing exactly like it. Any help would be appreciated.

    Thanks,
    BTW I can place some code to give an idea if that would help.

  2. #2
    Join Date
    Sep 2006
    Posts
    6
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Ok, I have something working, although with me being an ASP programmer, I am not sure how to call an array to cycle through all of the fields. I will post the code, this may be something that has not been done and could be pretty nice for a lot of data input.

    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <title>Untitled Document</title>
    <script>
    	var miLastID = 1;
    	function addNewElement(sourceCloneID, targetParentID){
    		var ndSource = document.getElementById(sourceCloneID)
    		var ndTargetParent = document.getElementById(targetParentID)
    		if(ndSource){
    			var ndClone = ndSource.cloneNode(true);
    			var ndCloneTarget = ndTargetParent.cloneNode(true);
    			ndClone.value='';
    			ndCloneTarget.value='';
    			ndClone.setAttribute('id', getNextID(ndClone.id))
    			ndTargetParent.setAttribute('id', getNextID(ndCloneTarget.id))
    			ndTargetParent.appendChild(ndCloneTarget)
    		}
    	}
    
    	function getNextID(sEdit){
    		var objEdit = new String(sEdit)
    		miLastID = miLastID + 1
    		return objEdit.substr(1, objEdit.length -1) + miLastID
    	}
    </script>
    </head>
    
    <body>
    <form name='frmTest' action='test2.html' method='post'>
    	<table width="680">
    		<tr>
    			<td>
    				Date
    			</td>
    			<td>
    				City
    			</td>
    			<td>
    				State
    			</td>
    			<td>
    				Event
    			</td>
    			<td>
    				Type
    			</td>
    			<td>
    				Place
    			</td>
    			<td>
    				Horse
    			</td>
    			<td>
    				Rider
    			</td>
    		</tr>
    		<tr id='frmTestID1'>
    			<td colspan="8" id='in1'>
    			    <input type="text" name="lblDate" onChange="addNewElement('in1', 'frmTestID1')">&nbsp;
    			    <input type="text" name="lblCity">&nbsp;
    				<input type="text" name="lblState">&nbsp;
    				<input type="text" name="lblEvent">&nbsp;
    				<input type="text" name="lblType">&nbsp;
    				<input type="text" name="lblPlace">&nbsp;
    				<input type="text" name="lblHorse">&nbsp;
    				<input type="text" name="lblRider">
    			</td>
    		</tr>
    		<tr>
    			<td colspan="8">
    			<input type="submit">
    			</td>
    		</tr>
    	</table>
    </form>
    Now that I have a screen full of data, how would I reproduce that on the screen. (Actually in would be saved in a database) Would that still be Javascript?

    If so how is that done?

    Thanks,

  3. #3
    Join Date
    Sep 2006
    Posts
    6
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Ok, well this must be tougher then I thought. We are currently 0 for 3, and in the 4 qtr.

    I have figured out the best way to retrieve all of the information from the user inputs, and I have setup a test server to just check it out.

    Pleople are welcome to look at it, http://www.jbrownspage.com/form/test.html

    The problem I am hopfully seeking out now is I don't want the date field to have anything in the box when it advances the next row. Any thoughts on this would be nice.

    I have tried a couple of different things including value=""

    Thanks in advance,

  4. #4
    Join Date
    Dec 2004
    Location
    UK
    Posts
    2,358
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Ok, well this must be tougher then I thought. We are currently 0 for 3, and in the 4 qtr.
    You asked this question less than 24 hours ago. Please have a little patience.


    I wrote something similar to this in response to a thread posted last month. The poster wanted to add items to a list. The implementation I wrote would send the item to the server in the background, as well as update the list. If these operations weren't supported by the user's browser, a normal form submission would take place.

    A similar implementation will be presented in a separate follow-up. There is no style sheet presented, so the default appearance will be rather bland. There's also the question of whether the input should be part of the results table, or included separately. The answer depends on how the document, as a whole, will be structured, which in turn is affected by how access to the document will be controlled.

    Validation is currently rather crude, at least for the text values. The date and place fields are validated more thoroughly. The former will accept any of yyyy-mm-dd, dd-mm-yyyy, and mm-dd-yyyy. Ambiguous entries that could match either of the latter two formats will be currently treated as month-first, though that can be changed to date-first by passing false as the second argument to the isDate function.

    There is no server-side implementation presented here (so testing has been relatively light). If an "AJAX" request is used, an additional name/value pair will be sent: "mode=ajax". The script will expect one of two response codes in this case. The first is 204 (No Content), which represents a successful update. The second is 409 (Conflict) which indicates a problem detected by the server. The intention is to return this status if the server performs further validation; the message body of the response contains a text message to display to the user via a dialogue box.

    If any other response code is received (including a 1xx, 2xx, or 3xx), it will be considered an error and the form will be submitted with the expectation that the server will return a document that describes the issue in more detail.

    If authentication is performed at the time of the submission (rather than logging in, perhaps), the code might be expanded to receive a 303 (Forbidden) and notify the user.

    Leading and trailing whitespace will be removed client-side, but this should also be repeated on the server. Be careful when choosing control names: only the control value is currently escaped.

    Hope this helps,
    Mike

  5. #5
    Join Date
    Dec 2004
    Location
    UK
    Posts
    2,358
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    HTML Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    
    <html>
        <head>
            <title>Riding results</title>
    
            <script type="text/javascript">
                function addData(form) {
                    var cell, row, rowIndex, tableSection, textNode, httpRequest;
    
                    if ((typeof encodeURIComponent == 'function') && form.submit && document.getElementById
                            && document.createTextNode && (row = document.getElementById('entry-row'))
                            && (typeof (rowIndex = row.sectionRowIndex) == 'number')
                            && (tableSection = row.parentNode) && tableSection.insertRow && tableSection.deleteRow
                            && (textNode = document.createTextNode('Sending request...'))
                            && (httpRequest = getRequestObject()) && (row = tableSection.insertRow(rowIndex))) {
                        if (!(row.insertCell && row.deleteCell && (cell = row.insertCell(-1))
                                && cell.appendChild)) {
                            tableSection.deleteRow(rowIndex);
                            return false;
                        }
                        cell.colSpan = 8;
                        cell.appendChild(textNode);
    
                        var controls = form.elements,
                            body = 'mode=ajax';
    
                        for (var i = 0, n = controls.length; i < n; ++i)
                            if (controls[i].type == 'text')
                                body += '&' + controls[i].name
                                    + '=' + encodeURIComponent(controls[i].value);
    
                        httpRequest.open(form.method, form.action, true);
                        httpRequest.onreadystatechange = function() {
                            if (httpRequest.readyState != 4) return;
                            if (httpRequest.status == 204) {
                                row.deleteCell(0);
                                for (var i = 0, n = controls.length; i < n; ++i)
                                    if (controls[i].type == 'text') {
                                        row.insertCell(-1).appendChild(
                                            document.createTextNode(controls[i].value));
                                        controls[i].value = '';
                                    }
                            } else {
                                tableSection.deleteRow(rowIndex);
                                if (httpRequest.status == 409)
                                    alert(httpRequest.responseText);
                                else form.submit();
                            }
    
                            controls = form
                                = httpRequest
                                = httpRequest.onreadystatechange
                                = row
                                = tableSection
                                = null;
                        };
                        httpRequest.setRequestHeader('Content-Length', body.length);
                        httpRequest.setRequestHeader('Content-Type',
                            'application/x-www-form-urlencoded; charset=utf-8');
                        httpRequest.send(body);
    
                        body = cell
                            = textNode
                            = null;
                        return true;
                    }
                    return false;
                }
    
                function getRequestObject() {
                    var object = null;
    
                    if ((typeof XMLHttpRequest == 'object') || (typeof XMLHttpRequest == 'function'))
                        object = new XMLHttpRequest();
                    else if ((typeof createRequest == 'object') || (typeof createRequest == 'function'))
                        object = createRequest();
                    else if (typeof ActiveXObject == 'function') {
                        /*@cc_on @*/
                        /*@if(@_jscript_version >= 5)
                        try {
                            object = new ActiveXObject('Msxml2.XMLHTTP');
                        } catch(e) {
                            try {
                                object = new ActiveXObject('Microsoft.XMLHTTP');
                            } catch(e) {
                                object = null;
                            }
                        }
                        @end @*/
                    }
                    return object;
                }
    
                function isDate(string, preferMDY) {
                    var match, year, month, date;
    
                    if ((match = /^([1-9][0-9]{3})([.\/-])([0-9]{1,2})\2([0-9]{1,2})$/.exec(string))) {
                        year = +match[1];
                        month = +match[3];
                        date = +match[4];
                    } else if ((match = /^([0-9]{1,2})([.\/-])([0-9]{1,2})\2([1-9][0-9]{3})$/.exec(string))) {
                        year = +match[4];
    
                        if (preferMDY) {
                            month = +match[1];
                            date = +match[3];
                        } else {
                            month = +match[3];
                            date = +match[1];
                        }
                        if (month > 12) {
                            var temp = month;
    
                            month = date;
                            date = temp;
                        }
                    }
                    with (new Date(year, --month, date))
                        if ((month == getMonth()) && (date == getDate())) return true;
                    return false;
                }
    
                function isPositiveInteger(string) {
                    return /^[1-9][0-9]*$/.test(string);
                }
    
                function validate(form) {
                    var controls = form.elements;
    
                    if (!isDate(controls.date.value = controls.date.value.trim(), true)) {
                        alert('Please enter a valid date.');
                        return false;
                    }
                    if (!(controls.city.value = controls.city.value.trim())) {
                        alert('Please enter the city.');
                        return false;
                    }
                    if (!(controls.state.value = controls.state.value.trim())) {
                        alert('Please enter the state.');
                        return false;
                    }
                    if (!(controls.event.value = controls.event.value.trim())) {
                        alert('Please enter the event.');
                        return false;
                    }
                    if (!(controls.type.value = controls.type.value.trim())) {
                        alert('Please enter the type.');
                        return false;
                    }
                    if (!isPositiveInteger(controls.place.value = controls.place.value.trim())) {
                        alert('Please enter the result.');
                        return false;
                    }
                    if (!(controls.horse.value = controls.horse.value.trim())) {
                        alert('Please enter the horse.');
                        return false;
                    }
                    if (!(controls.rider.value = controls.rider.value.trim())) {
                        alert('Please enter the rider.');
                        return false;
                    }
                    return true;
                }
    
                String.prototype.trim = function() {
                    return String(this).replace(/^\s+|\s+$/g, '');
                };
            </script>
        </head>
    
        <body>
            <form action="results" method="post" onsubmit="return validate(this) && !addData(this);">
                <fieldset>
                    <legend>Add result</legend>
    
                    <table>
                        <thead>
                            <tr>
                                <th>Date</th>
                                <th>City</th>
                                <th>State</th>
                                <th>Event</th>
                                <th>Type</th>
                                <th>Place</th>
                                <th>Horse</th>
                                <th>Rider</th>
                            </tr>
                        </thead>
        
                        <tbody>
                            <tr id="entry-row">
                                <td><input name="date" value="" size="10"></td>
                                <td><input name="city" value="" size="20"></td>
                                <td><input name="state" value="" size="3"></td>
                                <td><input name="event" value="" size="15"></td>
                                <td><input name="type" value="" size="15"></td>
                                <td><input name="place" value="" size="3"></td>
                                <td><input name="horse" value="" size="15"></td>
                                <td><input name="rider" value="" size="15"></td>
                            </tr>
                        </tbody>
                    </table>
    
                    <!-- Do NOT name or identify this control "submit" -->
                    <input type="submit" value="Submit">
                </fieldset>
            </form>
        </body>
    </html>
    Last edited by mwinter; 09-26-2006 at 12:13 AM.

  6. #6
    Join Date
    Sep 2006
    Posts
    6
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Ah yes, I understand this implementation is a great idea if I wasn't past that no tipping point. What I have already in place is beyond changing to this code, and my server doesn't support Ajax. Mostly what I want is the ability to add a new row of blank boxes when ever the first field is changed in any way. I have quite a bit of code here, and this is what I am thinking. If I misunderstood your response, please let me know.

    Ok, here it is, I believe I have almost have this figured out now. It is properly doing what I want it to do, although 1 minor thing.

    I am still using the onchange command to drop a new row of input boxes, and the submit is comma separating each column in each row. Perfect, with the simple ASP command instr I can separate each one into an array and then place them in the database. All of this is solved (Thank you Vladdy for the input, the cloning of the row is much better)

    Now what I am stuck with at this point, is I don't want the value of the first box to duplicate in the next set of rows. I have narrowed it down to a specific area, but my Javascript is just a little rusty. (Ok it is actually too rusty for Bondo)

    Code:
    	var miLastID = 1;
    	function addNewElement(sourceCloneID, targetParentID, SourceFieldID){
    		var ndSource = document.getElementById(sourceCloneID);
    		var ndTargetParent = document.getElementById(targetParentID);
    		var ndField = document.getElementById(SourceFieldID);
    		if(ndSource){
    			var ndCloneTarget = ndTargetParent.cloneNode(true);
    			var ndCloneField = ndField.cloneNode(true);
    			ndTargetParent.setAttribute('id', getNextID(ndCloneTarget.id))
    			ndCloneField.setAttribute('id', getNextID(ndField.id))
    			ndTargetParent.appendChild(ndCloneTarget)
    			ndCloneField.setAttribute('value','')
    		}
    	}
    
    	function getNextID(sEdit){
    		var objEdit = new String(sEdit)
    		miLastID = miLastID + 1
    		return objEdit.substr(1, objEdit.length -1) + miLastID
    	}
    Now I have colored some of the lines to make it a little easier to read. The bold, red, SourceFieldID is the id tag in the input field, called 'in1', then I am trying to clone that id (deep) then adding 1 to the id variable with the getNextID function. From here I am then trying to clear the value of that input box. It is only clearing the previous input box. Any suggestions?

    Here is the entire new code, which also can be seen in action at: http://www.jbrownspage.com/form/test.html

    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <title>Testing Database Enteries</title>
    <link href="style.css" rel="stylesheet" type="text/css">
    <script>
    	var miLastID = 1;
    	function addNewElement(sourceCloneID, targetParentID, SourceFieldID){
    		var ndSource = document.getElementById(sourceCloneID);
    		var ndTargetParent = document.getElementById(targetParentID);
    		var ndField = document.getElementById(SourceFieldID);
    		if(ndSource){
    			var ndCloneTarget = ndTargetParent.cloneNode(true);
    			var ndCloneField = ndField.cloneNode(true);
    			ndTargetParent.setAttribute('id', getNextID(ndCloneTarget.id))
    			ndCloneField.setAttribute('id', getNextID(ndField.id))
    			ndTargetParent.appendChild(ndCloneTarget)
    			ndCloneField.setAttribute('value','')
    		}
    	}
    
    	function getNextID(sEdit){
    		var objEdit = new String(sEdit)
    		miLastID = miLastID + 1
    		return objEdit.substr(1, objEdit.length -1) + miLastID
    	}
    
    	function handleEnter (field, event) {
    		var keyCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
    		if (keyCode == 13) {
    			var i;
    			for (i = 0; i < field.form.elements.length; i++)
    				if (field == field.form.elements[i])
    					break;
    			i = (i + 1) % field.form.elements.length;
    			field.form.elements[i].focus();
    			return false;
    		} 
    		else
    		return true;
    	}
    
    	function submitonce(theform){
    		//if IE 4+ or NS 6+
    		if (document.all||document.getElementById){
    			//screen thru every element in the form, and hunt down "submit" and "reset"
    			for (i=0;i<theform.length;i++){
    				var tempobj=theform.elements[i]
    				if(tempobj.type.toLowerCase()=="submit"||tempobj.type.toLowerCase()=="reset")
    				//disable em
    				tempobj.disabled=true
    			}
    		}
    	}
    </script>
    </head>
    
    <body>
    <form name='frmTest' action='test2.asp' method='post' onSubmit="submitonce(this)">
    	<table width="680" align="center">
    		<tr>
    			<td align="center">
    				<strong>Date</strong>
    			</td>
    			<td align="center">
    				<strong>City</strong>
    			</td>
    			<td align="center">
    				<strong>State</strong>
    			</td>
    			<td align="center">
    				<strong>Event</strong>
    			</td>
    			<td align="center">
    				<strong>Type</strong>
    			</td>
    			<td align="center">
    				<strong>Place</strong>
    			</td>
    			<td align="center">
    				<strong>Horse</strong>
    			</td>
    			<td align="center">
    				<strong>Rider</strong>
    			</td>
    		</tr>
    		<tr id='frmTestID1'>
    			<td id="if1">
    			    <input type="text" size="11" maxlength="10" id="in1" name="lblDate" onChange="addNewElement('in1', 'frmTestID1', 'in1')" onkeypress="return handleEnter(this, event)">&nbsp;
    			</td>
    			<td>
    			    <input type="text" name="lblCity" value="" onkeypress="return handleEnter(this, event)">&nbsp;
    			</td>
    			<td>
    				<input type="text" size="3" maxlength="2" name="lblState" value="" onkeypress="return handleEnter(this, event)">&nbsp;
    			</td>
    			<td>
    				<input type="text" name="lblEvent" value="" onkeypress="return handleEnter(this, event)">&nbsp;
    			</td>
    			<td>
    				<input type="text" name="lblType" value="" onkeypress="return handleEnter(this, event)">&nbsp;
    			</td>
    			<td>
    				<input type="text" size="3" maxlength="2" name="lblPlace" value="" onkeypress="return handleEnter(this, event)">&nbsp;
    			</td>
    			<td>
    				<input type="text" name="lblHorse" value="" onkeypress="return handleEnter(this, event)">&nbsp;
    			</td>
    			<td>
    				<input type="text" name="lblRider" value="" onkeypress="return handleEnter(this, event)">&nbsp;
    			</td>
    		</tr>
    		<tr>
    			<td align="center" colspan="8">
    			<input type="submit">
    			</td>
    		</tr>
    	</table>
    </form>

  7. #7
    Join Date
    Dec 2004
    Location
    UK
    Posts
    2,358
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Quote Originally Posted by jbrown1028
    Ah yes, I understand this implementation is a great idea if I wasn't past that no tipping point.
    What point would that be? Your client-side implementation needs to be completely rewritten anyway (you're attaching things in the wrong place: view with Firefox).

    What I have already in place is beyond changing to this code
    What's to change? The control names are a little different, but that just requires a little editing (and I would suggest moving away from that "lbl" prefix - it makes no sense). Your server-side process should already support accepting only a single set of results, so there's no change on that front. As far as I can see, all you'd have to add is a check for the "mode" name/value pair when determining how to respond to the request.

    ... and my server doesn't support Ajax.
    "AJAX" (stupid name) is a client-side feature that allows scripts to communicate with the server over HTTP, just like the browser itself does. If the server can understand HTTP (and as the Web is centred on that protocol, every Web server will), you can use AJAX.


    By the way, disabling the submit button is a bad idea. If the request fails (dropped connection, or whatever) and the user tries to go back using the Back button, they may not be able to resubmit (behaviour varies between browsers in this regard). If you want to prevent duplicate submissions, you should check the values that have previously been submitted. Fiddling with the Enter key is also a bad idea: you change how the user expects their browser to work.

    Mike

  8. #8
    Join Date
    Sep 2006
    Posts
    6
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Ok, per your advise, I redesigned it with your method. First off, I have spent many hours helping others with ASP, and without even a thank you. So being on this side of the fence, I personally want to thank you for your valuable time, and effort, I know what it is like.

    This Asyncronious Java Script and XML (Ajax) is rather new to me, I am unfamiliar with its features and scripting. Plus my JS is pretty rough cut as well.

    May I take up a little more of your time, and learn about the benifiets (only major ones, I can research the complete list) and ask why you perfer it over other means of programming.

    BTW: http://www.jbrownspage.com/form/test3.asp - I added a "last record entered" so she will know where she left off when entering the fields, and I will probably make the one entered editable in the near future, probably with the use of forward and backward buttons, so she can go back and forth through the records so she can fix any mistakes.

    Again, Thank you, and this method is a great start to my "seems like" never ending project.

    Good night,
    Jeff

  9. #9
    Join Date
    Dec 2004
    Location
    UK
    Posts
    2,358
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    I'd like to draw attention to a few minor edits in the script (my previous post has been updated), all of which apply to the addData function.

    Code:
    if (controls[i].type == 'text')
        row.insertCell(-1).appendChild(
            document.createTextNode(controls[i].value));
    should be changed to:

    Code:
    if (controls[i].type == 'text') {
        row.insertCell(-1).appendChild(
            document.createTextNode(controls[i].value));
        controls[i].value = '';
    }
    This clears the input controls once the data has been added successfully.

    Code:
    cell = controls
        = form
        = httpRequest
        = httpRequest.onreadystatechange
        = row
        = tableSection
        = null;
    should be changed to:

    Code:
    controls = form
        = httpRequest
        = httpRequest.onreadystatechange
        = row
        = tableSection
        = null;
    The cell variable can be cleared earlier (in time; later in source).

    Code:
    body = null;
    should be changed to:

    Code:
    body = cell
        = textNode
        = null;
    The textNode variable wasn't cleared at any point, and should have been.


    Quote Originally Posted by jbrown1028
    This Asyncronious Java Script and XML (Ajax) is rather new to me, I am unfamiliar with its features and scripting.
    The XMLHttpRequest object exposes basic HTTP functionality: request methods (though usually limited to HEAD, GET, and POST), setting request headers, sending message bodies, and retrieving the response equivalents. The returned data can be varied: the response code is sometimes enough; the message body may carry text (perhaps in a data exchange format like JSON); or, the data might be an XML document.

    May I take up a little more of your time, and learn about the benifiets (only major ones, I can research the complete list) and ask why you perfer it over other means of programming.
    In general, I don't. In fact, I think most uses of AJAX on the Web that I've seen are abominable, neglecting to reflect the fact that it is not a universally supported feature (the same is true of client-side scripting in general, both of which account for why the code I wrote gracefully degrades), rendering standard navigation controls useless, potential negative effects on cacheability, and more often than not, using it just for the sake of saying: "I used AJAX." This doesn't mean that all uses are bad, but it is a readily abused technology.

    The problems are magnified by the presence of AJAX frameworks, like the one I noticed that you included briefly (for no apparent reason). These tend to commit the same mistakes, only hiding them around a pretty interface. As these frameworks neglect to mention the drawbacks, developers that aren't aware of the issues themselves will be lured by the apparent ease-of-use into something that essentially breaks their site for a proportion of users.

    As for the benefits, they are primarily lighter server load, and lower bandwidth usage. Following a traditional approach, it would be up to the server to regenerate the document and return an updated version in addition to interacting with the file system or communicating with a database server. However, in this case, the client can handle updating the document via scripting, so a complete response is reduced to only a response code (upon success), or a short error message (on predictable failure). Traditional processing is only necessary when the client isn't capable of updating the document, using AJAX, or if an unexpected error occurs.

    I would note that a current disadvantage with the posted implementation is that of concurrency. If some other party adds data, the table won't be updated without reloading the document. Similarly, removing or performing edits to existing entries also won't be shown if a third-party does the editing. This could be worked around quite easily by sending a snapshot of the data back to the client rather than a simple 204 No Content response on success. This would work out rather well if only a subset of all of the data was shown at one time, perhaps by showing results from certain periods, or breaking data across "pages". Thatís probably excessive, in this case. In any case, as this isn't meant for public access (implied by your original description), it's not really something to worry about.


    The markup I posted doesn't have to be followed exactly, though there are two invariants: there will be a table row with the id attribute value, "entry-row", and that row will be a child of a tbody element. The newly added records are added before that row, though even that wouldn't be necessary with some tweaking. Specifically, you can change the rendering of the fieldset (removing the border, padding, and margins, and hiding the legend element), or even remove it (along with the legend element, though the submit button needs to have a block-level ancestor between it and the form element).


    As a final comment, I noticed that your server-side script doesn't seem to perform validation. Though the client-side code does, one should never rely on that. I realise that you might have simplified things during testing, but I did want to make sure that you were aware that this really isnít a good thing for production code.

    Mike

  10. #10
    Join Date
    Dec 2004
    Location
    UK
    Posts
    2,358
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Quote Originally Posted by mwinter
    Code:
    cell = controls
        = form
        = httpRequest
        = httpRequest.onreadystatechange
        = row
        = tableSection
        = null;
    should be changed to:

    Code:
    controls = form
        = httpRequest
        = httpRequest.onreadystatechange
        = row
        = tableSection
        = null;
    An exceedingly late correction, but it's only just been brought to my attention:

    Code:
    controls = form
        = httpRequest
        = row
        = tableSection
        = null;
    Assigning null to the onreadystatechange property raises an exception in MSIE as only function references are acceptable. I have no idea how I didn't notice that.

    Mike

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
  •