uiCalendar does not refresh when adding or removing events - javascript

I can't get uiCalendar to update after changing the elements in the event source.
The calendar is defined in the template as:
<div ui-calendar="uiConfig.calendar" class="span8 calendar" ng-model="EC.calendarEvents" calendar="eventsCalendar"></div>
When I add or remove elements from EC.calendarEvents the calendar doesn't update.
I've tried all of the following statements to try to get the calendar to refresh after modifying EC.calendarEvents:
uiCalendarConfig.calendars['eventsCalendar'].fullCalendar('render');
uiCalendarConfig.calendars['eventsCalendar'].fullCalendar('rerenderEvents');
uiCalendarConfig.calendars['eventsCalendar'].fullCalendar('refetchEvents');
I've also tried removing and re-adding the source:
uiCalendarConfig.calendars['eventsCalendar'].fullCalendar('removeEvents');
uiCalendarConfig.calendars['eventsCalendar'].fullCalendar('addEventSource', $scope.EC.calendarEvents);
But this just causes the following error to show up in the console:
TypeError: Cannot read property 'hasTime' of undefined
The error is occurring in fullcalendar.js in the normalizeEventTimes function on line 12272.
The error line is:
eventProps.allDay = !(eventProps.start.hasTime() || (eventProps.end && eventProps.end.hasTime()));
In this post they suggest maintaining the same reference to the array and pushing/splicing events in and out: AngularJS UI-calendar not updating events on Calendar
I tried this as well but it didn't make any difference.

The problem turned out to be an inconsistency in the format that ui-calendar expects to receive it's events in.
When the controller loads and I populate EC.calendarEvents, ui-calendar expects to receive an array of arrays. So the assignment looks like this:
$scope.EC.calendarEvents = [createCalendarEventsFromCoreEvents(coreEvents)];
However, whenever I want to alter EC.calendarEvents, it has to be an array only, not an array of arrays.
So subsequent updates to EC.calendarEvents look like this:
$scope.EC.calendarEvents = createCalendarEventsFromCoreEvents(filterEvents());
uiCalendarConfig.calendars['eventsCalendar'].fullCalendar('removeEvents');
uiCalendarConfig.calendars['eventsCalendar'].fullCalendar('addEventSource', $scope.EC.calendarEvents);
Note the lack of brackets [] around createCalendarEventsFromCoreEvents.

Related

Why isn's dom updates detected by subsequent dom reads?

I'm coding a small Vue app. I've got an element which has a data-range property written like this:
:data-range="form.appearence.height_min + '/7'"
form.appearence.height_min will change based on a select element values, selected by the user.
After every select change, I'll read again the data-range and do things based on it.
// from the vue app, a watcher
'form.appearence.xps':function(val, oldval){
// this will properly change the model and the dom as well
this.$set(this.form.appearence, 'height_min', xps_map[val]);
this.$emit('xps-updated');
}
// then from another script
this.options.vue.$on('xps-updated', function(){
this.options.vue.$nextTick(function(){
console.log($('#test5').data('range')) // issue: this value doesn't change
}.bind(this))
}.bind(this));
My issue is that the range value does change on dom, I can see it from console, but javascript will always read the initial value... For example, at start was 3/7, then it gets changed to 5/7, but $('#test5').data('range') will still read 3/7. Why?
Ok, I'll answer by myself. I found out that jquery objects do not follow Vue's dom updates, at least in this case. Therefore, even if dom gets updated by Vue, $('#test5').data('range') will always give the initial value.
Instead, by getting the 'real' element with vanilla js, like
let range = document.querySelector('#test5').dataset.range;
Will always return the updated value.

Event Object property "source" returns [object Object]

