I am new in DOJO grid. I have a grid which have multiple Date Boxes under project Start date for each user. When admin selects one date (e.g. user1 Start Date) and moves on to other field (e.g. description) and comes back and deletes the date (user1 Start Date) it shows 1 Jan 1970. I used formatter and changed the display, but when I submit date then its showing 1 Jan 1970 as selected date. How can I set it for Blank Value? If user deletes the date I want to show Blank value there. How am I suppose to achieve this?
Code I use is as follows
smallLayout.push({
field : editableFieldNames[index],
name : editableColumnNames[index],
sortable : true,
filterable : true,
autoComplete: true,
editable : true,
width : '100px',
styles : 'text-align: left; background:#A3C8EC; color: #000;',
type : dojox.grid.cells.DateTextBox,
constraint: {
datePattern : "dd MMM yyyy",
selector : "date"
},
formatter: formatDate
});
// Formatter to return date in correct format
var formatDate = function (val, rowIdx, cell) {
//dijit.byId('myid').reset();
cell.customClasses.push('noBackgroundClass');
if (val != '0000-00-00' && val != null) {
// If date is comming from database
if (typeof val == 'string') {
return "<div class = 'editableCell'>" + val + "</div>";
} else {
console.log(cell);
if (val.getFullYear == '1970') {
return "<div class = 'editableCell'><div>";
}
return "<div class = 'editableCell'>"
+ val.getDate() + ' '
+ month[val.getMonth() + 1] + ' '
+ val.getFullYear() + "</div>"
;
}
} else {
return "<div class = 'editableCell'><div>";
}
}
Thank You,
Amit
Related
Ok, I have a calendar on my page and each day is a formatted version of that date, eg.
Jan 2021
1 2 3 4
5 6 7 8
etc..
so the 1 cell will contain 1/1/2021 (but formatted to just show '1' [d])
I also have a cell (K5) on that page for a user to enter a date eg:[1/1/2021]
What i'd like is a script that changes the border colour of the day in the calendar if it matches the user entry cell.
The code:
function onEdit(e) {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getActiveSheet();
var date = sheet.getRange("K5").getValue();
if (e.range.getValue()== date) {
e.range.setBorder(true, true, true, true, true, true, "red", SpreadsheetApp.BorderStyle.solid); }
};
This doesn't work and I can't think of a way of having the code work for every cell of the calendar (there are 2 years worth so over 1000 cells).
It doesn't need to be onEdit, i was just testing to see if the actual setBorder function worked (which it does)
Also, I cant use conditional formatting as I've already used that to change to bg and font colours for something else (and there's no option to change boarder colour anyway)
I've made a mini version with just Jan if you'd like to have a look and see what you can do:
https://docs.google.com/spreadsheets/d/1oV4lE8cQB-e2bVc_HgiGM31ivk3uHxPcqsSdLdCxsmQ/edit?usp=sharing
One alternative to looking for all the dates would be to use a formula to show the dates and their addresses in a different sheet. This formula will output a series of dates and their addresses for your holidays. It can then be read with an onEdit() script to put borders on the correct addresses:
Formula:
=ARRAYFORMULA(IFERROR(QUERY(SPLIT(FLATTEN(N(Calendar!E9:AY)&"|"&ROW(Calendar!E9:AY)&"|"&COLUMN(Calendar!E9:AY)&"|"&LEN(TO_TEXT(Calendar!E9:AY))),"|",0,0),"select Col1,Col2,Col3 where Col4<3 and ("&TEXTJOIN(" or",TRUE," Col1="&FILTER(Calendar!BE28:BE100,Calendar!BE28:BE100<>""))&")")))
Script:
function onEdit(e){
holidayBorders(e);
}
function holidayBorders(e){
var sheet = e.range.getSheet();
if(e.value && sheet.getName()=='Calendar' && e.range.getColumn()==57 && e.range.getRow() >= 28){
SpreadsheetApp.flush();
Utilities.sleep(10000);
var datasheet = e.source.getSheetByName('DATA');
var rcs = datasheet.getRange('AQ3:AR').getValues().filter(e=> e[0]);
for (let i=0;i<rcs.length;i++){
sheet.getRange(rcs[i][0],rcs[i][1]).setBorder(true, true, true, true, true, true, "red", SpreadsheetApp.BorderStyle.solid);
}
}
}
You could do the following:
Get all values in your range, using getValues().
Iterate through all values in the resulting 2D array.
For each value, check if (1) the value is a Date (for example, using instanceof) and whether the two dates are from the same day (for example, doing this).
If both conditions are met, set the border.
Code snippet:
function setBorders() {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getActiveSheet();
var date = sheet.getRange("K5").getValue();
var firstRow = 7;
var firstCol = 5;
var data = sheet.getRange(firstRow, firstCol, sheet.getLastRow() - firstRow + 1, sheet.getLastColumn() - firstCol + 1).getValues();
data.forEach((row, i) => {
row.forEach((value, j) => {
if (value instanceof Date && sameDay(date, value)) {
sheet.getRange(i + firstRow, j + firstCol).setBorder(true, true, true, true, true, true, "red", SpreadsheetApp.BorderStyle.solid);
}
});
})
}
function sameDay(date1, date2) {
return date1.getFullYear() === date2.getFullYear() &&
date1.getMonth() === date2.getMonth() &&
date1.getDate() === date2.getDate();
}
I have a date column with format MMM d, yyyy. If user searches "2018", how can I filter it?
XML
<table:Column filterProperty="StartDate" sortProperty="StartDate" width="100px" tooltip="{i18n>ttStartDate}">
<Label text="Start Date"/>
<table:template>
<Text text="{path:'localModel>StartDate',formatter:'.formatter.date'}"/>
</table:template>
</table:Column>
Controller
searchTable: function (evt) {
var oTable = this.getView().byId("ordersTable");
var searchTerm = evt.getParameter("query");
if (searchTerm === "") {
//When clear was pressed on search field
oTable.getBinding("rows").filter(null);
} else {
var filters = [];
var outerFilters = [];
var searchTerms = searchTerm.split(" "); //words separated by space are considered as separate search terms.
for (var k = 0; k < searchTerms.length; k++) {
filters.push(new Filter("OrderType", sap.ui.model.FilterOperator.Contains, searchTerms[k]));
filters.push(new Filter("StartDate", sap.ui.model.FilterOperator.Contains, searchTerms[k]));
outerFilters.push(new Filter(filters));
filters = [];
}
oTable.getBinding("rows").filter(new Filter({
filters: outerFilters,
and: true //Default is OR between filters
}));
}
},
Date received as : StartDate: Sat Mar 23 2019 05:30:00 GMT+0530
Date formatted as: Mar 23,2019
I am aware that 'Contains' works only for Strings but how to make it work for date also
We faced a similar issue and there were 2 solutions,
One on the client side and another on the server side.
Client side:
Use a formatter on that property to parse the date to a string.
Server side:
Ask for another property that is that date as a string.
Looking at your code I can see you are already using a formatter (formatter.date) so we can explore the client side option.
In your formater.date function you can do something like this:
date(yourDateField)
{
let options = { year: 'numeric', month: 'short', day: 'numeric' };
return yourDateField.toLocaleDateString("en-US", options);
}
After inline edit is cancelled, the date column comes back as undefined instead of restoring the original value. Column is defined as following (dates are coming in 1970-01-01 format):
{name:'Release<br>Date',index:'Street_Date', sorttype:"date", width:70,
formatter: function (cellvalue, options, rowObject) {
return cellvalue === ('1970-01-01') ? "" : $.fn.fmatter.call(this, "date", cellvalue, options, rowObject);
},
formatoptions: {newformat:'d M y'},
editable:true,
editoptions: {
size:9,
dataInit: function(el, options) {
$(el).datepicker({
dateFormat: "d M y",
defaultDate: '01 Jan 70',
onSelect: function(dateText, inst) {
}
});
}
},
searchoptions: {
sopt: ['eq','ne','ge','le'],
dataInit: function (elem) {
$(elem).datepicker({ showButtonPanel: true, dateFormat: 'yy-mm-dd' })
}
}
},
The inline edit is setup as following:
ondblClickRow: function (rowid) {
var savedRows = $grid.jqGrid("getGridParam", "savedRow");
if (savedRows.length > 0 && savedRows[0].id !== rowid) {
// cancel editing
$grid.jqGrid("restoreRow", savedRows[0].id);
}
if (savedRows.length === 0) {
$grid.jqGrid("editRow", rowid, editOptions);
}
}
When Grid is loaded, the date shown like 07 Aug 18, entering the inline editing by double click, the date is still 07 Aug 18. After cancelling the edit either by clicking away or clicking Cancel button, date becomes NaN undefined N. After refresh, it comes back correctly though.
How to preserve the correct date after cancelling editing?
Grid behaves correctly with formatter: date
free jqGrid v jqGrid 4.13.5
Maybe the author of free-jqGrid will help better, but I would recommend you to add additional parameter (action='edit') when the formatter is called. Code below:
formatter: function (cellvalue, options, rowObject) {
return cellvalue === ('1970-01-01') ? "" : $.fn.fmatter.call(this, "date", cellvalue, options, rowObject, "edit");
},
Note the last parameter in $.fn.fmatter.call
UPDATE
This is working in my tests.
Since you use a custom date fomatter it is needed the value in savedRows to be unformated in order to be saved correct. In case of default formatter = date this is done automatically.
Below is the code that can be used, suppose you know the index of the field in colModel:
ondblClickRow: function (rowid) {
var savedRows = $grid.jqGrid("getGridParam", "savedRow");
if (savedRows.length > 0 && savedRows[0].id !== rowid) {
// cancel editing
savedRows[0].Release_Date = $.unformat.date.call($grid[0], savedRows[0].Release_Date, $grid[0].p.colModel[1]);
$grid.jqGrid("restoreRow", savedRows[0].id);
}
if (savedRows.length === 0) {
$grid.jqGrid("editRow", rowid, editOptions);
}
}
I have a JSON model which contains, among others, a few date values which are stored as epoch values:
var oData = [{
string : "SomeValue",
date : 1404172800000
}];
When I load my model, I convert this epoch to a proper Javascript Date object using:
for (var i = 0; i < oData .length; i++) {
var dateLong = oData[i].date;
oData[i].date = new Date(dateLong);
}
In my table, I then render the column using a formatter function:
var oDateColumn = new sap.ui.table.Column({
label: new sap.ui.commons.Label({
text: "A Date"
}),
template: (new sap.ui.commons.TextView({
text : {
parts : [date],
formatter : function(oValue) {
if (oValue != undefined) {
var yyyy = oValue.getFullYear().toString();
var mm = (oValue.getMonth()+1).toString(); // getMonth() is zero-based
var dd = oValue.getDate().toString();
return yyyy + '/' + (mm[1]?mm:"0"+mm[0]) + '/' + (dd[1]?dd:"0"+dd[0]);
} else return "";
}
},
textAlign : sap.ui.core.TextAlign.Right
})),
sortProperty : "date",
filterProperty : "date",
filterOperator : sap.ui.model.FilterOperator.EQ
});
This works ok, and the former epoch is now a date which is nicely rendered as '2014/07/01'
However, the filtering is not on the formatted date but on the original Date object -- if I filter on '2014/07/01' I get no results; if I filter on '1404172800000' I get the filtered results...
I tried using a formatter on the filterProperty but I wasn't able to get this to work.
Does anyone know how I can have users filter on the formatted date?
Using a date type might solve this issue
var dateType = new sap.ui.model.type.Date({
pattern: "yyyy/MM/dd"
});
...
sortProperty : "date",
filterProperty : "date",
filterType: dateType
look at this example for a simple use case on birthday column
i am using extjs 3.4 add add datefield in portal for selection of date range.Start date and end date means if i select 28 jan 2014 in start date then i want to validate end date after 28 jan 2014 is display with in 30 days interval only .
and i also want to validate difference between start date and end in only 30 days
{
id:'funnelStartId',
xtype: 'datefield',
format : 'd-M-Y',
editable:false,
emptyText:'Start date',
listeners:{
select: function (value,date){
getFunnelDateRange()
}
}
},{
id:'funnelEndId',
`enter code here` xtype: 'datefield',
format : 'd-M-Y',
editable:false,
emptyText:'End date',
listeners:{
select: function (value,date){
getFunnelDateRange()
}
}
}
I think you may be able to get a similar behavior to the one you describe by setting the min and max values of the datefield on select:
var dateValidate = function() {
var dateFld1 = Ext.getCmp('funnelStartId');
var dateFld2 = Ext.getCmp('funnelEndId');
startValue = dateFld1.getValue();
endValue = dateFld2.getValue();
maxEndValue = startValue.add(Date.DAY, 30);
if (endValue < startValue || endValue > maxEndValue) {
dateFld2.setValue(null);
}
dateFld2.setMinValue(startValue);
dateFld2.setMaxValue(maxEndValue);
}
I have a created fiddle demonstrating.