My checkbox filter is totally removing all data records instead of filtering.
I used this post as guidance: http://jsfiddle.net/65Pyj/
I can get and console the selected category. I am having problems filtering the list.
My data is like so:
{"product_title":"COPD Track Package","product_code":"COPDPKG2014","id":"a1u40000000C182AAC","Id":"a1u40000000C182AAC","sort_order":"6","sort_code":"COPDPKG2014","category":["Postgraduate Course, Continuing Education"]}
Here is the angular:
<div class="container">
<div class="ng-scope" ng-app="products">
<div class="ng-scope" ng-controller="ShoppingCartCtrl">
<div class="row">
<div class="col-sm-7"><h3 class="colored-title">Search Filter</h3>
<table class="table table-striped table-bordered">
<tbody>
<tr>
<td>By Product Title:</td>
<td><input ng-model="search.product_title" type="text"/></td>
</tr>
<tr>
<td>By Product Code:</td>
<td><input ng-model="search.product_code" type="text"/></td>
</tr>
<tr>
<td>By Presentation Title:</td>
<td><input ng-model="search.presentations" type="text"/></td>
</tr>
<tr>
<td>By Speaker Name:</td>
<td><input ng-model="search.speakers" type="text"/></td>
</tr>
<tr>
<td><input type="checkbox" ng-click="includeProduct('Postgraduate Course')"/>Postgraduate Course</td>
<td><input type="checkbox" ng-click="includeProduct('Continuing Education')"/>Continuing Education</td>
</tr>
<tr><td>Filter dump: {{productIncludes}}</td></tr>
</tbody>
</table></div>
</div>
<div>Sort by:<select ng-model="sortExpression">
<option value="sort_code">Product Code</option>
<option value="product_title">Product Title</option>
</select></div>
<table class="table table-bordered table-striped">
<thead>
<tr class="warning"><th>Product Code</th><th>Product Title</th></tr>
</thead>
<tbody>
<tr ng-repeat="item in items | orderBy:mySortFunction | filter:search |filter:productFilter">
<td valign="top">
{{item.id}}<div ng-repeat="c in item.cat" >{{c}}</div>
</td>
<td>
{{item.product_title}}
</tr>
</tbody>
</table>
</div>
$scope.productIncludes = [];
$scope.includeProduct = function(category){
var i = $.inArray(category, $scope.productIncludes);
if(i > -1){
$scope.productIncludes.splice(i,1);
}else{
$scope.productIncludes.push(category);
}
console.log($scope.items.length);
}
$scope.productFilter = function (items) {
if ($scope.productIncludes.length > 0) {
if ($.inArray(items.cat, $scope.productIncludes) < 0) return;
}
return items;
}
Basically it is problem with your data representations.
You have categories stored as "category":["Postgraduate Course, Continuing Education"] and you want to search in those categories as if it was an array like "category":["Postgraduate Course", "Continuing Education"].
I recommend you to represent your data like the second case and then you can iterate over it like this:
$scope.productFilter = function (items) {
if ($scope.productIncludes.length > 0) {
var result = $scope.productIncludes.filter(function(n) {
return items.category.indexOf(n) != -1
});
if(result.length < 1) {
return;
}
}
return items;
}
And here is your fiddle: http://jsfiddle.net/65Pyj/133/
Short explanation:
filter function in combination with the indexOf function will return an intersection of the two arrays.
Related
I'm trying to sort rows in alphabetical order based on which column header is clicked using jQuery. It works fairly fine when debugging except that it doesn't actually switch the rows in the HTML and so it doesn't display a sorted table on the webpage. I'm using Thymeleaf th:text to populate the table body rows but for the sake of this example, I hardcoded some values. You can run it here: https://jsfiddle.net/tg2khrd4
Javascript:
var table = $("#table");
$("#subject, #from, #id")
.wrapInner('<span title="sort this column"/>')
.each(function () {
var th = $(this),
thIndex = th.index(),
inverse = false;
th.click(function () {
table
.find("tbody")
.find("td")
.filter(function () {
return $(this).index() === thIndex;
})
.sort(
function (a, b) {
return $.text([a]) > $.text([b])
? inverse
? -1
: 1
: inverse
? 1
: -1;
},
function () {
// parentNode is the element we want to move
return this.parentNode;
}
);
inverse = !inverse;
});
});
HTML:
<table class="table table-hover" id="table" style="background-color:#fff;border: 1px solid #cccccc">
<thead style="background-color:#981e32;">
<tr>
<td class="tdsubj" id="id" style="padding:5px;">Id
</td>
<td class="tdsubj" id="subject" style="padding:5px;">
Subject
</td>
<td class="tdsubj" id="from" style="padding:5px;">
From
</td>
<td class="tdsubj" id="date" style="padding:5px;">
Date
</td>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Hello</td>
<td>Thor</td>
<td>2020-10-19</td>
</tr>
<tr>
<td>2</td>
<td>Dinos Suck</td>
<td>Meteor</td>
<td>2020-9-5</td>
</tr>
<tr>
<td>3</td>
<td>Big Ben won't stop ringing</td>
<td>The Queen</td>
<td>2020-8-19</td>
</tr>
</tbody>
</table>
Once the td sorted... You just have to loop throught it and append it's parent tr in the table...
var table = $("#table");
$("#subject, #from, #id")
// .wrapInner('<span title="sort this column"/>')
.each(function () {
var th = $(this),
thIndex = th.index(),
inverse = false;
th.click(function () {
let test = table
.find("tbody")
.find("td")
.filter(function () {
return $(this).index() === thIndex;
})
.sort(
function (a, b) {
return $.text([a]) > $.text([b])
? inverse
? -1
: 1
: inverse
? 1
: -1;
}
// That is useless...
/*function () {
// parentNode is the element we want to move
console.log(this.parentNode)
return this.parentNode;
}*/
);
// Added to demonstrate the sorting works
console.clear()
test.each(function () {
console.log(this.innerText);
});
// Now to apply the sorting on the DOM
// Find the tr containing it and append it to the table.
test.each(function () {
table.append($(this).parent("tr"))
});
inverse = !inverse;
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table table-hover" id="table" style="background-color:#fff;border: 1px solid #cccccc">
<thead style="background-color:#981e32;">
<tr>
<td class="tdsubj" id="id" style="padding:5px;">Id
</td>
<td class="tdsubj" id="subject" style="padding:5px;">
Subject
</td>
<td class="tdsubj" id="from" style="padding:5px;">
From
</td>
<td class="tdsubj" id="date" style="padding:5px;">
Date
</td>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Hello</td>
<td>Thor</td>
<td>2020-10-19</td>
</tr>
<tr>
<td>2</td>
<td>Dinos Suck</td>
<td>Meteor</td>
<td>2020-9-5</td>
</tr>
<tr>
<td>3</td>
<td>Big Ben won't stop ringing</td>
<td>The Queen</td>
<td>2020-8-19</td>
</tr>
</tbody>
</table>
I am using ng-table example from this page:
http://4dev.tech/2015/08/tutorial-basic-datatable-sorting-filtering-and-pagination-with-angularjs-and-ng-table/
Also I added selection method with ng-click method
<table ng-table="usersTable" id="productTable" class="table table-striped">
<tr>
<th ng-repeat="column in cols">{{column}}</th>
<th> Adet</th>
</tr>
<tr ng-repeat="row in data | filter: src_product">
#*<td ng-class="{ 'highlighted':row[column].isSelected }" ng-click ="selectCell(row[column])" ng-repeat="column in cols "> {{row[column]}} </td>*#
<td ng-class="{'highlighted':isSelected =='true'}" ng-model="product_field" ng-click="selectCell(this)" ng-repeat="column in cols ">{{row[column]}}</td>
<td><input class="input-group" type="text" style="width: 100%; height: 30px !important" name=" adet" value="0"></td>
</tr>
</table>
$scope.selectCell = function(cell) {
var selectedCellindex = (cell.$index) + (cell.$parent.$index) * ($scope.cols.length + 1);
var selectedCell = document.getElementsByTagName("td")[selectedCellindex];
if (selectedCell.getAttribute("class") === null) {
selectedCell.setAttribute("class", "highlighted");
} else {
selectedCell.removeAttribute("class");
}
}
The problem is that it only selects cells on current visible page. How can i solve this problem or store selected cells ?
I've got this problem:
I have a table in HTML, that I want to edit via Javascript.
The table info is of rooms with either value 0 or 1.
I have two buttons that can change a cell, that can set the value to 1 or 0, but I want a function connected to one button, that changes the value, as 1 gets to 0, and 0 gets to 1.
One solution I find is to give each cell an ID and change it, and the other one is to use row/cell from the table.
<table id="table1">
<table border="1" cellpadding="1" cellspacing="3">
<tr>
<td> Room </td>
<td> Status </td>
</tr>
<tr>
<td> r1 </td>
<td id="room1"> 0 </td>
</tr>
<tr>
<td> r2 </td>
<td> 0 </td>
</tr>
<tr>
<td> r3 </td>
<td> 1 </td>
</tr>
Currently I've tried:
<button type="button" onclick="metode1()">Room 1 => 0/1</button>
<button type="button" onclick="metode2()">Room 1 => 0</button>
<script>
function metode1(){
if(document.getElementById("room1").innerHTML > 0) {
document.getElementById("room1").innerHTML = 0;
}
else {
document.getElementById("room1").innerHTML = 1;
}
}
function metode2(){
document.getElementById("table1").rows[1].cells[1].innerHTML = 0;
}
</script>
But neither of them work..
What can I do?
metode1 would work, but your initial text in the element has spaces on either side of the 0, so > can't implicitly convert it to a number. If you remove the spaces (in the markup, or by doing .innerHTML.trim() on a modern browser), the implicit conversion from string to number will work. You might consider converting explicitly, but you'll still have to trim.
Live Example with the spaces removed in the markup:
function metode1() {
if (document.getElementById("room1").innerHTML > 0) {
document.getElementById("room1").innerHTML = 0;
} else {
document.getElementById("room1").innerHTML = 1;
}
}
<table border="1" cellpadding="1" cellspacing="3">
<tr>
<td>Room</td>
<td>Status</td>
</tr>
<tr>
<td>r1</td>
<td id="room1">0</td>
</tr>
<tr>
<td>r2</td>
<td>0</td>
</tr>
<tr>
<td>r3</td>
<td>1</td>
</tr>
</table>
<button type="button" onclick="metode1()">Room 1 => 0/1</button>
Live Example using trim:
function metode1() {
if (document.getElementById("room1").innerHTML.trim() > 0) {
document.getElementById("room1").innerHTML = 0;
} else {
document.getElementById("room1").innerHTML = 1;
}
}
<table border="1" cellpadding="1" cellspacing="3">
<tr>
<td>Room</td>
<td>Status</td>
</tr>
<tr>
<td>r1</td>
<td id="room1"> 0 </td>
</tr>
<tr>
<td>r2</td>
<td>0</td>
</tr>
<tr>
<td>r3</td>
<td>1</td>
</tr>
</table>
<button type="button" onclick="metode1()">Room 1 => 0/1</button>
Note that trim was added in ECMAScript5 (2009) and so may not be on some older JavaScript engines. It's easily shimmed, though.
Try this-
<button type="button" onclick="metode1()">Room 1 => 0/1</button>
function metode1(){
if(document.getElementById("room1").innerHTML.trim() =="1") {
document.getElementById("room1").innerHTML = 0;
}
else {
document.getElementById("room1").innerHTML = 1;
}
}
I have a dynamic html table:
<table>
<tbody>
<tr>
<td>Name</td>
<td>City</td>
</tr>
<tr class="new" id="item1">
<td><input class="names" value="John Smith" type="hidden">John Smith</td>
<td><input class="cities" value="London" type="hidden">London</td>
</tr>
<tr class="normal" id="item2">
<td><input class="names" value="Regina Mills" type="hidden">Regina Mills</td>
<td><input class="cities" value="Berlin" type="hidden">Berlin</td>
</tr>
<tr class="normal" id="item3">
<td><input class="names" value="Marcus Bell" type="hidden">Marcus Bell</td>
<td><input class="cities" value="Liverpool" type="hidden">Liverpool</td>
</tr>
</tr>
</tbody>
</table>
From my js file I'm storing the information in this way:
var arrayNames = [];
$(".names").each(function(){
arrayNames.push($(this).val());
})
var arrayCities = [];
$(".cities").each(function(){
arrayCities.push($(this).val());
})
params += '&names='+arrayNames;
params += '&cities='+arrayCities;
With this I am getting in my php:
$_REQUEST['names']
: string = John Smith,Regina Mills,Marcus Bell
$_REQUEST['cities']
: string = London,Berlin,Liverpool
But I only need in the $_REQUESTs the values when the class in the table tr's is "new"
How can I do that?
Thanks!
You could try
$(".names").each(function(){
if ($( this ).parent().attr( "class" ) == "new")
arrayNames.push($(this).val());
})
Just target the .names within .new. You can use map() to get the values:
var arrayNames = $('.new .names').map(function() { return this.value; }).get();
.. and do the same thing for .cities
Edit: I have solved this by myself. See my answer below
I have set up a nice sortable table with jQuery and it is quite nice. But now i want to extend it.
Each table row has a text box, and i want i am after is to, every time a row is dropped, the text boxes update to reflect the order of the text boxes. E.g. The text box up the top always has the value of '1', the second is always '2' and so on.
I am using jQuery and the Table Drag and Drop JQuery plugin
Code
Javascript:
<script type = "text/javascript" >
$(document).ready(function () {
$("#table-2").tableDnD({
onDrop: function (table, row) {
var rows = table.tBodies[0].rows;
var debugStr = "Order: ";
for (var i = 0; i < rows.length; i++) {
debugStr += rows[i].id + ", ";
}
console.log(debugStr)
document.forms['productform'].sort1.value = debugStr;
document.forms['productform'].sort2.value = debugStr;
document.forms['productform'].sort3.value = debugStr;
document.forms['productform'].sort4.value = debugStr;
},
});
});
</script>
HTML Table:
<form name="productform">
<table cellspacing="0" id="table-2" name="productform">
<thead>
<tr>
<td>Product</td>
<td>Order</td>
</tr>
</thead>
<tbody>
<tr class="row1" id="Pol">
<td>Pol</td>
<td><input type="textbox" name="sort1"/></td>
</tr>
<tr class="row2" id="Evo">
<td>Evo</td>
<td><input type="textbox" name="sort2"/></td>
</tr>
<tr class="row3" id="Kal">
<td>Kal</td>
<td><input type="textbox" name="sort3"/></td>
</tr>
<tr class="row4" id="Lok">
<td>Lok</td>
<td><input type="textbox" name="sort4"/></td>
</tr>
</tbody>
</table>
</form>
Hardnrg in #jquery ended up solving it for me.
It involved adding an id="" to each input:
<form name="productform">
<table cellspacing="0" id="table-2" name="productform">
<thead>
<tr><td>Product</td> <td>Order</td></tr>
</thead>
<tbody>
<tr class="row1" id="Pol"> <td>Pol</td> <td><input id="Pol_field" type="textbox" name="sort1"/></td> </tr>
<tr class="row2" id="Evo"> <td>Evo</td> <td><input id="Evo_field" type="textbox" name="sort2"/></td> </tr>
<tr class="row3" id="Kal"> <td>Kal</td> <td><input id="Kal_field" type="textbox" name="sort3"/></td> </tr>
<tr class="row4" id="Lok"> <td>Lok</td> <td><input id="Lok_field" type="textbox" name="sort4"/></td> </tr>
</tbody>
</table>
</form>
And add this js to the OnDrop event:
for (var i=0; i < rows.length; i++) {
$('#' + rows[i].id + "_field").val(i+1);
}
Easy peasy!
Hmmm..
I think you want to do something like this:
$("input:text", "#table-2").each( function(i){ this.value=i+1; });
The $().each() function's info is here: http://docs.jquery.com/Core/each