setting end of the fullcalendar event overwrites start - fullcalendar

When you drop external item on to fullcalendar it automatically sets start date of the event but end time is null. So what I want to do is set end time to 2h later.
eventReceive: function(event){
event.end = event.start;
console.log(event.start.format()); // 2014-12-14T07:00:00
event.end.add(2, 'h');
console.log(event.start.format()); // 2014-12-14T09:00:00
...
when ever I try to do that event.start is set to exact same time as event.end
EDIT
Solved by forceEventDuration, but still curious about why does it do that?

event.start is an object. You are passing the object reference, not the value. To see how this works in javascript execute this:
var x = {"a": 10}
var y = x
y["a"] = 5
console.log(x)
This will return {"a": 5} because you changed the referenced object. You would need to create a copy (clone) of the object first before you pass it.

Related

Remove date from Time in Google App Script

I am new to script and found a code that I have been tweaking for my needs but I keep running into a problem since I separated the date and time. My date field display and selected value match but the time fields keep defaulting to MM/DD/YY HH:MM A/P when selected. en I click on it (it displays correctly when not selected). I need to have the field only display the time and nothing else. so it will stop causing issues to my formulas on other sheets. I know my problem lies in the last part but so far what I have tried has failed.
//DEFINE ALL ACTIVE SHEETS
var ss = SpreadsheetApp.getActiveSpreadsheet();
//DEFINE MAIN SHEET
var mainSheet = ss.getSheetByName("MAIN");
//LAST ROW ON MAIN SHEET
var lastRow = mainSheet.getLastRow();
for (var j = 5; j <= lastRow; j++)
{
// CHECK CLOCK IN
if(mainSheet.getRange('b1:b1').getValue() == mainSheet.getRange(j, 1).getValue() && mainSheet.getRange(j,3).getValue() == '')
{
Browser.msgBox('Need to Clock Out before Clocking IN');
return;
}
}
// ADD CLOCK IN RECORD
mainSheet.getRange(lastRow + 1, 1).setValue(mainSheet.getRange('b1:b1').getValue()).setFontSize(12);
mainSheet.getRange(lastRow + 1, 2).setValue(new Date(new Date().setHours(0, 0, 0, 0))).setNumberFormat('MM/DD/YY').setHorizontalAlignment("center").setFontSize(12);
mainSheet.getRange(lastRow + 1, 3).setValue(new Date()).setNumberFormat("hh:mm A/P").setHorizontalAlignment("center").setFontSize(12);//````
You get a whole bunch of formatting options if you look for Utilities.formatDate
var date = Utilities.formatDate(new Date(), "Europe/Berlin", "dd.MM.yyyy")
var time = Utilities.formatDate(new Date(), "Europe/Berlin", "HH:mm")
Change "Europe/Berlin" to your location to get the current time. Now use the variables wherever you need them. Simple as that.
Pro tip: Try to use variables (just like shown above) for readability instead of fitting everything in one line.

Cannot get Realm result for objects filtered by the latest (nsdate) value of a property of a collection property swift (the example is clearer)

I Have the following model
class Process: Object {
#objc dynamic var processID:Int = 1
let steps = List<Step>()
}
class Step: Object {
#objc private dynamic var stepCode: Int = 0
#objc dynamic var stepDateUTC: Date? = nil
var stepType: ProcessStepType {
get {
return ProcessStepType(rawValue: stepCode) ?? .created
}
set {
stepCode = newValue.rawValue
}
}
}
enum ProcessStepType: Int { // to review - real value
case created = 0
case scheduled = 1
case processing = 2
case paused = 3
case finished = 4
}
A process can start, processing , paused , resume (to be in step processing again), pause , resume again,etc. the current step is the one with the latest stepDateUTC
I am trying to get all Processes, having for last step ,a step of stepType processing "processing ", ie. where for the last stepDate, stepCode is 2 .
I came with the following predicate... which doesn't work. Any idea of the right perform to perform such query ?
my best trial is the one. Is it possible to get to this result via one realm query .
let processes = realm.objects(Process.self).filter(NSPredicate(format: "ANY steps.stepCode = 2 AND NOT (ANY steps.stepCode = 4)")
let ongoingprocesses = processes.filter(){$0.steps.sorted(byKeyPath: "stepDateUTC", ascending: false).first!.stepType == .processing}
what I hoped would work
NSPredicate(format: "steps[LAST].stepCode = \(TicketStepType.processing.rawValue)")
I understand [LAST] is not supported by realm (as per the cheatsheet). but is there anyway around I could achieve my goal through a realm query?
There are a few ways to approach this and it doesn't appear the date property is relevant because lists are stored in sequential order (as long as they are not altered), so the last element in the List was added last.
This first piece of code will filter for processes where the last element is 'processing'. I coded this long-handed so the flow is more understandable.
let results = realm.objects(Process.self).filter { p in
let lastIndex = p.steps.count - 1
let step = p.steps[lastIndex]
let type = step.stepType
if type == .processing {
return true
}
return false
}
Note that Realm objects are lazily loaded - which means thousands of objects have a low memory impact. By filtering using Swift, the objects are filtered in memory so the impact is more significant.
The second piece of code is what I would suggest as it makes filtering much simpler, but would require a slight change to the Process model.
class Process: Object {
#objc dynamic var processID:Int = 1
let stepHistory = List<Step>() //RENAMED: the history of the steps
#objc dynamic var name = ""
//ADDED: new property tracks current step
#objc dynamic var current_step = ProcessStepType.created.index
}
My thought here is that the Process model keeps a 'history' of steps that have occurred so far, and then what the current_step is.
I also modified the ProcessStepType enum to make it more filterable friendly.
enum ProcessStepType: Int { // to review - real value
case created = 0
case scheduled = 1
case processing = 2
case paused = 3
case finished = 4
//this is used when filtering
var index: Int {
switch self {
case .created:
return 0
case .scheduled:
return 1
case .processing:
return 2
case .paused:
return 3
case .finished:
return 4
}
}
}
Then to return all processes where the last step in the list is 'processing' here's the filter
let results2 = realm.objects(Process.self).filter("current_step == %#", ProcessStepType.processing.index)
The final thought is to add some code to the Process model so when a step is added to the list, the current_step var is also updated. Coding that is left to the OP.

SwiftUI or Combine Clock/Timer events

Using SwiftUI (or Combine) how might I set up a series of one or more events that are triggered by the (system) clock. Examples might include:
Every night at midnight,
On the hour,
Every fifteen minutes on the quarter hour,
Finally, on a slightly different note: On the 29th of February 2020 at 12:15.
An approximation is easily achieved by setting up a timer event that fires every second and then checking the hours/minutes/seconds, etc. but this seems very inefficient for events that may be many hours or days apart.
I'm looking for something that is closely synchronised to the actual system clock and fires off a single event at the required time rather than firing loads of events and having each one ask "Are we there yet?".
I would suggest the following:
DispatchQueue.global(qos: .background).async {
let isoDate = "2020-01-13T16:58:30+0000"
let dateFormatter = ISO8601DateFormatter()
let date = dateFormatter.date(from:isoDate)!
let t = Timer(fire: date, interval: 2, repeats: true) { timer in
print("fired")
}
let runLoop = RunLoop.current
runLoop.add(t, forMode: .default)
runLoop.run()
}
string to date conversion I used this answer to format the time correctly.
The example is in GMT.
documentation apple you can look up timer tolerance which can be adjusted if you need the timer to be very accurate.
interval is in seconds so this solution won't get more accurate than seconds
You might want to enable the Background Modes capability to go for the very long running timers. Never done that so I can't help here.
All your examples should work. I hope this helps!
I had to implement this feature too using Combine / SwiftUI : a Timer that would execute at start then every day, hour or minutes (for testing), here is my solution if it can be useful or improved :)
class PeriodicPublisher {
var periodicFormat: PeriodicFormat = .daily
init(_ format: PeriodicFormat = .daily) {
self.periodicFormat = format
}
// Must have an equatable for removeDuplicate
struct OutputDate: Equatable {
let compared: String
let original: String
init(_ comparedDatePart: String, _ originalDate: String) {
self.compared = comparedDatePart
self.original = originalDate
}
static func ==(lhs: OutputDate, rhs: OutputDate) -> Bool {
return lhs.compared == rhs.compared
}
}
enum PeriodicFormat {
case daily
case hourly
case minutely
func toComparableDate() -> String {
switch self {
case .daily:
return "yyyy-MM-dd"
case .hourly:
return "HH"
case .minutely:
return "mm"
}
}
}
func getPublisher() -> AnyPublisher<OutputDate, Never> {
let compareDateFormatter = DateFormatter()
compareDateFormatter.dateFormat = self.periodicFormat.toComparableDate()
let originalTimerDateFormatter = DateFormatter()
originalTimerDateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
var nowDate: Just<OutputDate> {
let comparedDate = compareDateFormatter.string(from: Date())
let originalDate = originalTimerDateFormatter.string(from: Date())
return Just(OutputDate(comparedDate, originalDate))
}
let timerDate = Timer.publish(every: 2.0, tolerance: 1.0, on: .main, in: .default, options: nil)
.autoconnect()
.map { dateString -> OutputDate in
return OutputDate(compareDateFormatter.string(from: dateString), originalTimerDateFormatter.string(from: dateString))
}
.eraseToAnyPublisher()
return Publishers.Merge(nowDate, timerDate)
.map { $0 }
.removeDuplicates()
.eraseToAnyPublisher()
}
}
How does it work ?
Every 2 seconds the scheduler issue current date (with Timer.publish()), this date is used to create a "OutputDate" holding two properties : one "comparable" part used to compare if something has changed and one "original" part so it can be useful for the consumer.
Comparable property is Timer's date formatted with toComparableDate given the provided configuration (.daily, .hourly, .minutely). Using "removeDuplicates" on this property allow to publish "OutputDate" only when this value changes. Every day or hour or minute.
Publishers.Merge is used to publish a value immediately after instantiation, otherwise nothing happens before the first Timer.publish(every). Here 2 seconds.
How to use it ?
You would use it with Combine like this :
PeriodicPublisher(.daily).getPublisher().sink { date in
print("Day has changed \(date.original)")
}

momentjs - strange behave with startOf and endOf

I'm trying to get the start and the end a a specific day.
Here's the code:
var newDay, newDayEnd, newDayStart;
if (newDay === '') {
newDay = moment();
}
newDay.subtract('day', 1);
newDayStart = newDay.startOf('day');
newDayEnd = newDay.endOf('day');
I'm trying to debug it, and I noticed that when if goes trough the values are correct, but as soon as it reaches newDay.endOf('day') it sets all the variable to the end of the specified day (23.59.59)
I'm using the above function on button click. Every time I click a button, it goes back one day (newDay.subtract('day', 1)) and I need to be able to get start and end of the new day (newDay variable)
Any help?
What am I doing wrong here? I don't understand.
Thanks
Moment objects are mutable, so you have to clone() them before modifying them.
As you can read from the endOf docs:
Mutates the original moment by setting it to the end of a unit of time.
Working example:
var newDay, newDayEnd, newDayStart;
newDay = moment().subtract(1, 'day');
newDayStart = newDay.clone().startOf('day');
newDayEnd = newDay.clone().endOf('day');
console.log(newDayStart.format(), newDayEnd.format());
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js"></script>

global variable not getting set with proper values in another function in flex

I have a global variable 'csId' of string type. In the code below under drawChart() function, in for loop, csID variable should be set to '1' by the modelLocator when i=0 and csId should be set to '2' by modelLocator when i=1.(considering lengh=2).
Alert in drawchart() (for csId) seems to be printing the right 'csid' values(both 1 and 2) but in the dataFunction() 'columnSeries_labelFunc' i am always getting the csId Alert value as '2' and never as '1'.
Please find the code below:
drawchart() function::
public function drawChart():void
{
var cs:ColumnSeries= new ColumnSeries();
var lenght:Number=AppModelLocator.getInstance().ctsModel.productSummary.getItemAt(0).collMgmtOfcList.length;
myChart.series = [cs];
var tempObj:Object;
for(csLoop=0;csLoop<lenght;csLoop++)
{
cs = new ColumnSeries();
this.csId= new String(String(AppModelLocator.getInstance().ctsModel.productSummary.getItemAt(0).collMgmtOfcList[csLoop]));
Alert.show("csId="+this.csId);
cs.id=this.csId;
cs.displayName = 'Exposure';
cs.dataFunction=columnSeries_labelFunc;
myChart.series[csLoop] = cs;
}
columnSeries_labelFunc() function::
private function columnSeries_labelFunc(series:Series, item:Object, fieldName:String):Object {
var col:Number=0;
Alert.show("value of csid in columnSeries_labelFunc="+this.csId);
if(fieldName == "yValue" && series.id==csId){
return(item.exposureUSDList[0]);
}else if(fieldName == "yValue" && series.id==csId) {
return(item.exposureUSDList[1]);
}else if(fieldName == "xValue"){
return(item.rptType);
}else
return null;
}
Please Help!!!
First: Assigning a value to a global variable repeatedly inside a loop is a bad idea. Nothing good will happen from that.
It's hard to tell from the context here, but the most likely reason that you're having this problem is that the flow of execution is as follows:
drawChart() executes synchronously, counting through each step in the loop, creating the ColumnSeries, which are each invalidated, meaning they will redraw on the next frame. The function ends, with csID at the last value it held.
The app goes into the next step in the elastic racetrack and validates the invalidated components.
columnSeries_labelFunc is called, with csID still holding the terminal value from the loop.
The end result being that columnSeries_labelFunc isn't called until you're already completely finished in drawChart.
The simplest fix would be to read the id that you're setting on the series in the label function, rather than relying on a global variable at all.

Resources