I have 2 input boxes, beginDate and endDate, that when clicked, allows the user to select a range of dates with flatpickr.
I would like both textboxes to display the same date ranges where beginDate is populated with the minDate
and endDate is populated with maxDate. Ideally, I would like to have both boxes refer to the same instance of flatpickr, with
the selected date range persisted for both. Currently I have:
let resultMax;
$("#BeginDate").flatpickr({
mode: 'range',
dateFormat: "Y-m-d",
onOpen: function (selectedDates, dateStr, instance) {
instance.set('minDate', new Date(new Date().getTime()));
},
onClose: function (selectedDates, dateStr, instance) {
resultMin = new Date(new Date(selectedDates[0]).getTime());
resultMax = new Date(new Date(selectedDates[1]).getTime());
instance.set('selectedDates', resultMax);
}
});
$("#EndDate").flatpickr({
minDate: resultMin,
maxDate: resultMax,
mode: "range",
onOpen: function (selectedDates, dateStr, instance) {
const ONE_MINUTE_AGO = new Date(new Date().getTime());
instance.set('minDate', resultMin);
instance.set('maxDate', resultMax);
instance.set('selectedDates', resultMax);
instance.jumpToDate(resultMax);
},
onClose: function (selectedDates, dateStr, instance) {
instance.set('minDate', resultMin);
instance.set('maxDate', resultMax);
instance.set('selectedDates', resultMax);
instance.jumpToDate(resultMax);
}
});
This doesn't quite work. When BeginDate is selected first and the date range is set, those date are picked up with EndDate, although the dates are displayed
in bold instead of a shaded range.
Related
SlickGrid launches the calendar using a default US date format of mm/dd/yyyy. I store dates in my database in Australian format dd/mm/yyyy. how can I change the format of the calendar to take dd/mm/yyyy?
You can use the DatePicker of your choice by writing a new custom editor. The default date editor uses jQueryUI DatePicker.
Personally (I'm in Australia too), I use the default with the following settings:
function DateFormatter(rowIndex, cell, value, columnDef, grid, dataProvider) {
if (value == null || value === "") { return "-"; }
return moment.utc(value).format('ddd, D MMM YYYY');
}
... using moment.js to format the date, and in the DateEditor ...
$input.datepicker({
showOn: "button",
changeMonth: true,
changeYear: true,
dateFormat: 'd/m/yy',
buttonImageOnly: true,
buttonImage: "../images/calendar.gif"
});
Also you could just localise
You can write formatter for row (i use moment.js too):
function dateTimeFormatter (row, cell, value, columnDef, dataContext) {
var dateTime = Date.parse(value);
var result = moment(dateTime);
return result.format('DD.MM.YYYY hh:mm:ss');
}
First, add code to the slick.formatters.js file in your local library:
Add the custom date formatter in two spots:
$.extend(true, window, {
"Slick": {
"Formatters": {
"PercentComplete": PercentCompleteFormatter,
"PercentCompleteBar": PercentCompleteBarFormatter,
"YesNo": YesNoFormatter,
"Checkmark": CheckmarkFormatter,
"Checkbox": CheckboxFormatter,
"Date": Dateformatter //<< this one
}
}
});
and on the end of the file:
function Dateformatter(row, cell, value, columndef, datacontext) {
if (value === null) {
return "";
} else {
var d = new Date(value);
var m = d.getMonth() + 1;
return (d.getDate() + "/" + m + "/" + d.getFullYear());
}
}
})(jQuery); //<< this line is already present
Now you can add the date formatter in your column definitions:
{
id: "lastLoginDate", name: "LastLoginDate", field: "lastLoginDate", formatter: Slick.Formatters.Date
},
I'm now testing the capabilities of this grid and I'm having a look at this example at the moment.
Last week, I tried some basic loading of data, returned from the controller of the MVC app that I'm working on. It returns json, which I then give to the grid to be displayed.
The data, that I want to show, is stored in multiple tables. For now, I load data from only two of them for simplicity, because I'm only testing the capabilities of the grid - will it suit our needs.
The data, which arrives at the grid (in js), looks something like this:
{
Cars: [
{
car_Number: '123',
car_Color: 'red',
car_Owner: Owner: {
owner_ID: '234',
owner_Name: 'John'
},
car_DateBought: '/Date(1450648800000)/'
},
{
car_Number: '456',
car_Color: 'yellow',
car_Owner: Owner: {
owner_ID: '345',
owner_Name: 'Peter'
},
car_DateBought: '/Date(1450648800000)/'
},
{
car_Number: '789',
car_Color: 'green',
car_Owner: Owner: {
owner_ID: '567',
owner_Name: 'Michael'
},
car_DateBought: '/Date(1450648800000)/'
}
]
}
Here is some sample code of what I have done so far:
$.ajax({
type: 'post',
url: BASE_HREF + 'OpenUI5/GetAllCars',
success: function (result) {
var dataForGrid = result['rows'];
debugger;
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData(dataForGrid);
var oTable = new sap.ui.table.Table({
selectionMode: sap.ui.table.SelectionMode.Multi,
selectionBehavior: sap.ui.table.SelectionBehavior.Row,
visibleRowCountMode: sap.ui.table.VisibleRowCountMode.Auto,
minAutoRowCount: 10,
//visibleRowCount: 10,
showNoData: false
});
// define the Table columns and the binding values
oTable.addColumn(new sap.ui.table.Column({
label: new sap.ui.commons.Label({
text: "ID of car"
}),
template: new sap.ui.commons.TextView({ text: "{car_Number}" }),
sortProperty: "car_Number", // https://sapui5.netweaver.ondemand.com/sdk/test-resources/sap/ui/table/demokit/Table.html#__2
filterProperty: "car_Number"
}));
oTable.addColumn(new sap.ui.table.Column({
label: new sap.ui.commons.Label({ text: "Color of car" }),
template: new sap.ui.commons.TextView({ text: "{car_Color}" }),
sortProperty: "car_Color",
filterProperty: "car_Color"
}));
oTable.addColumn(new sap.ui.table.Column({
label: new sap.ui.commons.Label({ text: "Car Owner ID" }),
template: new sap.ui.commons.TextView({
// does not work like this -> text: "{Owner.owner_ID}"
text: {
path: 'Owner',
formatter: function (owner) {
return owner !== null ? owner['owner_ID'] : '';
}
}
}),
sortProperty: "Owner.owner_ID", // these two don't work
filterProperty: "Owner.owner_ID"
}));
oTable.addColumn(new sap.ui.table.Column({
label: new sap.ui.commons.Label({ text: "Car Owner Name" }),
template: new sap.ui.commons.TextView({
// does not work like this -> text: "{Owner.owner_Name}"
text: {
path: 'Owner',
formatter: function (owner) {
return owner !== null ? owner['Name'] : '';
}
}
}),
sortProperty: "Owner.owner_Name", // these two don't work
filterProperty: "Owner.owner_Name"
}));
var dateType = new sap.ui.model.type.Date({ // http://stackoverflow.com/questions/22765286/how-to-use-a-table-column-filter-with-formatted-columns
pattern: "dd-MM-yyyy"
});
oTable.addColumn(new sap.ui.table.Column({
label: new sap.ui.commons.Label({ text: "Date bought" }),
template: new sap.ui.commons.TextView({
text: {
path: 'car_DateBought',
formatter: dateFormatterBG
}
}),
sortProperty: "car_DateBought",
filterProperty: "car_DateBought",
filterType: dateType
}));
oTable.setModel(oModel);
oTable.bindRows("/");
oTable.placeAt("testTable", "only");
},
error: function (xhr, status, errorThrown) {
console.log("XHR:");
console.log(xhr);
console.log("Status:");
console.log(status);
console.log("ErrorThrown:");
console.log(errorThrown);
}
});
My problems:
I cannot sort or filter the list of cars by owner_ID or owner_Name. How should I do the filtering and sorting? Should it be done with the help of a formatter function in some way, or...?
I can sort by car_DateBought, but I cannot filter the cars by this field. First, I tried setting filterType: dateType, then I tried setting it to filterType: dateFormatterBG(it turns out, that dateType does exactly the same thing as my own dateFormatterBG does, btw).
function dateFormatterBG(cellvalue, options, rowObject) {
var formatedDate = '';
if ((cellvalue != undefined)) {
var date = new Date(parseInt(cellvalue.substr(6)));
var month = '' + (date.getMonth() + 1);
var day = '' + date.getDate();
var year = date.getFullYear();
if (month.length < 2) {
month = '0' + month;
}
if (day.length < 2) {
day = '0' + day;
}
formatedDate = [day, month, year].join('-');
}
return formatedDate;
}
Anyway, as I said, I tried both, but it doesn't work. When I click on the header of a column like in the example in the first link, I don't get any sort of a datepicker. How can I tell OpenUI5, that this column needs to be filtered by date and it should provide the user with a datepicker, when he/she clicks on the 'Filter' input field at the bottom of the dropdown menu? When I try to write the date in the filter field like '07-11-2016' (the way it is formatted), I get an empty table/grid. If I try to enter the huge number from field car_DateBought in the json object, all available rows in the table stay the same and when I reclick on the header, the filter field at the bottom of the dropdown menu appears with error-state.
Thank you in advance for your help and pieces of advice!
Edit:
This is just sample, dummy data. I try to load the real data and I see, that in the table I've got a couple of rows with date, which is today (07-11-2016, or 11/7/2016 if you prefer). That's why getting an empty table after trying to filter means it's not working correctly.
Sorting: in a sample I am looking at the following appears in the controller:
onInit : function () {
this._IDSorter = new sap.ui.model.Sorter("my_id", false);
},
....
Then in the view there is a button defined in the header column as
<Column>
<Label text="Project"/>
<Button icon="sap-icon://sort" press="onSortID" />
</Column>
And back in the controller there is a further function:
onSortID: function(){
this._IDSorter.bDescending = !this._IDSorter.bDescending;
this.byId("table").getBinding("items").sort(this._IDSorter);
},
I read this collectively as defining a sorter in the onInit(), then toggle/reversing it in the click event of the sort button in the column header via the onSortId() function. The OpenUI5 API doc re sorters indicates there are more parameters in the sorter constructor for initial sort direction and sorting function.
Following this pattern, for your needs to sort on the owner_ID or owner_Name, I assume you could set up a sorter as
this._OwnerIDSorter = new sap.ui.model.Sorter("car_Owner/owner_ID", false);
this._OwnerNameSorter = new sap.ui.model.Sorter("car_Owner/owner_Name", false);
I use drblue:fullcalendar. Display works fine but I cannot get any kind of event to work. I have tried different ones. In the following code snippet I have tried the loading event:
Template.Schedule.helpers({
calendarOptions: {
// Standard fullcalendar options
schedulerLicenseKey: 'CC-Attribution-NonCommercial-NoDerivatives',
slotDuration: '01:00:00',
minTime: '07:00:00',
maxTime: '22:00:00',
lang: 'en',
defaultView: 'agendaWeek',
contentHeight: 500,
firstDay: 1,
timeFormat: 'HH:mm',
timezone: 'UTC',
selectable: true,
// Function providing events reactive computation for fullcalendar plugin
events: function(start, end, timezone, callback){
var events = [];
Assignments.find().map(function(doc){
var startTimeHours = Number(doc.time.substr(0, 2));
var startTimeMinutes = Number(doc.time.substr(3, 2));
var startDateTime = new Date(doc.date);
startDateTime.setHours(startDateTime.getHours() + startTimeHours);
startDateTime.setMinutes(startDateTime.getMinutes() + startTimeMinutes);
var endDateTime = new Date(doc.date);
var effort = doc.state == 'finished' ? doc.realEffort : doc.effort;
endDateTime.setHours(startDateTime.getHours() + effort);
endDateTime.setMinutes(startDateTime.getMinutes());
var getColorForState = function(state)
{
switch(state)
{
case 'finished': return '#00bb00';
}
return '#1197C1';
};
var getBorderColorForState = function(state)
{
switch(state)
{
case 'finished': return '#009900';
}
return '#004781';
};
return{
id: doc.title,
start: startDateTime,
end: endDateTime,
title: doc.title,
backgroundColor: getColorForState(doc.state),
borderColor: getBorderColorForState(doc.state)
}
}).forEach(function(event){
events.push(event);
});
callback(events);
},
// Optional: id of the calendar
id: "calendar1",
// Optional: Additional classes to apply to the calendar
addedClasses: "col-md-12"
// Optional: Additional functions to apply after each reactive events computation
}
});
Template.Schedule.events({
loading: function(isLoading, view){
console.log('hi');
}
});
No JS error on client or server and no log entry, either. I have also tried dayClick, select and clickEvent but I do not get any log entry. If I put an alert into it I also do not receive anything.
Not sure why downvoted, if you need more information or details, please provide it.
Anyways, I was able to solve it. There was some "wrong" code out there and I did not find any example, but it works when I just add the corresponding event to the options, i.e.:
Template.Schedule.helpers({
calendarOptions: {
// all the various options
eventClick: function(event, jsEvent, view){
alert(event.title + "\r\n\r\n" + event.description);
},
I have the following requestStart in my kendoDatasource:
requestStart: function (e) {
var oldFilters = e.sender._filter ? e.sender._filter.filters : [],
endDateTime;
$.each(oldFilters, function (index, currFilter) {
if (currFilter.field === 'StatusChangeDate' && currFilter.operator == 'eq') {
endDateTime = new Date(currFilter.value.getYear(), currFilter.value.getMonth(), currFilter.value.getDay(), 23, 59, 59);
oldFilters.push({ field: currFilter.field, operator: 'gt', value: currFilter.value });
oldFilters.push({ field: currFilter.field, operator: 'lt', value: endDateTime });
oldFilters.splice(index, 1);
}
});
if (e.sender._filter) {
e.sender._filter.filters = oldFilters;
}
},
I want to change DateTime filter when it's operator is 'eq', in order to disable filter precision.
But when I modify filter in requestStart like in the code above, it doesn't work. The request sends with old filter.
I don't know what I'm doing wrong. Is there another way to achieve behavior like this?
By the time requestStart is called, the query is already committed to being sent as is. The event is just letting you know but doesn't give you the opportunity to change anything.
Rather than try to sneak in the back way, just call the dataSource's filter() method to filter any way you want. DataSource will filter the data either locally or make a request to the server depending on the value of the serverFiltering option.
var filters = myDataSource.filter() || [],
endDateTime;
$.each(filters, function (index, currFilter) {
if (currFilter.field === 'StatusChangeDate' && currFilter.operator == 'eq') {
endDateTime = new Date(currFilter.value.getYear(), currFilter.value.getMonth(), currFilter.value.getDay(), 23, 59, 59);
filters.push({ field: currFilter.field, operator: 'gt', value: currFilter.value });
filters.push({ field: currFilter.field, operator: 'lt', value: endDateTime });
filters.splice(index, 1);
}
});
// Now apply the new filter to the dataSource.
// This will generate a request if serverFiltering == true.
myDataSource.filter(filters);
One other note, you should try to avoid accessing any property that starts with "_" as in "e.sender._filter". This is generally considered to be a "private" property which could change with the next version. You can get the current filter by calling filter() with no arguments as in the code above. This is another general rule in Kendo, no args mean get a value, args mean set a value.
EDIT
You can also hijack the CRUD requests to modify and/or add parameters using the dataSource's transport.parameterMap property. Note that this method will not modify the dataSource's filter properties. It only changes the request parameters going to the server.
$("#myGrid").kendoGrid({
// Column definitions, etc...
dataSource = new kendo.data.DataSource({
transport: {
// create, read, update, destroy definitions...
parameterMap: function(data, type) {
if ((type === "read") && data.filter && data.filter.filters) {
var filters = data.filter.filters;
for (var index = 0; index < filters.length, index++) {
var currFilter = filters[index];
if (currFilter.field === 'StatusChangeDate' && currFilter.operator == 'eq') {
endDateTime = new Date(currFilter.value.getYear(), currFilter.value.getMonth(), currFilter.value.getDay(), 23, 59, 59);
filters.push({ field: currFilter.field, operator: 'gt', value: currFilter.value });
filters.push({ field: currFilter.field, operator: 'lt', value: endDateTime });
filters.splice(index, 1);
break;
}
});
}
return data;
}
}
}),
});
In my jqgrid when i am clicking on add new record i have date field prepopulated with current date. Format of the date is yyyy-MMM-d (e.g. 2010-Jan-23).
Date is required field and when i click submit button it fails validation and displays error that this date is invalid, and it wants Y-m-d format.
How can i check my value with jqgrid? In other words how to make jqgrid accept the following date format when validating 2010-Jan-23?
Thanks.
Here is my JSON data:
{"rows":[
{"id":1,"cell":["2010-Mar-3","Pepto","2","False","not active"]},
{"id":2,"cell":["2009-May-6","Tylenol","5","False","not active"]},
{"id":3,"cell":["2008-May-6","Aspirin","9","True","active"]}
]}},
Here is my date column definition:
{ name: 'Date',
index: 'date',
width: '80px',
align: 'center',
sortable: false,
editable: true,
datefmt: 'Y-M-d',
editoptions: { dataInit: function(elem) { $(elem).datepicker({ dateFormat: 'yy-M-d' });},value: getDate } ,
editrules: { required: true, date:true} },
The getdate function inserts current date into field. here is the function:
function getDate(){
var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
var now = new Date();
return now.getFullYear() + "-" + monthNames[now.getMonth()] + "-" + now.getDate();
}
Maybe this is because of this function? Can i insert current date from datepicker?
Amount of data sent from the server is not too big (about 10-30 rows) and this application will be used by maximum of 50 people, so there is no concerns regarding amounts of data.
Anytime when i have value as 2010-Jun-23 in the field, i get error message:Enter valid date value - Y-M-d
Verify that you defined datefmt: 'Y-M-d' in the column definition of colModel. In the list of editrules options (see http://www.trirand.com/jqgridwiki/doku.php?id=wiki:common_rules#editrules) is defined that if you use date: true as a editrules option, the validation will be done corresponds with the datefmt option.
Some more recommendations if you use date in jqGrid:
If you not yet use, think about of the usage of jQuery.datepicker (see http://jqueryui.com/demos/datepicker/#date-formats) inside of dataInit function of editoptions (like
editoptions: {
dataInit : function (elem) {
$(elem).datepicker();
}
// ...
}
in the simplest case). If you use searching for date fields, you can use dataInit with jQuery.datepicker also in searchoptions in the same way (see http://www.trirand.com/jqgridwiki/doku.php?id=wiki:singe_searching#colmodel_options). The usage of jQuery.datepicker in jqGrid is very easy, but it makes your program more comfortable.
Usage of standard date formatter (formatter: 'date') can be useful to convert source data format send to jqGrid to the new format which will be displayed. For example,
formatter: 'date', formatoptions: {srcformat:'y-m-d', newformat: 'Y-M-d' }
It is less interesting, but it can reduce a little the size of data send from server to client.
UPDATED: I must admit, I don't tested my suggestion with exactly your data format. Just now I tested all one more time and then read carefully jqGrid documentation about datefmt (see http://www.trirand.com/jqgridwiki/doku.php?id=wiki:colmodel_options). For datefmt are only numerical format for months is supported! So the value at the time of date verification must be in a numerical format. What can we do? For example following
we define as parameters of navGrid function "add" parameters (see http://www.trirand.com/jqgridwiki/doku.php?id=wiki:navigator parameter prmAdd) like following:
{ beforeCheckValues: function(posdata, formid, mode) {
var data = posdata.Date;
var dateParts = data.split("-");
var mounth = dateParts[1];
var mounths = $.jgrid.formatter.date.monthNames;
var iMounth = -1;
for (var i=0; i<12; i++) {
if (mounth === mounths[i]) {
iMounth = i;
break;
}
}
if (iMounth !== -1) {
posdata.Date = dateParts[0]+'-'+(iMounth+1)+'-'+dateParts[2];
}
},
beforeSubmit: function(postdata, formid) {
var data = postdata.Date;
var dateParts = data.split("-");
var mounths = $.jgrid.formatter.date.monthNames;
postdata.Date = dateParts[0]+'-'+
$.jgrid.formatter.date.monthNames[dateParts[1]-1]+
'-'+dateParts[2];
return [true,""];
}
}
So we convert the Date field to the numerical format inside of beforeCheckValues function and then convert all back to the original format (like 2010-Jan-23) after usage of checkDate. It will work.
The main question is now: have we some advantage from such kind of the date checking? We can just don't use editrules: { date:true } and implement our own date checking inside of beforeSubmit function. If we find out the wrong date we should return [false,"My error message"] and our custom error message "My error message" will be displayed by jqGrid.
So the easiest solution of your problem we receive if we could change the date format to any numerical form (Y-mm-d, mm/d/Y or another one). Usage of datepicker will makes for users the format problem not very important. Think about this and choose the way which your prefer.
I was facing similar issue. I have resolved it using custom function for validation. I am suing date format as '23-Jan-05'. You may modify it to suit your required date format.
function datecheck(value, colname) {
var dateParts = value.split("-");
var datePart = dateParts[0];
var mounth = dateParts[1];
var yearPart = dateParts[2];
var mounths = $.jgrid.formatter.date.monthNames;
var monthPart = -1;
for (var i = 0; i < 12; i++) {
if (mounth === mounths[i]) {
monthPart = i + 1;
break;
}
}
var dateText = monthPart + '-' + datePart + '-' + yearPart;
var date = Date.parse(dateText);
if (isNaN(date))
return [false,"Invalid date. Format expected: dd-mmm-yy. (23-Jul-05)"];
else
return [true,""];
}
JQGrid column details:
colModel: [name: 'JoiningDate', align: "center", editable: true,
editrules: { custom: true, custom_func: datecheck },
formatter: 'date', formatoptions: { srcformat: 'y-m-d', newformat: 'd-M-y' }, edittype: 'text', editable: true,
editoptions: { dataInit: function (el) { setTimeout(function () { $(el).datepicker({ dateFormat: 'd-M-y' }); }, 200); } }
},
Hope this helps.
Regards,
Abhilash