Reputation: 2737
I have a table, that I need to filter
Here is snippet
$(document).ready(function () {
var $rows = $('tbody#report tr')
var $filters = $('.table-filter').change(function(){
var filterArr = $filters.filter(function(){
return this.value
}).map(function(){
var $el = $(this);
var value = $el.is('select') ? $el.find(':selected').text() :$el.val()
return {
col: $el.data('col'),
value: value.toLowerCase()
}
}).get();
if(!filterArr.length){
$rows.show()
}else{
$rows.hide().filter(function(){
var $row = $(this)
return filterArr.every(function(filterObj, i){
var cellText = $row.find('td').eq(filterObj.col).text().toLowerCase();
return cellText.includes(filterObj.value);
})
}).show()
}
})
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/moment/moment/2.2.1/min/moment.min.js"></script>
<div class="row">
<div class="col-md-3">
<h4>Date from</h4>
<input type="date" class="table-filter form-control" id="datefilterfrom" data-date-split-input="true" data-col="1">
</div>
<div class="col-md-3">
<h4>Date to</h4>
<input type="date" class="table-filter form-control" id="datefilterto" data-date-split-input="true">
</div>
<div class="col-md-2">
<h4>Project</h4>
<select id="projectfilter" name="projectfilter" class="table-filter form-control" data-col="2">
<option value="">Select one</option>
<option value="1">Test project</option><option value="2">Test2</option></select>
</div>
<div class="col-md-2">
<h4>Service</h4>
<select id="servicefilter" name="servicefilter" class="table-filter form-control" data-col="3">
<option value="">Select one</option>
<option value="1">Test service</option><option value="2">Test2 service</option></select>
</div>
</div>
<table id="testTable" class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Date</th>
<th scope="col">Project</th>
<th scope="col">Service</th>
</tr>
</thead>
<tbody id="report">
<tr>
<td class="proposalId">9</td><td> 17/07/2018</td> <td> Test project</td><td> Test service</td>
</tr>
<tr><td class="proposalId">8</td><td> 18/07/2018</td><td> Test project</td><td> Test2 service</td></tr>
<tr><td class="proposalId">7</td><td> 17/07/2018</td><td> Test2</td><td> Test2 service</td></tr>
<tr style=""><td class="proposalId">3</td><td> 19/07/2018</td><td> Test2</td><td> Test service</td></tr>
</tbody>
</table>
It works great with text searches, it's 3 and 4 selectfields, but I cannot handle the date.
I was trying to do it like this
var value = $el.is('select') ? $el.find(':selected').text() : moment($el.val(), "YYYY-MM-DD").format('DD/MM/YYYY')
But it not works correctly. How I can solve it?
Here is my demo codepen snippet, you can use to test it
Upvotes: 1
Views: 74
Reputation: 32145
Well there are many things to correct in your code:
input
value is changed the whole filter is reset taking only only
this input value into account, you need to change the logic
behind that.select
value you just need $el.val()
instead of writing $el.is('select') ? $el.find(':selected').text() :$el.val()
.And you need to handle dates
separately in your filter
code, because .includes()
will be comparing strings
, so you need to calculate and compare date
objects here.
This is how should be your date comparison code:
if ($el.prop('type') == 'date') {
return filterArr.every(function(filterObj, i) {
var cellText = $row.find('td').eq(filterObj.col).text().toLowerCase();
if ($el.prop('id') == "datefilterfrom") {
return new Date(filterObj.value) <= new Date(cellText.split("/")[2], +cellText.split("/")[1] - 1, cellText.split("/")[0]);
}
if ($el.prop('id') == "datefilterto") {
return new Date(filterObj.value) >= new Date(cellText.split("/")[2], +cellText.split("/")[1] - 1, cellText.split("/")[0]);
}
})
}
Note:
For the date
inputs you need to pass 1
as col
value in your filter object because you have only one date column in your table:
if ($el.prop('type') == 'date') {
return {
col: 1,
value: value.toLowerCase()
}
}
Demo:
This is an updated working demo.
$(document).ready(function() {
var $rows = $('tbody#report tr')
var $filters = $('.table-filter').change(function() {
var $el = $(this);
var filterArr = $filters.filter(function() {
return this.value
}).map(function() {
var value = $el.val();
if ($el.prop('type') == 'date') {
return {
col: 1,
value: value.toLowerCase()
}
}
return {
col: $el.data('col'),
value: value.toLowerCase()
}
}).get();
if (!filterArr.length) {
$rows.show()
} else {
$rows.hide().filter(function() {
var $row = $(this);
if ($el.prop('type') == 'date') {
return filterArr.every(function(filterObj, i) {
var cellText = $row.find('td').eq(filterObj.col).text().toLowerCase();
if ($el.prop('id') == "datefilterfrom") {
return new Date(filterObj.value) <= new Date(cellText.split("/")[2], +cellText.split("/")[1] - 1, cellText.split("/")[0]);
}
if ($el.prop('id') == "datefilterto") {
return new Date(filterObj.value) >= new Date(cellText.split("/")[2], +cellText.split("/")[1] - 1, cellText.split("/")[0]);
}
})
} else {
return filterArr.every(function(filterObj, i) {
var cellText = $row.find('td').eq(filterObj.col).text().toLowerCase();
return cellText.includes(filterObj.value);
})
}
}).show()
}
})
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/moment/moment/2.2.1/min/moment.min.js"></script>
<div class="row">
<div class="col-md-3">
<h4>Date from</h4>
<input type="date" class="table-filter form-control" id="datefilterfrom" data-date-split-input="true" data-col="1">
</div>
<div class="col-md-3">
<h4>Date to</h4>
<input type="date" class="table-filter form-control" id="datefilterto" data-date-split-input="true">
</div>
<div class="col-md-2">
<h4>Project</h4>
<select id="projectfilter" name="projectfilter" class="table-filter form-control" data-col="2">
<option value="">Select one</option>
<option value="1">Test project</option>
<option value="2">Test2</option>
</select>
</div>
<div class="col-md-2">
<h4>Service</h4>
<select id="servicefilter" name="servicefilter" class="table-filter form-control" data-col="3">
<option value="">Select one</option>
<option value="1">Test service</option>
<option value="2">Test2 service</option>
</select>
</div>
</div>
<table id="testTable" class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Date</th>
<th scope="col">Project</th>
<th scope="col">Service</th>
</tr>
</thead>
<tbody id="report">
<tr>
<td class="proposalId">9</td>
<td> 17/07/2018</td>
<td> Test project</td>
<td> Test service</td>
</tr>
<tr>
<td class="proposalId">8</td>
<td> 18/07/2018</td>
<td> Test project</td>
<td> Test2 service</td>
</tr>
<tr>
<td class="proposalId">7</td>
<td> 17/07/2018</td>
<td> Test2</td>
<td> Test2 service</td>
</tr>
<tr style="">
<td class="proposalId">3</td>
<td> 19/07/2018</td>
<td> Test2</td>
<td> Test service</td>
</tr>
</tbody>
</table>
Upvotes: 2
Reputation: 76
Try this
var value = $el.is('select') ? $el.find(':selected').text() : moment($el.val().replace(/(\d{2})\/(\d{2})\/(\d{4}).*/, '$3-$2-$1'), "YYYY-MM-DD").format('DD/MM/YYYY')
for example
document.write(("17/07/2018").replace(/(\d{2})\/(\d{2})\/(\d{4}).*/, '$3-$2-$1'))
Upvotes: 0