Therapeutic refactoring, make interwebs angry
[deck.js.git] / extensions / goto / deck.goto.js
blob5992444656e65f62517bf8f32f4851911f46893f
1 /*!
2 Deck JS - deck.goto
3 Copyright (c) 2011 Caleb Troughton
4 Dual licensed under the MIT license and GPL license.
5 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
6 https://github.com/imakewebthings/deck.js/blob/master/GPL-license.txt
7 */
9 /*
10 This module adds the necessary methods and key bindings to show and hide a form
11 for jumping to any slide number/id in the deck (and processes that form
12 accordingly). The form-showing state is indicated by the presence of a class on
13 the deck container.
15 (function($, undefined) {
16   var $document = $(document);
17   var rootCounter;
19   var bindKeyEvents = function() {
20     $document.unbind('keydown.deckgoto');
21     $document.bind('keydown.deckgoto', function(event) {
22       var key = $.deck('getOptions').keys.goto;
23       if (event.which === key || $.inArray(event.which, key) > -1) {
24         event.preventDefault();
25         $.deck('toggleGoTo');
26       }
27     });
28   };
30   var populateDatalist = function() {
31     var options = $.deck('getOptions');
32     var $datalist = $(options.selectors.gotoDatalist);
34     $.each($.deck('getSlides'), function(i, $slide) {
35       var id = $slide.attr('id');
36       if (id) {
37         $datalist.append('<option value="' + id + '">');
38       }
39     });
40   };
42   var markRootSlides = function() {
43     var options = $.deck('getOptions');
44     var slideTest = $.map([
45       options.classes.before,
46       options.classes.previous,
47       options.classes.current,
48       options.classes.next,
49       options.classes.after
50     ], function(el, i) {
51       return '.' + el;
52     }).join(', ');
54     rootCounter = 0;
55     $.each($.deck('getSlides'), function(i, $slide) {
56       var $parentSlides = $slide.parentsUntil(
57         options.selectors.container,
58         slideTest
59       );
61       if ($parentSlides.length) {
62         $slide.removeData('rootIndex');
63       }
64       else if (!options.countNested) {
65         ++rootCounter;
66         $slide.data('rootIndex', rootCounter);
67       }
68     });
69   };
71   var handleFormSubmit = function() {
72     var options = $.deck('getOptions');
73     var $form = $(options.selectors.gotoForm);
75     $form.unbind('submit.deckgoto');
76     $form.bind('submit.deckgoto', function(event) {
77       var $field = $(options.selectors.gotoInput);
78       var indexOrId = $field.val();
79       var index = parseInt(indexOrId, 10);
81       if (!options.countNested) {
82         if (!isNaN(index) && index >= rootCounter) {
83           return false;
84         }
85         $.each($.deck('getSlides'), function(i, $slide) {
86           if ($slide.data('rootIndex') === index) {
87             index = i + 1;
88             return false;
89           }
90         });
91       }
93       $.deck('go', isNaN(index) ? indexOrId : index - 1);
94       $.deck('hideGoTo');
95       $field.val('');
96       event.preventDefault();
97     });
98   };
100   /*
101   Extends defaults/options.
103   options.classes.goto
104     This class is added to the deck container when showing the Go To Slide
105     form.
107   options.selectors.gotoDatalist
108     The element that matches this selector is the datalist element that will
109     be populated with options for each of the slide ids.  In browsers that
110     support the datalist element, this provides a drop list of slide ids to
111     aid the user in selecting a slide.
113   options.selectors.gotoForm
114     The element that matches this selector is the form that is submitted
115     when a user hits enter after typing a slide number/id in the gotoInput
116     element.
118   options.selectors.gotoInput
119     The element that matches this selector is the text input field for
120     entering a slide number/id in the Go To Slide form.
122   options.keys.goto
123     The numeric keycode used to show the Go To Slide form.
125   options.countNested
126     If false, only top level slides will be counted when entering a
127     slide number.
128   */
129   $.extend(true, $.deck.defaults, {
130     classes: {
131       goto: 'deck-goto'
132     },
134     selectors: {
135       gotoDatalist: '#goto-datalist',
136       gotoForm: '.goto-form',
137       gotoInput: '#goto-slide'
138     },
140     keys: {
141       goto: 71 // g
142     },
144     countNested: true
145   });
147   /*
148   jQuery.deck('showGoTo')
150   Shows the Go To Slide form by adding the class specified by the goto class
151   option to the deck container.
152   */
153   $.deck('extend', 'showGoTo', function() {
154     var options = $.deck('getOptions');
155     $.deck('getContainer').addClass(options.classes.goto);
156     $(options.selectors.gotoInput).focus();
157   });
159   /*
160   jQuery.deck('hideGoTo')
162   Hides the Go To Slide form by removing the class specified by the goto class
163   option from the deck container.
164   */
165   $.deck('extend', 'hideGoTo', function() {
166     var options = $.deck('getOptions');
167     $(options.selectors.gotoInput).blur();
168     $.deck('getContainer').removeClass(options.classes.goto);
169   });
171   /*
172   jQuery.deck('toggleGoTo')
174   Toggles between showing and hiding the Go To Slide form.
175   */
176   $.deck('extend', 'toggleGoTo', function() {
177     var options = $.deck('getOptions');
178     var hasGotoClass = $.deck('getContainer').hasClass(options.classes.goto);
179     $.deck(hasGotoClass ? 'hideGoTo' : 'showGoTo');
180   });
182   $document.bind('deck.init', function() {
183     bindKeyEvents();
184     populateDatalist();
185     markRootSlides();
186     handleFormSubmit();
187   });
188 })(jQuery);