I am using JS/Jquery to dynamically add rows to by Table. Here is a template that I found online:
<table id="tblCustomers" cellpadding="0" cellspacing="0" border="1">
<thead>
<tr>
<th>Name</th>
<th>Country</th>
<th></th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<td><input type="text" id="txtName" /></td>
<td><input type="text" id="txtCountry" /></td>
<td><input type="button" onclick="Add()" value="Add" /></td>
</tr>
</tfoot>
</table>
From what I gather, in order to ensure that the actual cell content values get passed on Post I need to assign them to hidden fields.
How do I read the actual contents of the cells.
I tried:
$("#submitForm").click(function(){
alert("submit Clicked");
$('#tblCustomers tfoot td').each(function() {
var cellText = $(this).html();
});
});
however, All I got was this as return value:
Can you let me know what I need to do to get actual value of cell.
I need to make a dynamic table/item list and i would like to send the list of items back to server for processing. Sort of like a purchase list etc..
BTW: the backend is Django 2.0
Thanks for your help.
Tanmay
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.
I have a table that lists a lot of data (each row is an offer, and there can be a couple hundred of them). Each offer has data associated with it: a group ID (multiple offers can be in the same group), a cost, if you must trade other items as a requirement to fulfill offer, etc.
I've made a fiddle to demonstrate:
http://jsfiddle.net/gd5Nd/
and since i need to include code with fiddle links:
<label class='checkbox'>
<input type='checkbox' class='toggle' id='filterToggle' value='true' data-toggle='filtering' />Filtering Options</label>
<fieldset id='filtering'>
<label class='checkbox'>
<input type='checkbox' class='filter' value='1' data-type='req' />Offers with Required Items</label>
<label class='checkbox'>
<input type='checkbox' class='toggle' id='groupToggle' value='true' data-toggle='groups' />Filter By Group</label>
<fieldset id='groups'>
<div class="col-md-3">
<label class='checkbox'>
<input type='checkbox' class='filter' value='11' data-type='group' />Cap Boosters</label>
</div>
<div class="col-md-3">
<label class='checkbox'>
<input type='checkbox' class='filter' value='475' data-type='group' />Datacores</label>
</div>
<div class="col-md-3">
<label class='checkbox'>
<input type='checkbox' class='filter' value='24' data-type='group' />Gunslinger Implants</label>
</div>
</fieldset>
</fieldset>
<table class='table table-striped table-hover table-condensed' id='offerList'>
<tr>
<th>Offer</th>
<th>Items Req</th>
<th>LP Cost</th>
<th>ISK Cost</th>
</tr>
<tr id='offer-1607' data-group='11' data-isk='60000' data-lp='60' data-req='1'>
<td><a href='offer/1607/'>20x Navy Cap Booster 25</a>
</td>
<td>1</td>
<td>60</td>
<td>60,000</td>
</tr>
<tr id='offer-1608' data-group='11' data-isk='125000' data-lp='125' data-req='1'>
<td><a href='offer/1608/'>20x Navy Cap Booster 50</a>
</td>
<td>1</td>
<td>125</td>
<td>125,000</td>
</tr>
<tr id='offer-1609' data-group='11' data-isk='185000' data-lp='185' data-req='1'>
<td><a href='offer/1609/'>20x Navy Cap Booster 75</a>
</td>
<td>1</td>
<td>185</td>
<td>185,000</td>
</tr>
<tr id='offer-1431' data-group='475' data-isk='250000' data-lp='250' data-req='0'>
<td><a href='offer/1431/'>5x Datacore - Amarrian Starship Engineering</a>
</td>
<td>0</td>
<td>250</td>
<td>250,000</td>
</tr>
<tr id='offer-1432' data-group='475' data-isk='250000' data-lp='250' data-req='0'>
<td><a href='offer/1432/'>5x Datacore - High Energy Physics</a>
</td>
<td>0</td>
<td>250</td>
<td>250,000</td>
</tr>
<tr id='offer-1433' data-group='475' data-isk='250000' data-lp='250' data-req='0'>
<td><a href='offer/1433/'>5x Datacore - Laser Physics</a>
</td>
<td>0</td>
<td>250</td>
<td>250,000</td>
</tr>
<tr id='offer-1434' data-group='475' data-isk='250000' data-lp='250' data-req='0'>
<td><a href='offer/1434/'>5x Datacore - Mechanical Engineering</a>
</td>
<td>0</td>
<td>250</td>
<td>250,000</td>
</tr>
<tr id='offer-1435' data-group='475' data-isk='250000' data-lp='250' data-req='0'>
<td><a href='offer/1435/'>5x Datacore - Nanite Engineering</a>
</td>
<td>0</td>
<td>250</td>
<td>250,000</td>
</tr>
<tr id='offer-1464' data-group='11' data-isk='250000' data-lp='250' data-req='1'>
<td><a href='offer/1464/'>20x Navy Cap Booster 100</a>
</td>
<td>1</td>
<td>250</td>
<td>250,000</td>
</tr>
<tr id='offer-249' data-group='24' data-isk='375000' data-lp='375' data-req='0'>
<td><a href='offer/249/'>1x Eifyr and Co. 'Gunslinger' Large Projectile Turret
LP-1001</a>
</td>
<td>0</td>
<td>375</td>
<td>375,000</td>
</tr>
<tr id='offer-252' data-group='24' data-isk='375000' data-lp='375' data-req='0'>
<td><a href='offer/252/'>1x Eifyr and Co. 'Gunslinger' Medium Projectile Turret
MP-801</a>
</td>
<td>0</td>
<td>375</td>
<td>375,000</td>
</tr>
<tr id='offer-255' data-group='24' data-isk='375000' data-lp='375' data-req='0'>
<td><a href='offer/255/'>1x Eifyr and Co. 'Gunslinger' Motion Prediction
MR-701</a>
</td>
<td>0</td>
<td>375</td>
<td>375,000</td>
</tr>
<tr id='offer-258' data-group='24' data-isk='375000' data-lp='375' data-req='0'>
<td><a href='offer/258/'>1x Eifyr and Co. 'Gunslinger' Small Projectile Turret
SP-601</a>
</td>
<td>0</td>
<td>375</td>
<td>375,000</td>
</tr>
<tr id='offer-261' data-group='24' data-isk='375000' data-lp='375' data-req='0'>
<td><a href='offer/261/'>1x Eifyr and Co. 'Gunslinger' Surgical Strike
SS-901</a>
</td>
<td>0</td>
<td>375</td>
<td>375,000</td>
</tr>
</table>
JS:
$(document).ready(function () {
// !- Bind checkboxes to show filters
$('input[type="checkbox"].toggle').bind("change", function () {
if (typeof $(this).data('toggle') != 'undefined') {
if ($(this).is(":checked")) {
$("#" + $(this).data('toggle')).show();
} else {
$("#" + $(this).data('toggle')).hide();
}
}
}).trigger('change');
$('input[type="checkbox"].filter').bind("change", function () {
switch ($(this).data('type')) {
case 'group':
var filtered = $('*[data-group="' + this.value + '"]');
console.log("Affected offers for " + this.value + ": " + filtered.length);
filtered.toggleClass('danger');
break;
case 'req':
var filtered = $('*[data-req="1"]');
filtered.toggleClass('danger');
break;
}
}).trigger('toggle');
});
The problem I'm having is that multiple filters may point to the same data row. For example: I have an offer that is part of group 11 (Cap Boosters), and it also requires items to trade. I have two filters that affect this: Has required items filter, and the group filter.
If I were to activate the group filter for group 11, I highlight the group 11 offers. However, when I activate the filter for offers with required items, I want it to remain highlighted. Instead, it removes the highlight.
This is because I'm toggling the class for the highlight on/off. I've tried show()/hide() which pretty much do the same thing (of course). One thing I tried that didn't work was addClass() and removeClass(). I thought it would append the class, so that if you had two filters that added the class, and then removed one filter, the other filter's class would still be active, but it seems that addClass only adds the class if it's not already present.
I could do some checking, such as if I choose to deactivate the group toggle, it will check to see if the req items toggle is still checked. However, that seems like a hack, and I'm not sure if it will work well (the example I have is a simplified version; in reality, there are about 10 groups and I would like to add more filters, so I'm not sure how feasible it would be to recursively check all filters and if they affect the data row every time one filter is checked/unchecked).
I was curious as to how best solve this problem of multiple filters pointing to the same data row.
Solution
I basically set up, as part of routine JS init, a 'filter container' object initially structured as so: rowID : Array(). Every time I add a filter, the filter will add itself to array for that row (so, having two filters in this example, each row could be filtered with group or req). Every time a filter is applied, we loop through the matching rows, and add/remove the filter from the list. If we're adding a filter, we go ahead and .hide() the element as well. If we remove the filter, we check to see if the array is empty, which means no filters are applied and we then .show() the element.
Sweet. A fellow EVE pilot.
I think your primary problem here is relying too much on simple notions like CSS classes or something to accomplish your goal. It sounds like what you need to do is keep track of all the different market items in a data structure, then go through and "turn on highlight" for the items you want. If it's already highlighted, who cares, otherwise turn it on (and vice versa). This is a strategy I typically use when I have complex hierarchies of collapsible items, or complex groupings such as what you're dealing with.
I think the solution you describe as a "hack" is fine - and is the only way I can think to do it simply. I had an idea involving adding an additional data-attribute for every filter option and then applying the styling via those instead of the class
IE:
<style>
.danger,
[data-req_style=1],
[data-group_style=11],
[data-group_style=475]{
...
}
</style>
Then rather than toggling the class you could safely add remove multiple filters without interfering with others. BUT that becomes really unmaintainable if you have an arbitrary or ever expanding list of filters.
Your "hack" solution is how I would implement it were it my project. Class selectors and determining the status of check boxes are comparably pretty fast so I wouldn't worry too much about performance even with really large data sets.
I have a simple HTML Form with one column having a select menu with 2 options: Moderate or High. I need to find all rows where the cell = "Moderate" and count the total of another cell in the same row, and repeat this for all rows where the cell = "High". Here's a JS Fiddle showing a sample completed table:
http://jsfiddle.net/8hn2H/
In this example the result for Total Moderate would be 1.6 and the result for Total High would be 8.7 (it's totalling the value in the Average Hours/Week column). The number of rows will not be fixed in advance - there could be 1 or more.
Here's the actual html for the form:
<div class="span8"><br>
<table id="activities" class="table table-bordered table-striped">
<thead>
<tr>
<th>Activity</th>
<th>Risk</th>
<th>Hours/Week</th>
<th>Weeks/Year</th>
<th>Average Hours/Week</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td><input name="Activity" id="Activity" type="text" value=""/></td>
<td><div class="controls">
<select id="Risk">
<option></option>
<option>Moderate</option>
<option>High</option>
</select>
</div></td>
<td><input class="span1" id="A1" type="text" value=""/></td>
<td><input class="span1" id="B1" type="text" value=""/></td>
<td><input class="span1" id="C1" type="text" value=""/></td>
<td><button class="btn">Delete Activity</button></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td>Total Moderate</td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td>Total High</td>
<td></td>
</tr>
</tbody>
</table>
</div>
var moderateTotal = 0;
var highTotal = 0;
$("#activities").find("tr").each(function() {
var tr = $(this);
var level = tr.find("td:nth-child(2)").html();
var value = tr.find("td:nth-child(5)").html();
switch(level)
{
case "Moderate":
moderateTotal += value*1;
break;
case "High":
highTotal += value*1;
break;
}
});
$("#activities tr:last td:last").prev().html("High Total: " + highTotal);
$("#activities tr:last").prev().find("td:last").prev().html("Moderate Total: " + moderateTotal);
I use jQuery's .find() and .each() function to iterate over each row. I use find again to find the level and value (2nd and 5th columns) and a switch statement to add the value to the totals. I need to do value*1 to convert the string to an integer so it will add. Default behavior here is concatenate.
The last two lines set the value of the table cells. It'd be a lot easier if you could just give those a specific ID so you can just do $("moderateTotal").html() but since that wasn't given I used some jQuery selectors to do it.
Demo
There are a number of ways to attack this, but I'd strongly recommend that you consider jQuery DataTables. It has built in functionality for summing fields, sorting, filtering, etc and is MUCH easier than having to home-brew something. Plus, it looks far better than just a bare table with full Themeroller support.
Here's a simple example with a footer callback to do sums: http://datatables.net/release-datatables/examples/advanced_init/footer_callback.html
Because all of the data in the table is fully available to you via API, it's easy to do math on it. You --could-- simply filter the table based on the the moderate or high flag and show only that data, allowing the user to modify that view on the fly.
And, if your data ever gets really long, it has paging and ajax loading options to improve the speed on the user's level.
I have a litte problem with the PicNet table Filter. Here is the demo.
Here is my JS:
$(document).ready(function() {
// Initialise Plugin
var options = {
additionalFilterTriggers: [$('#quickfind')]
};
$('#dataTable').tableFilter(options);
});
Here is the HTML:
<body>
Quick Find: <input type="text" id="quickfind"/>
<table id='dataTable'>
<thead>
<tr>
<th>File</th>
<th>Last Modified</th>
</tr>
</thead>
<tbody>
<tr>
<td class="left">10.pdf</td>
<td class="right">22.03.12 19:45:58</td>
</tr>
<tr>
<td class="left">20.pdf</td>
<td class="right">22.03.12 19:45:58</td>
</tr>
<tr>
<td class="left">22.pdf</td>
<td class="right">22.03.12 19:45:58</td>
</tr>
</tbody>
</table>
..
Is it possible to search with #quickfind in only one (first) column?
when I search in #quickfind for "22" I got 3 results because the right column has a "22" in the date and time.
I disabled in the CSS the .filter class with display:none; because I only want one searchfield. I copied the genererated javascript code and replaced it with the #quickfind.
<input type="text" id="filter_0" class="filter" >
filter_0 is for the first row. filter_1 is for the second row. And so on. But the code works only in the table! and not above.
Any ideas to solve the problem?
You can disable the search for column(s), just put filter='false' attribute in the header th tag(s).
<th filter='false'>Last modified</th>