I have some tables here, and using this javascript below, I made them hide and show every time a user click on their buttons. What I want to add in to this script, is when someone click on a table's button to show-up, all the other to be hidden. Any idea how can I do this? Thank you in advance!
This is my html code:
<table id="SC1_TH_" class="header_op"><tr><td>
<div id="SC1_BSH_" onClick="SC[1]();" class="hide_button">*</div>OPTION ONE
</td></tr></table>
<div id="SC1_BO_" style="display:dlock;">BLAH BLAH</div>
<table id="SC2_TH_" class="header_cl"><tr><td>
<div id="SC2_BSH_" onClick="SC[2]();" class="show_button">*</div>OPTION ONE
</td></tr></table>
<div id="SC2_BO_" style="display:none;">BLAH BLAH</div>
<table id="SC3_TH_" class="header_cl"><tr><td>
<div id="SC3_BSH_" onClick="SC[3]();" class="show_button">*</div>OPTION ONE
</td></tr></table>
<div id="SC3_BO_" style="display:none;">BLAH BLAH</div>
This is my javascript:
<script type="text/javascript">
var SC = [];
for (var i = 1; i < 10; i++) {
SC[i] = (function(i){
return function(){
var SC_TH = document.getElementById('SC'+i+'_TH_');
var SC_BSH = document.getElementById('SC'+i+'_BSH_');
var SC_BO = document.getElementById('SC'+i+'_BO_');
if (SC_BO.style.display == 'block' || SC_BO.style.display == ''){
SC_TH.className = 'header_cl';
SC_BSH.className = 'show_button';
SC_BO.style.display = 'none';}
else {SC_TH.className = 'header_op';
SC_BSH.className = 'hide_button';
SC_BO.style.display = 'block';}
}})(i);}
</script>
EDIT: In other words, I need something to say, if this button that clicking right now is something all the other to be hidden!!!
Here's a working example with some very simple jQuery (recommended) code.
HTML:
<table><tr><td>
<div class="toggle-button">*</div>OPTION ONE
</td></tr></table>
<div class="toggle">BLAH BLAH</div>
<table><tr><td>
<div class="toggle-button">*</div>OPTION ONE
</td></tr></table>
<div class="toggle">BLAH BLAH</div>
<table><tr><td>
<div class="toggle-button">*</div>OPTION ONE
</td></tr></table>
<div class="toggle">BLAH BLAH</div>
JS:
$(function() {
$('div.toggle').hide();
$('.toggle-button').click(function(){
$('div.toggle').hide();
$(this).closest('table').next('div.toggle').show();
});
});
As #StephenByrne mentioned, I also strongly recommend using an existing component such as jQuery Accordian. It takes minutes to implement and comes with a whole host of themes to chose from and is fully customisable. You could spend hours or days writing your own. Unless it's a learning exercise, it's simply a waste of time. No need to reinvent the wheel.
As you have indicated a strong push towards js-only, here's a working js-only solution.
HTML:
<table id="SC1_TH_" class="header_op"><tr><td>
<div id="SC1_BSH_" onclick="toggle(this);" class="hide_button">*</div>OPTION ONE
</td></tr></table>
<div id="SC1_BO_" style="display:block;">BLAH BLAH</div>
<table id="SC2_TH_" class="header_cl"><tr><td>
<div id="SC2_BSH_" onclick="toggle(this);" class="show_button">*</div>OPTION ONE
</td></tr></table>
<div id="SC2_BO_" style="display:none;">BLAH BLAH</div>
<table id="SC3_TH_" class="header_cl"><tr><td>
<div id="SC3_BSH_" onclick="toggle(this);" class="show_button">*</div>OPTION ONE
</td></tr></table>
<div id="SC3_BO_" style="display:none;">BLAH BLAH</div>
JS:
function toggle(src) {
var id = src.id;
var index = id.substring(2, 3);
var i = 1;
var toggleItem = document.getElementById('SC' + i.toString() + '_BO_');
while (toggleItem != null) {
var bShow = index == i;
var button = document.getElementById('SC' + i.toString() + '_BSH_');
var table = document.getElementById('SC' + i.toString() + '_TH_');
if (bShow) {
toggleItem.style.display = 'block';
toggleItem.className = 'setitemclassname';
button.className = 'setbuttonclassname';
table.className = 'settableclassname';
}
else {
toggleItem.style.display = 'none';
toggleItem.className = 'setitemclassname';
button.className = 'setbuttonclassname';
table.className = 'settableclassname';
}
toggleItem = document.getElementById('SC' + (++i).toString() + '_BO_');
}
}
Inside the while loop when index == i evaluates to true, you know you have the item to show. Add extra logic there to change your class names.
A cleaner solution involves altering your HTML a bit as well - getting rid of the onclick and replacing it with a class (toggleItem) that will allow the javascript to identify the items to be toggled. I also make sure that all the buttons have the class button so they can be identified.
<table id="SC1_TH_" class="header">
<tr>
<td>
<div id="SC1_BSH_" class="button">*</div>OPTION ONE</td>
</tr>
</table>
<div id="SC1_BO_" class="toggleItem">BLAH BLAH</div>
<table id="SC2_TH_" class="header">
<tr>
<td>
<div id="SC2_BSH_" class="button">*</div>OPTION ONE</td>
</tr>
</table>
<div id="SC2_BO_" class="toggleItem">BLAH BLAH</div>
<table id="SC3_TH_" class="header">
<tr>
<td>
<div id="SC3_BSH_" class="button">*</div>OPTION ONE</td>
</tr>
</table>
<div id="SC3_BO_" class="toggleItem">BLAH BLAH</div>
Then in the javascript:
var buttons = document.getElementsByClassName('button'),
toggleItems = document.getElementsByClassName('toggleItem'),
tables = document.getElementsByClassName('header');
for (var i = 0; i < buttons.length; i++) {
buttons[i].onclick = getFunction(toggle, i);
}
// getFunction is needed for reasons to do with variable scope
function getFunction(f, p) {return function() {f(p)}}
function toggle(selected) {
for (var i = 0; i < toggleItems.length; i++) {
toggleItems[i].style.display = i == selected ? '' : 'none';
tables[i].className = i == selected ? 'header open' : 'header closed';
buttons[i].className = i == selected ? 'button show' : 'button hide';
}
}
toggle(0); // initially show only the first one
(This does assume that the buttons and toggle items will be in the same order. If that is not the case you will have to revert to checking their IDs or find some other way to associate the items and buttons.)
(EDITED to include changing class of tables and buttons)
Just hide all of them, then show the one that should become toggled open. This script is not the elegantest solution, but integrates directly in your coding style:
for (var i = 1; i < 10; i++) {
SC[i] = (function(i){
var SC_TH = document.getElementById('SC'+i+'_TH_'),
SC_BSH = document.getElementById('SC'+i+'_BSH_'),
SC_BO = document.getElementById('SC'+i+'_BO_');
return function(action) {
if (!action) action = SC_BO.style.display=="none" ? "show" : "hide";
if (action == "show") {
for (var i=0; i<SC.length; i++)
SC[i]("hide");
SC_TH.className = 'header_op';
SC_BSH.className = 'hide_button';
SC_BO.style.display = '';
} else {
SC_TH.className = 'header_cl';
SC_BSH.className = 'show_button';
SC_BO.style.display = 'none';
}
};
})(i);
}
Related
I have a list of items, generated by PHP that is quite long. I don't want to show this list in a dropdown menu. Instead, I'm using jquery to have users type in a textbox, then filtering from that list based on user input:
Example HTML:
<table id = "table">
<tr>
<td>Select an animal:</td>
<td><input type="text" id = "animal" name="animal" placeholder="Choose an animal...">
<td id="animals">
<span class="animal_list">
<p onclick="insertme('horse')">Horse</p>
</span>
<span class="animal_list">
<p onclick="insertme('goat')">Goat</p>
</span>
<span class="animal_list">
<p onclick="insertme('sheep')">Sheep</p>
</span>
<span class="animal_list">
<p onclick="insertme('cow')">Cow</p>
</span>
</div>
</tr>
</table>
And the CSS to hide the list:
#animals .animal_list {
display: none;
}
JQuery filter:
$(document).ready(function(){
$('#animal').keyup(function() {
var search = this.value.split(';');
$('.animal_list').each(function(index, element) {
var text = $(element).text().toLowerCase();
var show = search.filter(function(e) {
return e != '' && text.indexOf(e.toLowerCase()) >= 0;
}).length > 0;
$(element).toggle(show);
});
});
});
And here's some JavaScript that allows users to click on the option to input it in the textbox:
function insertme(label){
document.getElementById('animal').value = label;
//when selected, hide all of variable 1 list
var list = document.getElementsByClassName("animal_list");
for (var i = 0; i < list.length; i++) {
list[i].style.display = "none";
};
}
This works great as is. However, for my application, the users need to be able to duplicate rows dynamically. My idea was to copy the html from the div (the "animals" div) and repeat it for every row:
function add_row(ID) {
var table = document.getElementById(ID);
var rowCount = table.rows.length;
var row = table.insertRow(rowCount);
// insert a row label
// insert a row label
var col1 = row.insertCell(0);
col1.innerHTML = "Select an animal:"
// second column...
// insert a search box
var col2 = row.insertCell(1);
var element = document.createElement("input");
element.type = "text";
element.name = "animal";
col2.appendChild(element);
// get the existing elements
var existing_list = document.getElementById("animals");
// create new object (so I can delete the first)
var list_copy = existing_list
// delete old list so it's not duplicating jquery effect across all rows
existing_list.remove();
//append list to new row
col2.appendChild(list_copy);
}
However, this doesn't seem to work. The second row doesn't filter based on the list anymore. According to my development console, the div does indeed get deleted from the first row, then inserted in the second row, but the list of items is not displaying based on user input. In other words, the JQuery filtering stops working at the second row.
Any ideas how to fix this? I'm happy to abandon my approach if there's a better way (i.e., better than copying a div to a new row and deleting the div associated with the original row).
(P.S. sorry for slovenly mixing JavaScript with JQuery. I'm a bit of a noob with both).
Putting it all together:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript">
function add_row(ID) {
var table = document.getElementById(ID);
var rowCount = table.rows.length;
var row = table.insertRow(rowCount);
// insert a row label
var col1 = row.insertCell(0);
col1.innerHTML = "Select an animal:"
// second column...
// insert a search box
var col2 = row.insertCell(1);
var element = document.createElement("input");
element.type = "text";
element.name = "animal";
col2.appendChild(element);
// get the existing elements
var existing_list = document.getElementById("animals");
// create new object (so I can delete the first)
var list_copy = existing_list
// delete old list so it's not duplicating jquery effect across all rows
existing_list.remove();
//append list to new row
col2.appendChild(list_copy);
}
function insertme(label){
document.getElementById('animal').value = label;
//when selected, hide all of variable 1 list
var list = document.getElementsByClassName("animal_list");
for (var i = 0; i < list.length; i++) {
list[i].style.display = "none";
};
}
$(document).ready(function(){
$('#animal').keyup(function() {
var search = this.value.split(';');
$('.animal_list').each(function(index, element) {
var text = $(element).text().toLowerCase();
var show = search.filter(function(e) {
return e != '' && text.indexOf(e.toLowerCase()) >= 0;
}).length > 0;
$(element).toggle(show);
});
});
});
</script>
<style type="text/css">
#animals .animal_list {
display: none;
}
</style>
</head>
<body>
<table id = "table">
<tr>
<td>Select an animal:</td>
<td><input type="text" id = "animal" name="animal" placeholder="Choose an animal...">
<td id="animals">
<span class="animal_list">
<p onclick="insertme('horse')">Horse</p>
</span>
<span class="animal_list">
<p onclick="insertme('goat')">Goat</p>
</span>
<span class="animal_list">
<p onclick="insertme('sheep')">Sheep</p>
</span>
<span class="animal_list">
<p onclick="insertme('cow')">Cow</p>
</span>
</div>
</tr>
</table>
<input type="button" onclick="add_row('table')" value = "Add Row">
</body>
</html>
The HTML for each row was incorrect.
Unclosed tags and hanging end tags. I've adjusted it so that the cells are consistent.
id must be unique, so I've changed it to be class="animals", which may be helpful in the future for DOM selection.
changed CSS style #animals -> .animals
It's important that each row is encapsulated, self-contained, and consistent so that DOM traversal can be done reliably. This allows for code related to each DOM node to be self-contained, so you can treat them like components. It will also help with CSS styling.
With this organization, all you have to do is cloneNode(true) the row to add a new one, and for the events traverse within the row to select the DOM nodes you need to target.
I've used Event Delegation to attach a single event to the table that targets every input[name="animals"] node inside it. So all new rows get targeted correctly.
Since all the DOM traversal and event handlers are self-contained for each row, the same event handler can be reused for all nodes.
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript">
function add_row(ID) {
var table = document.getElementById(ID);
var rowCount = table.rows.length;
// (full) clone the last row and append to table
table.appendChild(table.rows[rowCount - 1].cloneNode(true))
}
function insertme(el, label) {
var row = $(el).closest('tr')
row.find('input[name="animal"]')[0].value = label;
//when selected, hide all of variable 1 list
var list = row[0].getElementsByClassName("animal_list");
for (var i = 0; i < list.length; i++) {
list[i].style.display = "none";
};
}
$(document).ready(function() {
// event delegation on table for all inputs with name "animal"
$('#table').on('keyup', 'input[name="animal"]', function(event) {
var search = this.value.split(';');
// traverse DOM to find containing row, then search for animal list nodes
$(this).closest('tr').find('.animal_list').each(function(index, element) {
var text = $(element).text().toLowerCase();
var show = search.filter(function(e) {
return e != '' && text.indexOf(e.toLowerCase()) >= 0;
}).length > 0;
$(element).toggle(show);
});
});
});
</script>
<style type="text/css">
.animals .animal_list {
display: none;
}
</style>
</head>
<body>
<table id="table">
<tr>
<td>Select an animal:</td>
<td><input type="text" name="animal" placeholder="Choose an animal..."></td>
<td class="animals">
<span class="animal_list">
<p onclick="insertme(this,'horse')">Horse</p>
</span>
<span class="animal_list">
<p onclick="insertme(this,'goat')">Goat</p>
</span>
<span class="animal_list">
<p onclick="insertme(this,'sheep')">Sheep</p>
</span>
<span class="animal_list">
<p onclick="insertme(this,'cow')">Cow</p>
</span>
</td>
</tr>
</table>
<input type="button" onclick="add_row('table')" value="Add Row">
</body>
</html>
I need a vanilla JS way to count the number of hidden divs on a page.
I have three divs with inline styles display: none. I thought this would work, but no luck:
var hiddenContainers = (document.getElementsByClassName(".emp-container").style.display == "none").length;
I have tried several solutions from SO and found a few JQuery ones that were successful, but what I'm writing needs to be done exclusively in regular old JavaScript.
EDIT: This works, but it seems like an unnecessarily roundabout way to get what I want:
var hiddenContainers = [];
var containers = document.querySelectorAll(".emp-container");
for (var i = 0; i < containers.length; i++) {
if (containers[i].style.display == "none") {
hiddenContainers.push(containers[i]);
}
}
function countclick(){
var m = document.querySelectorAll('.divs[style*="display:none;"]').length;
document.getElementById('count').innerHTML = "Hidden Divs: "+m;
}
<div class='divs' style="display:none;">a</div>
<div class='divs' style="">b</div>
<div class='divs' style="">c</div>
<div class='divs' style="display:none;">d</div>
<div class='divs' style="">e</div>
<div class='divs' style="display:none;">f</div>
<hr/>
<span id="count">Hidden Divs: 0</span><br/>
<button onclick='countclick();'>Count</button>
I have 1-n <div class="project"> elements which can open their respective table with use of .collapse class. I filter the text content in every table to hide or show its content. Now I count the number of matching elements for every table. I want to display the value of the counter in every respective <span>of the <div> element. Someone may knows how I can do that?
My HTML:
<div class="project">
<div class="project-Content">
<div style="margin-top:10px; margin-bottom:10px; margin-left:10px">
<a data-toggle="collapse" data-target="#vw" style="cursor:pointer;">
<!--I WANT TO DISPLAY IT IN THE () of the span-->
<b>Volkswagen <span>()</span></b>
</a>
</div>
</div>
<div class="collapse" id="vw">
<table class="table table-striped table-hover">
<tr class="carsName">
<td>Golf</td>
</tr>
<tr class="carsName">
<td>Polo</td>
</tr>
<tr class="carsName">
<td>Passat</td>
</tr>
</table>
</div>
</div>
<!-- ...SOME MORE OF <div class="Project">... -->
<input type="text" class="form-control filter" id="testFilter" name="testFilter" placeholder="Search"/>
My JQuery:
//Filter and Count matching elements
$('#testFilter').keyup(function () {
var filter_array = new Array();
var filter = this.value.toLowerCase(); // no need to call jQuery here
filter_array = filter.split(' '); // split the user input at the spaces
var arrayLength = filter_array.length; // Get the length of the filter array
$('.collapse, .in').each(function() {
// counter for visible tr-elements
var nrOfVisibleCars = 0;
$(this).find("tr").each(function() {
var _this = $(this);
var car = _this.find('td').text().toLowerCase();
var hidden = 0; // Set a flag to see if a tr was hidden
// Loop through all the words in the array and hide the tr if found
for (var i=0; i<arrayLength; i++) {
if (car.indexOf(filter_array[i]) < 0) {
_this.hide();
hidden = 1;
}
}
// If the flag hasn't been tripped show the tr
if (hidden == 0) {
_this.show();
//count all visible tr-elements
nrOfVisibleCars++;
}
});
// Show for every closed Collapse (.collapse) or open Collapse (.in) the counter
alert(nrOfVisibleCars);
// HERE I NEED SOME NEW CODE TO SHOW 'nrOfVisibleCars'
// IN <span>()</span> OF EVERY RESPECTIVE <div>
});
});
Thanks in advance for the help.
Please try this
//Filter and Count matching elements
$('#testFilter').keyup(function () {
var filter_array = new Array();
var filter = this.value.toLowerCase(); // no need to call jQuery here
filter_array = filter.split(' '); // split the user input at the spaces
var arrayLength = filter_array.length; // Get the length of the filter array
$('.collapse, .in').each(function() {
// counter for visible tr-elements
var nrOfVisibleCars = 0;
var $parent = $(this).parent();
$(this).find("tr").each(function() {
var _this = $(this);
var car = _this.find('td').text().toLowerCase();
var hidden = 0; // Set a flag to see if a tr was hidden
// Loop through all the words in the array and hide the tr if found
for (var i=0; i<arrayLength; i++) {
if (car.indexOf(filter_array[i]) < 0) {
_this.hide();
hidden = 1;
}
}
// If the flag hasn't been tripped show the tr
if ($(this).is(':hidden')) {
//count all visible tr-elements
nrOfVisibleCars++;
}
});
// HERE I NEED SOME NEW CODE TO SHOW 'nrOfVisibleCars'
$parent.find('span').html($('tr').length - nrOfVisibleCars);
});
});
DEMO
I'm building a single page application in which i have a html table and i need to implement a search box that loops through the rows of the table and hides the ones that don't match the search-box text. The problem is that being a SPA all the javascript code i found on the internet that does this thing is based on $(document).ready(function() so it doesn't work. I tried the folowing approach:
In my viewmodel.js i have:
function filter2(search, tblData) {
window.phrase = document.getElementById(search).value;
var words = window.phrase.toLowerCase().split(" ");
var table = document.getElementById(tblData);
var ele;
for (var r = 1; r < table.rows.length; r++) {
ele = table.rows[r].innerHTML.replace(/<^>+>/g, "");
var displayStyle = 'none';
for (var i = 0; i < words.length; i++) {
if (ele.toLowerCase().indexOf(words[i]) >= 0)
displayStyle = '';
else {
displayStyle = 'none';
break;
}
}
table.rows[r].style.display = displayStyle;
}
}
and in my view.html:
<input type="text" id="search" placeholder="Search..." data-bind="click: filter2"/>
,where tblData is my html table and search is my searchbox.
This is not working, if anyone has any idea please share. Thank you in advance.
EDIT: This is the html for my table:
<table id="tblData"class="table table-striped" >
<thead>
<tr><th>Domain Name</th><th>Full name</th><th style="text-align:center">Email</th></tr>
</thead>
<tbody data-bind="foreach: employee">
<tr>
<td style="width:100px" data-bind="text: username"></td>
<td style="width:120px"data-bind="text: fullName"></td>
<td style="text-align:right;width:120px" data-bind="text: email"></td>
</tr>
</tbody>
</table>
Don't do vanilla javascript DOM manipulations if you use knockout. Filtering is quite simple, you just have to keep an observableArray of all your elements, and declare a computed that returns the filtered elements.
For a simple example, see this model:
function Model() {
var self = this
this.input = ko.observable("");
this.all = ko.observableArray(["John","James","Mark"]);
this.filtered = ko.computed(function() {
return ko.utils.arrayFilter(self.all(), function(item) {
return item.indexOf(self.input()) !== -1;
});
});
}
with this HTML:
<input placeholder="Type to filter" data-bind="value: input, valueUpdate: 'keyup'"/>
<ul data-bind="foreach: filtered">
<li data-bind="text: $data"></li>
</ul>
You can test it here: http://jsfiddle.net/qFYbW/1/
I have a code like this...
<html>
<head>
<title>test</title>
<script type="text/javascript">
var counter = 2;
var idCounter= 3;
function addNew() {
if(counter<=5){
// Get the main Div in which all the other divs will be added
var mainContainer = document.getElementById('mainContainer');
// Create a new div for holding text and button input elements
var newDiv = document.createElement('div');
newDiv.id='divs'+counter;
// Create a new text input
var newText = document.createElement('input');
var newText1 = document.createElement('input');
newText.type = "input";
newText.id="ans"+(idCounter);
idCounter++;
newText1.type = "input";
newText1.id="ans"+(idCounter);
idCounter++;
// newText.value = counter;
// Create a new button input
var newDelButton = document.createElement('input');
newDelButton.type = "button";
newDelButton.value = "Remove";
// Append new text input to the newDiv
newDiv.appendChild(newText);
newDiv.appendChild(newText1);
// Append new button input to the newDiv
newDiv.appendChild(newDelButton);
// Append newDiv input to the mainContainer div
mainContainer.appendChild(newDiv);
counter++;
// Add a handler to button for deleting the newDiv from the mainContainer
newDelButton.onclick = function() {
mainContainer.removeChild(newDiv);
counter--;
}
}
else{
alert('Only 5 rows are allowed');
}}sss
function removeRow(divId){
mainContainer.removeChild(divId);
counter--;
}
</script>
</head>
<body >
<div id="mainContainer">
<div><input type="button" value="Add New Row" onClick="addNew()"></div>
<div id="div1"><input type="text" id="ans1"><input type="text" id="ans2"><input type="button" value="Remove" onClick ="javascript:removeRow(div1);"></div>
</div>
</body>
</html>
I want to achieve the same using jQuery.I also need the values entered in each of these textboxes.Please help.
Okay, because I had nothing better to do, and, to be honest, I was curious, I put this together. As implied in my comment, above, I didn't particularly like the way you had it laid out, so I used the following (x)html:
<form action="#" method="post">
<fieldset id="rows">
<ul>
<li>
<input type="text" id="ans1" name="ans1" />
<input type="text" id="ans2" name="ans2" />
</li>
</ul>
</fieldset>
<fieldset id="controls">
<button id="addRow">add</button>
<button id="removeRow" disabled>remove</button>
</fieldset>
</form>
With the following jQuery (although I've clearly not optimised, or refined it, but it should meet your requirements):
$(document).ready(
function(){
$('#addRow').click(
function() {
var curMaxInput = $('input:text').length;
$('#rows li:first')
.clone()
.insertAfter($('#rows li:last'))
.find('input:text:eq(0)')
.attr({'id': 'ans' + (curMaxInput + 1),
'name': 'ans' + (curMaxInput + 1)
})
.parent()
.find('input:text:eq(1)')
.attr({
'id': 'ans' + (curMaxInput + 2),
'name': 'ans' + (curMaxInput + 2)
});
$('#removeRow')
.removeAttr('disabled');
if ($('#rows li').length >= 5) {
$('#addRow')
.attr('disabled',true);
}
return false;
});
$('#removeRow').click(
function() {
if ($('#rows li').length > 1) {
$('#rows li:last')
.remove();
}
if ($('#rows li').length <= 1) {
$('#removeRow')
.attr('disabled', true);
}
else if ($('#rows li').length < 5) {
$('#addRow')
.removeAttr('disabled');
}
return false;
});
});
JS Fiddle demo of the above
I'm not, however, sure what you mean by:
I also need the values entered in each of these textboxes.
If you can explain what that means, or how you want them to be available (and, ideally, why they're not already available to you) I'll do my best to help.
I have a solution which will help you use here is the code
<script type="text/javascript" src="js/jquery.js"></script>
<script type = 'text/javascript'>
var newRowNum = 1;
var project_id ;
$(function() {
$('#addnew').click(function()
{
newRowNum++; // This is counter
//var i = 0;
///////// <a> <td> <tr>
var addRow = $(this).parent().parent();
///////// In the line below <tr> is created
var newRow = addRow.clone();
$('input', addRow).val('');
$('td:first-child', newRow).html();
$('td:last-child', newRow).html('<a href="" class="remove span">Remove<\/a>');
var newID = 'project'+newRowNum;
var add = 'description'+newRowNum;
newRow.children().children().first('input').attr('id', newID).attr('name', newID);
newRow.children().children().eq(1).attr('id', add).attr('name', add);
$('#table').find('tr:last').after(newRow);
$('a.remove', newRow).click(function()
{
newRowNum--;
$('#table').find('tr:last').remove();
return false;
});
return false;
});
});
</script>
<table width="75%" border="0" align = "center" id = 'table'>
<tr>
<td align = "center">Project </td>
<td align = "center">Description</td>
<td align = "center">Add Row</td>
</tr>
<tr>
<td align = "center"><input type = 'text' size = '35'name = 'project[]' id="project" ></td>
<td align = "center"><input type = 'text'size = '55' name = "description[]" id = 'description'></td>
<td width = '10%'><a id="addnew" href= "" class = 'span'>Add</a></td>
</tr>
</table>
You can also give each text box unique name if you change code like this and changing these two variables
var newID = 'project'+newRowNum;
var add = 'description'+newRowNum;
if you use the first method i shown here it will be easy to post data using array. That's all.