PDA

View Full Version : Adding text to a list on the same webpage



new_to_js
08-24-2006, 03:08 AM
I've been trying to find a html javascript coding to display the function shown in the image file. Anyone came across anything like it before? or written one like it before?
http://static.flickr.com/76/223380695_53c4fee173.jpg

mburt
08-24-2006, 03:14 AM
Try this:


<html>
<head>
<script type="text/javascript">
var i = 2
function add() {
i=i+1
var newitem = document.createElement("SPAN")
newitem.className="listitem"
var text = document.createTextNode(i+". "+inputfld.value)
list.appendChild(newitem).appendChild(text)
}
</script>
<style type="text/css">
.listitem {
display:block;
font:11px verdana ref
}
</style>
</head>
<body>
<div id="list">
<span class="listitem">1. test</span>
<span class="listitem">2. test</span>
</div>
<input type="text" id="inputfld"><input type="button" value="Add" onclick="add()">
</body>
</html>

terkini
08-24-2006, 03:51 AM
Try this:


<html>
<head>
<script type="text/javascript">
var i = 2
function add() {
i=i+1
var newitem = document.createElement("SPAN")
newitem.className="listitem"
var text = document.createTextNode(i+". "+inputfld.value)
list.appendChild(newitem).appendChild(text)
}
</script>
<style type="text/css">
.listitem {
display:block;
font:11px verdana ref
}
</style>
</head>
<body>
<div id="list">
<span class="listitem">1. test</span>
<span class="listitem">2. test</span>
</div>
<input type="text" id="inputfld"><input type="button" value="Add" onclick="add()">
</body>
</html>
This is great! To prevent abuses, is it possible to prevent people from posting their name twice, and also is it possible to prevent certain names from being posted. e.g. "John" is banned from participating in the trip so when John type in his name, his name will simply not appear.

jscheuer1
08-24-2006, 05:08 AM
I have a question. Do you want subsequent users to see the added content? If so, you will need to go server side with something like PHP or ASP and probably a data base of some sort. These type of changes, if made by javascript alone, will disappear as soon as the page is reloaded.

mburt
08-24-2006, 03:13 PM
Seeings it was posted in the JavaScript section, I assumed it only involved JavaScript :)

Twey
08-24-2006, 03:40 PM
Since it's posted in the Javascript section, it's reasonable to assume the OP thinks the task only involves Javascript. Unfortunately, the OP doesn't always know best. :)

mwinter
08-24-2006, 07:34 PM
Try this:

Why on Earth did you create your own list-like "element" when ordered lists are already a feature of HTML?



<html>

It sets a good example if code samples follow best practice. That includes using a document type declaration...



<head>

...and a title element.



<script type="text/javascript">
var i = 2

If you'd used a list, tracking the next list number wouldn't be necessary, and this variable would become redundant.



