I want to get a button on the last datarecord called factuur. I would like to get a div or button there but how can i do this in an data array like this one.
I was thinking i should add an class to the td and replace the text in here with something like this:
$('.className').each(function(index, item){
$(item).html(yourButton html);
})
Someone knows how to do this or a better way to do this?I looked into this but cant figure out how to apply is on my json.
this is how my script looks like now:
<table id="oTable" border="1" class="table_tag">
<tr><thead>
<th>Ordernummer</th>
<th>Besteldatum</th>
<th>BTW</th>
<th>Totaalbedrag</th>
<th>Status</th>
<th>Verzonden</th>
<th>Factuur</th>
</thead></tr>
</table>
script:
$(function(){
// Basic Setup
var $tableSel = $('#oTable');
$tableSel.dataTable({
'aaData': data,
'aoColumns': [
{'mData': 'EAN'},
{'mData': 'Besteldatum'},
{'mData': 'BTW'},
{'mData': 'Totaalbedrag'},
{'mData': 'Status'},
{'mData': 'Verzonden'},
{'mData': 'Factuur'}
],
'sDom': ''
});
$('#filter').on('click', function(e){
e.preventDefault();
var startDate = $('#start').val(),
endDate = $('#end').val();
filterByDate(1, startDate, endDate);
$tableSel.dataTable().fnDraw();
});
// Clear the filter. Unlike normal filters in Datatables,
// custom filters need to be removed from the afnFiltering array.
$('#clearFilter').on('click', function(e){
e.preventDefault();
$.fn.dataTableExt.afnFiltering.length = 0;
$tableSel.dataTable().fnDraw();
});
});
/* Our main filter function
* We pass the column location, the start date, and the end date
*/
var filterByDate = function(column, startDate, endDate) {
// Custom filter syntax requires pushing the new filter to the global filter array
$.fn.dataTableExt.afnFiltering.push(
function( oSettings, aData, iDataIndex ) {
var rowDate = normalizeDate(aData[column]),
start = normalizeDate(startDate),
end = normalizeDate(endDate);
// If our date from the row is between the start and end
if (start <= rowDate && rowDate <= end) {
return true;
} else if (rowDate >= start && end === '' && start !== ''){
return true;
} else if (rowDate <= end && start === '' && end !== ''){
return true;
} else {
return false;
}
}
);
};
// converts date strings to a Date object, then normalized into a YYYYMMMDD format (ex: 20131220). Makes comparing dates easier. ex: 20131220 > 20121220
var normalizeDate = function(dateString) {
var date = new Date(dateString);
var normalized = date.getFullYear() + '' + (("0" + (date.getMonth() + 1)).slice(-2)) + '' + ("0" + date.getDate()).slice(-2);
return normalized;
}
var data = [
{
"EAN": "180199",
"Besteldatum": "2003-09-22",
"BTW": "€19,00",
"Totaalbedrag": "€109,00",
"Status": "Verzonden",
"Verzonden": "2003-09-22",
"Factuur": "here"
},
{
"EAN": "180200",
"Besteldatum": "2004-11-12",
"BTW": "€19,00",
"Totaalbedrag": "€109,00",
"Status": "Verzonden",
"Verzonden": "2003-09-22",
"Factuur": "here"
},
];
What about a selector for the last child of each TR?
$('tr:last-child').each(()=>{
$(this).append("<button>");
})
Related
I am using a fullcalendar for creating schedules. What I am doing is, for each week, there must be only 3 schedules (processing date, payout date and credit date). If there are already schedules for that week, I need to prompt the user that schedules are already set. But if there's no schedule set, user can still post new schedule. I am already done with the logic of this scheduler, the only problem I have is how to disable dates between the set schedules for the week?
Example, I set 04-24-2018(processing date), 04-24-18(payout date) and 04-26-18(credit date)..
How can I disable the 04-22-18,04-23-18,04-25-18,04-27-18 and 04-28-18 on that week so that user cant create new schedules for that week?
schedule image
JAVASCRIPT
select:
function (start, end, jsEvent, view, resource) {
IsDateHasEvent(start);
}
function IsDateHasEvent(date) {
var allEvents = [];
allEvents = $('#calendar').fullCalendar('clientEvents');
var event = $.grep(allEvents, function (v) {
//alert(v.start);
//return +v.start == +date;
if (v.start <= date) {
$("#eventIsAlreadySetModal").modal();
//alert(v.start);
}
});
return event.length > 0;
}
I can get all the dates with events whenever I try to alert the value of start date. But the dates between are still not disabled.
Can someone help me through this?
Thank you so much.
Full Javascript code
$(document).ready(function () {
var events = [];
var selectedEvent = null;
FetchEventAndRenderCalendar();
// ******************************************
// GET ALL SCHEDULES AND DISPLAY IN CALENDAR
// ******************************************
function FetchEventAndRenderCalendar() {
$.ajax({
type: 'GET',
url: '#Url.Action("GetSchedule")',
success: function (data) {
$.each(data, function (i, v) {
var eColor = "";
if (v.status == 'Completed')
{
eColor = '#3498DB';
}
if (v.status == 'Active') {
eColor = '#2CB05B';
}
if (v.status == 'Pending') {
eColor: '#DE6209';
}
events.push({
eventID: v.scheduleId,
title: v.processedDescription,
start: moment(v.processedDatetimeStart),
status: v.status,
color: eColor
});
events.push({
eventID: v.scheduleId,
title: v.payoutDescription,
start: moment(v.payoutDatetimeStart),
status: v.status,
color: eColor
});
events.push({
eventID: v.scheduleId,
title: v.creditDescription,
start: moment(v.creditDatetimeStart),
status: v.status,
color: eColor,
end: moment(v.creditDatetimeStart)
});
})
GenerateCalendar(events);
},
error: function (error) {
alert('failed');
}
})
}
// ******************************************
// GENERATE THE CALENDAR VIEW AND SCHEDULES
// ******************************************
function GenerateCalendar(events) {
$('#calendar').fullCalendar('destroy');
$('#calendar').fullCalendar({
contentHeight: 500,
header: {
left: 'prev,next today',
center: 'title',
right: 'month, agendaWeek, agendaDay, listWeek'
},
navLinks: true,
editable: true,
eventLimit: true,
eventColor: '#2CB05B',
droppable: false,
timeFormat: 'h(:mm)A',
timeZone: 'local',
events: events,
// **************************************
// display the saved schedule in calendar
// **************************************
eventClick:
function (calEvent, jsEvent, view) {
$("#statusLabel").text(calEvent.status);
$("#schedId").val(calEvent.eventID);
$("#schedDesc").html(calEvent.title);
$("#txtDateStart_Edit").val(calEvent.start.format("MM-DD-YYYY HH:mm A"));
$('#modalEditSchedule').modal();
if ($("#statusLabel").html() == "Completed")
{
$("#btnEditSched").hide();
}
if ($("#statusLabel").html() == "Active") {
$("#btnEditSched").hide();
}
},
// *************************************************
// select dates in calendar for posting new schedule
// *************************************************
selectable: true,
selectOverlap: true,
select:
function (start, end, jsEvent, view, resource) {
IsDateHasEvent(start);
},
// *********************************************
// disable past navigation button for past dates
// *********************************************
viewRender: function (currentView) {
var minDate = moment();
// Past dates
if (minDate >= currentView.start) {
$(".fc-prev-button").prop('disabled', true);
$(".fc-prev-button").addClass('fc-state-disabled');
}
else {
$(".fc-prev-button").removeClass('fc-state-disabled');
$(".fc-prev-button").prop('disabled', false);
}
},
// ******************************
// disable past dates in calendar
// ******************************
validRange: function (dateNow) {
return {
start: dateNow.subtract(1, 'days')
};
}
, dayClick: function (date) {
var events = $('#calendar').fullCalendar('clientEvents');
for (var i = 0; i < events.length; i++) {
//if (moment(date).isSame(moment(events[i].start))) {
if (moment(events[i].start) <= moment(date)) {
alert('with events');
break;
}
else //if (i == events.length - 1)
{
alert('none');
}
}
}
});
}
// **********************************
// show modal for adding new schedule
// **********************************
function openAddEditForm() {
$('#modalAddSchedule').modal();
}
});
function IsDateHasEvent(date) {
var allEvents = [];
allEvents = $('#calendar').fullCalendar('clientEvents');
var event = $.grep(allEvents, function (v) {
//alert(v.start);
//return +v.start == +date;
if (v.start <= date) {
$("#eventIsAlreadySetModal").modal();
//alert(v.start);
}
});
return event.length > 0;
}
You need to:
check if there's at least 3 schedules on the same week;
if is there, then disable the other dates of that week.
Right? I'll try to solve the first part of your problem with javascript Date class. I don't know about FullCalendar, so if anyone can solve that part I would be glad, hehe.
We must check when a week starts and when it ends. Just with that we'll get ready to do some crazy stuff.
function printDate(year, month, day) {
month = (month < 10 ? '0' : '') + month.toString();
day = (day < 10 ? '0' : '') + day.toString();
return year + '-' + month + '-' + day;
}
function weekStart(dateString) {
var dateObject = new Date(dateString);
var dayOfWeek = dateObject.getDay();
if(dayOfWeek > 0) {
dateObject.setDate(day - dayOfWeek);
}
return printDate(dateObject.getFullYear(), dateObject.getMonth()+1, dateObject.getDate());
}
function weekEnd(dateString) {
var dateObject = new Date(dateString);
var dayOfWeek = dateObject.getDay();
if(dayOfWeek < 6) {
dateObject.setDate(day + (6-dayOfWeek));
}
return printDate(dateObject.getFullYear(), dateObject.getMonth()+1, dateObject.getDate());
}
function weekRange(dateString) {
return [weekStart(dateString), weekEnd(dateString)];
}
Nice, now we can get a "week range" from a date. But from that, can we get all dates of that week? Sure.
function getDatesFromWeek(wStart) {
var dates = [],
date = new Date(wStart),
count = 0;
while(count <= 6) {
date.setDate(date.getDate() + count);
dates.push(printDate(date.getFullYear(), date.getMonth()+1, date.getDate());
count++;
}
return dates;
}
Perfect. So now we should count for each range. Assuming you're receiving your info on a variable called schedules and each schedule have an index called date:
var weeks = {}, lockedDates = [];
for(var x in schedules) {
var week = weekRange(schedules[x].date);
var weekID = week.join('-');
if(weeks[weekID] == undefined) {
weeks[weekID] = 1;
} else {
weeks[weekID]++;
}
if(weeks[weekID] == 3) {
lockedDates = lockedDates.concat(getDatesFromWeek(week[0]));
}
}
Then you have all those dates to disable listed on lockedDates variable in format YYYY-MM-DD. Do you know how to do the rest?
EDIT
Let's change the last part I made to this:
function Locker() {
this.dates = [];
this.weeks = {};
}
Locker.prototype.add = function(dateString) {
var wStart = weekStart(dateString);
if(this.weeks[wStart] == undefined) {
this.weeks[wStart] = 1;
} else {
this.weeks[wStart]++;
}
if(this.weeks[wStart] == 3) {
this.lock(getDatesFromWeek(wStart));
}
}
Locker.prototype.lock = function(dates) {
this.lockedDates = this.lockedDates.concat(dates);
// do something
}
var calendarLocker = new Locker();
// everytime an user add a date, call calendarLocker.add(date);
// so when it reaches the limit, the locker will call calendarLocker.lock
I have 2 DataTable in one page for both DataTable I have added date range using
function filterDateRangeService(){
$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex ) {
var dateStart = moment($("#fromDateSer").val(),"DD/MM/YYYY");
var dateEnd = moment($("#toDateSer").val(),"DD/MM/YYYY");
var evalDate= moment(data[5],"DD/MM/YYYY");
console.log("dateStart +"+dateStart+" dateEnd "+dateEnd)
// console.log("insidde")
if (evalDate >= dateStart && evalDate <= dateEnd) {
return true;
}
else {
return false;
}
}
);
function filterDateRangePatient(){
$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex ) {
var dateStart = moment($("#fromDate").val(),"DD/MM/YYYY");
var dateEnd = moment($("#toDate").val(),"DD/MM/YYYY");
var evalDate= moment(data[6],"DD/MM/YYYY");
console.log("dateStart +"+dateStart+" dateEnd "+dateEnd)
// console.log("insidde")
if (evalDate >= dateStart && evalDate <= dateEnd) {
return true;
}
else {
return false;
}
}
);
Both the function are called when respective checkbox is clicked. Problem is when I use date range for first function it filters the table for specific Date range, but When i try to filter the other table with 2nd function, only first function is called, i.e which ever function is called first only that function is called each time.
Calling function Using:
$('input[name="radioFilter"]').click(function(){
filterFunction();
});
$('input[name="radioFilterSer"]').click(function(){
filterFunctionSer();
});
function filterFunction(){
//some functions..
filterDateRangePatient()
}
function filterFunctionSer(){
//some functions..
filterDateRangeService()
}
How to resolve this, Why is the first function which is called first is only being called later also, or any thing I am doing Wrong. Or is it because of return Statement.
What about write single function with params and use it on both functions
function filterFunction(){
//some functions..
filterDateRange($("#fromDateSer").val(), $("#toDateSer").val(), 5)
}
function filterFunctionSer(){
//some functions..
filterDateRange($("#fromDate").val(), $("#toDate").val(), 6)
}
And the filterDateRange Function: (Updated: Added search pop function)
function filterDateRange(from, to, num){
$.fn.dataTable.ext.search.pop();
$.fn.dataTable.ext.search.push(function( settings, data, dataIndex ) {
var dateStart = moment(from,"DD/MM/YYYY");
var dateEnd = moment(to,"DD/MM/YYYY");
var evalDate= moment(data[num],"DD/MM/YYYY");
console.log("dateStart +"+dateStart+" dateEnd "+dateEnd);
if (evalDate >= dateStart && evalDate <= dateEnd) {
return true;
}
else {
return false;
}
});
}
It will work.
How to add date range filter..
like From-To .
I got working regular search and pagination, etc..
But I dont know how to make date range filter.
I'm using Datatables 1.10.11 version.
My code:
var oTable;
function callFilesTable($sPaginationType, $bPaginate, $bFilter, $iDisplayLength, $fnSortcol, $fnSortdir){
$.extend($.fn.dataTableExt.oStdClasses, {
sSortAsc : 'header headerSortDown',
sSortDesc : 'header headerSortUp',
sSortable : 'header'
});
oTable = $('#sort').DataTable({
dom : '<"table-controls-top"fl>rt<"table-controls-bottom"ip>',
pagingType : $sPaginationType,
paging : $bPaginate,
searching : $bFilter,
pageLength : $iDisplayLength,
order : [ [$fnSortcol, $fnSortdir] ],
columnDefs : [
{
width : '50%',
targets : [ 2 ],
orderable : true,
searchable : true,
type : 'natural'
},
{
width : '10%',
targets : [ 3 ],
orderable : true
},
{
width : '20%',
targets : [ 4 ],
orderable : true
},
{
targets : ['_all'],
orderable : false,
searchable : false
}
],
language : paginationTemplate,
drawCallback : function() {
checkSelecta();
placeHolderheight();
// hide pagination if we have only one page
var api = this.api();
var pageinfo = api.page.info();
var paginateRow = $(this).parent().find('.dataTables_paginate');
if (pageinfo.recordsDisplay <= api.page.len()) {
paginateRow.css('display', 'none');
} else {
paginateRow.css('display', 'block');
}
}
});
oTable.on( 'length.dt', function ( e, settings, len ) {
updateSession({ iDisplayLength: len });
});
}
And I'm using NaturalSort 0.7 version.
I got mine working base on https://www.datatables.net/examples/plug-ins/range_filtering.html. Here is my jsfiddle https://jsfiddle.net/bindrid/2bkbx2y3/6/
$(document).ready(function () {
$.fn.dataTable.ext.search.push(
function (settings, data, dataIndex) {
var min = $('#min').datepicker('getDate');
var max = $('#max').datepicker('getDate');
var startDate = new Date(data[4]);
if (min == null && max == null) return true;
if (min == null && startDate <= max) return true;
if (max == null && startDate >= min) return true;
if (startDate <= max && startDate >= min) return true;
return false;
}
);
$('#min').datepicker({ onSelect: function () { table.draw(); }, changeMonth: true, changeYear: true });
$('#max').datepicker({ onSelect: function () { table.draw(); }, changeMonth: true, changeYear: true });
var table = $('#example').DataTable();
// Event listener to the two range filtering inputs to redraw on input
$('#min, #max').change(function () {
table.draw();
});
});
Following one using momentsjs, the advantage of momentsjs is we can compare different types of date/date time as simple
$.fn.dataTableExt.afnFiltering.push(
function( settings, data, dataIndex ) {
var min = $('#min-date').val()
var max = $('#max-date').val()
var createdAt = data[0] || 0; // Our date column in the table
//createdAt=createdAt.split(" ");
var startDate = moment(min, "DD/MM/YYYY");
var endDate = moment(max, "DD/MM/YYYY");
var diffDate = moment(createdAt, "DD/MM/YYYY");
//console.log(startDate);
if (
(min == "" || max == "") ||
(diffDate.isBetween(startDate, endDate))
) { return true; }
return false;
}
);
I have a function in my dataTable where i need to filter the table based from selected date of the user.
i have a startDate and endDate. This function works fine in chrome. But when i try it in Firefox, it won't work. what is wrong with it. Can somebody help me with this one.
this is the part where the endDate is change
$('#end').on('change', function(e){
e.preventDefault();
var startDate = $('#start').val(),
endDate = $('#end').val();
filterByDate(1, startDate, endDate);
dtv_filter.dataTable().fnDraw();
});
and this is the function that filters my table.
var filterByDate = function(column, startDate, endDate) {
$.fn.dataTableExt.afnFiltering.push(
function( oSettings, aData, iDataIndex ) {
var rowDate = normalizeDate(aData[column]),
start = normalizeDate(startDate),
end = normalizeDate(endDate);
if (start <= rowDate && rowDate <= end) {
return true;
} else if (rowDate >= start && end === '' && start !== ''){
return true;
} else if (rowDate <= end && start === '' && end !== ''){
return true;
} else {
return false;
}
}
);
};
// converts date strings to a Date object, then normalized into a YYYYMMMDDHHII format (ex: 201312201001). Makes comparing dates easier.
var normalizeDate = function(dateString) {
var date = new Date(dateString);
var normalized = date.getFullYear() + '' + (("0" + (date.getMonth() + 1)).slice(-2)) + '' + ("0" + date.getDate()).slice(-2) + date.getHours() + date.getMinutes();
return normalized;
}
I am trying to make trigger based auto-complete in textarea using jQuery autocomplete. (when you type "#", the autocomplete starts).
Till now I am able to implement it for the case where the data is an array.
HTML
<textarea class="searchBox" rows="10" cols="20"></textarea>
jQuery
var triggered = false; // By default trigger is off
var trigger = "#"; // Defining the trigger
$(".searchBox").autocomplete({
source: [ // defining the source
"A",
"Apple",
"S",
"D",
"q"],
search: function () { // before search, if not triggerred, don't search
if (!triggered) {
return false;
}
},
select: function (event, ui) { // invokes the data source, search starts
var text = this.value;
var pos = text.lastIndexOf(trigger);
this.value = text.substring(0, pos + trigger.length) + ui.item.value;
triggered = false;
return false;
},
focus: function (event, ui) {
return false;
},
minLength: 0 // minimum length of 0 require to invoke search
});
$('.searchBox').keyup(function (e) {
if (e.keyCode == 38 || e.keyCode == 40) {
return;
}
var text = this.value;
var len = text.length;
var last;
var query;
var index;
if (triggered) {
index = text.lastIndexOf(trigger);
query = text.substring(index + trigger.length);
$(this).autocomplete("search", query);
} else if (len >= trigger.length) {
last = text.substring(len - trigger.length);
triggered = (last === trigger);
}
});
Here is its fiddle : http://jsfiddle.net/5x9ZR/4/
Now I was trying to implement it when the data is in the form of json object.
But the autocomplete isn't responding with results.
I tried it bare. ( without any trigger mechanism ). It isnt displaying any results.
Code:
HTML
<textarea class="searchBox" rows="10" cols="20"></textarea>
jQuery
var triggered = false; // By default trigger is off
var trigger = "#"; // Defining the trigger
var data = [{
"name": "needmoreinfo",
"email": "needmoreinfo"
}, {
"name": "explained",
"email": "explained"
}, {
"name": "raypipeline09",
"email": "raypipeline09"
}];
$(".searchBox").autocomplete({
source: data,
search: function () { // before search, if not triggred, don't search
if (!triggered) {
return false;
}
},
select: function (event, ui) { // invokes the data source, search starts
var text = this.value;
var pos = text.lastIndexOf(trigger);
this.value = text.substring(0, pos + trigger.length) + ui.item.email;
triggered = false;
return false;
},
focus: function () {
return false;
},
minLength: 0 // minimum length of 0 require to invoke search
})._renderItem = function (ul, item) {
return $("<li>")
.append("<a>" + item.name + "<br>" + item.email + "</a>")
.appendTo(ul);
};
$('.searchBox').keyup(function (e) {
if (e.keyCode == 38 || e.keyCode == 40) {
return;
}
var text = this.value;
var len = text.length;
var last;
var query;
var index;
if (triggered) {
index = text.lastIndexOf(trigger);
query = text.substring(index + trigger.length);
$(this).autocomplete("search", query);
} else if (len >= trigger.length) {
last = text.substring(len - trigger.length);
triggered = (last === trigger);
}
});
Here is the fiddle of what I tried. http://jsfiddle.net/HGxSX/
Where I am going wrong ? Please explain.
Solved it.
There is a bug in the jQuery due to which this was happening.
The data has to be in the form of "label" and "value". Otherwise it doesn't works.
Thanks to anyone who tried.
Here is the final working fiddle : http://jsbin.com/qakefini/7
PS: I tried making account on the jQuery website but could not login. Its saying some redirection problem. If someone has an account, please report the bug.
Doesnt seem to like json strings without a label - it uses this on its keyup to check values..
see your updated/destroyed fiddle:
http://jsfiddle.net/jFIT/HGxSX/1/
var data = [
{
value: "jquery",
label: "jQuery",
desc: "the write less, do more, JavaScript library",
icon: "jquery_32x32.png",
name: "needmoreinfo",
email: "needmoreinfo"
},{
and in your autocomplete function the renderitem was missing some things, you should update the version of jquery your using btw.. seems alot simpler in 1.9:
}).data( "autocomplete" )._renderItem = function( ul, item ) { console.log('wut');
return $( "<li>" )
.data( "item.autocomplete", item )
.append( "<a>" + item.email + "<br>" + item.name + "</a>" )
.appendTo( ul );
};