Good day people,so i have a jquery mobile page like that:
<div id="testTableDiv" style="overflow-y: auto; height: 250px">
<table class="ui-responsive ui-shadow gk-decorate table-stripe" id="testTable" is="jqm-table" data-role="table">
<thead>
<tr>
<th>Fruits</th>
<th>Numbers</th>
<th>Names</th>
<th>Countries</th>
<th>Animals</th>
</tr>
</thead>
<tbody>
.
.
content see Fiddle
</tbody>
</table>
</div>
<select id="selectId">
<option selected disabled>Choose Sort View</option>
<option>Names, Animals, Countries</option>
<option>Numbers, Fruits, Names</option>
<option>Countries, Numbers, Animales</option>
</select>
And based on the Selected option from the select menu i can filter that Table. Take a look at my snippet
function changeOrder(table, from, to) {
var rows = jQuery('tr', table);
var cols;
rows.each(function () {
cols = jQuery(this).children('th, td');
if (to < cols.length)
cols.eq(from).detach().insertBefore(cols.eq(to));
else
cols.eq(from).detach().insertAfter(cols.last());
});
}
$(document).ready(function() {
$('#testTable').data('origin-table', $('#testTable').html()).text();
$("body").on("change", "#selectId", function() {
if ($("#selectId option:selected").text() == "Names, Animals, Countries") {
$('#testTable').html($('#testTable').data('origin-table'));
var myTable = document.getElementById("testTable");
changeOrder(myTable,2,0);
changeOrder(myTable,4,1);
changeOrder(myTable,4,2);
$('td:nth-child(4),th:nth-child(4)').hide();
$('td:nth-child(5),th:nth-child(5)').hide();
}
if ($("#selectId option:selected").text() == "Numbers, Fruits, Names") {
$('#testTable').html($('#testTable').data('origin-table'));
var myTable = document.getElementById("testTable");
changeOrder(myTable,1,0);
$('td:nth-child(4),th:nth-child(4)').hide();
$('td:nth-child(5),th:nth-child(5)').hide();
}
if ($("#selectId option:selected").text() == "Countries, Numbers, Animales") {
$('#testTable').html($('#testTable').data('origin-table'));
var myTable = document.getElementById("testTable");
changeOrder(myTable,3,0);
changeOrder(myTable,2,1);
changeOrder(myTable,5,0);
$('td:nth-child(4),th:nth-child(4)').hide();
$('td:nth-child(5),th:nth-child(5)').hide();
}
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.css">
<div id="testTableDiv" style="overflow-y: auto; height: 250px">
<table class="ui-responsive ui-shadow gk-decorate table-stripe" id="testTable" is="jqm-table" data-role="table">
<thead>
<tr>
<th>Fruits</th>
<th>Numbers</th>
<th>Names</th>
<th>Countries</th>
<th>Animals</th>
</tr>
</thead>
<tbody>
<tr>
<td>Banana</td>
<td>2321</td>
<td>Kate</td>
<td>France</td>
<td>Tiger</td>
</tr>
<tr>
<td>Apple</td>
<td>819</td>
<td>John</td>
<td>Mexico</td>
<td>Dog</td>
</tr>
<tr>
<td>Orange</td>
<td>62</td>
<td>Jack</td>
<td>Italy</td>
<td>Cat</td>
</tr>
<tr>
<td>Banana</td>
<td>728</td>
<td>James</td>
<td>Spain</td>
<td>Lion</td>
</tr>
<tr>
<td>Mango</td>
<td>11</td>
<td>Charlie</td>
<td>Croatia</td>
<td>Turtle</td>
</tr>
<tr>
<td>Cherry</td>
<td>42</td>
<td>Ben</td>
<td>Japan</td>
<td>Bee</td>
</tr>
</tbody>
</table>
</div>
<select id="selectId">
<option selected disabled>Choose Sort View</option>
<option>Names, Animals, Countries</option>
<option>Numbers, Fruits, Names</option>
<option>Countries, Numbers, Animales</option>
</select>
Now i also want to sort that Table based on the first Column that will be shown.For example: When the user selectes the "Countires, Numbers, Animals" Select option i want to sort the table after the Countries like that:
Croatia 11 Mango
France 2321 Banana
Italy 62 Orange
Japan 42 Cherry
Mexico 819 Apple
Spain 728 Banana
The content gets added dynamically: But i have a array for each column like:countryArray[..]<br>numberArray[..]<br>... And i can already sort that array with the javascript method .sort()
Now comes my question how can i apply those sort changes onto my table? The column connection should of course still be available.
I managed to solve this problem with the answer from Alexander from this question here: Sorting multiple arrays at once.
What i did was: Since i got the Table content from each column in a array i simply ordered the appropriate array and adjust the others arrays to it. After that is done i just update my Table using the innerText method.
Related
I have a 6-column table. It has a dropdown menu so that viewers can select one of the four right-most columns (the "th"'s for those four columns are choiceA, choiceB, choiceC, choiceD). I want only the selected column to display; the other three non-selected columns would be hidden. The two left-most columns would always be visible.
i.e., The viewer would see only three columns in total (plus the dropdown of course). If she chooses, e.g., "Choice A, lbs" from the dropdown, the idea is to show the whole choiceA column and hide all the others.
I thought this would be a simple parent/child issue, but it has proved anything but simple. I have tried to map the dropdown options to the column heads for the choices
This is my jquery Code (bear in mind, I'm a beginner):
$(document).ready(function () {
$('#ddselect').change(function () {
var id = $(this).children(':selected').attr('id');
$('#' + id + '-sel').show().siblings('th.substance').hide();
$('.' + id + '-substance').show().not($('.' + id + '-substance')).hide();
});
});
This is the HTML:
<table>
<tr>
<th scope="col" align="left"></th>
<th scope="col"></th>
<th colspan="4" scope="col">
<select id='ddselect'>
<option class='ddselect' id="ChoiceA">ChoiceA, lbs</option>
<option class='ddselect' id="ChoiceB">ChoiceB, oz</option>
<option class='ddselect' id="ChoiceC">ChoiceC, oz</option>
<option class='ddselect' id="ChoiceD">ChoiceD, oz</option>
</select>
</tr>
<tr>
<th scope="col" align="left">Module</th>
<th scope="col" align="left">Units</th>
<th class='substance' id='ChoiceA-sel' scope="col">ChoiceA</th>
<th class='substance' id='ChoiceB-sel' scope="col">ChoiceB</th>
<th class='substance' id='ChoiceC-sel' scope="col">ChoiceC</th>
<th class='substance' id='ChoiceD-sel' scope="col">ChoiceD</th>
</tr>
<tr>
<td>type1</th>
<td>5,000</td>
<td class='ChoiceA-substance'>0</td>
<td class='ChoiceB-substance'>0</td>
<td class='ChoiceC-substance'>0</td>
<td class='ChoiceD-substance'>0</td>
</tr>
<tr>
<td>type2</th>
<td>545</td>
<td class='ChoiceA-substance'>288</td>
<td class='ChoiceB-substance'>8</td>
<td class='ChoiceC-substance'>9</td>
<td class='ChoiceD-substance'>0.2</td>
</tr>
<tr>
<td>type3</th>
<td>29</td>
<td class='ChoiceA-substance'>15</td>
<td class='ChoiceB-substance'>89</td>
<td class='ChoiceC-substance'>43</td>
<td class='ChoiceD-substance'>9.9</td>
</tr>
</tr>
I can show the right column head with the dropdown and hide the others, but cannot hide the "td"s that correspond to the hidden heads. (I would post a stack snippet, but the button is not appearing in my editor.)
Any ideas?
Let's break this down into a small sized example. It's better not to over complicate your code when you're working with concepts you don't fully grasp yet.
A good way to achieve what you want is to use common classes, and cross classes to pick and choose the right columns.
The code becomes much cleaner this way:
http://jsbin.com/megicegupa/1/edit?html,js,output
$('#sel').on('change', function () {
var val = $(this).val(),
target = '.' + val;
$('.choice').hide();
$(target).show();
});
<select id="sel">
<option value="one">1</option>
<option value="two">2</option>
</select>
<table>
<tr>
<th>Module</th>
<th>Units</th>
<th class="choice one">Choice One</th>
<th class="choice two">Choice Two</th>
</tr>
<tr>
<td>type1</td>
<td>5000</td>
<td class="choice one">100</td>
<td class="choice two">200</td>
</tr>
<tr>
<td>type2</td>
<td>350</td>
<td class="choice one">40</td>
<td class="choice two">90</td>
</tr>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Side note: You have some <td> tags that are followed by </th> tags. Make sure to validate your HTML for errors.
According to your code while loading the page we can see both column names "Choice One" and "Choice Two". So it's better to hide the column name on page load.
$('#sel').on('change', function() {
var val = $(this).val(),
target = '.' + val;
$('.choice').hide();
$(target).show();
});
/*Add below code for showing column name accordingly to select box change
*/
$('.choice').hide();
if ($('#sel').val() == 'one') {
$('.one').show()
} else {
$('.two').show()
}
<html>
<body>
<div>
<table border="1" id="topTable">
<thead>
<th>Item</th>
<th>Sold</th>
</thead>
<tbody id="topTableBody">
<tr>
<td>Apples</td>
<td>50</td>
</tr>
<tr>
<td>Apples</td>
<td>25</td>
</tr>
<tr>
<td>Oranges</td>
<td>30</td>
</tr>
<tr>
<td>Strawberry</td>
<td>60</td>
</tr>
<tr>
<td>Cherry</td>
<td>10</td>
</tr>
<tr>
<td>Guava</td>
<td>5</td>
</tr>
<tr>
<td>Strawberry</td>
<td>20</td>
</tr>
</tbody>
</table>
</div>
<button id="btn">Click</button>
</br>
<div>
<table border="1" id="bottomTable">
<thead>
<th>Item</th>
<th>Sold</th>
</thead>
<tbody id="bottomTableBody">
</tbody>
</table>
</div>
</body>
</html>
When I press on the button I want it to loop through the top table and get the item names that're alike and add them in one row with the sold amount combined in the bottom table ex: apples will have their own row with a sold amount of 75 and others who have no names that're alike will have their own row such as Oranges with the sold amount also.
If you can use JQuery.
(JSFiddle: http://jsfiddle.net/inanda/o9axgkaz/):
jQuery('#btn').on('click', function() {
var sumMap = {};
//Iterate through table rows
$("table tbody tr").each(function () {
if (sumMap[$(this).children('td:nth-child(1)').text()]) {
sumMap[$(this).children('td:nth-child(1)').text()] = sumMap[$(this).children('td:nth-child(1)').text()] +Number($(this).children('td:nth-child(2)').text());
} else {
sumMap[$(this).children('td:nth-child(1)').text()] = Number($(this).children('td:nth-child(2)').text());
}
})
//Append result to the other table
$.each(sumMap, function (i, val) {
$('#bottomTable tr:last').after('<tr><td>'+i+'</td><td>'+val+'</td>');
});
});
Pure javascript:
(JSFiddle: http://jsfiddle.net/inanda/2dmwudfj/ ):
appendResultToBottomTable= function() {
var sumMap = calculate();
appendResultToTable('bottomTableBody', sumMap);
}
function calculate() {
var table = document.getElementById("topTableBody");
var map = {};
for (var i = 0, row; row = table.rows[i]; i++) {
var itemType=(row.cells[0].innerText || row.cells[0].textContent);
var value=(row.cells[1].innerText || row.cells[1].textContent);
if (map[itemType]) {
map[itemType] = map[itemType] +Number(value);
} else {
map[itemType] = Number(value);
}
}
return map;
}
function appendResultToTable(tableId, sumMap){
var table = document.getElementById(tableId);
for (var item in sumMap){
var row = table.insertRow(table.rows.length);
var cellItem = row.insertCell(0);
var cellValue = row.insertCell(1);
cellItem.appendChild(document.createTextNode(item));
cellValue.appendChild(document.createTextNode(sumMap[item]));
}
}
If it is applicable for your project to use external libraries, you can do it with code like below:
alasql('SELECT Item,SUM(CONVERT(INT,Sold)) AS Sold \
INTO HTML("#res",{headers:true}) \
FROM HTML("#topTable",{headers:true}) \
GROUP BY Item');
Here:
SELECT Item, SUM(Sold) FROM data GROUP BY Item is a regular SQL expression to group and sum data from the table
CONVERT(INT,Sold) conversion procedure from string to INT type
FROM HTML() and INTO HTML() special functions to read/write data from/to HTML table, {headers:true} is a parameter to use headers
I added some minor CSS code (for table and cells borders), because Alasql generates the "plain" HTML table.
See the working snippet below.
(Disclaimer: I am an author of Alasql library)
function run() {
alasql('SELECT Item,SUM(CONVERT(INT,Sold)) AS Sold INTO HTML("#res",{headers:true}) FROM HTML("#topTable",{headers:true}) GROUP BY Item');
}
#res table {
border:1px solid black;
}
#res table td, th{
border:1px solid black;
}
<script src="http://alasql.org/console/alasql.min.js"> </script>
<div>
<table border="1" id="topTable">
<thead>
<th>Item</th>
<th>Sold</th>
</thead>
<tbody id="topTableBody">
<tr>
<td>Apples</td>
<td>50</td>
</tr>
<tr>
<td>Apples</td>
<td>25</td>
</tr>
<tr>
<td>Oranges</td>
<td>30</td>
</tr>
<tr>
<td>Strawberry</td>
<td>60</td>
</tr>
<tr>
<td>Cherry</td>
<td>10</td>
</tr>
<tr>
<td>Guava</td>
<td>5</td>
</tr>
<tr>
<td>Strawberry</td>
<td>20</td>
</tr>
</tbody>
</table>
</div>
<button id="btn" onclick="run()">Click</button>
</br>
<div id="res"></div>
I have a table generated from database. And each field hidden until selected from select dropdown list. Also need calculate visible rows. I have this code, but it calculates all rows, even visibly. Could you advice how I can fix the code to calculate only visibly rows.
TABLE:
<table width="100%" border="0" id="sum_table">
<tr style="color:white;background:gray;">
<td>Name</td>
<td>Column 1</td>
<td>Column 2</td>
<td>Column 3</td>
<td>Column 4</td>
</tr>
<tr id="one">
<td>Service 1</td>
<td>12</td>
<td>45</td>
<td>45</td>
<td>54</td>
</tr>
<tr id="two">
<td>Service 2</td>
<td>8</td>
<td>42</td>
<td>35</td>
<td>23</td>
</tr>
<tr id="three">
<td>Service 3</td>
<td>6</td>
<td>65</td>
<td>16</td>
<td>26</td>
</tr>
<tr id="result" style="background:silver;">
<td>TOTAL:</td>
<td id="total1">0</td>
<td>0</td>
<td></td>
<td></td>
</tr>
</table>
<br>ADD LINE:
<select id="select_stud">
<option>-- Select --</option>
<option>one</option>
<option>two</option>
<option>three</option>
</select>
JS:
$(document).ready(function () {
$('#one').hide();
$('#two').hide();
$('#three').hide();
$('#select_stud').change(function () {
$('#'+$(this).val()).show();
})
});
$("#sum_table tr:last td:not(:first,:last)").text(function(i){
var t = 0;
$(this).parent().prevAll().find("td:nth-child("+(i+2)+")").each(function(){
t += parseInt( $(this).text(), 10 ) || 0;
});
return "= " + t;
});
Also I need to calculate only 2 columns.
Here is full code: http://jsfiddle.net/stanencendo/u7a27vth/9/
Thanks.
Here's an example of what you are trying to do: http://jsfiddle.net/u7a27vth/10/
To only look at visible rows when calculating your sum, you can add a condition like this:
if ( $(this).parent().css('display') != 'none' )
You'll also want to update the sums every time you add a new column. You can do that by wrapping your sum calculation in a function (in this case, updateSums) and call it within your change function for the select element:
$('#select_stud').change(function () {
$('#'+$(this).val()).show();
updateSums();
})
That said, your approach probably isn't the best way to handle this. Typically, you want your view to be derived from your data, not the other way around.
Edit: As pointed out in the comments, if you want the last column to be calculated as well, you need to change $("#sum_table tr:last td:not(:first,:last)") to $("#sum_table tr:last td:not(:first)")
It wasn't clear to me whether or not this was you intention.
$("#sum_table tr:last td:not(:first,:last)").text(function(i){
var t = 0;
$(this).parent().prevAll().find("td:nth-child("+(i+2)+")").filter(":visible").each(function(){
t += parseInt( $(this).text(), 10 ) || 0;
});
return "= " + t;
});
the text input filtering is working but i don`t know how to implement with category using combo box. the category is using by there age.
please help my to this task:(
this is my sample code
this is my view
<select>
<option>all age</option>
<option>16</option>
<option>18</option>
<option>20</option>
</select>
<input />
<table class="AvailableGroupLab availGrpLabs avalLabs">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr>
<td><span>wewe</span>
</td>
<td>16</td>
</tr>
<tr>
<td><span>Melvin</span>
</td>
<td>18</td>
</tr>
<tr>
<td><span>Marvin</span>
</td>
<td>20</td>
</tr>
<tr>
<td><span>wewex</span>
</td>
<td>20</td>
</tr>
</tbody>
</table>
this is javascript
function filter(element) {
var $trs = $('.AvailableGroupLab tbody tr').hide();
var regexp = new RegExp($(element).val(), 'i');
var $valid = $trs.filter(function () {
return regexp.test($(this).find('td:first-child').text())
}).show();
$trs.not($valid).hide()
}
$('input').on('keyup change', function () {
filter(this);
})
The problem with you code is that you are comparing regexp with 1st child of tr, while you age is in 2nd child.
var $valid = $trs.filter(function () {
return regexp.test($(this).find('td:eq(1)').text())
// or
return regexp.test($(this).find('td:last-child').text())
}).show();
I hope this will help you.
i have set of drop downs with a select button below.
what i want to try to do is once the user has been through the three drop downs and pressed select, the option that is chosen is shown in a corresponding table in its assigned category
HTML:
<form method="POST">
<select name='first' id='first'>
<option selected="selected" value="nothing">choose</option>
<option value='opt_a'>opt a</option>
<option value='opt_b'>opt b</option>
</select>
<select name='sec' id='sec'>
</select>
<select name='third' id='third'>
</select>
<br />
<br />
<button id="select_btn" type="select" name="select">select</button>
<br />
<br />
<div id="result">
<table>
<tr>
<th>category</td>
<th>choice</td>
</tr>
<tr>
<td>choice 1</td>
<td></td>
</tr>
<tr>
<td>choice 2</td>
<td></td>
</tr>
<tr>
<td>choice 3</td>
<td></td>
</tr>
<tr>
<td>choice 4</td>
<td></td>
</tr>
<tr>
<td>choice 5</td>
<td></td>
</tr>
<tr>
<td>choice 6</td>
<td></td>
</tr>
<tr>
<td>choice 7</td>
<td></td>
</tr>
<tr>
<td>choice 8</td>
<td></td>
</tr>
</table>
</div>
</form>
JS:
data = {
opt_a: ['choose_1','choose_2','choose_3','choose_4'],
opt_b: ['choose_5','choose_6','choose_7','choose_8'],
choose_1: ['yes','no','unsure','still unsure'],
choose_2: ['yes','no','unsure','still unsure'],
choose_3: ['yes','no','unsure','still unsure'],
choose_4: ['yes','no','unsure','still unsure'],
choose_5: ['a','b','avg','unclear'],
choose_6: ['a','b','avg','unclear'],
choose_7: ['a','b','avg','unclear'],
choose_8: ['a','b','avg','unclear']
}
$('#first').change(function(){
var firstopts = ''
$.each(data[$(this).val()],function(i,v){
firstopts += "<option value='"+v+"'>"+v+"</option>"
})
$('#sec').html(firstopts)
})
$('#sec').change(function(){
var secopts = ''
$.each(data[$(this).val()],function(i,v){
secopts += "<option value='"+v+"'>"+v+"</option>"
})
$('#third').html(secopts)
})
CSS:
select{width:150px;}
#result{width:450px; border:2px solid #234323;}
td{width:225px; text-align:center}
th{background:#656454; color:#eee; text-align:center}
Thank You in advance for any help.
Since your data keys are called choose_N and your columns have the text choice N, you can match them by splitting the value and getting the last part:
var number1 = 'choose_1'.split('_')[1];
var number2 = 'choice 1'.split(' ')[1];
return number1 == number2; // corresponding choice
You could also annotate your HTML with the corresponding value, if you want something more exact:
<tr data-choice="choose_1">
<td>choice 1</td>
<td></td>
</tr>
$(myselector).data("choice"); // Will return "choose_1"
Now all you have to do is to select the right row (the one that corresponds to the value currently selected in #sec) and set the second column to the value currently selected in #third. You could do it on the click callback of the select button, but a better option is to do it on $('#third').change directly (so the user is saved from one extra button press):
$('#third').change(function() {
$('table tr').filter(function() { // Filters the rows, by:
var number1 = $('#sec').val().split('_')[1]; // comparing the value at #sec
var number2 = $(this).find('td:eq(0)').text().split(' ')[1]; // with the text of the first column.
return number1 == number2;
}).find('td:eq(1)').text($(this).val()); // Updates the second column.
});
Working example at jsFiddle. The only caveat is that, if the user wants to select the first option (the one already selected), he'll have to change it and change again for the event to trigger (in this sense, a select button is cleaner).
if you still want to do that only on button press, just replace $('#third').change(...) with $('#select_btn').click(...) (Edit: and $(this) to $('#third')). You might also have to use event.preventDefault, so the form isn't submitted.