So I'm using Full Calendar JavaScript in my project. I set an attribute to each day cell inside day render function. Question: Can I get those attributes using date range? Is that doable? Any suggestions are much appreciated thanks.
Each of the day cells has the class fc-day, and each of them has a property data-date showing the date it represents (e.g. 2017-09-19).
So for example, let's say you are in a month view showing September 2017, and a custom attribute called "MyCustomAttr" (showing what day of the whole year that day is) has been added to those date cells via dayRender, like this:
dayRender: function(date, cell) {
cell.attr("MyCustomAttr", "Day Of Year: " + date.format("DDD"));
},
Then, you want to get the custom attribute values of all the cells in the range 10th-15th September (exclusive), you can run this code (as long as it runs at some time after the dayRender callback was executed):
var days = $(".fc-day");
var attributes = [];
var rangeStart = moment("2017-09-10");
var rangeEnd = moment("2017-09-15");
days.each(function(index, element) {
var day = moment($(this).data("date"));
if (day.isBetween(rangeStart, rangeEnd))
{
attributes.push($(this).attr("MyCustomAttr"));
}
});
console.log(JSON.stringify(attributes));
You can see a working example here: http://jsfiddle.net/sbxpv25p/20/
N.B. I have just put the attribute values into an array as an example, which isn't very useful in itself, since they aren't associated with the days anymore. You didn't say what you wanted to do with the attributes once you've got them, so I'll leave it to you to modify the example to suit your needs.
Related
Im trying to change the fullcalendar (v3) day cell background-color for specific days declared in a databse table. So far i was able to try it with manual input for only one day which works fine with the following code:
dayRender: function (date, cell) {
var day_declared_in_database = '2022-05-13';
var specific_day = moment('' + day_declared_in_database + 'T00:00Z');
if (date.isSame(specific_day, "day")) {
cell.css("background-color", "blue");
}
},
Any idea how to get external data into dayRender and loop through all days to apply the color to multiple different days?
Issue in Qliksense SelectValues Field API when the field is Date format
Hi ,
Just to provide you background - We have multiple qlik apps opened in our web application and when the user makes the selections in primary app - we apply the common selection across all the apps opened. We have this strange issue with fields that are tagged as Date in the datamodel. Please check below example.
Version : June 2020 Patch 7 v13.82.15
I have issue with selectValues Field API when the field is in Date format.
1. Scenario 1 - Field : Month_Year is date datatype:
Let say, I have val array in which I have selected values of the date type field "Month_Year".
Var FieldName = "Month_Year"; // field in datamodel script : Date#(Month_Year,'MMM YYYY') AS Month_Year
var valArray[]= {
0:"Jan 2020"
1:"Feb 2020"
2:"Mar 2020"
}
app.Field(FieldName ).selectValues(valArray);
it is not selecting the value in desired "app" because the FieldName = Month_Year is derived as Date#(Month_Year,'MMM YYYY').
2. Scenario 2 - Field : Month_Year is TEXT() string datatype:
Let say, I have val array in which I have selected values of the text/string type field "Month_Year".
Var FieldName = "Month_Year"; // field in datamodel script : Text(Month_Year) AS Month_Year
var valArray[]= {
0:"Jan 2020"
1:"Feb 2020"
2:"Mar 2020"
}
app.Field(FieldName ).selectValues(valArray);
Now the same field is making the selections in the field if we bring the field as text(Month_Year) as Month_Year.
did anyone faced this issue in your mash up application?
Thats because under the hood Qlik is storing the values in dual representation - number and text (especially for fields that are flagged as date). The actual value for 01/01/2020 is actually 43831 and its displayed as 01 Jan 2020 (or whatever is the date format). So when trying to select Jan 2020 nothing is happening because such value do not exists.
When you "break" the dual representation (using the Text() function) then the selection is working but potentially there can be performance implications (based on the data volume in the app mostly)
Have a look at the dual() function documentation for more info about this behaviour.
In order to select something in this case you'll have to find the underlying values or element numbers and select them.
Personally I'm creating temporary listbox for the required filed and when I have to select I'm finding the qElemNumber of the required values and then selecting them in the listbox
// let values = ['array', 'of', 'values', 'to', 'select']
// create the session object
let sessionObj = await qDoc.createSessionObject(lbDef);
// get the layout so we can loop through the data pages
let layout = await sessionObj.getLayout();
// get the qElemNumber for the required values
// WARNING: if the field contains more than 1000 (i think) DISTINCT values then we'll have to loop through all the databased
let index = layout.field.qListObject.qDataPages[0].qMatrix.filter(function (m) {
return values.indexOf(m[0].qText) > -1
}).map(function (e) {
return e[0].qElemNumber
});
// perform the selection
let selection = await sessionObj.selectListObjectValues('/field/qListObjectDef', index, toggle);
I've used such approach here
Some background: We have a shared Google Sheet to track our openings, screenings, and other events at a movie theater. We have a main tab ("Master") that contains all of our events and the details that go with them, and a tab for archiving ("Archive").
I would like to write a script within Google Sheets to detect events & screenings that are from yesterday and earlier based on the date (in column E), take the full row(s) (events) that meet that criteria, copy & paste them to the separate "Archive" tab, and then delete the row(s) from the "Master" tab.
Anything to point me in the right direction would be super helpful. I found a few similar responses to this but they're specific to Excel/VBA and I'm not familiar with that (or much Javascript, for that matter).
I suggested that you do some tutorials to familiarise yourself with how to write scripts.
In this answer, I will flesh out the steps that your code needs to address. You will find many existing topics on the same or similar question. This is merely in order to enable you to better search for the elements of code that you need. Consider that this may be just one way of achieving your outcome.
You have one spreadsheet with two sheets and you will refer to both sheets at different stages. getSheetByName(name) will enable you to create a re-usable variable for a sheet.
You will need to find the bottom row in each sheet. getLastRow() will help.
You want to find rows in "Master" for dates, so you need to get ALL values for "Master".
You'll start by defining the range - use getRange(row, column, numRows, numColumns), though this is just one of 5 ways to define a range.
Having defined the range you'll need the values in "Master" so that you can access the date field. Use getValues() in conjunction with the range that defined. FWIW, note how this is in plural because there are lots of values. If you just wanted a single cell, you'd use getValue().
You'll want to loop through the rows in "Master" and find those rows that have a date prior to today. The "Removing Duplicate Rows in a Spreadsheet" tutorial shows one way of looping, and you can read up on basic JavaScript "Loops and iteration".
In your scenario, there is a 'hitch' with looping. If one adopts the "usual" process, then one will loop from the first row to the last. However, you are deleting a row from "Master" and, as each row is deleted, the row numbers of the remaining rows will/may change; so the "usual" process won't do. What you need to do is two things: first) loop from the bottom of the range; this will ensure that the row numbers of remaining rows will never change; second) sort the data so that the oldest dates are at the bottom. So... now you will loop from the bottom to the top, and you will evaluate all the oldest dates without any risk that when you encounter a date greater than "today", there will be NO risk of further rows with a date less than "today". Of course, once the code is complete, you can always re-sort the data on "Master" back to any order that you might wish.
You need to compare the date in the row in "Master" with today's date and then build a if...else statement so that you can define what to do depending on the result. Comparing dates is sometimes easier said than done. This topic is relevant Checking if one date is greater than the other using Google Script and you can search on other topics for "Google Sheets Script date comparison".
When you find a date less than today, you want to copy the details of that row to "Archive". This is a two part process first) to gather there the data from the row on "Master", and second) to "copy" that data to "Archive". Gathering the data will have been covered in the tutorials. There are many options for copying the data to "Archive". You could append a row and use setValues to update the new values. An alternative is to accumulate the additional "Archive" data and add it to the "Archive" after the loops have been completed.
When you find a date less than today, you want to delete the row from "Master". There's a command for that: deleteRow(rowPosition).
You can process your function manually, on demand, or you may prefer it to be automated as a time-driven installable trigger. The option is yours.
There are many ways that you can combine these elements.
In preparing the summary above, I had to make sure that I was providing accurate and complete advice. So the following is but one approach to achieving your goal. It should be noted that my test data assumes that columns A and C are formatted for date and time respectively.
function so5710086103() {
// set up spreadsheet and sheets
var ss = SpreadsheetApp.getActiveSpreadsheet();
var master = ss.getSheetByName("Master");
var archive = ss.getSheetByName("Archive");
// get the last row and column of Master
var masterLR = master.getLastRow();
var masterLC = master.getLastColumn();
// get the last row and column of Archive
var archiveLR = archive.getLastRow();
var archiveLC = archive.getLastColumn();
//Logger.log("DEBUG: Last Row - Master = "+masterLR+", and Archive = "+archiveLR);
//Logger.log("DEBUG: Last Column - Master = "+masterLC+", and Archive = "+archiveLC);
// create a range, sort it and get the data from "Master"
var masterRange = master.getRange(2, 1, masterLR - 1, masterLC);
// sort master based on date
masterRange.sort({
column: 1,
ascending: false
});
// Logger.log("DEBUG: Master range = "+masterRange.getA1Notation());
var masterData = masterRange.getValues();
//Logger.log("DEBUG: Length of Master data = "+masterData.length);
// create a range and get the data from "Archive"
var archiveRange = archive.getRange(1, 1, archiveLR, archiveLC);
var archiveData = archiveRange.getValues();
// create a formatted date for today
var formattedToday = Utilities.formatDate(new(Date), 'GMT+10',
'dd MMMM yyyy');
// loop through the rows
// from bottom to top
for (var i = (+masterLR - 2); i > 0; i--) {
// convert cell dates to comparable format
var DBdate = Utilities.formatDate(masterData[i][0], 'GMT+10',
'dd MMMM yyyy');
var DBtime = Utilities.formatDate(masterData[i][2], 'GMT+10',
'hh:mm a');
//Logger.log("DEBUG: i = "+i+", DBdate = "+DBdate+", Today = "+formattedToday);
// clear the temporary row array
var archivecells = [];
if (DBdate < formattedToday) {
// the table date is less than today, so archive the data
// Logger.log("DEBUG: i = "+i+", DBdate = "+DBdate+", Today = "+formattedToday+" - DB value is less than Today. ACTION: Archive this row");
// copy the row cells to temporary row array
archivecells.push(DBdate);
archivecells.push(masterData[i][1]);
archivecells.push(DBtime);
archivecells.push(masterData[i][3]);
archivecells.push(masterData[i][4]);
// copy the temporary row array to archivedata
archiveData.push(archivecells);
// delete the Master Row
master.deleteRow(i + 2);
} else {
// the table date is NOT less than today, so do nothing
// Logger.log("DEBUG: i = "+i+", DBdate = "+DBdate+", Today = "+formattedToday+" - DB value is NOT less than Today. ACTION: Do nothing");
}
// update the accumulated data to Archive.
archive.getRange(1, 1, archiveData.length, archiveLC).setValues(
archiveData);
}
}
getSheetByName(name)
getLastRow()
getRange(row, column, numRows, numColumns)
getValues()
Loops and iteration
Javascript if...else
deleteRow(rowPosition)
Master - Before
Master - After
Archive - After
I have a table in which one of the Column has sap.m.Datepicker element. There is a checkbox which says "same start date for all" and a plus button to add a row. So when plus button is clicked i am pushing a empty row in the table model, but if check box is ticked then start date should be same in the new row as in previous row.
But if i am unchecking the checkbox, still start date in a new row is setting the same.
See the code below:
var datepickered = new sap.m.DatePicker({
value: {
path:"{Start_Date}",
type: new sap.ui.model.type.Date({
pattern:"MMM dd yy",
source:{pattern:"MM/dd/yy"}
})
},});
Now i am setting the date in new row.
var modelData = sap.ui.getCore().byId("tableid").getModel().getData();
var value = sap.ui.getCore().byId("tableid").getItems()[0].getCells()[3];
modelData.push({Start_Date:value.getValue()});
sap.ui.getCore().byId("tableid").setModel(modelData);
sanpshot of the rows
Just call sap.ui.getCore().byId("tableid").getModel().refresh(true) to refresh the model manually and apply the changes made on the underlying data object.
It's unnecessary to use the sap.ui.getCore().byId("tableid").setModel(modelData) code, because the model itself is already assigned to the table.
Also make sure that sap.ui.getCore().byId("tableid").getModel().getData() returns an array, not an object with a property which points to the desired array. It depends on your JSON data model.
Edit:
According to the attached JSBin source code, I found the following issues:
var datepickerst = new sap.m.DatePicker({
value: {
path:"{Start_Date}",
type: new sap.ui.model.type.Date({
pattern:"MMM dd yy",
source:{pattern:"MM/dd/yy"}
})
}
});
You should align the pattern and source properties to support the same format (because you are using getValue(), which will return the date in MMM dd yy format, but the DatePicker itself waits for a date in format MM/dd/yy.
The other thing is that path property should not contain the curly braces. Based on these things, a correct DatePicker definition should look like this:
var datepickerst = new sap.m.DatePicker({
value: {
path:"Start_Date",
type: new sap.ui.model.type.Date({
pattern:"MMM dd yy",
source:{pattern:"MMM dd yy"}
})
}
});
Also make sure that you align pattern in the initialization phase of your code to the correct source format.
EDIT 4/16/2012: I solved the issue of getting the timezone abbreviated into a letter format, had to download a third party sorting method and add a few things to get the desired results. The only problem now is Daylight Savings Time handlers, but there are a bunch of subjects on that. However if anyone knows how to handle UTC Daylight Savings hanlers, please feel free to help.
Thank you everyone.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
I've made an html table that I've binded with a javscript viewmodel using knockoutjs that pulls the info from a private server usin JSON function. I'm trying to make each column sortable (click on the column header once to get everything in descending order according to that column's info; click header again to get everything in ascending, and a third time to get everything in it's original order).
PLEASE NOTE: I have searched for my problem and have seen other solutions, but nothing so far has worked for me. I'm hoping to find a solution specific towards my code.
The Javascript ViewModel.js file is basically like this:
Event(column1, column2, ...., columnN){
var self = this;
self.column1 = column1;
self.column2 = column2;
.
.
}
//Sort column2 that has the Dates (dd (day) HHMM (hours/minutes) mmm (month) yy (year) format)
self.sortColumn = "Column2"
self.sortAscending = true;
self.SortByDates = function(){
if(self.sortColumn == "Column2")
self.sortAscending = !self.sortAscending;
else{
self.sortColumn = "Column2"
self.sortAscending = true;
}
self.rows.sort(function(a,b){
if(self.sortAscending == true)
for(self.Column2 in self.rows)
return a.Column2 > b.Column2 ? 1 : a.Column2 < b.Column2 ? -1 : 0;
else
return a.Column2 < b.Column2 ? 1 : a.Column2 > b.Column2 ? -1 : 0;
});
}
//specify location of server and info and get them
function getEvents(){
$.getJSON("http://.........",
function (data){
$.each(data.d, function(i, item){
handleEvent(item)
})
}
);
}
//pushes (AKA populates) info from server into the table
function handleEvent(item){
var newEvent = new Event(item.Column1InfoFromServer,
formatJSONDate(item.Column2DateInfoFromServer), .....)
this.Model.rows.push(newEvent);
}
//Formats the date info from server into dd (day) HHMM (hours/minutes) mmm (month) yy (year)
formatJSONDate(jsonDate){
var date = new Date(parseInt(jsonDate.substr(6)));
return date.format("dd HHMM mmm yy");
}
this.Model = new ViewModel();
this.getEvents();
ko.applyBindings(this.Model);
I'm having one hell of a hard time getting the Date in its converted form (yes it HAS to be in that form --> actually, I still need to figure out how to include the time-zone abbreviation right after the 'HHMM' part based off of UTC). So lets say I have "11 1136 Apr 12" and "22 1624 Jan 12" among other dates in the table. Right now when I try sorting the table according to the dates, they don't sort appropriately. Any help is appreciated, thank you.
EDIT: To be clear, I'm trying to display the timezones in military timezone codes (timezones 'A'-'Z'). Also, the dates being taken from the server are already in UTC.
UPDATE:
I was looking at another question, and someone created a knockout grid addon:
https://github.com/ericmbarnard/KoGrid
I bet this might help you out :-)
---OLD ANSWER for nostalgia----
There are some great helper functions in the Underscore library, one of them being sort:
http://documentcloud.github.com/underscore/#sortBy
sortBy_.sortBy(list, iterator, [context]) Returns a sorted copy of
list, ranked in ascending order by the results of running each value
through iterator. Iterator may also be the string name of the property
to sort by (eg. length).
_.sortBy([1, 2, 3, 4, 5, 6], function(num){ return Math.sin(num); });
=> [5, 4, 6, 3, 1, 2]
I'd give this a shot, along with creating a better model for your dates. It sounds like you need to store a property which is a unique point in time, along with a text value for the user.
Well, to get numeric values for your date objects, sort by pDate.valueOf(). This will give you the # of millisecond since epoch.
However, there is an issue inside of your sort function, but I'm not sure what it is supposed to do. You can't walk an object inside of a sort function and return values like that.