Tablesorter: child rows above total - mysql

I get a MySQL query with detail rows and total. I would love to use Tablesorter child rows functionality to hide the details rows but face the problem that need to convert the csv file into html (no problem with that) but my total rows are at the bottom of every list of detailed rows, not above.
The question is, can I use Tablesorter child rows in a way that clicking the link related upper rows unfold?
My sample table (before converting it to html) is:
n_cli n_inv date_inv date_due eur +exp
----------------------------------------------------------------------------------
10289 21222321-1 2012-10-04 2012-12-30 1,031.05 1,072.29
10289 21222479-1 2012-10-09 2012-12-30 257.28 267.57
----------------------------------------------------------------------------------
Total CUSTOMER1 NAME 1,288.33 1,339.86
10416 21110039-1 2011-06-22 2011-06-22 136.28 145.28
----------------------------------------------------------------------------------
Total CUSTOMER2 NAME 136.28 145.28
By the way, can I use Child Rows with three levels of details? for instance, "total sales per customer / total per invoice/ product lines per invoice" ?
Thanks,
EDITED: This is the source (sample) file:
n_cli;n_inv;date_inv;date_due;eur;+exp
10289;21222321-1;2012-10-04;2012-12-30;1,031.05;1,072.29
10289;21222479-1;2012-10-09;2012-12-30;257.28;267.57
Total;CUSTOMER1 NAME;;;1,288.33;1,339.86
10416;21110039-1;2011-06-22;2011-06-22;136.28;145.28
Total;CUSTOMER2 NAME;;;136.28;145.28
And my html, which is obviously not working as I am unable to:
Edit the CSVTOTABLE process through the loadComplete function (¿?) in
order to tag the rows to show and the rows to hide.
Hide the upper rows (above Total) instead of bottom rows.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" type="text/css" href="/js/ts/css/theme.default.css">
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script type="text/javascript" src="/js/ts/js/jquery.tablesorter.min.js"></script>
<script type="text/javascript" src="/js/ts/js/jquery.tablesorter.widgets.min.js"></script>
<script type="text/javascript" src="/js/csv/js/jquery.csvToTable.js"></script>
<script>
$(function() {
$('#tabla1').CSVToTable('dat.txt',
{
startLine: 0,
separator: ";"
}
).bind("loadComplete",function() {
$(document).find('#tabla1').tablesorter({widgets:
["zebra", "stickyHeaders"]});
});;
});
</script>
</head>
<body>
<div>
<table id="tabla1" class="tablesorter">
</div>
</table>
</body>
</html>

