JavaScript/FullCalendar - Attaching event to event rendering - javascript

My full code is here: http://pastebin.com/nctMtX9m
I've got an instance of FullCalendar, and using the 'className' property of the event object, I'm adding icons to certain events after the calendar renders. These simple icons indicate if a job (event) on the calendar has been shipped.
$(window).load(function(){
$('a.shipped div span').prepend("<img src=\"/img/truck_white.png\" title=\"Shipped\" alt=\"Shipped\" style=\"padding:2px 5px 5px 0; width=\"16\" height=\"16\" />");});
This works great! The problem is that whenever I change the view, like changing the month then coming back, FullCalendar completely re-renders the events! This means they are without my icons now since my icon adding process only occurs once, after the initial render.
I need my icon adding process to fire every time the FullCalendar renders events.
I've found this: http://arshaw.com/fullcalendar/docs/event_data/events_function/ but unfortunately my evens are written to the page by PHP, so they are statically defined as far as the script is concerned. This example leads me to believe that I can only do this with an external data source. This level of JavaScript is admittedly not my forte.
How do I attach my icon adding process to something that fires every time Fullcalendar renders events if my event data is statically defined?
Thanks!
edit I found out how to do what I want using eventRender, but I can't seem to reference the part of the element that I want to, because now the rendering is slightly off. I'll work on this further and update when I find the answer.
edit 2 Figured it out, can't post answer because I'm new. Will post answer tomorrow.

The solution was to use eventRender.
eventRender: function(event, element) {
if(event.className == 'shipped'){
var find = '<span class="fc-event-title">';
var replace = find + '<img src="/img/truck_white.png" title="Shipped" alt="Shipped" class="event_icon" />';
var newHTML = $(element).html().replace(find, replace);
$(element).html(newHTML);
}
}
It's a bit of a convoluted find/replace, but it works.

Related

Semantic UI dropdown lags entire ui when setting values

I have a large select with about ~1500 items in it. Whenever i call this code
$('#multi-select').dropdown('set exactly', ['my value']);
to set its value, the entire UI locks up and lags. Now I know this is due to the large dropdown (1500 items) but I'd like to know if there is a way to keep that many items without flushing the user experience down the toilet.
I've put together an example below. You can try clicking the button once, or multiple times consecutively to see the browser choke.
http://jsfiddle.net/qhy9do4w/1/
I've looked in the code and profiled the click. Somewhere in its bowels Semantic fires a lot of events and most of the lag time is taken by module.trigger something. Inside the code looks like this:
trigger: {
change: function() {
var
events = document.createEvent('HTMLEvents'),
inputElement = $input[0]
;
if(inputElement) {
module.verbose('Triggering native change event');
events.initEvent('change', true, false);
inputElement.dispatchEvent(events);
}
}
}
I don't see any way to disable the event handling part.
I had a look into the semantic.js code for the dropdown set exactly and it is quite something: https://github.com/Semantic-Org/Semantic-UI/blob/74fea12e1fd548cb870872ba5ed59f5acdcc57ba/dist/components/dropdown.js#L2219:L2295
You could try figure if the code is slow somewere or wether you can do any sort of shortcut.
But, that is hard and you might want to think about an alernative like a search.
Our solution was to simply cache the contents and only put in a selected subset of options into the drop down itself.

Add class to dynamically generated HTML

I'm working to use custom checkbox styles with a checkbox which is dynamically generated by javascript for the Google Identity Toolkit. For example, we add this div:
<div id="gitkitWidgetDiv"></div>
And the Google Identity Toolkit script generates new html for that div.
I need to add a class to the HTML which is added by the javascript without any action by the user and I'm struggling to make it work. For example, here is my code:
$("#gitkitWidgetDiv").on('ready', ".gitkit-sign-in-options label", function() {
$(this).addClass('checkbox');
});
I've tried switching 'ready' for a few other options and also using the livequery plugin, but nothing is working for me. It works if I use an active event like 'click,' but I can't figure out how to do this when the page loads. Could someone please help? Thanks!
Modern browsers (including IE11) support mutation obervers. You can use one to monitor the parent node of the div that will be added. When the div has been added, just add the class.
Here's something I made which comes in handy in annoying cases like this where it's difficult to tell when the element you need has finished loading in: https://gist.github.com/DanWebb/8b688b31492632b38aea
so after including the function it'd be something like:
var interval = 500,
stopTime = 5000,
loaded = false;
setIntervalTimeout(function() {
if($('.dynanicElementClass').length && !loaded) {
$('.dynanicElementClass').addClass('checkbox');
loaded = true;
}
}, interval, stopTime);
It's not perfect and I'm sure there are better solutions out there but in most cases like this it does the job.

Dynamic CFTab onClose event

