Hello experts,
Could you please recommend:
I have two tables:
<tr id='firs_table'>
<td id="team">team1</td><td>45</td>
<td id="team">team2</td><td>47</td>
</tr>
<tr id='second_table'>
<td id="team">team1</td><td id="service">service name1</td><td id="count">count1</td>
<td id="team">team1</td><td id="service">service name2</td><td id="count">count2</td>
<td id="team">team1</td><td id="service">service name3</td><td id="count">count3</td>
<td id="team">team2</td><td id="service">service name1</td><td id="count">count1</td>
<td id="team">team2</td><td id="service">service name2</td><td id="count">count2</td>
</tr>
I need to create dictionary like:
team1: ['service name1','service name2','service name3'], [count1,count2, count3]
team2: ['service name1','service name2'], [count1,count2]
could you please advise algorithm with jquery ?
I need that result in order create RGraph graph.
Thank you in advance.
I could not provide any working example of jquery code, I could not find a way how to iterate over $("tr#first_table td"#team") value and compare it with $("tr#second_table td"#team"), if values are the same => return array of [[$("tr#second_table td"#service")], [$("tr#second_table td"#count")] ].
I mean, I could not find idea.
This should do what you need
var res = {}
$('table tr').each(function () {
var cellText = $(this).find('td').map(function (i, el) {
return $(el).text();
}).get();
if (!res[cellText[0]]) {
res[cellText[0]] = [[],[]];
}
res[cellText[0]][0].push(cellText[1]);
res[cellText[0]][1].push(cellText[2]);
});
If you have a heading row can use $('table tr:gt(0)')
DEMO
Related
Title might be a bit confusing, but this is the best I could come up with.
I need to find all tr elements which contains td elements matching the filter criteria provided.
Here is my sample,
<tr class="row" id="1">
<td class="philips">PHILIPS</td>
<td class="h4">H4</td>
<td class="lamp">Lamp<td>
</tr>
<tr class="row" id="2">
<td class="philips">PHILIPS</td>
<td class="h5">H5</td>
<td class="bulb">Bulb<td>
</tr>
<tr class="row" id="3">
<td class="neglin">NEGLIN</td>
<td class="w5w">W5W</td>
<td class="tube">Tube<td>
</tr>
<tr class="row" id="4">
<td class="philips">PHILIPS</td>
<td class="h4">H4</td>
<td class="bulb">Bulb<td>
</tr>
<tr class="row" id="5">
<td class="osram">OSRAM</td>
<td class="hb3">HB3</td>
<td class="tube">Tube<td>
</tr>
<tr class="row" id="6">
<td class="neglin">NEGLIN</td>
<td class="w5w">W5W</td>
<td class="lamp">Lamp<td>
</tr>
If I pass filter[0] as 'phillips', the result return tr with id
1
2 and
4
Then if I pass second filter; filter[1] as 'h4', the result should be filtered down to
1 and
4
I have tried this question.
Which has this answer.
$('tr')
.has('td:nth-child(1):contains("Audi")')
.has('td:nth-child(2):contains("red")')
.doSomeThing();
But, I want my filters to be applied dynamically. How would I be able to insert a 3rd has function?
I don't want to go the if-else or switch-case way, if this is possible with out them.
You can try this.
<script type="text/javascript">
$(document).ready(function () {
var result = filter([".philips", ".h4"]);
alert(result);
var result_2 = filter([".philips"]);
alert(result_2);
});
function filter(params) {
var select = "tr";
for (var i = 0; i < params.length; i++) {
select += ":has(" + params[i] + ")";
}
return $(select).map(
function () {
return $(this).attr('id');
}
).get();
}
</script>
if you have an array of filters needed, iterate that array and pass the filter string to the has?
var filters = ['PHILIPS', 'H4', 'Bulb']
var result = $('tr');
for(var i = 0; i < filters.length; i++){
var nchild = i+1;
result = result.has('td:nth-child('+nchild+'):contains("+'filters[i]'+")');
}
edit to your needs of course, but this way you can take user input, compile that into the needed array and then iterate whatever is in the array to filter down results.
You should wrap the $.has() into a separate function (I've just used jquery's easy extensions supports) which will expose the usage as a composite function chain via javascript's syntax...
$( document ).ready(function() {
$('tr')
.nthFilter('td:nth-child(1):contains("PHILIPS")')
.nthFilter('td:nth-child(2):contains("H4")')
.nthFilter('td:nth-child(3):contains("Bulb")')
.css("background-color", "red");
});
jQuery.fn.extend({
nthFilter: function(filter) {
return $(this).has(filter);
}
});
I've put together a small jsfiddle for you to fiddle with :)
You can supply your filter as a string:
var filter = ".philips, .h4";
$("tr").has("td").has(filter).map(function() { return this.id; });
// returns ["1", "2", "4"]
and if you want the elements then obviously leave the map off:
$("tr").has("td").has(filter);
// returns array of <tr>
Edit: Just noticed you want recursive filtering so change the filter to use sibling selector ~.
var filter = ".philips ~ .h4";
// returns ["1", "4"]
So if you want a third level then just:
var filter = ".philips ~ .h4 ~ .bulb";
// returns ["4"]
I have a series of table rows with data attributes. I would like to collect all the value of these data attributes and add them to an array. How do I do this?
<tr data-title-id="3706" role="row" class="odd"></tr>
<tr data-title-id="3707" role="row" class="odd"></tr>
Or the simplest method which will create the array and fill it in one step:
var dataIds = $("table tbody tr").map(function() { return $(this).data('title-id'); });
You could do something like this:
var data = [];
$('tr', yourTable).each(function() {
data.push($(this).attr('data-title-id'));
}
It can be useful to get all data attrs to array of objects.
var a = $('tr').map(function(x){
return $(this).data();
}).toArray();
alert(JSON.stringify(a,null,'\t'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body><table>
<tr data-title-id="3706" data-title-val="Hello" role="row" class="odd"></tr>
<tr data-title-id="3707" role="row" class="odd"></tr>
</table></body>
I am using handlebars to compile and get the html from the JS object. Is it possible to transform (html) back to JS object (using handlebars or anyother library)? To be more precise; Using handlebars, I have the following template:
<tr>
<td>{{qty}}</td>
<td>{{rate}}</td>
<td>{{gstPerc}}</td>
<td>{{discountPerc}}</td>
<td>{{amount}}</td>
</tr>
and following JS Object:
{
qty : 12,
rate : 1000,
gstPerc : 10,
discountPerc : 2,
amount: 1500
}
after compilation using handlebars, it gets transform to simple html i.e following, for example.
<tr>
<td>12</td>
<td>1000</td>
<td>10</td>
<td>2</td>
<td>1500</td>
</tr>
Now what I was wondering is, Is it possible (using handlebars), to transform the given HTML back to the object?
give give data-name as qty ,rate etc
var obj = getElementsByTagName('td');
$data = {};
for(var i=0;i<obj.length;i++)
{
$data[obj[i].dataset.name] = obj[i].innerHtml;
}
you can do reverse process you want to populate table with object data
You can use grid control like jqgrid for easy integration
For arbitrary templates and values, this is not possible. Consider the following template:
<td>{{cell1}}</td><td>{{cell2}}</td>
and the following result:
<td></td><td></td><td></td>
Which of cell1, cell2 is empty, and which contains </td><td>?
If you know the HTML inserted is valid and you know the template in advance, this is easy. For your specific template:
var table = document.createElement("table")
table.innerHTML = input
var tds = table.rows[0].cells
return {qty: tds[0].innerHTML, rate: tds[1].innerHTML ...}
If you know the values inserted should be numbers, you can convert them as such:
return {qty: +tds[0].innerHTML, rate: +tds[1].innerHTML ...}
Maybe you could use jQuery and end up with something like this
In your template: add classes to the <td> elements:
<table>
<tr id='someId'>
<td class='qty'>12</td>
<td class='rate'>1000</td>
<td class='gstPerc'>10</td>
<td class='discountPerc'>2</td>
<td class='amount'>1500</td>
</tr>
</table>
Create your object again:
var myObj = {};
$("#someId td").each(function() {
var td = $(this);
myObj[td.attr("class")] = td.text();
});
alert(JSON.stringify(myObj));
how can i find the highest number in the array and sort the array so it has the highest numbers first?
I am using jQuery also, if that should make it easier. I cannot figure out how to sort it, and then outputs the sorted arrays with html into usersInRoom div.
Hope someone can help me though this!
I have readed a little bit about the "max" in javascript, but it was complicate, and didn't match my code.
I will sort the mydivs[.......]['number'] and not mydivs, because it contains an array in an array.
<div id="usersInRoom">
<div class="entry in_room" id="userInRoom-2" style="background-color: rgb(255, 255, 255);">
<table style="width:100%">
<tbody>
<tr>
<td style="width:32px">
<img
src="https://fbcdn-profile-a.akamaihd.net/hprofile-ak-prn1/c33.33.414.414/s200x200/996882_221295918024677_1913237122_n.jpg"
style="height:32px;width:32px">
</td>
<td style="vertical-align:middle"><strong>Stefanie Pedersen</strong>
</td>
<td align="right" style="vertical-align:middle;color:#999"><span id="exp-2" class="exp">6</span> exp.
</td>
</tr>
</tbody>
</table>
</div>
<div class="entry in_room" id="userInRoom-1" style="background-color: rgb(155, 229, 162);">
<table style="width:100%">
<tbody>
<tr>
<td style="width:32px">
<img
src="https://fbcdn-profile-a.akamaihd.net/hprofile-ak-frc1/c176.49.608.608/s200x200/429356_10151257167066983_1091687280_n.jpg"
style="height:32px;width:32px">
</td>
<td style="vertical-align:middle"><strong>Bare Kald Mig Jesper</strong>
</td>
<td align="right" style="vertical-align:middle;color:#999"><span id="exp-1" class="exp">14</span> exp.
</td>
</tr>
</tbody>
</table>
</div>
</div>
And here is my jQuery code to insert the HTML and the numbers into array, after this it should "just" sort it and outputs it again.
<script>
var numbers = [];
var mydivs = [];
var arr = $("#usersInRoom").find(".exp");
$.each(arr, function (e) {
var eq = arr[e];
console.log(eq);
mydivs.push({
"html": $(eq).parents(".entry").parents("div").html(),
"number": parseInt($(eq).text())
});
});
</script>
I WILL SORT THE mydivs[.......]['number'] <----
This one should work with more than 2 elements:
var aRows = jQuery.makeArray($('#usersInRoom').children());
aRows.sort(function(a,b) {
return parseInt($(b).find('.exp').text()) -
parseInt($(a).find('.exp').text());
});
$('#usersInRoom').empty().append(aRows);
I don't know what your array looks like but I think that you can use the JavaScript sort method.
var NumbersArray = [400,200,600,300,1000];
var SortedArray = NumbersArray.sort(function(a,b){return b-a});
alert(SortedArray);
http://www.w3schools.com/jsref/jsref_sort.asp
If you want to find the highest number before sorting you can try something like this:
var NumbersArray = [400,200,600,300,1000];
var MaxPreviousNumber = 0;
for (var i = 0; i <= NumbersArray.length; i++) {
var MaxPreviousNumber = Math.max(MaxPreviousNumber, NumbersArray[i]);
}
I think this is doing what you want:
http://jsfiddle.net/j8bLc/2/
var arr = $("#usersInRoom").find(".exp");
$.each(arr, function (key, el) {
var curr = parseInt($(el).text());
var top = parseInt($("#usersInRoom .exp").eq(0).text());
if(curr > top) {
$(el).closest(".entry").prependTo('#usersInRoom');
}
});
But there might be a better solution with less DOM manipulations.
To print your array data in reverse order you can find array length like,
for(var i=mydivs.length-1;i>=0;i++)
{
console.log(mydivs[i]['html']);
}
Fiddle
If you will look closer here: http://www.w3schools.com/jsref/jsref_sort.asp, you can see that sort has a parameter - your own sorting function which you can use.
So, you can sort the array using you own comparing function
function compare(a,b) {
if (a.number < b.number)
return -1;
if (a.number > b.number)
return 1;
return 0;
}
objs.sort(mydivs);
this will sort your array
I have an HTML table with combined row td's, or how to say, I don't know how to express myself (I am not so good at English), so I show it! This is my table:
<table border="1">
<thead>
<tr>
<th>line</th>
<th>value1</th>
<th>value2</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="2">1</td>
<td>1.1</td>
<td>1.2</td>
</tr>
<tr>
<td>1.3</td>
<td>1.4</td>
</tr>
<tr>
<td rowspan="2">2</td>
<td>2.1</td>
<td>2.2</td>
</tr>
<tr>
<td>2.3</td>
<td>2.4</td>
</tr>
</tbody>
</table>
(you can check it here)
I want to convert this table to a JSON variable by jquery or javascript.
How should it look like, and how should I do it? Thank you, if you can help me!
if you want to convert only text use this one :
var array = [];
$('table').find('thead tr').each(function(){
$(this).children('th').each(function(){
array.push($(this).text());
})
}).end().find('tbody tr').each(function(){
$(this).children('td').each(function(){
array.push($(this).text());
})
})
var json = JSON.stringify(array);
To make a somehow representation of your table made no problem to me, but the problem is how to parse it back to HTML! Here a JSON with the first 6 tags:
{"table":{"border":1,"thead":{"th":{"textContent":"line","tr":"textContent":"value1",...}}}}}...
OR for better understanding:
{"tag":"table","border":1,"child":{"tag":"thead","child":{"tag":"th","textContent":"line",
"child":{"tag":"tr","textContent":"value1","child":...}}}}...
Closing tags are included.
For further explanations I need to know whether your table is a string or part of the DOM.
I belive this is what you want:
var jsonTable = {};
// add a new array property named: "columns"
$('table').find('thead tr').each(function() {
jsonTable.columns = $(this).find('th').text();
};
// now add a new array property which contains your rows: "rows"
$('table').find('tbody tr').each(function() {
var row = {};
// add data by colum names derived from "tbody"
for(var i = 0; i < jsonTable.columnsl.length; i++) {
row[ col ] = $(this).find('td').eq( i ).text();
}
// push it all to the results..
jsonTable.rows.push( row );
};
alert(JSON.stringify(jsonTable));
I think there should be some corrections, but this is it I think.