So, you can use the CSVToTable load complete callback function to modify the table however you want.
I put together this code & demo* to show how you can assign child rows and make the rows above the total collapsible:
$(function () {
$('table')
.CSVToTable('csv.txt', {
startLine: 0,
separator: ';'
})
.bind("loadComplete", function () {
$('table')
.find('td:contains("Total")')
.each(function () {
var $cell = $(this).prepend('<i/>'),
$totalRow = $cell.parent().addClass('totals tablesorter-childRow'),
group = $totalRow.prevUntil('.totals');
group.last().addClass('tablesorter-parentRow');
group.slice(0, -1).addClass('tablesorter-childRow');
}).end()
.tablesorter({
theme: 'blue',
widgets: ["zebra", "stickyHeaders"]
})
.find('tr.totals').click(function () {
$(this)
.toggleClass('collapsed')
.prevUntil('.totals').toggle();
});
});
});
*The demo isn't using the CSVToTable script, but the added HTML would be the same.
The arrow inside the "Total" cell is styled by css, so you can change them as desired:
/* collapsed arrow */
tr.totals.collapsed td i {
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
border-left: 5px solid #888;
border-right: 0;
margin-right: 10px;
}
tr.totals td i {
display: inline-block;
width: 0;
height: 0;
border-bottom: 4px solid transparent;
border-top: 4px solid #888;
border-right: 4px solid #888;
border-left: 4px solid transparent;
margin-right: 7px;
}
Update: Because you are folding the rows up, you'll need a custom parser to find the custom names in the last row instead of the first, so it sorts properly. Here is the parser to use and an updated demo
$.tablesorter.addParser({
id: 'findname',
format: function (s, table, cell, cellIndex) {
var $cell = $(cell).parent().nextAll('tr.totals').eq(0).find('td').eq(cellIndex);
return $cell.text();
},
// set type, either numeric or text
type: 'text'
});
Update #2: Well, you'll need another parser for numeric columns so they sort properly as well; here's an updated demo:
$(function () {
$.tablesorter.addParser({
id: 'findname',
format: function (s, table, cell, cellIndex) {
var $cell = $(cell).parent().nextAll('tr.totals').eq(0).find('td').eq(cellIndex);
return $cell.text();
},
type: 'text'
});
$.tablesorter.addParser({
id: 'findnumber',
format: function (s, table, cell, cellIndex) {
var $cell = $(cell).parent().nextAll('tr.totals').eq(0).find('td').eq(cellIndex);
return $.tablesorter.formatFloat($cell.text(), table);
},
type: 'numeric'
});
$('table')
.CSVToTable('csv.txt', {
startLine: 0,
separator: ';'
})
.bind("loadComplete", function () {
$('table')
.find('td:contains("Total")')
.each(function () {
var $cell = $(this).prepend('<i/>'),
$totalRow = $cell.parent().addClass('totals tablesorter-childRow'),
group = $totalRow.prevUntil('.totals');
group.last().addClass('tablesorter-parentRow');
group.slice(0, -1).addClass('tablesorter-childRow');
}).end()
.tablesorter({
theme: 'blue',
headers: {
1: { sorter: 'findname' },
4: { sorter: 'findnumber' },
5: { sorter: 'findnumber' }
},
widgets: ["zebra", "stickyHeaders"]
})
.find('tr.totals').click(function () {
$(this)
.toggleClass('collapsed')
.prevUntil('.totals').toggle();
});
});
});
Update #3
To style the parent and child rows separately, you can use the applied class names tablesorter-parentRow and tablesorter-childRow, but to avoid confusion, I renamed the tablesorter-parentRow to tablesorter-firstChildRow because within the plugin it is actually the parent row, but for styling purposes, it would be better to name it as a child row since we're working form the bottom up. The "Totals" row also has the class name tablesorter-childRow applied to it, so in order to differentiate it you can use the totals class name instead.
Anyway, here is an updated demo with the class name change and css, as well as the addition to make sure it only targets cells in the tbody (.find('tbody td:contains("Total")'))
/* child row styling */
.tablesorter-firstChildRow td, .tablesorter-childRow td {
color: red;
}
/* Totals row */
tr.totals td {
color: blue;
}

Related

How to get the value of Jpicker (color picker) for each row in a loop

I have two questions.
I have a dynamic grid. In which the user clicks on AddNewRow button and it generates a new row with jpicker in it . Each row has a different id ofcourse. Now when Im saving the values of color picker for each row in a loop. I am using this syntax
$('#tblCUS tbody tr').each(function () {
color = '#' + $.jPicker.List[0].color.active.val('ahex');
Grid+= color + "♥";
Which only gives me the value of the first row. and for each loop it is giving me the value of the first picker. How do I get the values of color picker for each row? I have made several google searches and only one syntax is available.
Ater saving when my page gets reloaded the color picker disappears. How do I show my color picker with the values that were saved in the database? Here is my code
<DIV id=divsomeid style="WIDTH: 100%">
<TABLE class=display id=tblsometable style="WIDTH: 100%">
<THEAD>
<TR>
<TH class=Greyheader style="WIDTH: 5%">S.No</TH>
<TH class=Greyheader style="WIDTH: 35%">Color</TH>
<TH class=Greyheader>Action</TH></TR></THEAD>
<TBODY>
<TR class=GreyBorder id=tblSBPComments_3 pkid="3">
<TD class=GreyBorder>1</TD>
<TD class=GreyBorder><SPAN class=colorPicker id=clcColor1 value="#00ff00ff"></SPAN></TD>
<TD align=center class=GreyBorder> </TD></TR></TBODY></TABLE><BR></DIV>
page load
$('#tblTable tbody tr .colorPicker').each(function (index) {
$(this).jPicker({
window: {
expandable: true,
position: {
x: 'right', // acceptable values "left",
"center", "right", "screenCenter", or relative px value
y: 'bottom' // acceptable values "top",
"bottom", "center", or relative px value
},
color: {
active: $(this).attr('value')
}
}
});
});
});
Whenever your page gets load you can add active color for all instances of jPicker depending on the value attribute of span tag so that it will show correct colors . i.e :
$('#tblSBPComments tbody tr .colorPicker').each(function(index) {
$(this).jPicker({
window: {
expandable: true
},
color: {
active: $(this).attr("value") //setting active color on load
}
});
})
Then , to save these values in string or array you can use the index of the row which is been iterated and using that get the active color i.e :
var color = []; //storing value in array
var SBPCommentsGrid = "";//or in string
//loop though table
$('#tblSBPComments tbody tr').each(function(index) {
color.push('#' + $.jPicker.List[index].color.active.val('ahex') + "♥"); //push value in array here index will be 0, 1..etc
SBPCommentsGrid += '#' + $.jPicker.List[index].color.active.val('ahex') + "♥";
})
Working Example

