Thursday, May 3, 2012

Jquery plugins occupy the same function name -> conflict


I've ran into a problem using jquery expose plugin alongside Masked Input plugin. The problem is they both occupy $.mask function which leads to conflict. But I vitally need this two plugins to work together. I would rename $.mask in one of them to... let's say, $.msk , but in this case I'll always need to remember it and if I want to upgrade to new version, I will rename again.



Looking for better solution on how to cope with this kind of conflicts between jquery plugins.


Source: Tips4all

3 comments:

  1. I think I agree with mu's answer. One addition might be to use jQuery.sub().

    Since most plugins use the jQuery global during construction, you should be able to alias jQuery before loading one of the plugins. Then you could re-alias afterwards to whatever you choose.

    <script src="http://cdn.jquerytools.org/1.2.5/full/jquery.tools.min.js?foo"></script>
    <script type="text/javascript">
    var jQuery = $.sub();
    </script>
    <script src="jquery.maskedinput.js" type="text/javascript"></script>
    <script type="text/javascript">
    var $$$ = jQuery;
    jQuery = $;
    </script>


    The only possible advantage to this approach is that it might isolate one plugin from the changes that another plugin might make to jQuery methods. It's slightly convoluted but the only alternative to altering the plugins, that I can think of.

    ReplyDelete
  2. I think you have a choice between solutions that require you to remember something, the question is how often do you want to remember.

    If you rename one of them then you have to remember to patch any upgrades. I don't think this is such a big deal, it happens all the time in software development.

    An alternative is to pull in one of the plugins and then immediately load a namespace patcher that simply does, for example, jQuery.fn.masked_input = jQuery.fn.mask; and then the expose plugin can be loaded after that. This approach will work as long as the renamed plugin doesn't reference its own name anywhere. And, you'd have to remember the specific loading order for your plugins. This sort of thing also occurs all the time in software development.

    ReplyDelete
  3. Ok. I'm answering my question now.

    I've considered mu is too short's approach, but it's not quite fits. My colleague offered following:

    We create new instance of jQuery like so:

    var $$$ = $.extend( true, function(selector, context) {
    return new $$$.fn.init( selector, context );
    }, $);
    $$$.fn = $$$.prototype = jQuery.prototype;


    And we create plugins closure of $ function on it (since $ is used inside of plugin):

    (function($) {
    ... plugin code goes here ...
    $.fn.extend({
    myplugin: function(maybe_some_options) {
    ...
    })($$$);


    Now we can call $$$(<selector>).myplugin( { do : 'great job', and : 'be happy' } ); and $(<selector>).myplugin() at the same time.

    We have no problems with this approach so far and I don't see a reason why it would break, so we decided to go with this decision.

    ReplyDelete