Jquery why class must be made empty?

Dear All,
I have a code as below. Each time I press the add button it will create a new row. What I notice is that if I comment this line prot.attr(“class”, “”) it does not work why must I make the class empty then only it works. Secondly when I add a new row it copies the data from the first row always. So I added this line prot.find(“#col4”).attr(“value”, “”); but it does not work either too. Any help please.

<html>
	<head>
		<script src="http://code.jquery.com/jquery-1.5.1.min.js"></script>
		<script>
		$(document).ready(function() {
			var id = 0;
			
			// Add button functionality
			$("table.dynatable button.add").click(function() {
				id++;
				var master = $(this).parents("table.dynatable");
				
				// Get a new row based on the prototype row
				var prot = master.find(".prototype").clone();
				prot.attr("class", "")
				prot.find(".id").attr("value", id);
				//prot.find("#col4").attr("value", "");				
				master.find("tbody").append(prot);
			});
			
			// Remove button functionality
			$("table.dynatable button.remove").live("click", function() {
				$(this).parents("tr").remove();
				
			});
		});
		</script>
		<style>
			.dynatable {
				border: solid 1px #000; 
				border-collapse: collapse;
			}
			.dynatable th,
			.dynatable td {
				background-color:#ccc; 
				font-size:14px;
				font-color:#ffffff;
				font-family:Calibri;
			}
			.dynatable .prototype {
				
			}
		</style>
	</head>
	<body>
		<form action="<?=$_SERVER['PHP_SELF']?>" method="post" name="form1" enctype="multipart/form-data" id=form1 >
		<table class="dynatable">
			<thead>
				<tr>
					<th>ID</th>
					<th>Name</th>
					<th>Col 3</th>
					<th>Col 4</th>
					<th><button class="add">Add</button></th>
				</tr>
			</thead>
			<tbody>
				<tr class="prototype">
					<td><input type="text" name="id[]" value="0" class="id" /></td>
					<td><input type="text" name="name[]" value="" /></td>
					<td><input type="text" name="years" value="" /></td>
					<td><input type="text" name="col4[]" value="" /></td>
					<td><button class="remove">Remove</button>
				</tr>
				
		</table>
		<input class="buttons" type="Submit" name="Submit" value="Submit">
	</form>
	</body>
</html>

First, the course itself doesn’t deal with JQuery, this question should go is better fitted in the main Javascript forum since it is not an example related to the course. My logic is that may confuse other students.

If you want me to move it to the main forum, let me know.

Second, I confess that I don’t understand how it works, even if it is empty.

Why do you have a variable named id++? there is no loop at all. You use ++ when you’re adding up one unit to automatically to the variable (in this case, id) each time Javascript gets to that line of the code, but in your case is only one time, the very beginning.

And the starting value of id is undefined (see that you have a field name id[] in your html code, but not id)

Additionally, you’re naming your input fields as if they were arrays.

<input type="text" name="id[]" value="0" class="id" />

You’re confusing terms here, I think. HTML is not a programming language and you’re a mixing how Javascript communicates with HTML to get the data it needs to do its magic with HTML itself.

HTML is only a MarkUp language (when a coder says that he programs in HTML, you know for sure that a) he doesn’t have a clue what he’s talking about or b) He got the wrong concepts and ideas).

And definitely, you can’t get an array as a result of an input field as it can only hold one value. Giving an array-like name to a field makes no sense. It is not necessary to give array-like names to HTML elements. If the result of the user’s input is an array, Javascript will create it automatically. Then, in Javascript you will call the appropriate value from the array using name_of_variable[index]. But that’s in Javascript, not in HTML

Also, the id attribute from your form tag has not double quotes and you forgot to close your tbody tag.

My first suggestion is that you correct your HTML and make sure that validates. Some of your problems will be due to wrong HTML code. That may affect how Javascript find the nodes to work with, so it is important to start with good code.

Then, we will start from there :wink:

Dear Molona,
Yes you can move it to the main forum no problem. Thank you.

It does if you have several fields and give them all the same name with on the end as that then passes those fields to the server as an array.

In JavaScript you are better off referencing form fields using their id rather than their name. All the form fields will need an id anyway as that’s how you attach their label.

When we stop providing 2st-level support for IE6, there won’t be any other need to use explicit label association will there?

As you said, you will create the array in Javascript (not in the HTML) with the values from various input field. What I’m saying is that it doesn’t make sense (at least to me) to name a HTML input field “name

If it’s only JavaScript interacting with the form then there are better naming schemes. The square brackets on the name are a shim (a workaround), that’s only there to force PHP to treat them as if they were an array.

<input type=“text” name=“name”>
<input type=“text” name=“name”>
<input type=“text” name=“name”>
<input type=“text” name=“name”>

will pass those four fields to the server as an array. The names are there so that those fields can be used when passing the data to the server. It has nothing whatever to do with JavaScript and you are best off not trying to refer to input fields in a server side array like that via their names in JavaScript.

