1/** 2 * Created by Sara on 24-Oct-17. 3 */ 4 5VNP.Areas.Search = new function () { 6 7 var self = this; 8 var FORMAT_DATE = VNP.formatDate; 9 var $loading = $('.vc_container_search .vc_loading'); 10 var rangeYears = []; /* store years range already found and call the ws just if the title has not range yet.*/ 11 var numLi = 5; // <li> to print 12 var $paginator = $('.vc_container_search #pagination-search'); 13 var $noResults = $('.vc_container_search .vc_no_results'); 14 var $contForm = $(".vc_search_edition"); 15 var $contSearch = $("#vc_search"); 16 var $results = $("#vc_container_results"); 17 var $paginationInfo = $(".vc_pagination_info"); 18 var $summary = $(".vc_summary_results"); 19 var $contTotalPages = $('.vc_container_search .vc_total_pages'); 20 var $contActivePages = $('.vc_container_search .vc_active_page'); 21 var totalPages; // total pages self.params.totResults / self.params.rows 22 var totResults; // total results self.params.totResults 23 var defaultOpts = { 24 startPage: 1, 25 totalPages: totalPages, 26 visiblePages: numLi, 27 first: "«", 28 last: "»", 29 prev: "<", 30 next: ">" 31 }; 32 $paginator.twbsPagination(defaultOpts); 33 34 35 /* render the from/to calendars 36 * 37 * @title {String} : directory 38 * @skipSearchCurrentEdition {Boolean} : true/false 39 * */ 40 self.renderSearchCalendars = function (title, skipSearchCurrentEdition) { 41 42 var dateRange; 43 44 // fix year format for datepicker. Datepicker wants yy to display four digits 45 var dateFormat = FORMAT_DATE.toUpperCase(); 46 var regex = /[yyyy]+/gi; 47 var replaceYYYY = dateFormat.match(regex); 48 var currentEditionDate = null; 49 50 if (replaceYYYY[0].length > 2) { 51 // year 4 digits 52 dateFormat = dateFormat.replace(regex, "YY"); 53 54 } else if (replaceYYYY[0].length == 1) { 55 // year 2 digits 56 dateFormat = dateFormat.replace(regex, "YY"); 57 } 58 59 /* to search without considering the title, the ws will get the first and the last published issue */ 60 if (typeof title == "undefined") { 61 title = ""; 62 } 63 64 // get data already stored 65 if ( typeof rangeYears[title] != "undefined" ){ 66 67 setCalendarsDate( rangeYears[title], skipSearchCurrentEdition ); 68 69 } else { 70 71 /* get data from ws 72 restrict search to the years range in which there are the published editions */ 73 VNP.Areas.Newsstand.getAvailableYears(title).done(function (data) { 74 75 var minMonthYear; 76 var maxMonthYear; 77 var minDate; 78 var maxDate; 79 80 if (typeof data === "object" && Object.keys(data).length > 0) { 81 82 minMonthYear = data.minDate; 83 maxMonthYear = data.maxDate; 84 var minYear = minMonthYear.split("-")[1]; 85 var minMonth = minMonthYear.split("-")[0]; 86 var minDay = data.minDay; 87 88 var maxYear = maxMonthYear.split("-")[1]; 89 var maxMonth = maxMonthYear.split("-")[0]; 90 var maxDay = data.maxDay; 91 // use yyyy,mm-1,dd because otherwise edge,ie and safari will not working 92 minDate = new Date(minYear, minMonth - 1, minDay); 93 maxDate = new Date(maxYear, maxMonth - 1 , maxDay); 94 95 // else set them to today 96 } else { 97 98 minMonthYear = moment(new Date()).format("MM-YYYY"); 99 maxMonthYear = moment(new Date()).format("MM-YYYY"); 100 minDate = new Date(); 101 maxDate = new Date(); 102 103 } 104 105 // set the current edition date to input but skip it if already have this dates 106 if ( isSearchingForCurrentEdition() ) { 107 108 var editionDate = window.parent.VNP.editionDateFourDigit; 109 var isFourDigit = ( editionDate.length > 6 ) ? true : false; 110 var year = (isFourDigit) ? editionDate.substr(0, 4) : editionDate.substr(0, 2); 111 var month = (isFourDigit) ? editionDate.substr(4, 2): editionDate.substr(2, 2); 112 var day = (isFourDigit) ? editionDate.substr(6, 2) : editionDate.substr(4, 2); 113 114 currentEditionDate = new Date(parseInt(year), parseInt(month - 1), parseInt(day)); 115 116 } else { 117 currentEditionDate = null; 118 } 119 120 dateRange = { 121 minMonthYear: minMonthYear, 122 maxMonthYear: maxMonthYear, 123 minDate: minDate, 124 maxDate: maxDate, 125 currentEditionDate: currentEditionDate, 126 dateFormat: dateFormat.toLowerCase() 127 }; 128 129 setCalendarsDate(dateRange, skipSearchCurrentEdition); 130 rangeYears[title] = dateRange; 131 132 }); 133 } 134 135 }; 136 137 138 /* 139 * Set the minimum and maximum dates to the calendars and set the date to display 140 * @dateRange {Object} : 141 * minMonthYear (MM-YYYYY) 142 * maxMonthYear (MM-YYYYY) 143 * minDate date object 144 * maxDate date object 145 * currentEditionDate {array} new Date([year,month,day]) 146 * */ 147 var setCalendarsDate = function(dateRange, skipSearchCurrentEdition){ 148 149 //console.log("setCalendarsDate", dateRange); 150 151 var options = { 152 selectMonths: true, 153 selectYears: parseInt(dateRange.maxMonthYear.split("-")[1]) - parseInt(dateRange.minMonthYear.split("-")[1]) + 1, 154 format: dateRange.dateFormat, 155 formatSubmit: "yyyymmdd" 156 }; 157 158 var searchDateFrom = $("[name='from']").pickadate(options); 159 var searchDateTo = $("[name='to']").pickadate(options); 160 161 var pickDateFrom = searchDateFrom.pickadate('picker'); 162 var pickDateTo = searchDateTo.pickadate('picker'); 163 164 // init calendar for the search, pickdate wants only integer or array as date 165 if( dateRange.currentEditionDate && !skipSearchCurrentEdition ){ 166 167 // reset the title to the current one 168 var title = window.parent.VNP.getTitle(); 169 $("[name='title']").val(title); 170 171 /* set min max to update the calendars input */ 172 pickDateTo.set('min', dateRange.currentEditionDate ); 173 pickDateTo.set('max', dateRange.currentEditionDate ); 174 175 pickDateFrom.set('min', dateRange.currentEditionDate ); 176 pickDateFrom.set('max', dateRange.currentEditionDate ); 177 178 pickDateFrom.set('select', dateRange.currentEditionDate ); 179 pickDateTo.set('select', dateRange.currentEditionDate ); 180 181 } else { 182 183 /* set min max to update the calendars input */ 184 pickDateTo.set('min', dateRange.minDate); 185 pickDateTo.set('max', dateRange.maxDate); 186 187 pickDateFrom.set('min', dateRange.minDate); 188 pickDateFrom.set('max', dateRange.maxDate); 189 190 pickDateFrom.set('select', dateRange.minDate); 191 pickDateTo.set('select', dateRange.maxDate); 192 193 } 194 195 }; 196 197 198 /* 199 * set and get the if searching for the current edition or not 200 * @return boolean 201 * if the editionDate is undefined it means the view is called outside the reader 202 * */ 203 var isSearchingForCurrentEdition = function(){ 204 205 return ( typeof window.parent.VNP.editionDate == "undefined" ) ? false : true; 206 207 }; 208 209 /* open the search view 210 * 211 * @setAllTitles {boolean} set as default all titles in all interfaces where we have more than one title 212 * */ 213 self.openSearch = function (setAllTitles) { 214 215 var param = (setAllTitles) ? '?setAll=true' : ''; 216 217 var options = { 218 url: VNP.baseUrl + "/newsstand/search" + param, 219 title: VNP.getLanguagesKey["search_title"], 220 buttons: [], 221 size: "lg", 222 classname: "vc_no_footer_dg", 223 useBin: true 224 }; 225 226 eModal.iframe(options); 227 228 }; 229 230 /* submit the form */ 231 self.search = function () { 232 233 var arrayFields = []; 234 //get the fields value from the form 235 var formFields = $($contForm).serializeArray(); 236 237 var pagination = { 238 start: 0, 239 rows: 8 240 }; 241 242 //fill in the array with form's values 243 $.each(formFields, function (i, field) { 244 arrayFields[field.name] = field.value; 245 }); 246 247 // don't send form without keywords 248 if ( $.trim(arrayFields["q"]) == "" ) { 249 $("#vc_cont_query").addClass("has-error"); 250 return false;
251 } 252 253 //set params to webservice 254 self.params = { 255 q: arrayFields.q, 256 title: arrayFields.title, 257 from: arrayFields.from_submit, 258 to: arrayFields.to_submit, 259 fromFormatted: arrayFields.from, 260 toFormatted: arrayFields.to, 261 type: arrayFields.type, 262 start: pagination.start, 263 rows: pagination.rows 264 }; 265 266 $loading.show(); 267 268 // get data from webservice getResultsSearch.jsp 269 var results = self.getResults(self.params); 270 271 results.done(function (data) { 272 273 if (data.results.length == 0) { 274 275 $noResults.show(); 276 $results.hide(); 277 $paginationInfo.hide(); 278 $loading.hide(); 279 $($contSearch).collapse("show"); 280 $($contSearch).removeClass("collapse"); 281 $summary.hide(); 282 283 } else { 284 285 $results.show(); 286 $summary.show(); 287 $paginationInfo.show(); 288 $noResults.hide(); 289 self.params.totResults = data.header.totResults; 290 self.renderResults(data.results); 291 self.renderSummarySearch(data); 292 self.initPagination(); 293 294 $($contSearch).collapse("hide"); 295 $($contSearch).addClass("collapse"); 296 $loading.hide(); 297 298 } 299 }) 300 .fail(function (x) { 301 // Tell the user something bad happened 302 console.log("fail search() ", x); 303 304 $loading.hide(); 305 VNP.setNotifications({ 306 classname: "alert-danger", 307 message: x.statusText, 308 close: { 309 auto: false 310 } 311 }); 312 313 }); 314 315 // set stats 316 push_stats(stats.category.title, stats.event.search, arrayFields.q); 317 }; 318 319 /* get results from webservice 320 * /webservice/search/getSearchResults.jsp 321 * */ 322 self.getResults = function (params) { 323 324 return $.ajax({ 325 //url: VNP.baseUrl + "/assets/js/debug/results.json", 326 url: VNP.baseUrl + "/webservice/search/getSearchResults.jsp", 327 data: params, 328 method: "POST", 329 dataType: "json", 330 timeout: 60000 331 }); 332 }; 333 334 self.getConfig = function(){ 335 return $.ajax({ 336 url: VNP.baseUrl + "/webservice/search/getSearchConfig.jsp", 337 method: "GET", 338 dataType: "json", 339 timeout: 60000 340 }); 341 }; 342 343 /* hide/show advanced filters */ 344 self.toggleAdvancedFilters = function(element){ 345 346 var $advancedFilter = $(".vc_advanced_filter"); 347 var skipSearchCurrentEdition = false; 348 var title = window.parent.VNP.getTitle(); 349 350 // hide filters 351 if( $advancedFilter.hasClass("active") ){ 352 353 // 1 advanced filters / 0 search in current edition 354 if( $(element).val() == 1 ) { 355 356 return; 357 358 } else { 359 360 $advancedFilter.removeClass("active"); 361 362 //set the date calendar to current edition date 363 self.renderSearchCalendars(title, skipSearchCurrentEdition); 364 } 365 366 367 }else { 368 369 // show filters 370 if( $(element).val() == 0 ) { 371 372 return; 373 374 } else { 375 376 skipSearchCurrentEdition = true; 377 $advancedFilter.addClass("active"); 378 self.renderSearchCalendars(title, skipSearchCurrentEdition); 379 380 } 381 382 } 383 384 }; 385 386 /* 387 * render the results after searching 388 * */ 389 self.renderResults = function (results) { 390 391 if (typeof results === "object" && results.length > 0) { 392 393 $("#vc_container_results").empty(); 394 395 $.each(results, function (index, result) { 396 // clone the template 397 var $template = $('#vc_template_results .vc_result').clone(); 398 var contResult = $template; 399 var thumb = $template.find(".vc_img_thumb"); 400 var edition = $template.find(".vc_edition"); 401 var date = $template.find(".vc_date"); 402 var pageNumber = $template.find(".vc_page_number"); 403 var highlight = $template.find(".vc_highlight"); 404 405 $(contResult).attr("data-edition", result.editionName); 406 $(contResult).attr("data-title", result.title); 407 $(contResult).attr("data-page", result.page); 408 $(thumb).removeAttr("data-src"); 409 $(thumb).attr("src", result.thumb); 410 $(edition).html(result.titleFullName); 411 $(date).html(result.formattedDate); 412 $(pageNumber).html(result.page); 413 $(highlight).html(result.highlight); 414 415 $(contResult).attr("data-edition", result.editionName); 416 $(contResult).attr("data-title", result.title); 417 $(contResult).attr("data-page", result.page); 418 419 //add the cloned element to the container 420 $('#vc_container_results').append($template); 421 }); 422 423 424 } else { 425 426 $noResults.show(); 427 $results.hide(); 428 $loading.hide(); 429 430 } 431 432 }; 433 434 // get parameters and set call openEdition 435 self.openSearchedEdition = function (element) { 436 var page = $(element).attr("data-page"); 437 var title = $(element).attr("data-title"); 438 var edition = $(element).attr("data-edition"); 439 var url = title + "/" + edition + "/#/" + page + "/"; 440 441 VNP.openEdition(url, "_blank"); 442 443 }; 444 445 /* 446 * get total pages for pagination 447 * */ 448 self.getTotalPages = function () { 449 totResults = self.params.totResults; 450 totalPages = Math.ceil(totResults / self.params.rows); // number of pages viewable 451 return totalPages; 452 }; 453 454 455 /* 456 * init the pagination 457 * used external jquery plugin 458 * jQuery pagination plugin (bootstrap powered) 459 * */ 460 self.initPagination = function () { 461 totalPages = self.getTotalPages(); // total pages 462 $paginator.twbsPagination('destroy'); 463 $paginator.twbsPagination($.extend({}, defaultOpts, { 464 totalPages: totalPages, 465 onPageClick: function (event, page) { 466 //set active page 467 $contActivePages.text(page); 468 //set total page 469 $contTotalPages.text(totalPages); 470 //get the start point (webservice wants parameter start, index to get results) 471 var start = (page - 1) * self.params.rows; 472 //go to page selected and render the results 473 self.goToPage(start); 474 } 475 })); 476 $paginator.twbsPagination(defaultOpts); 477 }; 478 479 480 /* 481 * go to page 482 * @param start {Integer} : index start 483 * 484 * */ 485 self.goToPage = function (start) { 486 487 self.params.start = start; 488 var results = self.getResults(self.params); 489 490 results.done(function (data) { 491 self.renderResults(data.results); 492 self.renderSummarySearch(data); 493 }) 494 .fail(function (x) { 495 // Tell the user something bad happened 496 console.log("fail goToPage() ", x); 497 $loading.hide(); 498 }); 499 }; 500 501 502 // render the summary search results 503 self.renderSummarySearch = function (data) { 504 505 if (data.results.length > 0) { 506 507 var totalPages = self.getTotalPages(); 508 $paginationInfo.find(".vc_results_number").html(data.header.totResults); 509 $paginationInfo.find(".vc_from").html(self.params.fromFormatted); 510 $paginationInfo.find(".vc_to").html(self.params.toFormatted); 511 $summary.show(); 512 513 } else { 514 $summary.hide(); 515 } 516 517 }; 518 519 self.init = function(){ 520 521 let titleSelected = window.parent.VNP.getTitle(); 522 const isAvailable = titleSelected !== null && typeof titleSelected !== "undefined"; 523 524 if(isAvailable && $("#vc_search_adv").attr("data-title") !== titleSelected){ 525 $("#vc_search_adv").attr("data-title", titleSelected); 526 } 527 528 VNP.Areas.Banners.load("#vc_search_adv"); 529 530 /* validator form for required fields */ 531 var selectorForm = ".vc_search_edition"; 532 533 // if on the reader view the search should be in the current edition 534 var skipSearchCurrentEdition = false;
535 536 // don't go ahead if there is not the form 537 if($(selectorForm).length === 0){ 538 return; 539 } 540 541 var validator = FormValidator({ 542 selectorForm: selectorForm, 543 classRequired: ".required", 544 errorFormClass: "has-error" 545 }); 546 547 $(validator.mandatoryFields).on("keyup", function(){ 548 validator.required(this); 549 }); 550 551 552 // show advanced filters outside the reader and hide the current search filter 553 if(!isSearchingForCurrentEdition()){ 554 $(".vc_container_filters").hide(); 555 $(".vc_advanced_filter").show(); 556 skipSearchCurrentEdition = true; 557 }else{ 558 let results = self.getConfig(); 559 results.done(function(data){ 560 if(data.hasOwnProperty("showAdvanceSearch") && !data.showAdvanceSearch){ 561 $(".vc_container_filters").hide(); 562 } 563 }); 564 } 565 566 if(location.search.includes("setAll=true")){ 567 document.getElementById("all").selected = "true"; 568 }else{ 569 // select the title in the select tag form 570 if(isAvailable){ 571 document.getElementById(titleSelected).selected = "true"; 572 } 573 } 574 575 self.renderSearchCalendars(titleSelected, skipSearchCurrentEdition); 576 }; 577};
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.