datatables create filter checkbox - datatables

Does anyone have examples on how to create a Datatablest filter checkbox? I want to display only rows that have a value above X or below Y being controlled by a checkbox.

You would have to write your own custom filtering function but after that the code would be vary simple
$(document).ready(function() {
$.fn.dataTableExt.afnFiltering.push(function(oSettings, aData, iDataIndex) {
var checked = $('#checkbox').is(':checked');
if (checked && aData[4] > 1.5) {
return true;
}
if (!checked && aData[4] <= 1.5) {
return true;
}
return false;
});
var oTable = $('#example').dataTable();
$('#checkbox').on("click", function(e) {
oTable.fnDraw();
});
});​
fiddle http://jsfiddle.net/nicolapeluchetti/WVYNX/2/

Related

Array is not cloned, wrapped inside Proxy

Im executing this code inside vue created() method:
const width = window.innerWidth;
const columns = this.columns.slice()
let colVis = columns.map((element) => {
if(element.sClass == 'min-tv' && width < 2500) {
element.visible = false;
return element;
} else if(element.sClass == 'min-desktop-lg' && width < 1980) {
element.visible = false;
return element;
} else {
return element;
}
});
console.log(columns);
console.log(colVis);
For some reason both arrays returns same values (and this.columns too).
Everything is wraped inside Proxy - arrays and their values.
I cant understand whats going on and why i can't have clone of array?
I don't use computed, because it's initialization values (for Datatables colvis).
You should use filter to filter data from an array.
const width = window.innerWidth;
const columns = this.columns.slice()
let colVis = columns.map((element) => {
if(element.sClass == 'min-tv' && width < 2500) {
element.visible = false;
return element;
} else if(element.sClass == 'min-desktop-lg' && width < 1980) {
element.visible = false;
return element;
} else {
return element;
}
}).filter((element) => element.visible);
console.log(columns);
console.log(colVis);
It turns out to be vue bug.
Using inline window.innerWidth breaks its normal behavior.

Highcharts with decrease order in each interval

Is it possible to create a graph sorted in each time interval using Highcharts?
For expample, in this picture for January data will be in order: New York, Tokyo, London, Berlin. The same for each months - data should be shown decrease order
Highcharts doesn't have a built-in function to do that, but for example you can use the render event and organize columns, by changing their positions in the way you need.
events: {
render: function() {
var series = this.series,
longestSeries = series[0],
sortedPoints = [],
selectedPoints = [];
// find a series with the highest amount of points
series.forEach(function(s) {
if (s.points.length > longestSeries.points.length) {
longestSeries = s;
}
});
longestSeries.points.forEach(function(point) {
series.forEach(function(s) {
selectedPoints.push(s.points[point.index]);
});
sortedPoints = selectedPoints.slice().sort(function(a, b) {
return b.y - a.y;
});
selectedPoints.forEach(function(selectedPoint) {
if (
selectedPoints.indexOf(selectedPoint) !==
sortedPoints.indexOf(selectedPoint) &&
selectedPoint.graphic
) {
// change column position
selectedPoint.graphic.attr({
x: sortedPoints[selectedPoints.indexOf(selectedPoint)].shapeArgs.x
});
}
});
sortedPoints.length = 0;
selectedPoints.length = 0;
});
}
}
Live demo: https://jsfiddle.net/BlackLabel/tnrch8v1/
API Reference:
https://api.highcharts.com/highcharts/chart.events.render
https://api.highcharts.com/class-reference/Highcharts.SVGElement#attr
#ppotaczek Thank You for help a lot! I solve my issue, but i had to make some changes to your code:
events: {
render: function() {
if (this.series.length === 0) return
var series = this.series,
longestSeries = series[0],
sortedPoints = [],
selectedPoints = [];
// find a series with the highest amount of points
series.forEach(function(s) {
if (s.points.length > longestSeries.points.length) {
longestSeries = s;
}
});
longestSeries.points.forEach(function(point) {
series.forEach(function(s) {
selectedPoints.push(s.points[point.index]);
});
sortedPoints = selectedPoints.slice().sort(function(a, b) {
return b.y - a.y;
});
selectedPoints.forEach(function(selectedPoint) {
if (
selectedPoints.indexOf(selectedPoint) !==
sortedPoints.indexOf(selectedPoint) &&
selectedPoint.graphic
) {
// change column position
selectedPoint.graphic.attr({
x: selectedPoints[sortedPoints.indexOf(selectedPoint)].shapeArgs.x
});
}
});
sortedPoints.length = 0;
selectedPoints.length = 0;
});
}
},
}
So i changed:
// change column position
selectedPoint.graphic.attr({
x: sortedPoints[selectedPoints.indexOf(selectedPoint)].shapeArgs.x
});
to:
// change column position
selectedPoint.graphic.attr({
x: selectedPoints[sortedPoints.indexOf(selectedPoint)].shapeArgs.x
});

