Callback before calendar view is changed - fullcalendar

I added bootstrap popovers to the calendar events which open on click:
eventClick: (event, jsEvent, view) ->
if event.ajaxUrl?
elem = jQuery(#)
elem.popover('destroy')
jQuery.ajax({url: event.ajaxUrl})
.done (result) ->
elem.popover(
placement: 'top'
html: true
trigger: 'manual'
title: moment(event.start).format('dddd, DD. MMMM YYYY - HH:mm')
content: result
container: 'body')
elem.popover('show')
My problem is, that these popovers stay open when I change the calendar view (e.g. change the month or to week/day layout). As the popovers are bound to the .fc-event divs/spans within the calendar, I need to access these DOM elements to run .popover('destroy').
Whenever a fullCalendar view is changed, the old DOM-Elements are replaced with the ones for the new view, so I would have to access them before the view is actually changed. Unfortunately there are only callbacks for event loading (loading which happens after the view is changed) and viewDisplay (same, but you get the new view).
To make sure I understood viewDisplay correctly, I added a small test to the calendar which always gives me "0" (the data-selector comes from jquery data selector)
viewDisplay: (view) ->
alert(jQuery('.fc-event:data(popover)').size())
Is there a way to hook into the calendar process everytime the view is to be changed - but before the view is actually changed?
Edit
For now I'm simply destroying the popovers once the mouse is moved over any calendar button (as a bind to click would be executed after the view change), but this solution is just a workaround
jQuery('.fc-button').on 'mouseover', () ->
jQuery('.fc-event:data(popover)').popover('destroy')

V3
I think you are looking for http://fullcalendar.io/docs/display/viewRender/
From doc
viewRender
Triggered when a new date-range is rendered, or when the view type
switches. function( view, element ) view is the View Object for the
new view. element is a jQuery element for the container of the new
view.
This callback will get triggered when the user changes the view, or
when any of the date navigation methods are called.
This callback will trigger after the view has been fully rendered,
but, before events have been rendered (see also: eventAfterAllRender).
UPDATE
V4 renamed from viewRender to datesRender https://fullcalendar.io/docs/v4/datesRender
V5 renamed from datesRender to datesSet https://fullcalendar.io/docs/datesSet

In V4, viewRender was deprecated, check out the release notes, now they have:
"viewSkeletonRender" callback which is triggered when the new view is mounted, it receives a view object containing a lot of good stuff in it.
"viewSkeletonDestroy" callback which is triggered right before the old view is about to get unmounted.
--
Alternatively, thought may not answer the question directly, you can use the "datesRender" callback. I needed was to run a function when previous, next, or the view changed. (I had to compute the total number of hours of an event type based on the date range and the views)

Related

algolia wordpress autocomplete

I'm trying to tweak the WordPress plugin https://github.com/algolia/algoliasearch-wordpress to suit our needs. What we want to be able to do is have a search result that will load the data up in the same page.
I have my WordPress posts and its data being indexed successfully. I have added a search box to the page, and autocomplete is being fired.
Out of the box, the WordPress plugin template wraps the result in an anchor tag and assigns it the URL of the found result. When clicked, this navigates you to that post. However, what I want to do is intercept that click and load the result in the same page without navigating away.
I have removed the href from the anchor. I have also edited the supplied autocomplete.php template where the call to autocomplete:selected occurs. In there I have removed the call to navigate away by removing window.location.href.
Now I have two main issues.
1 - When the user clicks the search result I would like the input to be populate with the title of the item they clicked on. I added this in the autocomplete:selected callback by adding $searchInput[0].value = suggestion.post_title. Which seems to change the value of the input correctly, but as soon as I click away from the input, it is re-set back to the original typed value. So if I type 'may' and click the result 'mayonnaise', the result data can be accessed but the input returns back to 'may'. My function looks this:
/* Instantiate autocomplete.js */
var autocomplete = algoliaAutocomplete($searchInput[0], config, sources)
.on('autocomplete:selected', function (e, suggestion) {
console.log(suggestion);
autocomplete.autocomplete.close();
});
2 - It seems that the autocomplete dropdown does not hide when the user clicks away. To resolve this i've had to use what I think is a bit of a nasty hack with jQuery. I was wondering if this is really required? My code just below the autocomplete:selected call looks like this:
jQuery('body').on("click", function(event){
if (!jQuery(event.target).closest($searchInput[0]).length) {
autocomplete.autocomplete.close();
}
});
Found some answers to my questions.
1 - In order to populate the input with the title of the selected search result I added a call to the setVal method of the autocomplete object. I'[m still not sure why this is required.
/* Instantiate autocomplete.js */
var autocomplete = algoliaAutocomplete($searchInput[0], config, sources)
.on('autocomplete:selected', function (e, suggestion) {
autocomplete.autocomplete.setVal(suggestion.post_title);
});
2 - It looks like the config of the autocomplete object uses the value of WP_DEBUG in order to set the debug value. The options available for the autocomplete component can be found here https://github.com/algolia/autocomplete.js#options. This lead me to find that when debug is set to true, the autocomplete box does not hide on selection. This is to allow for easier debugging and styling of the component.

How can I simulate a click event on an anchor tag without actually calling click or refreshing?

I am using meteor with iron router and meteors standard blaze tempting.
I have an ul set up so that when one of my li items is clicked its containing anchor tag is clicked on using the function click. The only problem is that when that a is clicked with the function it counts as another click on my li and my menu isn't toggling right.
I am wondering if there is a way to call the pathFor without actually calling a click function.
Thanks for any help!
Update, here is the code its working along with a pretty standard drop down nav. I am not sure if I can catch that event the same as a jquery event since I think it is the standard browser click event working on the [0], but I think I should be able to make a function that matches href to route and call Router.go
Template.nav.rendered = () ->
# set initial page view and take care of refeshes
currentPageHtlm = getCurrentPage(window.location.pathname)
$('#currentPage').find('span').html(currentPageHtlm)
$("li").on "click", () ->
#simulate anchor click and set currentPage session
$(this).find("a")[0].click()
Session.set 'pageName', getCurrentPage($(this).find("a").attr("href"))
currentPageHtlm = Session.get 'pageName'
$('#currentPage').find('span').html(currentPageHtlm)
# toggle nav and arrow if mobile view
if $('.smOnly').css('display') != 'none'
$('#nav').slideToggle('slow')
$('#dropArrow').toggleClass('fa-caret-square-o-down fa-caret-square-o-up')
It sounds like you're looking for a way to programatically redirect from JS rather than via UI interaction, in which case you need to use Router.go('ROUTE_NAME'), as per the docs (you can use the route name as in pathFor as an alternative to supplying the actual path).

Meteor JS Template rendered function called before template is rendered?

I'm trying to use the Buttonset widget in JQuery UI. I've got the package loaded and my template renders the radio buttons fine. I have a "rendered" function to call the JQ UI routine to setup the buttonset:
Template.teamList.rendered = function () {
$("#buttonsetID").buttonset();
}
But it looks like the rendered function is being called before the template is rendered! I stick a console.log in the function and it prints out to the console before there's anything on the screen. So none of the radio buttons are set up, therefore the .buttonset() call does nothing. If I make that call in the console after the page is rendered, JQuery UI does the right thing and my button set appears.
Isn't the .rendered function supposed to be called after everything's set up? Am I doing something wrong?
Thanks!
edit:
As an example, the same thing is seen in the leaderboard example.
If you add:
Template.leaderboard.rendered = function() {
alert($('.player').length);
}
When the page is displayed, it will show 0. This makes it difficult to access the DOM items if you need to add some JQuery events or, in this case, a JQuery UI element.
rendered only works for elements which will appear in the DOM the very first time the template is added to the page. Assume that subscription data takes infinitely long to arrive, then look at the template and see which elements would appear in the default state.
Using the leaderboard example, we can't assume that players are available when the leaderboard template renders (it depends on a subscription). To target a player, you should use the rendered callback on the player template.
It's hard to generalize a strategy for when to apply jQuery plugins, but here are some ideas:
Use the rendered callback if the element will always be added in the default state (e.g. the element is hard-coded and doesn't depend on a conditional).
Use the rendered callback of the most specific child template to target that child (e.g. the player template from above).
Consider using an event handler callback to target the element if it's appearance depends on an event (e.g. a button click).
Consider using a template autorun callback to target the element if it's appearance depends on reactive state. See this question for an example.

Capturing clicks in a column of buttons (with dojo)

I am trying to capture the click event of a row using a column of "use" buttons. This is similar to the "selectable" feature in the Kendo grid, but having a button makes it more obvious for the user in our case.
Because there are multiple buttons (and I don't know if you can dynamically assign button id values), I tied a CSS class to the button, and I will use that to determine what row I am on when the user clicks the USE button.
Here is a dojo of what I am trying to accomplish, but for some reason, the click event (alert statement) is never executed.
http://dojo.telerik.com/UkIW/2
Can anyone spot the problem?
As far as I can see you're using jQuery and no Dojo code so far. But there are some mistakes here, first of all, you should put the event handler for hte buttons in the ready() handler as well, so move it inside:
$(document).ready(function() {
// ...
});
And then second, if you're binding to dynamic elements with jQuery, the preferred way of doing so is by adding it to a parent element (for example the <body>) and then adding a second parameter as shown below:
$(document).ready(function() {
// ...
$("body").on("click", ".use", function() {
// ...
});
});
I created a milestone in your example: http://dojo.telerik.com/UkIW/5

Alternative method for creationcomplete

I am trying to load bunch of product detail into a canvas component from a List component.
Every time the user clicks on a product inside my List, the product detail will be displayed in the canvas component. The product detail might contain null and I want to check it before displaying in my canvas component.
In my canvas component, I use createcomplete to check if the productDetail==null then do something. My problem is if the user clicks the product with the non-null detail first time, the statement "if (productDetail==null) then do something" won't work if the user click a null product detail because the canvas component has been created the first time user clicks a non-null product detail.
I want to check if the productDetail==null every time the user click a product...I hope I explain my question well and appreciate any helps.
My code..
AS:
protected function changeHandler(event:IndexChangeEvent):void{
compDetailinfoResult.token=getCompList.compDetail(event.target.selectedItem.productId);//get the product detail clicked by the user
}
<s:List dataProvider={productData}/> //when user click a product,
//the canvas will show product detail..
<comp:productDetail productData={compDetailinfoResult.lastResult} //custom property
change="changeHandler"/> //if the product detail is
//null, the statement inside
//the canvas will check via
//creationComplete. but if the
//user click the non-null product,
//the creationComplete check pass. User clicks a null product again,
//the check won't work anymore...
code for my productDetail component:
public var productData:arrayCollection
protected function canvas1_creationCompleteHandler(event:FlexEvent):void
{
var undefinedBrand:String=dataFromClick.getItemAt(0).brand;
if(undefinedBrand==null){ // I want to check every time the user click a List item
brand.text="Brand: No Brand";
switchView.enabled=false;
displayPictureBig.source="assets/vacant.jpg";
}
}
<s:Panel>
<label id="brand" text="productDate.getItemAt(0).brand"/>
//I want the brand to be displayed..
//but if brand is null..it will display No Brand..
//see AC above...but createComplete only fire once.
//Anyway to keep tracking if the brand that is sent by List is null?
</s:Panel
Thanks for the helps..
I'm having some trouble understanding your issue. Are you referring explicitly to Canvas, the Halo container? Or did you name one of your custom components Canvas? If it is custom, as your code suggests, what is inside the component?
creationComplete is an event that only fires once, when the component finishes running the component lifecycle creation process for the first time. Your code snippets do not show any data being passed from the list into the canvas, so that could be one reason why the data is null.
If someone selects a new item on the list, the change event should dispatch. You can add an event listener to the change event and use it to update the data you are sending into your canvas component.

Resources