There is a form for configuring options for the flexslider. It would be great if it allowed for adding callback functions. Is there a way to override the ctools plugin? Or, does the module need a patch to accomplish that?

Files: 
CommentFileSizeAuthor
#25 flexslider.load_.js-1580902.patch1.01 KBkenorb
Test request sent.
[ View ]
#17 flexslider-callback_functions-1580902-17.patch2.47 KBrooby
Test request sent.
[ View ]
#13 flexslider-1580902-13.patch910 bytesyang_yi_cn
Test request sent.
[ View ]
#7 flexslider_add_callbacks.patch3.32 KBwiktorb
Test request sent.
[ View ]

Comments

Status:Active» Postponed (maintainer needs more info)

What kind of callback are you looking for? Do you mean in javascript when certain actions occur in the slideshow? Or a hook of some kind in PHP to act on something?

There are 4 callback functions in flexslider configuration:

start: function(){}, //Callback: function(slider) - Fires when the slider loads the first slide
before: function(){}, //Callback: function(slider) - Fires asynchronously with each slider animation
after: function(){}, //Callback: function(slider) - Fires after each slider animation completes
end: function(){} //Callback: function(slider) - Fires when the slider reaches the last slide

but you can't setup it in current release unless you hack the module. It would be nice if I can add js file with callback functions to theme, and then specify functions names in configuration set admin/config/media/flexslider/edit/set_name

They are js functions that come standard with flexslider... any plans to integrate them?

Status:Postponed (maintainer needs more info)» Postponed

I'm a little hesitant adding a set of text areas where a user can enter arbitrary javascript to be executed.

I'll give it some thought, see how I might be able to get this in.

I'm a little hesitant adding a set of text areas where a user can enter arbitrary javascript to be executed.

I was just wondering if there was a way to do this in code? I'm sure there is a way but I couldn't figure it out.

I was also looking for more than a month a way to use the after callback function, and right now I have just got it working. I'm using Flexslider Views Slideshow module for creating the sliders.

I edited the file flexslider/flexslider_views_slideshow/js/flexslider_views_slideshow.js in this file you can find all the current options, I added the after callback. In that file there is a variable called fullId which can be used to know which code to add to each slider:

...
          manualControls:settings.manualcontrols,
          start: function(slider) {
            flexslider_views_slideshow_register(fullId, slider);
          },
  after: function(slider){
if(fullId == "#slider1"){
    // some code
}
else{
   // other code
}
  }
...

this worked for me very well,

hope this can help you,

Eduardo

StatusFileSize
new3.32 KB
Test request sent.
[ View ]

I made a patch which adds callbacks settings to optionset.

Status:Postponed» Needs review

Has there been any update to this? I tried running the patch in #7, which gave me the options in the drupal interface, but as far as I could tell, they didn't actually work