Trying to change <td> background color based on checkbox value on Razor page

I would like this to turn red whenever the checkbox inside it is checked.
The Html.DisplayFor makes things a little more complicated. The Inactive field in SQL server table is boolean, zero or one.
<td align="center">
#Html.DisplayFor(modelItem => item.Inactive)
</td>
When looking at the table, the value is either 0 or 1. The page shows a checkbox which is desired but I am stuck trying to reference it's value and set the background-color of the surrounding table cell.
Try to use EditFor to replace DisplayFor,and then add the following js to your view:
function changeColor(t) {
if (t.checked) {
$(t).parent().css('background', 'red');
} else {
$(t).parent().css('background', 'none');
}
}
$('input[type=checkbox]').change(function () {
changeColor(this);
})
$(function () {
$('input[type=checkbox]').each(function () {
changeColor(this);
});
})

Struggling to understand the subtlety of relectToAttribute

I am struggling to understand the subtlety of reflectToAttribute on a Polymer elements property.
I have an pair of elements for transmitting values around the dom tree like iron-meta which I have called akc-meta and akc-meta-query. In my test fixture I am doing this
<test-fixture id="basic-test">
<template>
<template is="dom-bind" id=app>
<akc-meta key="[[key1]]" value="{{value1}}" id="meta1"></akc-meta>
<akc-meta-query key="[[key2]]" value="{{value2}}" id="meta2"></akc-meta-query>
<akc-meta-query key="[[key3]]" value="{{value3}}" id="meta3"></akc-meta-query>
<akc-meta key="[[key4]]" value="{{value4}}" id="meta4"></akc-meta>
</template>
</template>
</test-fixture>
and in my test suite I can set values like this
app.key1 = 'keya';
app.key2 = 'keya';
app.key3 = 'keya';
app.value1 = 'This is a multiple query test';
expect(app.value2).to.equal('This is a multiple query test');
expect(app.value3).to.equal('This is a multiple query test');
app.value1 = 'New Value';
expect(app.value2).to.equal('New Value');
expect(app.value3).to.equal('New Value');
where these elements transmit values under the hood between the elements when the keys are the same.
Neither of the elements use reflectToAttribute on any of the properties, although the value property of akc-meta-query does use notify:true
So what does reflectToAttribute actually do and why do you need it?
I have created a small example in this jsbin.
<style>
x-test {
display: block;
}
x-test[prop1="initialvalue1"] {
border: 5px solid yellow;
}
x-test[prop2="initialvalue2"] {
background: green;
}
x-test[prop1="newvalue1"] {
border: 5px solid black;
}
x-test[prop2="newvalue2"] {
background: red;
}
</style>
<dom-module id="x-test">
<template>
<div>{{prop1}}</div>
<div>{{prop2}}</div>
<button on-click="update1">Update Prop1</button>
<button on-click="update2">Update Prop2</button>
</template>
</dom-module>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'x-test',
properties:{
prop1: {
type:String
},
prop2: {
type:String,
reflectToAttribute: true
},
},
update1: function(){
this.prop1 = "newvalue1";
},
update2: function(){
this.prop2 = "newvalue2";
}
});
});
</script>
<x-test prop1="initialvalue1" prop2="initialvalue2"></x-test>
The element here has two properties. prop1 is not reflected to the attribute, but prop2 is. Both are set to an initial value. If you open the developer tools, you will see something like this:
There is an update button to change either prop1 or prop2. If you click each button and update both properties, you will get this picture
As you can see, prop1 still has its old state. The state change has not been reflected back to the attribute. In contrast, prop2 has been reflected and has changed.
Now if you access either property through JavaScript, you will get the updated value. However, when you access the HTML attribute, in case of prop1 you will not.
A use case for this could be when you have CSS rules with attribute selectors as in my example. The selector x-test[prop1="newvalue1"] does not apply when prop1 is updated. On the other hand x-test[prop2="newvalue2"] does apply after the update of prop2, because it is configured to reflect to attribute.

Creating a Range with two value with the Polymer Paper-Slider

