Dynamically add columns to html table and sending input to database - javascript

I have a table in an HTML form in which the total columns depends on the user. The additional columns are added with a button click. The rows that come with the added columns are supposed to be array inputs which will be sent to MySQL database once the form is submitted.
I am new at javascript and jquery. I did some search on the internet and found a lot of 'creating HTML tables with dynamic rows/columns' related stuff but none of them were related to having input cells in the rows that came with the dynamic columns and sending them to the database.
I came across this link that gave me a headstart but I am stuck: Dynamic columns - Stack Overflow
In the image above, the columns 'Bus1 kW' etc. are added when a button is clicked, including the button in the screenshot would just make the image unnecessarily longer. The rows to all added columns are supposed to be input fields, the reason I can change the value of those fields is that I enabled 'content editable'. I tried adding input fields that are arrays but when I do so the button that adds columns stops working.
How do I make the rows that come with the dynamic columns to have input fields as arrays so that I can access them in PHP? How do I add this: <input type="text" required="required" name="Bus1_kW[]"> to the rows that come with the dynamic columns in such a way that all rows for column lets say 'Bus1 kW' are stored in an array that I can access in PHP when I submit the form?
Here is the script code that is producing the image above (jquery):
<script type="text/javascript">
var i = 1;
// This part works fine
$("#addColumn").click(function () {
$("tr:first").append("<td>Bus"+i+" kW</td>");
$("tr:not(:first)").append("<td contenteditable="+true+"> </td>");
i = i+1;
});
</script>
This is what I tried to do but it's not working:
<script type="text/javascript">
var i = 1;
// This is what I tried to do but it's not working
$("#addColumn").click(function () {
$("tr:first").append("<td>Bus"+i+" kW</td>");
$("tr:not(:first)").append("<input type="+text+" required="+required+" name="+"Bus"+i+"_kW[]"+">");
i = i+1;
});
</script>
This is the table inside the HTML form:
<table id="busDataTable" class="form-group-sm" border="1">
<tbody>
<tr>
<th>Interval Number</th>
<th>Time Interval (30min)</th>
</tr>
<tr> <td>1</td> <td>0</td> </tr> <!-- -->
<tr> <td>2</td> <td>0.5</td> </tr> <!-- -->
<tr> <td>3</td> <td>1</td> </tr> <!-- -->
<tr> <td>4</td> <td>1.5</td> </tr> <!-- -->
<!-- Table rows continue until 48 rows -->
</tbody> <button id="addColumn">Add Column</button>
</table>
I would appreciate any solution/help, jquery or javascript, I just barely got into javascript and do not know which would be preferred and why between javascript and jquery. Thank you for your time