Status:Needs review» Closed (won't fix)

We can't add the callbacks to the UI. The function drupal_json_encode takes any javascript and converts it to a string value. Which means the browser won't treat the text as "code" and you'll get errors.

If you want to use the callbacks, you'll have to use the library the old fashioned way. I'm keeping my eye on a module which offers a replacement for the default drupal_json_encode function which allows "code" text to be sent, but it's got some show-stopping issues at the moment.

Why don't you forward the events to the dom container so one can delegate multiple event handlers to it from anywhere?

I changed my flexslider.load.js in this way:

var optionset = settings.flexslider.optionsets[settings.flexslider.instances[id]];

to
var optionset = settings.flexslider.optionsets[settings.flexslider.instances[id]];
optionset = $.extend(optionset || {}, {
  before: function(slider) {
    slider.trigger('before');
  },
  after: function(slider) {
    slider.trigger('after');
  }
});

and then use:

$('.flexslider').on('after', function () {
}

You could also add the flexslider object as parameter.

I know this might not be the best implementation on my side, but i think you get the idea.

Status:Closed (won't fix)» Active

I think a configurable UI might be too complicated, but #11 is a good solution for anyone want to implement it in code.

Can we get it committed?

StatusFileSize
new910 bytes
Test request sent.
[ View ]

convert #11 to a patch

Status:Active» Needs work

There's no means of rendering the js from a text area in drupal to the browser (filters automatically kill that option).

But I do want to implement something like what you've done in that patch. Reading this post from lullabot http://www.lullabot.com/articles/your-javascript-should-expose-apis-too I just need time/feedback on which technique would work best.

Btw, I don't think we can use the .on method with jquery 1.4.4. But I could be wrong.

it looks like you can catch the event using .on() after jQuery 1.7 (that's the way the official jQuery doc uses), but before that you can use .bind() to catch an event (that's the way done in the lullabot article).

In both case the event can be send by .trigger(), so I don't think it's a problem to put the trigger function in here, it's added since jQuery 1.0 with the ability to trigger default javascript events, and in 1.3 you can trigger custom events.

Title:Can a callback function be added to the flexslider options?Allow the use of the flexslider callback functions?
Category:support» feature

We can't add the callbacks to the UI. The function drupal_json_encode takes any javascript and converts it to a string value. Which means the browser won't treat the text as "code" and you'll get errors.

The views slideshow cycle module allows you to enter js code for callbacks via the slideshow display setting in the views configuration. - However I believe it only lets you add, not edit, so to edit a snippet you have to remove it and re-enter it.

Having said that, I am also not a fan of the idea of entering code snippets into the database via the UI.
It introduces a possible world of pain.

I would love a solution where I can just integrate via javascript in a module or theme, either like #13 or like #14.

Status:Needs work» Needs review
StatusFileSize
new2.47 KB
Test request sent.
[ View ]

New version of patch in #13.

Also supports the views slideshow implementation.

Use bind() instead of on() with the default drupal jQuery, as mentioned in #14.

rooby, exactly what i was thinking.
agree with minorOffense, providing events to act on makes this easily extensible.
keep js out of text inputs.

maybe the events should be more uniquely identified though, a preface of "flexslider_" ought to do the job

I've implemented the patch from #17, working great!

Any chance this patch could be re-rolled for 7.x-2.x-dev version. Thanks in advance

I'm also looking for this patch for version 7.x-2.
@gooddesignusa: did you find a way to get this working?

@chefnelone
I actually got this working manually. Since the patch didn't apply. I didn't create a patch because I didn't have enough time to test to make sure it added the callback to every scenario.

If you want to look over the changes and make a patch / test feel free.
This is what my flexslider.load.js looks like

(function ($) {
// Behavior to load FlexSlider
Drupal.behaviors.flexslider = {
  attach: function(context, settings) {
    var sliders = [];
    for (id in settings.flexslider.instances) {
      if (settings.flexslider.optionsets[settings.flexslider.instances[id]] !== undefined) {
        if (settings.flexslider.optionsets[settings.flexslider.instances[id]].asNavFor !== '') {
          // We have to initialize all the sliders which are "asNavFor" first.
          _flexslider_init(id, settings.flexslider.optionsets[settings.flexslider.instances[id]], context, settings);
        }
        else {
          // Everyone else is second
          sliders[id] = settings.flexslider.optionsets[settings.flexslider.instances[id]];
        }
      }
    }
    // Slider set
    for (id in sliders) {
      _flexslider_init(id, settings.flexslider.optionsets[settings.flexslider.instances[id]], context, settings);
    }
  }
};
/**
* Initialize the flexslider instance
*/
function _flexslider_init(id, optionset, context, settings) {
  $('#' + id, context).once('flexslider', function() {
    // Remove width/height attributes
    // @todo load the css path from the settings
    $(this).find('ul.slides > li > img').removeAttr('height');
    $(this).find('ul.slides > li > img').removeAttr('width');
    if (optionset) {
      //$(this).flexslider(optionset);
                  // Add events that developers can use to interact.
            $(this).flexslider($.extend(settings.flexslider.optionsets[optionset], {
              start: function(slider) {
                slider.trigger('start');
              },
              before: function(slider) {
                slider.trigger('before');
              },
              after: function(slider) {
                slider.trigger('after');
              },
              end: function(slider) {
                slider.trigger('end');
              },
              added: function(slider) {
                slider.trigger('added');
              },
              removed: function(slider) {
                slider.trigger('removed');
              }
            }));
    }
    else {
      $(this).flexslider();
    }
  });
}
}(jQuery));

Inside my theme script file I was running this code
jQuery(document).ready(function($) {
  $body = $('body');
  if($body.hasClass('front')){
    $('.flexslider').bind('start', function () {
      // add code here //
    });
  }
});

@gooddesignusa: thanks!
Your code works but all sliders are shown with the Default "option set" even when you select another option set, for instance: "basic carousel". Have you tried using other option set (provided by the example module) than default?

@23

replace

$(this).flexslider($.extend(settings.flexslider.optionsets[optionset], {

with

$(this).flexslider($.extend(optionset, {

StatusFileSize
new1.01 KB
Test request sent.
[ View ]

Patch for 7.x-2.0-alpha1, should work also for 7.x-2.x (based on #22 and #24)

If jQuery hooks doesn't work, make sure that flexslider.load.js file is loaded. If not, please add flexslider_add(); into your preprocess function. Also if you're using Views, please make sure that you're using FlexSlider, not Slideshow format.

Patch in #25 works for me, thanks!

Status:Needs review» Reviewed & tested by the community

@kenorb, not that I don't appreciate it, but it might be best to let others review this, setting to RTBC based off of one successful use case might be jumping the gun a bit :)

To summarise:
Patch from #7 has a little different approach as it's adding the settings for callbacks in UI.
Patch #25 is actually based on #17
The only suggestion about this patch is that triggers should use different names at #18

But based on #18, #19, #21, #22, #26 it seems that it was quite heavily tested by community.
So let maintainer decide what to do next.

Status:Reviewed & tested by the community» Closed (fixed)

Committed to dev.

Thanks for all the great work everyone!

Version:7.x-1.x-dev» 7.x-2.x-dev

I was looking for a way to utilize callback functions to add some custom functionality to my flexslider created with views and luckily I found this post! The update that was submitted was very helpful, but the only thing it was lacking was the slider object parameter. I saw that in #11, Novascreen said "You could also add the flexslider object as parameter.", but this was never actually added to the update.

Unless I'm missing something, this is very important if you want to be able to customize the slider.

In \assets\js\flexslider.load.js under "_flexslider_init", I added the "slider" object as an optional parameter in the trigger function. Feel free to patch this if you think it's valuable to include.

if (optionset) {
// Add events that developers can use to interact.
$(this).flexslider($.extend(optionset, {
start: function(slider) {
slider.trigger('start', [slider]);
},
before: function(slider) {
slider.trigger('before', [slider]);
},
after: function(slider) {
slider.trigger('after', [slider]);
},
end: function(slider) {
slider.trigger('end', [slider]);
},
added: function(slider) {
slider.trigger('added', [slider]);
},
removed: function(slider) {
slider.trigger('removed', [slider]);
}
}));

@justinen: I second that. Was looking for the same thing.

To properly catch that event with the slider (adding an optionial pause here):

$('.flexslider').bind('end', function(event, slider) {
  slider.pause();
  setTimeout(function(){
    slider.play();
  }, 1000);
});

If you have something valuable to add please open a new issue and suply a patch file.

So how do you access the slider if it's not passed as a parameter in the callback? I think this issue is half-way done.

For example it's quite easy to make tabindex work if there would be slider object:

jQuery('.flexslider').bind('start', function(e, slider) {
  slider.slides.eq(slider.currentSlide).siblings().find('a').attr('tabindex', '-1');
});
jQuery('.flexslider').bind('after', function(e, slider) {
  slider.slides.find('a').attr('z-index', '');
  slider.slides.eq(slider.currentSlide).siblings().find('a').attr('tabindex', '-1');
});

Proposed solution #32 from justinen works.

Issue summary:View changes
Status:Closed (fixed)» Needs work