I would like to render events differently based on the source of the Event Object, but even though the fullcalendar documentation states
source "Event Source Object. Automatically populated. A reference to
the event source that this event came from."
I am unable to query the "source" property of the Event Object.
console.log(event.source); results in [object Object]
I am using multiple Google Calendar eventSources, but nothing in the documentation seems to indicate that I shouldn't be able to do this.
I initially planned to render events based on filtered eventSources (triggered by a custom button which invokes a modal containing checkboxes), but I spent way to long reading up docs, code samples and numerous suggestions before I finally decided to throw in the towel on this idea. In the end I removed all eventSources using 'removeEventSources' before adding each source one by one using 'addEventSource' (depending on what filter options are selected).
It seems that there is no built in mechanism or straight forward functionality to filter eventSources (especially Google Calendars) and I suspect the ability to query the "sources" property of the Event Object would allow us a different approach to accomplish such functionality and improve load times.
Other use case example:
If want to determine the "source" at eventClick or render to decide whether to use certain fields e.g.
if event source == Holiday Cal do not display event.start & event.end
or
if source == eventSource1 use Modal1 else use Modal2
etc
So my question is:
Does anyone know why I cannot query the "source" property of the Event Object as documented in the following link?
https://fullcalendar.io/docs/event-object
Fullcalendar documentation screen shot:
The message you're seeing tells you that event.source is an Object, so console.log() won't show you much. But console.dir() will, including:
...
calendar: t {loadingLevel: 0, ignoreUpdateViewSize: 0, freezeContentHeightDepth: 0, el: w.fn.init(1), viewsByType: {…}, …}
className: ["TestCase"]
googleCalendarId: "e0kujgeepc0ev00eojborllms8#group.calendar.google.com"
... etc
You can use any of those properties to test which source you're looking at, for eg (not sure why className is an array but that's not relevant to this problem):
$target = (event.source.className[0] === 'HolidaysUK') ? $modal1 : $modal2;
Here's a much simplified Codepen which opens your events on click in different modals, depending on source, which is what I understand is one of the things you are trying to do.
Side note - you'll make it much easier for ppl to help if you try to create a minimal, complete, and verifiable example of your problem. Your Codepen includes loads of stuff entirely unrelated to the problem, which we have to wade through and evaluate and discard while looking at the problem.

PhysicsJs - how to remove a world behavior, "constant-acceration' after it has been added

My behaviors on initialization are added as follows:
world.add([
Physics.behavior('interactive', { el: renderer.el }),
Physics.behavior('constant-acceleration'),
Physics.behavior('body-impulse-response'),
Physics.behavior('sweep-prune'),
edgeBounce
]);
I'd like to, at a later time, remove the "constant-acceleration" behavior. I read a couple of posts that said to use the remove() method but I'm not getting anything to happen using it like follows:
world.remove( Physics.behavior('constant-acceleration') );
Can anyone advise how I could achieve removing a specific behavior from the world after it has been added?
The Physics.behavior docs indicate that a Behavior object is returned when you call Physics.behavior (because it constructs a new one). So you need to keep a reference to the Behavior object you'd get back from the call you've put into your world.add array, then pass that reference to world.remove later. As it is now, you're making a new Behavior (separate from the one you made first) and immediately passing that brand new object to world.remove, which will basically do nothing.

Stuck with simple calculation from form elements

I'm using a script template to create chunks of code when a user clicks a button, this works fine, but I want to be able to calculate a total within these cloned regions so I have a in-line onBlur statement as follows
onblur = "multiply.call(this, this.form.elements.Qty{{ID}}.value, this.form.elements.Cost{{ID}}.value, this.form.elements.Total{{ID}})"
As the cloning function updates ID to a value this evaluates to
onblur = "multiply.call(this, this.form.elements.Qty1.value, this.form.elements.Cost1.value, this.form.elements.Total1)"
My function is
function multiply(one, two, three) {
console.dir(three);
document.getElementById(three).value = (parseFloat(one) + parseFloat(two)).toFixed(2); // error here
};
If I display one and two they have the values from the form, however I get an error writing back to the for of Uncaught TypeError: Cannot set property 'value' of null.
The console shows the ID of the element three as Total1
I think this might be something to do with the jQuery clone and the DOM not being updated. The values are passed OK, but the object might not be.
Any ideas?
document.getElementById(three) returns no match (thus the undefined).
You're passing an element to your function multiply as parameter three, and you're later using it as a string representing the ID of it.
If three is verified to be an element, don't call document.getElementById(three).value in first place, but directly three.value.

Get the ID from an Element in BIRT-Designer

Can someone told me, how i get the value from an Element in BIRT-Report Designer?
I tried the follwing in a dynamic Text Element but it didn´t work
var e = reportContext.getDesignHandle().getElementByID(5514);
if(e > 13)
{
"bigger"
}
else
{
"smaller"
}
(5514) is the ID from a Data report Item.
It count a column in my dataset.
I also tried to get the value from this element by using:
reportContext.getDesignHandle().findElement("myElementId")
But also not working
Thanks for helping me!
Logging in the onFetch event and in fact anywhere in BIRT is definitely possible, we are using it frequently.
Probably your DS does not return any data or an exception occurs.
Add logging statements to the beforeOpen and afterOpen events, that will tell you if the query is executing at all (and you're able to log the actual DS parameter values using this.getInputParamaeterValue("param_Foo").
Quite often, you find that a parameter is null or uses a default value because you forgot to set the DS parameter bindings in the layout.
If the beforeOpen event runs, but not afterOpen, then the DB doesn't like your query.
If the afterOpen event runs, but not the onFetch, then your query returned zero rows.
Also, run your report as HTML to see if there's a JavaScript error (shown in red at the end of the output).

Categories

Resources