1 2/* 3Item Name: Winter Treefield 4Author: wpdirectorykit 5Author URI: https://wpdirectorykit.com/ 6Version: 1.0 7*/ 8 9jQuery.fn.wdkTreefield = function (options) 10{ 11 var defaults = { 12 ajax_url: null, 13 ajax_param: {}, 14 text_search: 'Search term', 15 text_no_results: 'No results found', 16 per_page: 10, 17 offset: 0, 18 attribute_id: 'id', 19 attribute_value: 'value', 20 language_id: null, 21 user_check: 'false', 22 sql_where: '', 23 hide_fields: '', 24 skip_id: null, 25 empty_value: ' - ', 26 callback_selected: function(key) { 27 console.log('called callback: '+key); 28 } 29 }; 30 31 var options = jQuery.extend(defaults, options); 32 33 var jqxhr; 34 var is_loading = false; 35 var request; 36 var search_enter_focus = false; 37 38 /* Public API */ 39 /* 40 this.getCurrent = function() 41 { 42 return options.currElImg; 43 } 44 45 this.getIndex = function(){ 46 return options.currIndex; 47 }; 48 */ 49 50 return this.each (function () 51 { 52 options.obj = jQuery(this); 53 54 options.firstLoad=true; 55 options.endLoad=false; 56 57 options.currValue=options.empty_value; 58 if(options.obj.val() != '') 59 options.currValue = options.obj.val(); 60 61 generateHtml(); 62 63 64 // Add loading indicator 65 options.obj.parent().find(".circle-loading-bar").addClass(options.progressBar); 66 67 // open scroll part 68 options.obj.parent().find('.btn-group:first button').on('click', function(event) { 69 var container = options.obj.parent().find('.list_container'); 70 71 if( container.hasClass('win_visible') ) 72 { 73 container.hide(); 74 container.removeClass('win_visible'); 75 container.parent().removeClass('win_open'); 76 } 77 else 78 { 79 container.show(); 80 container.parent().addClass('win_open'); 81 container.addClass('win_visible'); 82 if(options.firstLoad) 83 options.obj.parent().find('.list_scroll').scrollTop(0); 84 options.firstLoad=false; 85 86 jQuery(options.obj.parent().find('.search_term')).focus(); 87 } 88 89 options.obj.parent().find('.list_scroll li').removeClass('selected'); 90 91 return false; 92 }).on('keypress', function(event) { 93 var keyCode = event.keyCode || event.which; 94 95 if(keyCode == 13) // Enter 96 { 97 var container = options.obj.parent().find('.list_container'); 98 99 if( container.hasClass('win_visible') ) 100 { 101 container.hide(); 102 container.removeClass('win_visible'); 103 container.parent().removeClass('win_open'); 104 } 105 else 106 { 107 container.show(); 108 container.parent().addClass('win_open'); 109 container.addClass('win_visible'); 110 if(options.firstLoad) 111 options.obj.parent().find('.list_scroll').scrollTop(0); 112 options.firstLoad=false; 113 114 //options.obj.parent().find('.list_scroll li').first().addClass('selected'); 115 116 search_enter_focus = true; 117 jQuery(options.obj.parent().find('.search_term')).focus(); 118 } 119 120 return false; 121 } 122 }) 123 124 // hide when click outside 125 jQuery(document).on('mouseup keyup', function (e) 126 { 127 var container = options.obj.parent().find('.wdk_dropdown_tree'); 128 var container_hidder = options.obj.parent().find('.list_container'); 129 130 if (!container.is(e.target) // if the target of the click isn't the container... 131 && container.has(e.target).length === 0) // ... nor a descendant of the container 132 { 133 container_hidder.hide(); 134 container_hidder.parent().removeClass('win_open'); 135 container_hidder.removeClass('win_visible'); 136 } 137 }); 138 139 // load first n values
140 loadMore(); 141 142 // scroll 143 var scroll_container = options.obj.parent().find('.list_scroll'); 144 var list_items = options.obj.parent().find('.list_items'); 145 146 jQuery(scroll_container).on('scroll', function () { 147 if (jQuery(scroll_container).scrollTop() + jQuery(scroll_container).height() >= (jQuery(list_items).height() - 3)) { 148 if(!options.endLoad) 149 loadMore(); 150 } 151 }); 152 153 // keypress/typing event 154 jQuery(options.obj.parent().find('.search_term')).on('keyup', function(event) { 155 var keyCode = event.keyCode || event.which; 156 157 if(keyCode == 13) // Enter 158 { 159 if(options.obj.parent().find('.list_scroll li.selected').length > 0) 160 { 161 if(!search_enter_focus) 162 { 163 var elSel = options.obj.parent().find('.list_scroll li.selected'); 164 165 options.obj.parent().find('button:first-child').html(elSel.html()); 166 options.obj.val(elSel.attr('key')); 167 168 options.obj.parent().find('.list_container').hide(); 169 options.obj.parent().find('.list_container').parent().removeClass('win_open'); 170 options.obj.parent().find('.list_container').removeClass('win_visible'); 171 options.obj.parent().find('.list_scroll li').removeClass('selected'); 172 173 options.callback_selected(elSel.attr('key')); 174 } 175 176 return false; 177 } 178 179 if(search_enter_focus) 180 { 181 search_enter_focus = false; 182 return false; 183 } 184 } 185 else if(keyCode == 38) // Up 186 { 187 var elSel = options.obj.parent().find('.list_scroll li.selected'); 188 189 if(elSel.length == 0) 190 { 191 options.obj.parent().find('.list_scroll li').first().addClass('selected'); 192 } 193 194 if(!elSel.is(':first-child')) 195 { 196 elSel.prev().addClass('selected'); 197 elSel.removeClass('selected'); 198 199 var container = options.obj.parent().find('.list_scroll'); 200 var scrollTo = elSel.prev(); 201 202 // Calculating new position of scrollbar 203 var position = scrollTo.offset().top 204 - container.offset().top 205 + container.scrollTop(); 206 207 // Setting the value of scrollbar 208 if(!isVisible(scrollTo)) 209 container.scrollTop(position); 210 } 211 return false; 212 } 213 else if(keyCode == 40) // Down 214 { 215 var elSel = options.obj.parent().find('.list_scroll li.selected'); 216 217 if(elSel.length == 0) 218 { 219 options.obj.parent().find('.list_scroll li').first().addClass('selected'); 220 } 221 222 if(!elSel.is(':last-child')) 223 { 224 elSel.next().addClass('selected'); 225 elSel.removeClass('selected'); 226 227 var container = options.obj.parent().find('.list_scroll'); 228 var scrollTo = elSel.next(); 229 230 // Calculating new position of scrollbar 231 var position = scrollTo.offset().top 232 - container.offset().top 233 + container.scrollTop(); 234 235 // Setting the value of scrollbar 236 237 if(!isVisible(scrollTo)) 238 container.scrollTop(position); 239 } 240 return false; 241 } 242 243 options.endLoad=false; 244 options.offset=0; 245 246 //if(is_loading === false)
247 loadMore(); 248 249 }).on('keypress', function(event) { 250 if ( event.which == 13 ) { 251 return false; 252 } 253 }); 254 255 jQuery(options.obj.parent().find('span.input-group-addon')).on('click', function() { 256 options.endLoad=false; 257 options.offset=0; 258 259 if(is_loading === false) 260 loadMore(); 261 }); 262 263 264 265 return this; 266 }); 267 268 function isVisible($el) { 269 var container = options.obj.parent().find('.list_scroll'); 270 271 var winTop = container.scrollTop(); 272 var winBottom = winTop + container.height(); 273 var elTop = $el.offset().top-container.offset().top+winTop; 274 var elBottom = elTop + $el.height(); 275 276 return ((elBottom <= winBottom) && (elTop >= winTop)); 277 } 278 279 function loadMore() 280 { 281 282 283 var search_term_val = options.obj.parent().find('.search_term').val(); 284 285 if(options.offset == 0) 286 options.obj.parent().find('ul').html(''); 287 288 var param = { offset: options.offset, 289 per_page: options.per_page, 290 curr_id: options.obj.val(), 291 attribute_id: options.attribute_id, 292 attribute_value: options.attribute_value, 293 search_term: search_term_val, 294 language_id: options.language_id, 295 skip_id: options.skip_id, 296 user_check: options.user_check, 297 sql_where: options.sql_where, 298 hide_fields: options.hide_fields 299 }; 300 301 jQuery.extend( param, options.ajax_param ); 302 303 // Assign handlers immediately after making the request, 304 // and remember the jqxhr object for this request 305 if(jqxhr != null) 306 jqxhr.abort(); 307 308 options.callback_selected(options.obj.val()); 309 310 showSpinner(); 311 312 is_loading=true; 313 jqxhr = jQuery.post( options.ajax_url, param, function(data) { 314 hideSpinner(); 315 var list_items = options.obj.parent().find('ul'); 316 317 if(data.success == false) 318 { 319 options.endLoad=true; 320 list_items.html('<span class="no_results">'+options.text_no_results+'</span>'); 321 alert(data.message); 322 } 323 else 324 { 325 jQuery.each( data.results, function( key, row ) { 326 if(key == 'lang_id') return true; 327 list_items.append("<li key='"+row.key+"'>"+row.value+"</li>"); 328 }); 329 330 if(options.offset == 0) 331 options.obj.parent().find('.list_scroll').scrollTop(0); 332 333 if(options.firstLoad) 334 options.obj.parent().find('button:first-child').html(data.curr_val); 335 336 if(data.results.length == 0) 337 options.endLoad=true; 338 339 if(options.offset == 0 && data.results.length == 0) 340 list_items.html('<span class="no_results">'+options.text_no_results+'</span>'); 341 342 options.offset+=options.per_page; 343 resetElements(); 344 } 345 346 is_loading=false; 347 }) 348 .fail(function() { 349 //alert( "error" ); 350 console.log( "abort" ); 351 hideSpinner(); 352 is_loading=false; 353 }); 354 } 355 356 function hideSpinner() 357 { 358 options.obj.parent().find('.loader-spiner').removeClass('fa-spinner'); 359 options.obj.parent().find('.loader-spiner').removeClass('fa-spin'); 360 options.obj.parent().find('.loader-spiner').addClass('fa-search'); 361 } 362 363 function showSpinner() 364 { 365 options.obj.parent().find('.loader-spiner').addClass('fa-spinner'); 366 options.obj.parent().find('.loader-spiner').addClass('fa-spin'); 367 options.obj.parent().find('.loader-spiner').removeClass('fa-search'); 368 } 369 370 function resetElements() 371 { 372 options.obj.parent().find("li *").off(); 373 options.obj.parent().find("li").on('click', function() { 374 options.obj.parent().find('button:first-child').html(jQuery(this).html()); 375 options.obj.val(jQuery(this).attr('key')); 376 options.obj.parent().find('.list_container').hide(); 377 options.obj.parent().find('.list_container').parent().removeClass('win_open'); 378 options.obj.parent().find('.list_container').removeClass('win_visible'); 379 380 options.callback_selected(jQuery(this).attr('key')); 381 }); 382 383 } 384 385 function generateHtml() 386 { 387 // hide input element 388 options.obj.css('display', 'none'); 389 390 options.obj.before( 391 '<div class="wdk_dropdown_tree">'+ 392 // showing value, always visible 393 '<div class="btn-group ">'+ 394 '<button class="btn btn-default" type="button">'+ 395 options.currValue+' '+ 396 '</button>'+ 397 '<button type="button" class="btn btn-default dropdown-toggle"> <i class="fa fa-angle-down"></i> </button>'+ 398 '</div>'+ 399 // hidden part with scroll and search 400 '<div class="list_container color-primary">'+ 401 '<div class="list_scroll">'+ 402 '<ul class="list_items">'+ 403// '<li key="key_1">test text adr 1</li>'+ 404 '</ul>'+ 405 '</div>'+ 406 // search input and loading indicator 407 '<div class="input-group">'+ 408 '<input type="text" class="form-control search_term" placeholder="'+options.text_search+'" aria-describedby="basic-addon2" autocomplete="off">'+ 409 '<span class="input-group-addon"><i class="loader-spiner fa fa-spinner fa-spin"></i></span>'+ 410 '</div>'+ 411 '</div>'+ 412 '</div>' 413 ); 414 } 415 416} 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.