I would like to create a range with Polymer Paper-Slider. A range that the user can move the Min and Max Pin and it has two outputs and not just one. For instance a Min and Max price that I can use to filter choices on an e-commerce site.
Hope someone can help.
Thanks
I've been looking for this as well, and found this Component http://ewgenius.github.io/paper-interval-slider/components/paper-interval-slider/
Works almost perfectly.
I am building on the comments above, using two sliders for min/max range.
It looks good thanks to the css hacking on the left slider, however the behavior is awkward due to working with two sliders and adjusting min / max on both.
This is what I got so far in case it's useful for somebody else.
(sample http://jsfiddle.net/zLk6h91v/)
<base href="//www.polymer-project.org/0.5/components/">
<link href="./paper-slider/paper-slider.html" rel="import">
<polymer-element name="xpm-range" attributes="rmin rmax vmin vmax onChangeRange">
<template >
<style>
paper-slider.min-slider::shadow #sliderKnobInner {
background-color: #3f51b5;
}
paper-slider.min-slider::shadow #sliderContainer {
width: calc(100% - 0px);
}
paper-slider.min-slider::shadow #sliderBar::shadow #activeProgress {
background-color: #c8c8c8;
}
paper-slider.min-slider::shadow #sliderBar::shadow #secondaryProgress {
background-color: #3f51b5;
}
paper-slider.min-slider::shadow #sliderBar::shadow #progressContainer {
background-color: #3f51b5;
}
</style>
<div layout horizontal >
<span self-center>Min {{vmin}}</span>
<paper-slider id="smin" flex pin min="{{rmin}}" max="{{vmax}}" value="{{vmin}}" on-change="{{onChange}}" class="min-slider"></paper-slider>
<paper-slider id="smax" flex pin min="{{vmin}}" max="{{rmax}}" value="{{vmax}}" on-change="{{onChange}}"></paper-slider>
<span self-center>Max {{vmax}}</span>
</div>
</template>
<script>
Polymer({
created: function() {
this.rmin = 0; this.rmax = 100;
},
onChange: function(e,d,s){
if (this.onChangeRange)
window[this.onChangeRange](e,d,s);
else console.log(this.vmin + " - " + this.vmax); // just while testing
},
ready: function(){
this.vmin = this.rmin;
this.vmax = this.rmax;
},
});
</script>
</polymer-element>
<span><br>Choose the range</span>
<xpm-range id="range1" style="width:100%" rmin="0" rmax="200" > </xpm-range>

Form tag-like inputs

I have no idea what this is even called so not sure where to start, hoping you all are able to point me in the right direction. I am trying to create something like this:
The idea being that when a user types something in and then separates with a comma, their input into this form field will turn into a little tag-like box that they can then delete with the x.
Any ideas on where to start?
Thanks!
Here is simple example: http://jsfiddle.net/9tzb4/
HTML:
<form>
Tags:
<div class="tag_field">
<input type="text">
<input type="hidden" name="tags">
</div>
<br>
<input type="submit" value="Submit">
</form>
CSS:
.tag_buttons {
position: absolute;
}
.tag_buttons div {
display:inline-block;
margin: 2px;
border: 1px solid #666;
padding: 1px;
}
.tag_field input[type=text] {
padding: 5px;
width: 300px;
border: 1px solid #666;
}
JavaScript:
$(".tag_field").each(function() {
var buttons = $("<div/>");
var input = $(this).find("input[type=text]");
var output = $(this).find("input[type=hidden]");
var update_padding = function() {
input.css("padding-left", buttons.width() + 2);
};
setInterval(update_padding, 300);
$(this).prepend(buttons);
buttons.addClass("tag_buttons");
buttons.css({ left: input.offset().left + 1,
top: input.offset().top + 2 });
input.bind("keyup change paste", function() {
var i = input.val().indexOf(",");
if (i >= 0) {
var new_tag = input.val().substr(0, i);
input.val(input.val().substr(i+1));
buttons.append("<div id='button'><span class='value'>"+new_tag+"</span> <span class='close'>(x)</span></div>");
}
});
var form = $(this).closest("form");
if (form.length > 0) {
form.submit(function() {
var v = [];
form.find(".tag_buttons div").each(function() {
v.push($(this).find(".value").html());
});
output.val(v.join(","));
return false;
});
}
});
$(document).on("click", ".tag_buttons span.close", {}, function(e) {
$(e.target).closest("div").detach();
});
Check this out. http://davidwalsh.name/dw-content/jquery-chosen.php This is the things I guess will perfectly suite your application.
Check out the amazing jQuery chosen, which - among other things - does exactly what you're looking for.
select2 is a similar plugin, and it also allows you to add your own tags (as well as use an AJAX source).
Update from the select2 docs:
Note that when tagging is enabled the user can select from pre-existing tags or create a new tag by picking the first choice which is what the user has typed into the search box so far.
You may find the jQuery Tags Input Library helpful. It gives you something like this