function add() {
i=i+1

Why not the increment (post- or pre-) operator (++i)?



var newitem = document.createElement("SPAN")

You should determine whether the createElement method is supported before calling it. You should also check the return value as not all browsers are equally dynamic; some will only create certain elements.



var text = document.createTextNode(i+". "+inputfld.value)

Checking for support of the createTextNode method is also a very good idea. The same applies to the appendChild method, below.



list.appendChild(newitem).appendChild(text)

From where did you get object reference for the list variable. I hope you weren't trying to use MSIE's poor habit of introducing elements with id attribute values as global variables. Not all browsers do that (and good for them).



.listitem {
display:block;

Again, this wouldn't have been necessary if you'd just used a list.



font:11px verdana ref

Don't use pixel lengths for font sizes, and don't use Verdana if you feel the need to reduce its size. And what's that "ref" all about? A list of font families should end with a generic family (sans-serif, in this case).


As the OP wasn't very specific, I wrote an over-the-top client-side implementation. It attempts to use the XMLHttpRequest object to send the new value to the server after checking that it isn't currently in the list. However, if that fails, or manipulation of the document tree isn't possible, it will fall back to a simple POST submission. If only a client-side implementation is necessary, then the AJAX-related code can simply be replaced with the DOM manipulation code that it would eventually call.

Comparisons with existing list items is performed case-insensitively. Leading and trailing whitespace is removed from any entered values (something that would also need to repeated server-side).



<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Adding to lists.</title>

<script type="text/javascript">
var global = this;

function getRequestObject() {
var object = null;

if ((typeof global.XMLHttpRequest == 'object')
|| (typeof global.XMLHttpRequest == 'function'))
object = new XMLHttpRequest();
else if ((typeof global.createRequest == 'object')
|| (typeof global.createRequest == 'function'))
object = createRequest();
else if (typeof global.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 validate(form) {
var value = form.elements['new-item'].value.trim(),
list;

if (!value) {
alert('Please enter a name.');
return false;
}
if (document.getElementById && (list = document.getElementById('list'))) {
if (hasMatchingItem(list, value)) {
alert('The value, "' + value + '", already exists.');
return false;
}
return addItem(list, value, form);
}
return true;
}

function addItem(list, value, form) {
var control, httpRequest, item, textNode;

if (document.createElement && document.createTextNode && list.insertBefore
&& form.submit && (httpRequest = getRequestObject())
&& (control = document.getElementById('input'))
&& (item = document.createElement('li')) && item.appendChild
&& (textNode = document.createTextNode(value))) {
var body = 'mode=thick&new-item=' + escape(value);

httpRequest.open('POST', form.action, true);
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState == 4) {
if (httpRequest.status == 204) {
item.appendChild(textNode);
list.insertBefore(item, control);
} else if (httpRequest.status == 409)
alert(httpRequest.responseText);
else form.submit();
control = form
= httpRequest
= item
= list
= textNode
= null;
}
};
httpRequest.setRequestHeader('Content-Length', body.length);
httpRequest.setRequestHeader('Content-Type',
'application/x-www-form-urlencoded');
httpRequest.send(body);
return false;
}
return true;
}

function hasMatchingItem(list, value) {
if (list.getElementsByTagName) {
var items = list.getElementsByTagName('li');
value = value.toLowerCase();

for (var i = 0; i < items.length - 1; ++i) {
var item = items[i];

if (item.firstChild && (item.firstChild.data.toLowerCase() == value))
return true;
}
}
return false;
}

String.prototype.trim = function() {return String(this).replace(/^\s+|\s+$/g, '');};
</script>
</head>

<body>
<form action="list-handler" method="post" onsubmit="return validate(this);">
<ol id="list">
<li id="input">
<input type="text" name="new-item" value="">
<input type="submit" value="Add">
</li>
</ol>
</form>
</body>
</html>

When the client sends the data transparently, it adds a parameter named "mode" with the value "thick" (as the browser is attempting to do much of the work, it's acting as a thick client). This parameter is absent when the server is expected to return a new document containing the added item.

In "thick-client" mode, there are only two responses expected from the server: 204 and 409. The 204 No Content response indicates success; the data has been stored by the server and there were no problems. The 409 Conflict response is used to mean that the item sent conflicts with existing data; the body of the response contains the error message. Any other response is considered an error, and the browser will revert to simple form submission.

Mike

blm126
08-24-2006, 08:11 PM
As the OP wasn't very specific, I wrote an over-the-top client-side implementation.
That is an understatement. Wow. However, wouldn't 201 Created be better than 204?

mwinter
08-24-2006, 08:36 PM
However, wouldn't 201 Created be better than 204?

No. The intent of 201 is to signify that the server created a resource. That new resource should be accessible using the URI returned in the response. In this case, the server would be updating a file or database to include the new item.

If you haven't already, read 9.5 POST, 9.6 PUT, and 10.2.2 201 Created in RFC 2616, and notice the emphasis on resource creation. Then consider the definition of "resource" given in 1.3 Terminology:


A network data object or service that can be identified by a URI, as defined in section 3.2. Resources may be available in multiple representations (e.g. multiple languages, data formats, size, and resolutions) or vary in other ways.

Mike

blm126
08-24-2006, 08:49 PM
Ah, I see. I didn't realize that a resource needed to have a URI.