So if for example you are using PHP on the server then that is an array with four entries in it in PHP but not in JavaScript.

That depends on whether you want to be non-semantic by making the input field a part of the label or keep the label and the input field separate.

It’s a useful semantic when there is the need to support browsers like IE6. One of the problems that I see with explicit association is that it introduces far too many unique identifiers to the page. It makes it tempting to access form fields through those unique identifiers, when access to those fields really should be in a controlled manner via the form elements collection instead.

Dear All,
MY actual problem is that I would like to build dynamic rows based on the press of the Add button. Then for each of the row I would like to have validation done e.g. some just allows decimals numbers. So based on you guys experience what is the best suggestion and can you give some examples please? Thank you.

Work out what you want for each row, then crate a function that returns the elements for that row.

bear in mind that these examples are to demonstrate the types of techniques you can use. They are deliberately general to help highlight the techniques involved, and have not be customized to the strict requirements of your own particular situation.

If your intended added row is something like:


<p><label>Username: <input name="username"></p>

You should not put it in your HTML code. Instead, you can create it with this function:


function createFormRow(label, name) {
    var p = document.createElement('p'),
        label = document.createElement('label'),
        text = document.createTextNode(label),
        input = document.createElement('input');
    input.name = name;
    p.appendChild(label);
    p.appendChild(text);
    p.appendChild(input);
    return p;
}
var row = createFormRow('Name: ', 'name');

Then you can use an onclick event on the add button, to add what you need.


<button id="addRow">Add</button>


function addRow() {
    var form = this.form,
        fieldsets = form.getElementsByTagName('fieldset'),
        rowContainer = fieldsets[0],
        row = createFormRow('Name: ', 'name');
    rowContainer.appendChild(row);
}
document.getElementById('addRow').onclick = addRow;

For validation, you could attach a validation function on to the form itself. That validation function would then loop through each row processing them. That way you don’t need to attach any new events on to the form when you add rows.

Dear Paul,
Below is my codes. I dont see the <p> being created even though I have checked the createFormRow function is executed. Then when I press the button it is not calling the function addRow. So I guess your suggestion is use javascript rather than jquery is it. What is the diffrence between them.

<html>
<head>

	&lt;script&gt;
	function createFormRow(label, name) 
	{    
		alert("createForm");
		var p = document.createElement('p'),        
		label = document.createElement('label'),        
		text = document.createTextNode(label),        
		input = document.createElement('input');    
		input.name = name;    
		p.appendChild(label);    
		p.appendChild(text);    
		p.appendChild(input);    
		return p;
	}
	var row = createFormRow('Name: ', 'name');
	function addRow() 
	{    
		alert("addRow");
		var form = this.form,        
		fieldsets = form.getElementsByTagName('fieldset'),        
		rowContainer = fieldsets[0],        
		row = createFormRow('Name: ', 'name');   
		rowContainer.appendChild(row);
	}
		document.getElementById('addRow').onclick = addRow;
	&lt;/script&gt;
	
&lt;/head&gt;
&lt;body&gt;
	&lt;form action="&lt;?=$_SERVER['PHP_SELF']?&gt;" method="post" name="form1" enctype="multipart/form-data" id=form1 &gt;
	
	&lt;button id="addRow"&gt;Add&lt;/button&gt;
	
	
		
&lt;/form&gt;
&lt;/body&gt;

</html>

The code I gave are only samples of an example.

Since you are using jQuery, the type of technique that you might use could be something like this:


$('addRow').click(function () {
    var row = ('<p><label>Name: <input name="name" class="required"></p>');
    $('fieldset:first', this.form).append(row);
});

Assuming that you use the jQuery validation plugin, the validation of the added fields should work right in with your existing validation.

I can now spare the time right now to customize things to your exacting requirements, but perhaps someone else might.

Dear Paul,
I am confuse which to use javascript or jquery what is your advice? How the validation works for jquery must get a separate plugin is it?

Since you are already using jQuery, that seems to be the best option for you.
jQuery is also JavaScript as well. jQuery is just a library of JavaScript functions that help to simplify things such as working with document elements and event handling.

jQuery can have plugins added to it, to help extend its usefulness. One of those plugins is jQuery validation. You don’t have to get the validation plugin, but it can help to reduce large amounts of work for you.

Dear Paul,
If you look into my first post with jquery now everything works fine. When I put the name as “col4” in brackets it captures well in the php when I run it as array? So is that a problem by itself is it? Because I think I better continue with the code which I have just that I dont know how to to include the validation and allow of the column just for decimal places.

I’ll have a look at things tonight to see if there’s some simple advice I can give you on this.

Dear Paul,
Thank you very much for your kind help and will wait for your help.

Getting your script working is fairly straight-forward.

  1. You have a mis-spelling in your script file name. The minjs should be min.js

<script src="http://code.jquery.com/jquery-1.5.1.min.js"></script>

  1. Stop the add button from submitting when you click, by returning false from the end of the click function.

$("table.dynatable button.add").click(function() {
    ...
    return false;
}