Aurelia refresh property dependencies

Validate if checkbox should be displayed in html page:
get canPerformCommand() {
let r = false;
let valids = ['Success', 'Error'];
if (this.requests.length == 0) return false;
if (valids.indexOf(this.myresult[0].requestStatus) > 0) {
r = true;
}
return r;
}
Html page:
<span if.bind="canPerformCommand" class="panel-heading-buttons">
<button click.trigger="confirm()">Confirm</button>
</span>
Search:
return this.myService.getRequests()
.then(data => {
this.requests = data
//Somehow refresh canPerformCommand here?
});
this.requests will be empty on first page load, resulting in canPerformCommand = false.
I want to refresh canPerformCommand when using the search function.
Currently canPerformCommand will not refresh itself after a search has been done.
How do I refresh canPerformCommand after search using Property Dependencies?
Solution:
The easiest and most logical solution would be to change canPerformCommand into two separate entities -- a flag variable and a function. Make the flag variable be canPerformCommand and keep the if.bind=canPerformCommand but change the name of your function to updateCanPerformCommand() so that you can easily call this function from your return this.myService.getRequests() .then function.
Details:
Set up your view-model like this:
export class App { // <-- (or whatever yours is called)
canPerformCommnad = false;
constructor() {
// ...
}
updateCanPerformCommand() {
let r = false;
let valids = ['Success', 'Error'];
if (this.requests.length == 0) {
this.canPerformCommand = false;
} else if (valids.indexOf(this.myresult[0].requestStatus) > 0) {
this.canPerformCommand = true;
}
}
}
I believe you need to change myresult to requests in the canPerformCommand getter:
get canPerformCommand() {
let r = false;
let valids = ['Success', 'Error'];
if (this.requests.length == 0) return false;
if (valids.indexOf(this.requests[0].requestStatus) > 0) {
r = true;
}
return r;
}
Since this getter will be dirty checked by Aurelia, it will be called every 200ms. To avoid that, you can add a computedFrom decorator:
import {computedFrom} from 'aurelia-framework';
export class MyClass {
....
#computedFrom('requests')
get canPerformCommand() { ....
I replaced:
if (valids.indexOf(this.myresult[0].requestStatus) > 0) {
r = true;
}
With
if (valids.includes(this.requests[0].requestStatus)) {
r = true;
}
And now it works. I was using the indexOf function on other pages aswell, and strangely enough it worked on most of them. Must have been something wrong in my model.
Also, I agree that it would be better to use computedFrom.

Mithril redraw only 1 module

If I have like 10 m.module on my page, can I call m.startComputation, m.endComputation, m.redraw or m.request for only one of those modules?
It looks like any of these will redraw all of my modules.
I know only module 1 will be affected by some piece of code, I only want mithril to redraw that.
Right now, there's no simple support for multi-tenancy (i.e. running multiple modules independently of each other).
The workaround would involve using subtree directives to prevent redraws on other modules, e.g.
//helpers
var target
function tenant(id, module) {
return {
controller: module.controller,
view: function(ctrl) {
return target == id ? module.view(ctrl) : {subtree: "retain"}
}
}
}
function local(id, callback) {
return function(e) {
target = id
callback.call(this, e)
}
}
//a module
var MyModule = {
controller: function() {
this.doStuff = function() {alert(1)}
},
view: function() {
return m("button[type=button]", {
onclick: local("MyModule", ctrl.doStuff)
}, "redraw only MyModule")
}
}
//init
m.module(element, tenant("MyModule", MyModule))
You could probably also use something like this or this to automate decorating of event handlers w/ local
Need multi-tenancy support for components ? Here is my gist link
var z = (function (){
//helpers
var cache = {};
var target;
var type = {}.toString;
var tenant=function(componentName, component) {
return {
controller: component.controller,
view: function(ctrl) {
var args=[];
if (arguments.length > 1) args = args.concat([].slice.call(arguments, 1))
if((type.call(target) === '[object Array]' && target.indexOf(componentName) > -1) || target === componentName || target === "all")
return component.view.apply(component, args.length ? [ctrl].concat(args) : [ctrl])
else
return {subtree: "retain"}
}
}
}
return {
withTarget:function(components, callback) {
return function(e) {
target = components;
callback.call(this, e)
}
},
component:function(componentName,component){
//target = componentName;
var args=[];
if (arguments.length > 2) args = args.concat([].slice.call(arguments, 2))
return m.component.apply(undefined,[tenant(componentName,component)].concat(args));
},
setTarget:function(targets){
target = targets;
},
bindOnce:function(componentName,viewName,view) {
if(cache[componentName] === undefined) {
cache[componentName] = {};
}
if (cache[componentName][viewName] === undefined) {
cache[componentName][viewName] = true
return view()
}
else return {subtree: "retain"}
},
removeCache:function(componentName){
delete cache[componentName]
}
}
})();

Dojo - don't repeat yourself

Is there a simpler way to write something like this in dojo (instead of having a function for each thing i want to show or hide)? I know there must be a way to avoid such repetition but I'm not sure how to do it.
on(dom.byId("thing_toggle2"), "click", function(){
if(thing_list2.style.display == "none") {
thing_list2.style.display = "block";
dom.byId("toggle2_sign").innerHTML = "(-)";
} else {
thing_list2.style.display = "none";
dom.byId("toggle2_sign").innerHTML = "(+)";
};
});
on(dom.byId("thing_toggle3"), "click", function(){
if(thing_list3.style.display == "none") {
thing_list3.style.display = "block";
dom.byId("toggle3_sign").innerHTML = "(-)";
} else {
thing_list3.style.display = "none";
dom.byId("toggle3_sign").innerHTML = "(+)";
};
});
I didn't test this, but it should give you a starting point. Adding an additional section, would just involve adding to the array of data.
var fnToggle = function(nodeMap) {
var expand = domStyle.get(dom.byId(nodeMap.contentNode), 'display') == 'none';
domStyle.set(dom.byId(nodeMap.contentNode), 'display', expand ? 'block' : '');
html.set(dom.byId(nodeMap.expandoNode), expand ? '+' : '-');
};
var nodes = [
{ eventNode: 'thing_toggle2', contentNode: thing_list2, expandoNode: 'toggle2_sign' },
{ eventNode: 'thing_toggle3', contentNode: thing_list3, expandoNode: 'toggle3_sign' }
];
array.forEach(nodes, function(nodeMap) {
on(dom.byId(nodeMap.eventNode), "click", function(){ fnToggle(nodeMap); });
});
// domStyle -> dojo/dom-style
// html -> dojo/html
// array -> dojo/_base/array
You could use dojo/fx/Toggler which uses dojo/_base/fx.fadeOut and dojo/_base/fx.fadeIn
I actually decided to do this as a plain old javascript function which I can reuse elsewhere, including pages that might not need dojo. Something like this:
[1]
[2]
<div id="myName" style="display:none;">Antonio</div>
<div id="anothername" style="display:none;">Elliot</div>
<script type="text/javascript">
function showlayer(layer){
var myLayer = document.getElementById(layer).style.display;
if(myLayer=="none"){
document.getElementById(layer).style.display="block";
} else {
document.getElementById(layer).style.display="none";
};
}
</script>