Conditions | 1 |
Paths | 32 |
Total Lines | 252 |
Lines | 0 |
Ratio | 0 % |
Changes | 1 | ||
Bugs | 0 | Features | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
1 | /** global: GLSR, jQuery */ |
||
2 | ;(function( _, wp, x ) { |
||
3 | |||
4 | 'use strict'; |
||
5 | |||
6 | var Search = function( selector, options ) { |
||
7 | this.el = x( selector ); |
||
8 | this.options = options; |
||
9 | this.searchTerm = null; |
||
10 | this.init_(); |
||
11 | }; |
||
12 | |||
13 | Search.prototype = { |
||
14 | defaults: { |
||
15 | action: null, |
||
16 | exclude: [], |
||
17 | onInit: null, |
||
18 | onResultClick: null, |
||
19 | results: {}, |
||
20 | selected: -1, |
||
21 | selectedClass: 'glsr-selected-result', |
||
22 | selectorEntries: '.glsr-strings-table tbody', |
||
23 | selectorResults: '.glsr-search-results', |
||
24 | selectorSearch: '.glsr-search-input', |
||
25 | // entriesEl |
||
26 | // resultsEl |
||
27 | // searchEl |
||
28 | }, |
||
29 | |||
30 | /** @return void */ |
||
31 | init_: function() { |
||
32 | this.options = x.extend( {}, this.defaults, this.options ); |
||
33 | if( !this.el.length )return; |
||
34 | this.options.entriesEl = this.el.parent().find( this.options.selectorEntries ); |
||
35 | this.options.resultsEl = this.el.find( this.options.selectorResults ); |
||
36 | this.options.searchEl = this.el.find( this.options.selectorSearch ); |
||
37 | this.options.searchEl.attr( 'aria-describedby', 'live-search-desc' ); |
||
38 | if( typeof this.options.onInit === 'function' ) { |
||
39 | this.options.onInit.call( this ); |
||
40 | } |
||
41 | this.initEvents_(); |
||
42 | }, |
||
43 | |||
44 | /** @return void */ |
||
45 | initEvents_: function() { |
||
46 | this.options.searchEl.on( 'input', _.debounce( this.onSearchInput_.bind( this ), 500 )); |
||
47 | this.options.searchEl.on( 'keyup', this.onSearchKeyup_.bind( this )); |
||
48 | this.options.searchEl.on( 'keydown keypress', function( ev ) { |
||
49 | if( GLSR.keys.ENTER !== ev.which )return; |
||
50 | ev.preventDefault(); |
||
51 | }); |
||
52 | x( document ).on( 'click', this.onDocumentClick_.bind( this )); |
||
53 | x( document ).on( 'keydown', this.onDocumentKeydown_.bind( this )); |
||
54 | }, |
||
55 | |||
56 | /** @return void */ |
||
57 | abort_: function() { |
||
58 | if( 'undefined' === typeof this.searchRequest )return; |
||
59 | this.searchRequest.abort(); |
||
60 | }, |
||
61 | |||
62 | /** @return void */ |
||
63 | clearResults_: function() { |
||
64 | this.abort_(); |
||
65 | this.options.resultsEl.empty(); |
||
66 | this.el.removeClass( 'is-active' ); |
||
67 | x( 'body' ).removeClass( 'glsr-focus' ); |
||
68 | }, |
||
69 | |||
70 | /** @return void */// Manage entries |
||
71 | deleteEntry_: function( index ) { |
||
72 | var row = this.options.entriesEl.children( 'tr' ).eq( index ); |
||
73 | var search = this; |
||
74 | row.find( 'td' ).css({ backgroundColor:'#faafaa' }); |
||
75 | row.fadeOut( 350, function() { |
||
76 | x( this ).remove(); |
||
77 | search.options.results = {}; |
||
78 | search.reindexRows_(); |
||
79 | search.setVisibility_(); |
||
80 | }); |
||
81 | }, |
||
82 | |||
83 | /** @return void */ |
||
84 | displayResults_: function( items ) { |
||
85 | x( 'body' ).addClass( 'glsr-focus' ); |
||
86 | this.options.resultsEl.append( items ); |
||
87 | this.options.resultsEl.children( 'span' ).on( 'click', this.onResultClick_.bind( this )); |
||
88 | }, |
||
89 | |||
90 | /** @return void */// Manage entries |
||
91 | makeSortable_: function() { |
||
92 | this.options.entriesEl.on( 'click', 'a.delete', this.onEntryDelete_.bind( this )); |
||
93 | this.options.entriesEl.sortable({ |
||
94 | items: 'tr', |
||
95 | tolerance: 'pointer', |
||
96 | start: function( ev, ui ) { |
||
97 | ui.placeholder.height( ui.helper[0].scrollHeight ); |
||
98 | }, |
||
99 | sort: function( ev, ui ) { |
||
100 | var top = ev.pageY - x( this ).offsetParent().offset().top - ( ui.helper.outerHeight( true ) / 2 ); |
||
101 | ui.helper.css({ |
||
102 | top: top + 'px', |
||
103 | }); |
||
104 | }, |
||
105 | }); |
||
106 | }, |
||
107 | |||
108 | /** @return void */ |
||
109 | navigateResults_: function( diff ) { |
||
110 | this.options.selected += diff; |
||
111 | this.options.results.removeClass( this.options.selectedClass ); |
||
112 | if( this.options.selected < 0 ) { |
||
113 | // reached the start (should now allow keydown scroll) |
||
114 | this.options.selected = -1; |
||
115 | this.options.searchEl.focus(); |
||
116 | } |
||
117 | if( this.options.selected >= this.options.results.length ) { |
||
118 | // reached the end (should now allow keydown scroll) |
||
119 | this.options.selected = this.options.results.length - 1; |
||
120 | } |
||
121 | if( this.options.selected >= 0 ) { |
||
122 | this.options.results.eq( this.options.selected ) |
||
123 | .addClass( this.options.selectedClass ) |
||
124 | .focus(); |
||
125 | } |
||
126 | }, |
||
127 | |||
128 | /** @return void */ |
||
129 | onDocumentClick_: function( ev ) { |
||
130 | if( x( ev.target ).find( this.el ).length && x( 'body' ).hasClass( 'glsr-focus' )) { |
||
131 | this.clearResults_(); |
||
132 | } |
||
133 | }, |
||
134 | |||
135 | /** @return void */ |
||
136 | onDocumentKeydown_: function( ev ) { |
||
137 | if( !this.options.results )return; |
||
138 | if( GLSR.keys.ESC === ev.which ) { |
||
139 | this.clearResults_(); |
||
140 | } |
||
141 | if( GLSR.keys.ENTER === ev.which || GLSR.keys.SPACE === ev.which ) { |
||
142 | var selected = this.options.resultsEl.find( '.' + this.options.selectedClass ); |
||
143 | if( selected ) { |
||
144 | selected.trigger( 'click' ); |
||
145 | } |
||
146 | } |
||
147 | if( GLSR.keys.UP === ev.which ) { |
||
148 | ev.preventDefault(); |
||
149 | this.navigateResults_(-1); |
||
150 | } |
||
151 | if( GLSR.keys.DOWN === ev.which ) { |
||
152 | ev.preventDefault(); |
||
153 | this.navigateResults_(1); |
||
154 | } |
||
155 | }, |
||
156 | |||
157 | /** @return void */// Manage entries |
||
158 | onEntryDelete_: function( ev ) { |
||
159 | ev.preventDefault(); |
||
160 | this.deleteEntry_( x( ev.target ).closest( 'tr' ).index() ); |
||
161 | }, |
||
162 | |||
163 | /** @return void */ |
||
164 | onResultClick_: function( ev ) { |
||
165 | ev.preventDefault(); |
||
166 | if( typeof this.options.onResultClick === 'function' ) { |
||
167 | this.options.onResultClick.call( this, ev ); |
||
168 | } |
||
169 | this.clearResults_(); |
||
170 | }, |
||
171 | |||
172 | /** @return void */ |
||
173 | onSearchInput_: function( ev ) { |
||
174 | this.abort_(); |
||
175 | if( this.searchTerm === ev.target.value && this.options.results.length ) { |
||
176 | return this.displayResults_( this.options.results ); |
||
177 | } |
||
178 | this.options.resultsEl.empty(); |
||
179 | this.options.selected = -1; |
||
180 | this.searchTerm = ev.target.value; |
||
181 | if( this.searchTerm === '' ) { |
||
182 | return this.reset_(); |
||
183 | } |
||
184 | this.el.addClass( 'is-active' ); |
||
185 | this.searchRequest = wp.ajax.post( GLSR.action, { |
||
186 | request: { |
||
187 | action: this.options.action, |
||
188 | exclude: this.options.exclude, |
||
189 | nonce: this.el.find( '#_search_nonce' ).val(), |
||
190 | search: this.searchTerm, |
||
191 | }, |
||
192 | }).done( function( response ) { |
||
193 | this.el.removeClass( 'is-active' ); |
||
194 | this.displayResults_( response.items ? response.items : response.empty ); |
||
195 | this.options.results = this.options.resultsEl.children(); |
||
196 | delete this.searchRequest; |
||
197 | }.bind( this )); |
||
198 | }, |
||
199 | |||
200 | /** @return void */ |
||
201 | onSearchKeyup_: function( ev ) { |
||
202 | if( GLSR.keys.ESC === ev.which ) { |
||
203 | this.reset_(); |
||
204 | } |
||
205 | if( GLSR.keys.ENTER === ev.which ) { |
||
206 | this.onSearchInput_( ev ); |
||
207 | ev.preventDefault(); |
||
208 | } |
||
209 | }, |
||
210 | |||
211 | /** @return void */// Manage entries |
||
212 | onUnassign_: function( ev ) { |
||
213 | ev.preventDefault(); |
||
214 | var assigned = this.el.find( '.description' ); |
||
215 | this.el.find( 'input#assigned_to' ).val( '' ); |
||
216 | assigned.find( 'a' ).css({ color:'#c00' }); |
||
217 | assigned.fadeOut( 'fast', function() { |
||
218 | x( this ).html( '' ).show(); |
||
219 | }); |
||
220 | }, |
||
221 | |||
222 | /** @return void */// Manage entries |
||
223 | reindexRows_: function() { |
||
224 | var search = this; |
||
225 | this.options.exclude = []; |
||
226 | this.options.entriesEl.children( 'tr' ).each( function( index ) { |
||
227 | x( this ).find( '.glsr-string-td2' ).children().filter( ':input' ).each( function() { |
||
228 | var input = x( this ); |
||
229 | var name = input.attr( 'name' ).replace( /\[\d+\]/i, '[' + index + ']' ); |
||
230 | input.attr( 'name', name ); |
||
231 | if( input.is( '[data-id]' )) { |
||
232 | search.options.exclude.push({ id: input.val() }); |
||
233 | } |
||
234 | }); |
||
235 | }); |
||
236 | }, |
||
237 | |||
238 | /** @return void */ |
||
239 | reset_: function() { |
||
240 | this.clearResults_(); |
||
241 | this.options.results = {}; |
||
242 | this.options.searchEl.val( '' ); |
||
243 | }, |
||
244 | |||
245 | /** @return void */// Manage entries |
||
246 | setVisibility_: function() { |
||
247 | var action = this.options.entriesEl.children().length > 0 ? 'remove' : 'add'; |
||
248 | this.options.entriesEl.parent()[action + 'Class']( 'glsr-hidden' ); |
||
249 | }, |
||
250 | }; |
||
251 | |||
252 | GLSR.Search = Search; |
||
253 | })( window._, window.wp, jQuery ); |
||
254 |