22

I have this jsfiddle

which uses toggle event - not to be confued with toggle - jQuery version set to EDGE

It suddenly stopped working and removed the cell I wanted as a trigger, since it obviously reverts to toggle.

I cannot find any deprecation tags or such

http://api.jquery.com/category/deprecated/ gives a 404

If I add the Migrate module my jsFiddle then works and I see the warning in the console (elaborated by https://github.com/jquery/jquery-migrate/blob/master/warnings.md as posted by Frédéric Hamidi)

I see Deprecate fn toggle and issue 24 and Ticket #11786 but not in places I would expect to see it.

What am I missing and where do I find the replacement and documentation for it?

NOTE: I understand the reason for deprecation, I just can't find official documentation for the deprecation

$('#tbl .xx').toggle(
  function() {
    $(this).siblings().each(function(){
      var t = $(this).text();
      $(this).html($('<input />',{'value' : t}));
    });
  },
  function() {
    $(this).siblings().each(function(){
      var inp = $(this).find('input');
      if (inp.length){
        $(this).text(inp.val());
      }
    });
  }    
);

Code in MIGRATE:

jQuery.fn.toggle = function( fn, fn2 ) {
  // Don't mess with animation or css toggles
  if ( !jQuery.isFunction( fn ) || !jQuery.isFunction( fn2 ) ) {
    return oldToggle.apply( this, arguments );
  }
  migrateWarn("jQuery.fn.toggle(handler, handler...) is deprecated");
  // Save reference to arguments for access in closure
  var args = arguments,
  guid = fn.guid || jQuery.guid++,
  i = 0,
  toggler = function( event ) {
    // Figure out which function to execute
    var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
    jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
    // Make sure that clicks stop
    event.preventDefault();
    // and execute the function
    return args[ lastToggle ].apply( this, arguments ) || false;
  };
  // link all the functions, so any of them can unbind this click handler
  toggler.guid = guid;
  while ( i < args.length ) {
    args[ i++ ].guid = guid;
  }
  return this.click( toggler );
};

UPDATE I have asked if they could keep the code as fn.toggler so it is a rename instead of a remove

mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • 1
    According into [ticket #11786](http://bugs.jquery.com/ticket/11786) in [bugs.jquery.com](http://bugs.jquery.com), it seems that the [toggle event](http://api.jquery.com/toggle-event/) is deprecating/deprecated; but you're right, I can't see that in [toggle event](http://api.jquery.com/toggle-event/)'s page either. I suggest you to add a comment to the ticket. – Pang Jan 13 '13 at 09:09
  • I remember hearing about this a little while back and was confused that it didn't seem to be marked in the frontend docs as deprecated. – Jared Farrish Jan 13 '13 at 10:12
  • Why the downvote? It never fails to amaze me that some people have time to down vote but cannot be bothered to tell why. – mplungjan Sep 12 '14 at 08:18

4 Answers4

15

Deprecation of jquery .toggle() is now documented at api.jquery.com. I found a nice replacement for it at forum.jquery that I am now using. It works great :)

$.fn.toggleClick = function() {
  var functions = arguments,
      iteration = 0;
  return this.click(function() {
    functions[iteration].call();
    iteration = (iteration + 1) % functions.length;
  });
}

Usage:

$("#target").toggleClick(function() {
  alert( "First handler for .toggle() called." );
}, function() {
  alert( "Second handler for .toggle() called." );
});

Edit Aug. 6, 2014: I reconsidered the original code and found that .apply is not the right thing to use. Changed that to .call with no args passed in.

Oliver
  • 9,239
  • 9
  • 69
  • 100
Randy Skretka
  • 3,488
  • 3
  • 22
  • 14
  • I ended up adding "this" into functions[iteration].call(this); as some old code I was using was referencing "this" in the toggle handlers – Matthew Lock Mar 08 '17 at 04:13
9

You can find official documentation about toggle()'s deprecation in the list of warnings emitted by the jQuery Migrate plugin:

JQMIGRATE: jQuery.fn.toggle(handler, handler...) is deprecated

Cause: There are two completely different meanings for the .toggle() method. The use of .toggle() to show or hide elements is not affected. The use of .toggle() as a specialized click handler was deprecated in 1.8 and removed in 1.9.

Solution: Rewrite the code that depends on $().toggle(), use the minified production version of the jQuery Migrate plugin to provide the functionality, or extract the $().toggle() method from the plugin's source and use it in the application.

Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479
  • Thanks for pointing me at that. That is however not where I expected it. Is there an official deprecation at the API or did I miss something? As you saw, I already applied the MIGRATE but hadn't found the .md file that elaborated on it – mplungjan Jan 13 '13 at 10:09
  • 1
    @mplungjan, you did not miss anything, the documentation page for `toggle()` has not yet been updated with this information. The API docs have just been revamped/updated, though (they now say `then()` is the same thing as `pipe()` for instance), maybe `toggle()` will be part of the next batch. – Frédéric Hamidi Jan 13 '13 at 10:12
2

jQuery 1.9 isn't final yet. As per the upgrade guide:

"For now, this guide serves as an appendix to the standard jQuery API documentation, and those pages may not describe the behavior of version 1.9. Please be patient while we update the documentation for the individual pages at api.jquery.com to reflect the changes in 1.9."

In this case, we just haven't documented it yet. You SO folk are faster than us! Please file a documentation ticket here: http://github.com/jquery/api.jquery.com

Mike Sherov
  • 13,277
  • 8
  • 41
  • 62
1

The code that I use:

$('#example').click(function()
    {
    isClicked=$(this).data('clicked');
    if (isClicked) {isClicked=false;} else {isClicked=true;}
    $(this).data('clicked',isClicked);

    if(isClicked)
        {
        ...do stuff...
        }
    else
        {
        ...do stuff...
        }
    });

The optimized code (suggest by mplungjan) is:

$('#example').click(function()
    {
    $(this).data('clicked',!$(this).data('clicked'));

    if ($(this).data('clicked'))
        {
        ...do stuff...
        }
    else
        {
        ...do stuff...
        }
    });
Cuarcuiu
  • 467
  • 1
  • 8
  • 20
  • That is not very slick. You can toggle the isCicked with !isClicked but whoever uses your code needs to be aware that you toggle before you test so the if has to be reverse of what one would expect. `$(this).data('clicked',!$(this).data('clicked'));` – mplungjan May 23 '13 at 04:19
  • beautiful! I usually use a readable code without "compressing". Thanks! – Cuarcuiu May 23 '13 at 09:40
  • You are welcome. Just a note: Your code only handles TWO clicks. The code for fn.toggle handled ANY clicks. So 5 or 10 clicks or whatever could have a different effect for each click. – mplungjan May 23 '13 at 09:42
  • Ah, ok. I simply wanted to make a version of the code easier for those who needed quickly instead the deprecated toggle method. Hello and thank you! – Cuarcuiu May 23 '13 at 13:38