I simply can't find any real documentation on ColdFusion Layout Tabs. For the most part I've got them working, but I'd like to tie some logic to a close event. I was wondering if anyone had a working example they could show me? The catch is that I will need to trigger these events in JavaScript. But if you have a working version in plain ColdFusion, I'd still love to see it!
var tab = ColdFusion.Layout.getTabLayout("innerTabLayout").activeTab._cf_body;
$('#' + tab).on('close', blah); // doesn't work
tab.on('close', blah) // doesn't work
ColdFusion.Layout.getTabLayout("innerTabLayout").activeTab._cf_body.onTabClose( function(), blah ); //doesn't work
I have also tried setting the event on tab creation:
var tab = ColdFusion.Layout.createTab();
tab.onTabClose()
tab.on('close');
However, none of these work either. I've tried looking at EXT.JS which is what CFtabs were created from, but I don't seem to have any luck there either.
The Coldfusion.Layout object has a function for tab closing, so there must be a way to trigger it! (I would think, haha).
So after spending some too much messing around with the tab, I've got a solution.
ColdFusion.Layout.getTabLayout('innerTabLayout').activeTab.on('close', function(e) {
console.log(this) //this will return the tab object
console.log(e)//this also returns the tab object
});
This will trigger the event when the active tab within a parent is closed. I'm interested to see if there's another, better solution.

How to remove an event out of content script scope?

I'm trying to unbind an event from a specific element and upon research, I found this. Which is useful. In itself. I didn't know you could do that. But:
Is there a way to make it work in a browser/Chrome extension? I'm talking about content scripts.
The reason why this doesn't work the way it's described there is that the website which has attached the event in question with its own script is using a different jQuery object than the one in my extension's includes/ folder. And I can try to search the event via jQuery._data(el, 'click'); but that is my jQuery object, not the one of the website where the events are apparently stored. I'm glad I figured that out after hours of fiddling around.
Or maybe it is possible to access the website's jQuery object itself?
EDIT:
What I'm ultimately trying to achieve works in theory but … it's complicated. The original script uses a plugin event and keeps reinstalling it with .on('mouseleave',….
Anyway, this is what I got thanks to you, pdoherty926:
var $el = $('div.slideshow');
$('h2', $el).click(function(){ console.log('ouch!'); }); // test event
var $slides = $('.slides', $el).detach();
$copy = $el.clone(false);
$slides.prependTo($copy);
$el.replaceWith($copy);
The test event doesn't get triggered but the event I'm actually trying to remove still fires. I can imagine figuring it out, though, now that I got closer to my goal.
Okay, the aforementioned re-installation on mouseleave really messed up this otherwise satisfying suggestion. (The site is using the jQuery Timer plug-in by Cyntaxtech). So here's how I solved it instead: I simply changed the class name (-.-' )
Now the re-installation code cannot find the element anymore.
This is how my finished script looks like:
function stop_happening() {
var $el = $('div.fullwall div.slideshow');
$el
// first, stop the current automation.
.timer('stop') // Timer plug-in
// next, change class name in order to prevent the timer
// from being started again.
.removeClass('slideshow').addClass('slideshow-disabled-automation');
//--- copied some extra code from the website itself for the onclick
// events which are supposed to keep working. I wish I could do *that*
// programmatically but I'm glad I got as far as I got. ---//
// […]
}

How do we set an onExpand event in a cfLayout accordion

We're using CFLayout to create a tab structure in our web application. After creation of that layout we call this function:
mytabs = ColdFusion.Layout.getTabLayout("#attributes.cflayoutName#");
mytabs.on('tabchange',
function(tablayout,tab) {
var tabtitle = tab.title;
alert(tabtitle); // Actual code does various useful 'stuff' here.
}
);
That piece of code works very well, and the alert will show each time the user clicks on a tab.
The problem is that we are now trying to do the same thing with a CFLayout type of "accordion", and I cannot get an event to fire when the user switches which accordion pane they are looking at. We've tried leaving the above as is, as well as changing the "tabchange" attribute to "expand", "beforeexpand", "activate", and "collapse".
For this testing I'm using the following simple JS function to avoid issues arising from the JS within the onchange event:
mytabs = ColdFusion.Layout.getAccordionLayout("#attributes.cflayoutName#");
mytabs.on('expand',
function(tablayout,tab) {
console.log('test');
}
);
We do not receive any errors. Nothing is logged to the console at all. I've tried replacing the console.log to an alert to rule out any problems with that line.
I found that the Ext library documentation to be very helpful with finding a solution to this problem: here.
The Ext library has a getComponent method that allows you to reference the accordion layout panel that you are trying to add the expand event to. Once you have this, you can use the "on" method you are using above to assign the expand event to each panel individually.
for (x=1; x<accordionLayoutArray.length; x++) {
mytabs.getComponent(accordionPanelName).on('expand',
function(tab) { ... });
}
This became too long for a comment so adding as an answer
After some Google searches I found what I think are some related posts. It appears as though the accordion in Ext JS does not have the same events as the tab. Instead you need to add a listener in order to catch the expanding.
See this post - in case something happens to that page here is the relevant piece:
You'd need to listen to the expand event of the child panels in the accordion, you could do something like:
Code:
myAccordion.add(myFunc('myTitle'));
function myFunc(title)
{
return new Ext.Panel(
{
title: title,
listeners: { 'expand': {fn: something, scope: foo}}
}
);
}
And I also found another similar post here on SO - see both answers
Once you know that the accordion needs a listener you can find a number of results on Google. Such as How do I attach an event handler to a panel in extJS?
This Google search will give you lots of examples.
Hope that helps.

Categories