@@ -260,6 +260,10 @@ const TABLE_STYLE = """
260260 color: white;
261261}
262262
263+ .constraint-filter-btn { background: #ccc; color: #333; } /* default gray */
264+ .constraint-filter-btn.positive { background: #4caf50; color: white; } /* green */
265+ .constraint-filter-btn.negative { background: #f44336; color: white; } /* red */
266+
263267/* ==============================
264268 Filters (Inputs / Selects)
265269 ============================== */
@@ -610,32 +614,56 @@ function initProblemsTable() {
610614 filterContainer.append(html);
611615
612616 \$ (document).on('click', '.constraint-filter-btn', function() {
613- \$ (this).toggleClass('active');
617+ if (\$ (this).hasClass('positive')) {
618+ \$ (this).removeClass('positive').addClass('negative'); // green → red
619+ } else if (\$ (this).hasClass('negative')) {
620+ \$ (this).removeClass('negative'); // red → gray
621+ } else {
622+ \$ (this).addClass('positive'); // gray → green
623+ }
614624 applyConstraintFilter();
615625 });
616626
617627 function applyConstraintFilter() {
618- const active = [];
619- \$ ('.constraint-filter-btn.active').each(function(){ active.push(\$ (this).data('type')); });
628+ const activeConditions = [];
629+
630+ \$ ('.constraint-filter-btn.positive').each(function(){
631+ const c = \$ (this).data('type');
632+ activeConditions.push({type: c, check: 'positive'});
633+ });
634+ \$ ('.constraint-filter-btn.negative').each(function(){
635+ const c = \$ (this).data('type');
636+ activeConditions.push({type: c, check: 'negative'});
637+ });
638+
620639 const logic = \$ ('#constraints-logic').val();
621640
622641 // Remove old constraint filter
623642 \$ .fn.dataTable.ext.search = \$ .fn.dataTable.ext.search.filter(f => f !== constraintFilter);
624643
625- // New constraint filter
626644 constraintFilter = function(settings, data, dataIndex){
627- if(active.length === 0) return true;
628645 const rowData = table.row(dataIndex).data();
629- const hasConstraints = active.map(c => rowData["Dim"+{
630- x:"StateConstraint", u:"ControlConstraint", v:"VariableConstraint", c:"PathConstraint", b:"BoundaryConstraint"
631- }[c]] > 0);
632- return logic==="AND" ? hasConstraints.every(v=>v) : hasConstraints.some(v=>v);
646+ const map = {
647+ x:"StateConstraint", u:"ControlConstraint",
648+ v:"VariableConstraint", c:"PathConstraint", b:"BoundaryConstraint"
649+ };
650+
651+ // Build conditions
652+ const results = activeConditions.map(cond => {
653+ const val = rowData["Dim"+map[cond.type]];
654+ return cond.check === 'positive' ? (val > 0) : (val === 0);
655+ });
656+
657+ if (results.length === 0) return true;
658+
659+ return logic === "AND" ? results.every(v=>v) : results.some(v=>v);
633660 };
634661
635662 \$ .fn.dataTable.ext.search.push(constraintFilter);
636663 table.draw();
637664 }
638665
666+
639667 \$ (document).on('change', '#constraints-logic', applyConstraintFilter);
640668}
641669</script>
0 commit comments