The button to add rows shouldn't be between the closing tags </tbody> and </table> as this is invalid HTML. I just moved it before the table. I adjusted the append() function by adding a surrounding <td> for the input field and moving all static content (text and required) to the correct place as text and required are no variables.
var i = 1;
$("#addColumn").click(function() {
$("tr:first").append("<td>Bus" + i + " kW</td>");
$("tr:not(:first)").append("<td><input type='text' required='required' name='Bus" + i + "_kW[]'></td>");
i = i + 1;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="addColumn">Add Column</button>
<table id="busDataTable" class="form-group-sm" border="1">
<tbody>
<tr>
<th>Interval Number</th>
<th>Time Interval (30min)</th>
</tr>
<tr>
<td>1</td>
<td>0</td>
</tr> <!-- -->
<tr>
<td>2</td>
<td>0.5</td>
</tr> <!-- -->
<tr>
<td>3</td>
<td>1</td>
</tr> <!-- -->
<tr>
<td>4</td>
<td>1.5</td>
</tr> <!-- -->
<!-- Table rows continue until 48 rows -->
</tbody>
</table>

Related

Can anyone help me convert a table such as this example into a dynamic one in Javascript by using the for loop?

Can anyone help me learn how to convert an HTML table into a dynamic Javascript table using the for loop? This is an example I found in my book and wanted to see how I could go about doing this.
Heading There is sections of the table that need to have the rows combined and he columns combined. I have been struggling with this for some time. Any help would be appreciated. I did not include the CSS portion of the code only the table.
<html>
<body>
<table class="table">
<tr>
<th colspan= "3" class= "MH">Conversion Tables</th>
</tr>
<tr>
<th rowspan="3" class="heading1">Meters to
<br />Feet</th>
<td>1 meter</td>
<td>3.28 feet</td>
</tr>
<tr class="difrow">
<td>50 meters</td>
<td>164.04 feet</td>
</tr>
<tr>
<td>100 meters</td>
<td>328.08 feet</td>
</tr>
<tr class="difrow">
<th rowspan="3" class="heading1">Kilometers to
<br />Miles</th>
<td>1 kilometer</td>
<td>0.62 miles</td>
</tr>
<tr>
<td>50 kilometers</td>
<td>31.07 miles</td>
</tr>
<tr class="difrow">
<td>100 kilometers</td>
<td>62.14 miles</td>
</tr>
</table>
</body>
</html>
you can add id attribute to table tag then call a javascript method on page load:
<table class="table" id="tableId">
function createRows(){
var items = "<tr><td></td></tr>...";
document.getElementById("tableId").innerHTML = items;
}
in javascript method you can use for to generate table rows.

Change table header with response to button click ,where rows update using JSTL for loop

<div class="btn-group" >
<button type="submit" onclick="display">DISPLAY SCHEDULE</button>
<button type="submit" onclick="open" >OPEN SCHEDULE</button>
</div>
<table class="table table-striped responsive">
<!-- column headers -->
<% Result result = (Result)request.getAttribute("result");%>
<thead>
<tr>
<th id="change"> Transfer Switch </th>
</tr>
</thead>
<!-- column data -->
<tbody>
<c:forEach var="row" items="${result.rows}">
<tr>
<td>
<c:out value="${row.Schedule_ID}"/>
</td>
</tr>
</c:forEach>
</tbody>
</table>
I am trying to change my table header name with button click, so what i did was added a simple java script as follows.
<script>
function display(){
document.getElementById("change").innerHTML="display"
}
function open(){
document.getElementById("change").innerHTML="open"
}
</script>
but since my JSTL result row gets updated for every loop my header changed too thus ending myself with the same header Transfer switch.
Can i solve this using Jquery on load ??, not sure how to use it.
I heard of solutions to make 2 tables but that's not the solution i am looking for since the table is responsive uses bootstrap and also has some buttons in its rows .
Two things I have changed from your code, now it looks fine,
Don't use the JS reserved keyword(s) like open. Use openSchedule() instead.
For better practice, Use span tag for change the text instead of giving id to th.
Your HTML with rendered table rows (Assume I could not able to reproduce jsp values here.)
<div class="btn-group" >
<button type="button" onclick="displaySchedule()">DISPLAY SCHEDULE</button>
<button type="button" onclick="openSchedule()" >OPEN SCHEDULE</button>
</div>
<table class="table table-striped responsive">
<thead>
<tr>
<th><span id="change">Transfer Switch</span></th>
</tr>
</thead>
<tbody>
<!-- Here I assumed two rows, since It's JSP value I couldn't reproduce -->
<tr>
<td>Text1</td>
</tr>
<tr>
<td>Text2</td>
</tr>
</tbody>
</table>
Your Script,
window.displaySchedule = function(){
document.getElementById("change").innerHTML="display";
}
window.openSchedule = function(){
document.getElementById("change").innerHTML="open";
}
See fiddled demo here for live sample.

handle mdl table check box

I'm using material desigin lite in my website
I have implemented this example:
http://www.getmdl.io/components/index.html#tables-section
<table class="mdl-data-table mdl-js-data-table mdl-data-table--selectable mdl-shadow--2dp">
<thead>
<tr>
<th class="mdl-data-table__cell--non-numeric">Material</th>
<th>Quantity</th>
<th>Unit price</th>
</tr>
</thead>
<tbody>
<tr>
<td class="mdl-data-table__cell--non-numeric">Acrylic (Transparent)</td>
<td>25</td>
<td>$2.90</td>
</tr>
<tr>
<td class="mdl-data-table__cell--non-numeric">Plywood (Birch)</td>
<td>50</td>
<td>$1.25</td>
</tr>
<tr>
<td class="mdl-data-table__cell--non-numeric">Laminate (Gold on Blue)</td>
<td>10</td>
<td>$2.35</td>
</tr>
</tbody>
</table>
my question is how to handle the check box in the table , they are added by the class : .mdl-data-table--selectable
there is no Id or class for them so what is the way to use them in javascript or sql server (deleting rows what i'm trying to implement)
You could check if they're are clicked with a jquery on method, why am not using the normal .click is to because of event delegation. Jquery docs do a perfect job explaining that.
Before I explain how I did it I will have a snippet that you can immediately play with under my explanation.
I basically used inspect element to look at the tables structure and it looked something like this
<tr>
<td>
<label>clickable checkbox code</label>
</td>
<td>Acrylic</td>
<td>25</td>
<td>$2.90</td>
With that information, we can do a lot. I personally used this to listen to clicks.
$(document).on("click",".mdl-checkbox__ripple-container.mdl-js-ripple-effect.mdl-ripple--center", function() { /* Code here*/ });
And with jquery parents & children methods we can achieve a lot, like read the content of all the table data with the following code in our click event listener
foo = $(this).parents().eq(2).children().text();
Or we can perhaps delete a whole row?
$(this).parents().eq(2).fadeOut();
What that would do is, look at the clicked checkbox using "this" as reference. Then go to levels up and remove a whole row.
<tr><!-- eq 2 -->
<td> <!-- eq 1 -->
<label>clickable checkbox code</label>
</td>
<td>Acrylic</td>
<td>25</td>
<td>$2.90</td>
Or we can check for the content of a specific child like this
var secondChildContent = $(this).parents().eq(2).children().eq(2).text();
Where secondChildContent will be return the content. You can always change the eq (The one after children) value to the desired child number you want. In the following case secondChildContent would return "Acrylic"
<tr>
<td> <!-- eq 1 -->
<label>clickable checkbox code</label>
</td>
<td>Acrylic</td> <!-- eq 2 -->
<td>25</td> <!-- eq 3 -->
<td>$2.90</td> <!-- eq 4 -->
$(document).ready(function() {
$(document).on("click", ".mdl-checkbox__ripple-container.mdl-js-ripple-effect.mdl-ripple--center", function() {
//Removing row
$(this).parents().eq(2).delay(500).fadeOut(300);
var secondChildContent = $(this).parents().eq(2/*child number*/).children().eq(2).text();
var allChildrenContent = $(this).parents().eq(2).children().text();
var parentID = $(this).parents().eq(2).attr('id');
//Removing table on click of first checkbox
if (parentID == "header") {
$("#mdlTable").fadeOut(1000);
$("#log").html("<b>Table removed!</b>");
} else {
//Don't pay attention to this
$("#log").html(
"<b>Second child content is: </b>" + secondChildContent +
"<br><b>All children content is: </b>" + allChildrenContent
)
}
});
});
#log,
#mdlTable {
margin: 1% 1% 1% 1%;
}
<!DOCTYPE html>
<html>
<head>
<title>Table</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<link rel="stylesheet" href="https://storage.googleapis.com/code.getmdl.io/1.0.4/material.indigo-pink.min.css">
<script src="https://storage.googleapis.com/code.getmdl.io/1.0.4/material.min.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
</head>
<body>
<table id="mdlTable" class="mdl-data-table mdl-js-data-table mdl-data-table--selectable mdl-shadow--2dp">
<thead>
<tr id="header">
<th class="mdl-data-table__cell--non-numeric">Material</th>
<th>Quantity</th>
<th>Unit price</th>
</tr>
</thead>
<tbody>
<tr>
<td class="mdl-data-table__cell--non-numeric">Acrylic (Transparent)</td>
<td>25</td>
<td>$2.90</td>
</tr>
<tr>
<td class="mdl-data-table__cell--non-numeric">Plywood (Birch)</td>
<td>50</td>
<td>$1.25</td>
</tr>
<tr>
<td class="mdl-data-table__cell--non-numeric">Laminate (Gold on Blue)</td>
<td>10</td>
<td>$2.35</td>
</tr>
</tbody>
</table>
<div id="log"></div>
</body>
When a checkbox is selected, the tr gets the class "is-checked" with Material Design Lite.
So your jquery can be like this:
$("table").find("tr.is-checked").each(function(){
// Do some stuff!
});
Update: Just read that the class "mdl-data-table--selectable " is being deprecated... This is the article on github
You can use this OnClick API function.
It uses like Android onClickListener, but it is for JavaScript.
TablesOnClickListener = function() {
var fun;
this.setOnClickListener = function(listener) {
fun = listener;
$(document).on("click", ".mdl-checkbox__ripple-container.mdl-js-ripple-effect.mdl-ripple--center", function() {
//$(this).parents().eq(2).delay(500).fadeOut(300);
var secondChildContent = $(this).parents().eq(2 /*child number*/ ).children().eq(2).text();
var allChildrenContent = $(this).parents().eq(2).children().text();
var parentID = $(this).parents().eq(2).attr('id');
fun({
sen: secondChildContent,
text: allChildrenContent,
id: parentID
});
});
}
How to use:
Step 1: create new TablesOnClickListener
var tocl = new TablesOnClickListener()
Step 2: set Item OnClickListener
tocl.setOnClickListener(function(data){
console.log(data);
});
Now your Tables Item Listener are all set!

Get row elements without using "closest" selector - jquery javascript

I have a table with 4 columns . 4th column is a button (not shown in below code). When I click on the button in a row, I want to get row elements.
I have done it using closest selector. Is there any way to find table row element "Without using closest". This is the requirement for some reason.
Please assume there is a button at end of each row
<table id="food">
<thead>
<tr>
<th>Number</th>
<th>Name</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr class='details'>
<td>1</td>
<td>Apple</td>
<td>Fruit</td>
</tr>
<tr class='details'>
<td>2</td>
<td>Mango</td>
<td>Fruit</td>
</tr>
<tr class='details'>
<td>3</td>
<td>Grape</td>
<td>Fruit</td>
</tr>
</tbody>
</table>
Here is the existing code, I need to replace closest. It will be awesome if I can use class names like $(this).somethin('.details');
$('#button1').click(function(){
var row = $(this).closest('tr');
//Do some stuff
})
Thanks
Use parents() and pass a class selector like
$('#button1').click(function(){
var row = $(this).parents('.details');
//Do some stuff
})
Note, you could also use closest in this case and pass the class selector
var row = $(this).closest('.details');

Order by clicking table header

I have an form on my web site that a user can use to order a table of data by a column of choice. Essentially it is similar to this:
<form action="" method="post">
<select name="orderby">
<option value="col_1">Column 1</option>
<option value="col_2">Column 2</option>
<option value="col_3">Column 3</option>
</select>
<input type="submit" value="Order By"/>
</form>
It works well, but I want to update how this is done by allowing the user to click on the table column header instead. My attempt to do this was to add the onclick event to my table headers and use Javascript to POST the same array back to the page. In other words, Array ( [orderby] => col_2 ) when Column 2 is clicked on will remain exactly the same. This would preserve all of my other code. Here is the change I made to my table headers:
<table>
<tr>
<th onclick="post('col_1')">Column 1</th>
<th onclick="post('col_2')">Column 2</th>
<th onclick="post('col_3')">Column 3</th>
</tr>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
<tr>
<td>B</td>
<td>C</td>
<td>A</td>
</tr>
</table>
And here is the Javascript I wrote:
<script>
function post(clm) {
$.post('mypage.php',{orderby:clm});
}
</script>
This isn't working. Can anyone tell me what I need to change to get it to work? Right now if I click on the table headers, the $_POST array remains empty. (mypage.php is the same page that is calling the function. I also tried it with nothing between the single quotes, like you would with the form action attribute, but it didn't work that way either.)
This is what I arrived at for a solution. I embedded a form into each of the table header columns. The form contains hidden inputs with the information that I want included in the $_POST array. In the simplified example I used for my post, it is simply name="orderby" and value="the column name". In the the th tag, I kept the onclick event and have it calling a javascript function that allows me to pass the form name. The javascript function submits the form, which passes the $_POST array back to the page so all of the php code I'm concerned about executes. The array ( [orderby] => col_3 ) is used to update the ORDER BY attribute in my SQL query, so the correct data is returned to the page.
HTML:
<table>
<tr>
<th onclick="submitform('postdata1')">
Column 1
<form action="" name="postdata1" method="post">
<input type="hidden" name="orderby" value="col_1"/>
</form>
</th>
<th onclick="submitform('postdata2')">
Column 2
<form action="" name="postdata2" method="post">
<input type="hidden" name="orderby" value="col_2"/>
</form>
</th>
<th onclick="submitform('postdata3')">
Column 3
<form action="" name="postdata3" method="post">
<input type="hidden" name="orderby" value="col_3"/>
</form>
</th>
</tr>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
<tr>
<td>B</td>
<td>C</td>
<td>A</td>
</tr>
</table>
Here is the javascript function:
<script>
function submitform(formname) {
document[formname].submit();
}
</script>
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.pack.js"></script>
<script type="text/javascript" src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<script src="https://raw.github.com/padolsey/jQuery-Plugins/master/sortElements/jquery.sortElements.js" type="text/javascript"></script>
<script type="text/javascript">
var st;
$(window).load(function(){
var table = $('table');
$('#col1, #col2, #col3') //all ID, za each
.wrapInner('<span title="sort this column"/>')
.each(function(){
var th = $(this),
thIndex = th.index(),
inverse = false;
th.click(function(){ //on click on any TH DOM object
table.find('td').filter(function(){
return $(this).index() === thIndex; //index of clicked element
}).sortElements(function(a, b){ //function sortElements.js
return $.text([a]) > $.text([b]) ?
inverse ? -1 : 1
: inverse ? 1 : -1;
}, function(){
return this.parentNode;
});
inverse = !inverse;
});
});
});
</script>
</head>
<body>
<table id="tabela">
<thead>
<tr>
<th id="col1"><b>Column 1</b></th>
<th id="col2"><b>Column 2</b></th>
<th id="col3"><b>Column 3</b></th>
</tr>
<tr>
<td>aaa</td>
<td>bbb</td>
<td>ccc</td>
</tr>
<tr>
<td>ddd</td>
<td>eee</td>
<td>fff</td>
</tr>
<tr>
<td>ggg</td>
<td>hhh</td>
<td>iii</td>
</tr>
</thead>
<tbody>
</tbody>
</table>
</body>
</html>
Here is an working example, hope it helps. And you don't have to make a request every time user clicks the table header.
Nice regards, Rok Jambrošič
try jqGrid.it is easy to order column recored by clicking on header.

Categories