1WebGis.SearchPanel = OpenLayers.Class( 2{ 3 /********************************************************************************************/ 4 /********************************* Variables ************************************************/ 5 /********************************************************************************************/ 6 7 Config: null, 8 MapControl: null, 9 TabSettings: [], 10 11 TabPanelID: "advSearchTabPanel", 12 13 TabBar_Class: "wgTabBar", 14 TabPanel_Class: "wgTabPanel", 15 TabPanelBody_Class: "wgTabPanelBody", 16 TabHeaderS_Class: "wgTabHeader_S", 17 TabHeaderM_Class: "wgTabHeader_M", 18 TabBody_Class: "wgTabBody", 19 TabBtns_Class: "wgContainerBtns", 20 Button_Class: "wgTabPnlBtn", 21 22 GridSelectedItem_Class: "wgResultGrid_SelectedItem", 23 Grid_Class: "wgResultGridPanel", 24 GridBody_Class: "wgResultGridPanelBody", 25 GridColumn_Class: "wgResultColumn", 26 GridCell_Class: "wgResultCell", 27 GridPagingToolbar_Class: "wgPagingtoolbar", 28 29 Msg_NoSearchPerformed: properties.menu.AdvSearch_NoSearchPerformed, 30 Msg_NoResultFound: properties.menu.AdvSearch_NoResultFound, 31 32 BtnShowFeature_Text: properties.menu.AdvSearch_BtnShowFeature_Text, 33 BtnShowFeature_IconCls: "icon-sagetele", 34 35 Feature_Tooltip: properties.menu.AdvSearch_Feature_Tooltip, 36 37 SearchUtil: null, 38 39 EM_FEATURE_NOT_FOUND: properties.menu.AdvSearch_EM_FeatureNotFound, 40 EM_FEATURE_GEOMETRY_NOT_FOUND: properties.menu.AdvSearch_EM_FeatureGeometryNotFound, 41 EM_RELATED_FEATURE_NOT_FOUND: properties.menu.AdvSearch_EM_RelatedGeometryNotFound, 42 43 /********************************************************************************************/ 44 45 /********************************************************************************************/ 46 /********************************* Constructor **********************************************/ 47 /********************************************************************************************/ 48 49 initialize: function (mapControl) { 50 51 meAdvSearch = this; 52 this.events = new OpenLayers.Events(this); 53 this.MapControl = mapControl; 54 this.SearchUtil = new WebGis.Search.Util(); 55 }, 56 57 /********************************************************************************************/ 58 59 /********************************************************************************************/ 60 /******************************* Main functions used outside the class *********************/ 61 /********************************************************************************************/ 62 63 init: function (_config) { 64 65 this.Config = _config.map.advancedSearches; 66 this.ExtractTabsSettigs(); 67 }, 68 69 //Create advanced search control and render it to the div received as parameter 70 CreateControl: function (divID) { 71 72 this.DefineControl(); 73 Ext.create('WebGis2.view.SearchCtrl', { renderTo: divID }); 74 75 $(window).resize(function () { 76 Ext.getCmp(meAdvSearch.TabPanelID).doLayout(); 77 }); 78 }, 79 80 //Cancel drawing - used when onother btn from othet panel gets focus 81 CancelDrawing: function () { 82 for (var i = 0; i < this.TabSettings.length; i++) { 83 this.TabSettings[i].FilterDrawing.disableDrawing(); 84 } 85 }, 86 87 /********************************************************************************************/ 88 89 /********************************************************************************************/ 90 /**************************** Main functions used to extract settings **********************/ 91 /********************************************************************************************/ 92 93 //Extract tabs' settings used to create the search tabs and to display results 94 ExtractTabsSettigs: function () { 95 96 this.TabSettings = []; 97 for (var i = 0; i < this.Config.length; i++) { 98 this.TabSettings.push( 99 this.ExtractTabSettings(this.Config[i], i)); 100 } 101 }, 102 103 //Extract tab settings used to create the search tabs and to display results 104 ExtractTabSettings: function (advSearch, tabIndex) { 105 106 var tabSetting = {}; 107 tabSetting.GUID = advSearch.Guid; 108 tabSetting.Title = advSearch.Name; 109 110 tabSetting.FilterDrawing = new WebGis.Drawing(_mapControl.map, "FilterLayer_" + tabIndex.toString(),null, null) 111 112 //Filter settings 113 tabSetting.Filters = []; 114 for (var i = 0; i < advSearch.Filters.length; i++) { 115 116 if (!advSearch.Filters[i].ForDesktopTemplate) { 117 continue; 118 } 119 120 var filterSettings = { 121 fieldName: advSearch.Filters[i].Field, 122 label: advSearch.Filters[i].Label, 123 fieldType: this.getType(advSearch.Filters[i].FieldType), 124 filterType: this.getFilterCtrlType(advSearch.Filters[i].FieldInterpretationType, advSearch.Filters[i].IsDropDownList, 125 this.getOpType(advSearch.Filters[i].FilterOpType)), 126 filterOp: this.getOpType(advSearch.Filters[i].FilterOpType), 127 filterSettings: this.getFilterCtrlSettings(advSearch.Filters[i], tabIndex, tabSetting.FilterDrawing), 128 validationFunction: advSearch.Filters[i].ValidationFunction 129 } 130 131 if (filterSettings.fieldType != null && filterSettings.filterType != null) { 132 tabSetting.Filters.push(filterSettings); 133 } 134 } 135 136 //Result settings 137 tabSetting.Results = {}; 138 tabSetting.Results.LoadByDefault = advSearch.LoadByDefault; 139 tabSetting.Results.Template = advSearch.ResultItemTemplate; 140 tabSetting.Results.Fields = this.SearchUtil.getResultFields(advSearch); 141 tabSetting.Results.RelatedFeature = this.SearchUtil.getResult_RelatedFeature(advSearch); 142 tabSetting.Results.IsMapRealated = advSearch.ShowResultsByDefault && tabSetting.Results.RelatedFeature != null; 143 144 //The Guid for the layers related to a certain search (one layer for default Search, two layers for Map Related Search- main layer 145 //& layer for other related features) 146 tabSetting.RelatedLayerGUID = advSearch.Guid; 147 if (tabSetting.Results.IsMapRealated) { 148 tabSetting.MainLayerGUID = "Main_" + advSearch.Guid; 149 } 150 151 tabSetting.Results.StoreName = this.SearchUtil.getStore(tabSetting.Results.IsMapRealated, advSearch, tabSetting.MainLayerGUID); 152 return tabSetting; 153 }, 154 155 /********************************************************************************************/ 156 157 /********************************************************************************************/ 158 /******************* Main functions used to define the Search Control **********************/ 159 /********************************************************************************************/ 160
161 //Define the search panel control - a TabPanel with a tab for each advanced search 162 DefineControl: function () { 163 164 Ext.define('WebGis2.view.SearchCtrl', { 165 extend: 'Ext.tab.Panel', 166 id: this.TabPanelID, 167 cls: this.TabPanel_Class, 168 bodyCls: this.TabPanelBody_Class, 169 width: "100%", 170 height: "100%", 171 items: this.GetTabItems(), 172 tabBar: { 173 cls: this.TabBar_Class, 174 }, 175 config: { 176 //Deactivate the tab related to a certain search 177 deactivateTab: function (ctrl, advSearchGUID) { 178 var tabs = ctrl.items.items; 179 for (var i = 0; i < tabs.length; i++) { 180 if (tabs[i].advSerachGuid == advSearchGUID) { 181 tabs[i].config.deactivate(tabs[i]); 182 break; 183 } 184 } 185 }, 186 //Activate the tab related to a certain search 187 activateTab: function (ctrl, advSearchGUID) { 188 var tabs = ctrl.items.items; 189 for (var i = 0; i < tabs.length; i++) { 190 if (tabs[i].advSerachGuid == advSearchGUID) { 191 tabs[i].config.activate(tabs[i]); 192 break; 193 } 194 } 195 }, 196 }, 197 listeners: { 198 beforetabchange: function (tabPanel, newCard, oldCard, opts) { 199 200 $event.notify("advancedSearch_BeforeTabChange", { 201 newTab_advSearchGUID: newCard.advSerachGuid, 202 oldTab_advSearchGUID: oldCard.advSerachGuid, 203 }, this); 204 if(this.cancelEvent) { 205 this.cancelEvent = false; 206 return false; 207 } 208 return true; 209 }, 210 tabchange: function (tabPanel, newCard, oldCard, eOpts) { 211 212 //Disable drawing for the old tab and hide the filter layer 213 var tabSettings = meAdvSearch.getTabSettings_ByGuid(oldCard.advSerachGuid); 214 meAdvSearch.destroyLayer(tabSettings.RelatedLayerGUID); 215 if (tabSettings.MainLayerGUID != null && _mapControl.GetLayerByGuid(tabSettings.MainLayerGUID) != null) { 216 _mapControl.GetLayerByGuid(tabSettings.MainLayerGUID).setVisibility(false); 217 } 218 tabSettings.FilterDrawing.disableDrawing(); 219 tabSettings.FilterDrawing.setLayerVisibility(false); 220 221 //Show the filter layer for the new tab 222 tabSettings = meAdvSearch.getTabSettings_ByGuid(newCard.advSerachGuid); 223 tabSettings.FilterDrawing.setLayerVisibility(true); 224 if (tabSettings.MainLayerGUID != null && _mapControl.GetLayerByGuid(tabSettings.MainLayerGUID)) { 225 _mapControl.GetLayerByGuid(tabSettings.MainLayerGUID).setVisibility(true); 226 } 227 } 228 } 229 }); 230 }, 231 232 //Get the tab items that should be added to the search panel 233 GetTabItems: function () { 234 235 var tabItems = []; 236 for (var i = 0; i < this.TabSettings.length; i++) { 237 tabItems.push(this.GetTabItem(this.TabSettings[i])); 238 } 239 240 return tabItems; 241 }, 242 243 //Create a tab item according to the settings received as parameter 244 //It contains 3 sections: the filter section (controls for each filters), 245 //the button section (search and clear section), the result section (a list with the search results) 246 GetTabItem: function (tabSetting) { 247 248 var tabItem = { 249 xtype: "panel", 250 layout: "fit", 251 hideMode: 'offsets', 252 advSerachGuid: tabSetting.GUID, 253 title: tabSetting.Title, 254 tabConfig: { 255 cls: this.TabHeaderS_Class, 256 }, 257 cls: this.TabBody_Class, 258 padding: "10 10 10 10", 259 layout: { 260 type: 'vbox' 261 }, 262 config: { 263 264 //Deactivate the items from the current tab 265 deactivate: function (ctrl) { 266 267 var tabItems = ctrl.items.items; 268 for (var i = 0; i < tabItems.length - 1; i++) { 269 var tabContainerItems = tabItems[i]; 270 for (var j = 0; j < tabContainerItems.items.items.length; j++) { 271 tabContainerItems.items.items[j].setDisabled(true); 272 } 273 } 274 tabItems[tabItems.length - 1].setDisabled(true); 275 }, 276 277 //Reactivate the items for the current tab 278 activate: function (ctrl) { 279 280 var tabItems = ctrl.items.items; 281 for (var i = 0; i < tabItems.length - 1; i++) { 282 var tabContainerItems = tabItems[i]; 283 for (var j = 0; j < tabContainerItems.items.items.length; j++) { 284 tabContainerItems.items.items[j].setDisabled(false); 285 } 286 } 287 tabItems[tabItems.length - 1].setDisabled(false); 288 }, 289 290 }, 291 items: [ 292 //Filter Section 293 { 294 xtype: 'container', 295 items: this.GetFilterItems(tabSetting), 296 width: "100%", 297 }, 298 //Clear and Search ButtonsSection 299 { 300 xtype: 'container', 301 width: "100%", 302 layout: { 303 type: 'hbox', 304 pack: 'end', 305 padding: "10 0 10 0", 306 }, 307 itemCls: this.TabBtns_Class, 308 items: [ 309 { 310 xtype: 'button', 311 text: properties.menu.AdvSearch_BtnClear_Text, 312 store_name: tabSetting.Results.StoreName, 313 advSerachGuid: tabSetting.GUID, 314 cls: this.Button_Class, 315 listeners: { 316 click: { 317 scope: this, 318 fn: function (button, e, eOpts) { 319 320 $event.notify("advancedSearch_CleanBtn_OnClick", { advSearchGUID: button.advSerachGuid }, this); 321 if (this.cancelEvent) { 322 this.cancelEvent = false; 323 return false; 324 } 325 326 var panelItem = button.up("container").up("panel"); 327 328 //Clear filters 329 var filtersContainer = panelItem.items.items[0]; 330 var filterItems = filtersContainer.items.items; 331 for (var i = 0; i < filterItems.length; i++) { 332 filterItems[i].clearField(); 333 } 334 335 //Change the empty msg and clear the grid 336 var grid = panelItem.down("grid"); 337 grid.getView().emptyText = "<div class='x-grid-empty'>" + meAdvSearch.Msg_NoSearchPerformed + "</div>"; 338 var store = Ext.StoreManager.getByKey(button.store_name); 339 store.loadPage(0); 340 341 //Destroy the layer for the related features (the main layer for map related search 342 //is destroyed when the grid is cleared) 343 var tabSettings = meAdvSearch.getTabSettings_ByGuid(button.advSerachGuid); 344 meAdvSearch.destroyLayer(tabSettings.RelatedLayerGUID); 345 } 346 } 347 } 348 }, 349 { 350 xtype: 'button', 351 text: properties.menu.AdvSearch_BtnSearch_Text, 352 store_name: tabSetting.Results.StoreName, 353 cls: this.Button_Class, 354 advSerachGuid: tabSetting.GUID, 355 listeners: { 356 click: { 357 scope: this, 358 fn: function (button, e, eOpts) { 359 360 $event.notify("advancedSearch_SearchBtn_OnClick", { advSearchGUID: button.advSerachGuid }, this); 361 if (this.cancelEvent) { 362 this.cancelEvent = false; 363 return false; 364 } 365 366 var panelItem = button.up("container").up("panel"); 367 368 //Use filters to create the store query 369 var query = ""; 370 var filtersContainer = panelItem.items.items[0]; 371 var filterItems = filtersContainer.items.items; 372 var errorList = []; 373 for (var i = 0; i < filterItems.length; i++) { 374 var filterItem = filterItems[i]; 375 376 //check the filter value 377 if (typeof window[filterItem.validationFunction] === "function") { 378 var response = null; 379 if (filterItem.filterOp == "Between") { 380 response = window[filterItem.validationFunction](filterItem.getValue_From(), 381 filterItem.getValue_To()); 382 } 383 else { 384 response = window[filterItem.validationFunction](filterItem.getValue()); 385 } 386 if (response.error && response.errorMsg != null && response.errorMsg != "") { 387 errorList.push(response.errorMsg); 388 } 389 } 390 391 var filterQuery = filterItem.getSearchQuery(); 392 if (filterQuery != null && filterQuery != "") { 393 query += (query == "" ? "" : "&") + filterQuery; 394 } 395 } 396 397 //if there are invalid filters, don't perfom the search 398 if (errorList.length > 0) { 399 var msg = ""; 400 for (var i = 0; i < errorList.length; i++) { 401 msg += errorList[i] + "<br>"; 402 } 403 404 Ext.Msg.alert('', msg, Ext.emptyFn); 405 return; 406 } 407 408 //Change the empty msg and load the grid 409 var grid = panelItem.down("grid"); 410 grid.getView().emptyText = "<div class='x-grid-empty'>" + meAdvSearch.Msg_NoResultFound + "</div>"; 411 412 var store = Ext.StoreManager.getByKey(button.store_name); 413 store.proxy.url = store.proxy.backupUrl + "&" + query; 414 store.loadPage(1); 415 416 //Destroy the layer for the related features (the main layer for map related search 417 //is recreated when the grid is loaded) 418 var tabSettings = meAdvSearch.getTabSettings_ByGuid(button.advSerachGuid); 419 tabSettings.FilterDrawing.disableDrawing(); 420 meAdvSearch.destroyLayer(tabSettings.RelatedLayerGUID); 421 } 422 } 423 } 424 } 425 ] 426 }, 427 428 //The Grid for results 429 this.GetResultItem(tabSetting) 430 ], 431 432 }; 433 return tabItem; 434 }, 435 436 //Get tab filter items 437 GetFilterItems: function (tabSettings) { 438 439 var filterItems = []; 440 for (var i = 0; i < tabSettings.Filters.length; i++) { 441 filterItems.push({ 442 xtype: tabSettings.Filters[i].filterType, 443 fieldLabel: tabSettings.Filters[i].label, 444 fieldName: tabSettings.Filters[i].fieldName, 445 type: tabSettings.Filters[i].fieldType, 446 filterOp: tabSettings.Filters[i].filterOp, 447 filterSettings: tabSettings.Filters[i].filterSettings, 448 validationFunction: tabSettings.Filters[i].validationFunction 449 }); 450 } 451 return filterItems; 452 }, 453 454 //Get the item used to show the search results inside a tab 455 GetResultItem: function (tabSettings) { 456 457 if (tabSettings.Results.IsMapRealated) { 458 return this.GetResultItem_MapRelated(tabSettings); 459 } 460 else { 461 return this.GetResultItem_Default(tabSettings); 462 } 463 }, 464 465 //The Grid Panel for the default search (the results are not displayed into the map) 466 GetResultItem_Default: function (tabSettings) { 467 468 var item = { 469 xtype: 'gridpanel', 470 disableSelection: true, 471 header: false, 472 store: tabSettings.Results.StoreName, 473 cls: this.Grid_Class, 474 flex: 1, 475 bodyCls: this.GridBody_Class, 476 autoScroll: true, 477 width: "100%", 478 viewConfig: { 479 deferEmptyText: false, 480 emptyText: this.Msg_NoSearchPerformed, 481 selectedItemCls: this.GridSelectedItem_Class, 482 loadMask: false, 483 }, 484 loadByDefault: tabSettings.Results.LoadByDefault, 485 486 columns: [ 487 { 488 xtype: 'templatecolumn', 489 text: properties.menu.AdvSearch_ResultGrid_Header, 490 menuDisabled: true, 491 sortable: false, 492 tpl: tabSettings.Results.Template, 493 advSerachGUID: tabSettings.GUID, 494 flex: 1, 495 cls: this.GridColumn_Class, 496 tdCls: this.GridCell_Class, 497
497 renderer: function (value, metaData, record, row, col, store, gridView) { 498 499 var template = this.columns[0].tpl.html; 500 var tabSettings = meAdvSearch.getTabSettings_ByGuid(this.columns[0].advSerachGUID); 501 var resultFields = tabSettings.Results.Fields; 502 var relatedFeature = tabSettings.Results.RelatedFeature; 503 504 //Use the results to create the template 505 for (var i = 0; i < resultFields.length; i++) { 506 var text = meAdvSearch.getResultField_Text(record.data[resultFields[i].Field], resultFields[i], record, 507 tabSettings.RelatedLayerGUID, this.columns[0].advSerachGUID); 508 template = template.replaceAll("{" + resultFields[i].Field + "}", text); 509 } 510 511 //Add btn to show related feature if any 512 if (relatedFeature != null && record.data[relatedFeature.FeatureID] != null && record.data[relatedFeature.FeatureID] != "" 513 && record.data[relatedFeature.FeatureID] != 0) { 514 var colNr = meAdvSearch.getColumnCount($(template)); 515 var btnHtml = "<a title='" + meAdvSearch.Feature_Tooltip + "' class='" + meAdvSearch.BtnShowFeature_IconCls + "' href='javascript:meAdvSearch.showFeatures(\"" 516 + this.columns[0].advSerachGUID + "\",\"" + tabSettings.RelatedLayerGUID + "\",null,\"" 517 + record.data[relatedFeature.FeatureID].toString() + "\", true);'> " 518 + meAdvSearch.BtnShowFeature_Text + " </a>"; 519 var rowHtml = "<tr><td align='right' style='padding-bottom:5px;' colspan='" + colNr.toString() + "'>" + btnHtml + "</td></tr>"; 520 template = $(template).last().append(rowHtml)[0].outerHTML; 521 } 522 523 524 //Correct the templet html- remove links with href='-' 525 if ($(template).find("a[href=-]").length > 0) { 526 527 var emptyLinks = $(template).find("a[href=-]"); 528 for (var i = 0; i < emptyLinks.length; i++) { 529 template = template.replaceAll(emptyLinks[i].outerHTML, "-"); 530 } 531 532 533 } 534 535 //Correct the templet html- remove imgs with src='-' 536 if ($(template).find("img[src=-]").length > 0) { 537 var emptyImages = $(template).find("img[src=-]"); 538 for (var i = 0; i < emptyImages.length; i++) { 539 template = template.replaceAll(emptyImages[i].outerHTML, "-"); 540 template = template.replaceAll(emptyImages[i].outerHTML.replaceAll("\"", "'"), "-"); 541 template = template.replaceAll(emptyImages[i].outerHTML.replaceAll("'", "\""), "-"); 542 } 543 } 544 545 return template; 546 } 547 }, 548 ], 549 dockedItems: [ 550 { 551 xtype: 'pagingtoolbar', 552 dock: 'bottom', 553 width: "100%", 554 displayInfo: false, 555 store: tabSettings.Results.StoreName, 556 cls: this.GridPagingToolbar_Class 557 } 558 ], 559 listeners: { 560 afterrender: function (ctrl, eOpts) { 561 ctrl.getStore().gridID = ctrl.getId(); 562 //perform default search if the grid should be loaded by default 563 if (this.loadByDefault) { 564 ctrl.getStore().loadPage(1); 565 } 566 }, 567 beginDrag: function () { 568 if (this.floatingDescendants) { 569 this.floatingDescendants.hide(); 570 } 571 }, 572 573 endDrag: function () { 574 if (this.floatingDescendants) { 575 this.floatingDescendants.show(); 576 } 577 }, 578 579 }, 580 config: { 581 582 //Apply custom scrollbar inside the grid 583 applyCustomScrollBar: function (ctrl) { 584 585 $("#" + ctrl.getId() + " .wgResultGridPanelBody .x-grid-view").css("overflow-y", "auto"); 586 $("#" + ctrl.getId() + " .wgResultGridPanelBody .x-grid-view").mCustomScrollbar(); 587 }, 588 589 //Remove custom scrollbar from the grid 590 removeCustomScrollBar: function (ctrl) { 591 592 $("#" + ctrl.getId() + " .wgResultGridPanelBody .x-grid-view").css("overflow-y", "hidden"); 593 $("#" + ctrl.getId() + " .wgResultGridPanelBody .x-grid-view").mCustomScrollbar("destroy"); 594 } 595 } 596 }; 597 598 return item; 599 }, 600 601 //The Grid Panel for the map related search (the grid results' features are displayed into the map) 602 GetResultItem_MapRelated: function (tabSettings) { 603 604 var item = { 605 xtype: 'gridpanel', 606 disableSelection: false, 607 header: false, 608 store: tabSettings.Results.StoreName, 609 cls: this.Grid_Class, 610 flex: 1, 611 bodyCls: this.GridBody_Class, 612 autoScroll: true, 613 width: "100%", 614 viewConfig: { 615 deferEmptyText: false, 616 emptyText: this.Msg_NoSearchPerformed, 617 selectedItemCls: this.GridSelectedItem_Class, 618 loadMask: false, 619 }, 620 loadByDefault: tabSettings.Results.LoadByDefault, 621 622 columns: [ 623 { 624 xtype: 'templatecolumn', 625 text: properties.menu.AdvSearch_ResultGrid_Header, 626 menuDisabled: true, 627 sortable: false, 628 tpl: tabSettings.Results.Template, 629 advSerachGUID: tabSettings.GUID, 630 flex: 1, 631 cls: this.GridColumn_Class, 632 tdCls: this.GridCell_Class, 633 renderer: function (value, metaData, record, row, c
633ol, store, gridView) { 634 635 var template = this.columns[0].tpl.html; 636 var tabSettings = meAdvSearch.getTabSettings_ByGuid(this.columns[0].advSerachGUID); 637 var resultFields = tabSettings.Results.Fields; 638 639 //Use the results to create the template 640 for (var i = 0; i < resultFields.length; i++) { 641 var text = meAdvSearch.getResultField_Text(record.data[resultFields[i].Field], resultFields[i], record, 642 tabSettings.RelatedLayerGUID, this.columns[0].advSerachGUID); 643 template = template.replaceAll("{" + resultFields[i].Field + "}", text); 644 } 645 646 //Correct the templet html- remove links with href='-' 647 if ($(template).find("a[href=-]").length > 0) { 648 649 var emptyLinks = $(template).find("a[href=-]"); 650 for (var i = 0; i < emptyLinks.length; i++) { 651 template = template.replaceAll(emptyLinks[i].outerHTML, "-"); 652 } 653 } 654 655 //Correct the templet html- remove imgs with src='-' 656 if ($(template).find("img[src=-]").length > 0) { 657 var emptyImages = $(template).find("img[src=-]"); 658 for (var i = 0; i < emptyImages.length; i++) { 659 template = template.replaceAll(emptyImages[i].outerHTML, "-"); 660 template = template.replaceAll(emptyImages[i].outerHTML.replaceAll("\"", "'"), "-"); 661 template = template.replaceAll(emptyImages[i].outerHTML.replaceAll("'", "\""), "-"); 662 } 663 } 664 665 return template; 666 } 667 }, 668 ], 669 dockedItems: [ 670 { 671 xtype: 'pagingtoolbar', 672 dock: 'bottom', 673 width: "100%", 674 displayInfo: false, 675 store: tabSettings.Results.StoreName, 676 cls: this.GridPagingToolbar_Class 677 } 678 ], 679 listeners: { 680 afterrender: function (ctrl, eOpts) { 681 ctrl.getStore().gridID = ctrl.getId(); 682 //Perform default search if the grid must be loaded by default 683 if (this.loadByDefault) { 684 ctrl.getStore().loadPage(1); 685 } 686 }, 687 beforecellclick: function (ctrl, td, cellIndex, record, tr, rowIndex, e, eOpts) { 688 689 //if the user perform the click on a link - avoid item selection 690 if (e.target.href != null) {
691 this.getSelectionModel().deselectAll(); 692 this.getSelectionModel().clearSelections(); 693 return false; 694 } 695 }, 696 697 //On click on the result item 698 cellclick: function (ctrl, td, cellIndex, record, tr, rowIndex, e, eOpts) { 699 700 //if the user perform the click on a link - avoid item selection 701 if (e.target.href != null) { 702 this.getSelectionModel().deselectAll(); 703 this.getSelectionModel().clearSelections(); 704 return; 705 } 706 707 $event.notify("advancedSearch_BeforeShowFeature", { advSearchGUID: this.columns[0].advSerachGUID }, this); 708 if (this.cancelEvent) { 709 this.getSelectionModel().deselectAll(); 710 this.getSelectionModel().clearSelections(); 711 this.cancelEvent = false; 712 return; 713 } 714 715 //Clear feature selection 716 _mapControl.featureSelection.ClearSelection(); 717 718 //Find the feature related to the selected result item and select it 719 var tabSettings = meAdvSearch.getTabSettings_ByGuid(this.columns[0].advSerachGUID); 720 var layer = _mapControl.GetLayerByGuid(tabSettings.MainLayerGUID); 721 var relatedFeature = tabSettings.Results.RelatedFeature; 722 723 var featureID_Field = relatedFeature.FeatureID; 724 var featureID = record.data[featureID_Field]; 725 726 //If the result has no related feature - inform the user 727 if (featureID == null) { 728 Ext.Msg.alert('', meAdvSearch.EM_RELATED_FEATURE_NOT_FOUND, Ext.emptyFn); 729 return; 730 } 731 732 //Try to find and select the feature 733 for (var i = 0; i < layer.features.length; i++) { 734 735 if (featureID == layer.features[i].data[featureID_Field]) { 736 737 _mapControl.FitFeatures([layer.features[i]], 1.1, layer.zoomLevel, false); 738 _mapControl.featureSelection.SelectFeature(layer.features[i]); 739 return; 740 } 741 742 } 743 744 //If the result has no related feature - inform the user 745 Ext.Msg.alert('', meAdvSearch.EM_RELATED_FEATURE_NOT_FOUND, Ext.emptyFn); 746 747 } 748 }, 749 config: { 750 //Apply custom scrollbar inside the grid 751 applyCustomScrollBar: function (ctrl) { 752 753 $("#" + ctrl.getId() + " .wgResultGridPanelBody .x-grid-view").css("overflow-y", "auto"); 754 $("#" + ctrl.getId() + " .wgResultGridPanelBody .x-grid-view").mCustomScrollbar(); 755 }, 756 //Remove custom scrollbar from the grid 757 removeCustomScrollBar: function (ctrl) { 758 759 $("#" + ctrl.getId() + " .wgResultGridPanelBody .x-grid-view").css("overflow-y", "hidden"); 760 $("#" + ctrl.getId() + " .wgResultGridPanelBody .x-grid-view").mCustomScrollbar("destroy"); 761 } 762 } 763 }; 764 765 return item; 766 }, 767 768 /********************************************************************************************/ 769 770 /********************************************************************************************/ 771 /******************* Main functions used to define the Search Control **********************/ 772 /********************************************************************************************/ 773 774 //Get column type 775 getType: function (type) { 776 777 switch (type) { 778 case 1: 779 return "Boolean"; 780 case 2: 781 return "Int"; 782 case 3: 783 return "Double"; 784 case 4: 785 return "String"; 786 case 5: 787 return "Date"; 788 case 6: 789 return "Time"; 790 case 7: 791 return "DateTime"; 792 case 8: 793 return "Geometry"; 794 } 795 }, 796 797 //Get column type 798 getFilterCtrlType: function (type, isDDL, op) { 799 800 if (isDDL) { 801 return "wgListOfValuesFilter"; 802 } 803 804 switch (type) { 805 case 1: 806 return "wgBooleanFilter"; 807 case 2: 808 return op == "Between" ? "wgIntIntervalFilter" : "wgIntFilter"; 809 case 3: 810 return op == "Between" ? "wgDoubleIntervalFilter" : "wgDoubleFilter"; 811 case 4: 812 return "wgStringFilter"; 813 case 5: 814 return op == "Between" ? "wgDateIntervalFilter" : "wgDateFilter"; 815 case 6: 816 return op == "Between" ? "wgTimeIntervalFilter" : "wgTimeFilter"; 817 case 7: 818 return "wgDateTimeFilter"; 819 case 8: 820 return "wgGeometryFilter"; 821 } 822 }, 823 824 //Get the settings according to the filter ctrl type 825 getFilterCtrlSettings: function (filterSettings, tabIndex, FilterDrawing) { 826 827 if (filterSettings.IsDropDownList) { 828 return { ListOfValues: filterSettings.ListOfValues }; 829 830 } 831 832 switch (filterSettings.FieldInterpretationType) { 833 case 4: 834 return { RemoveDiacritics: filterSettings.RemoveDiacritics }; 835 case 2: 836 return { AllowNumberFormat: filterSettings.AllowNumberFormat }; 837 case 3: 838 return { NumberOfDecimals: filterSettings.NumberOfDecimals }; 839 case 8: 840 return { ButtonGroup: "Tab_" + tabIndex.toString(), FilterDrawing: FilterDrawing}; 841 } 842 843 return null; 844 }, 845 846 //Get filter item type 847 getOpType: function (type) { 848 849 switch (type) { 850 case 1:
851 return "Equals"; 852 case 2: 853 return "SP_Intersect"; 854 case 3: 855 return "SP_Contains"; 856 case 4: 857 return "Contains"; 858 case 5: 859 return "StartsWith"; 860 case 6: 861 return "EndsWith"; 862 case 7: 863 return "SmallerThan"; 864 case 8: 865 return "SmallerOrEqualThan"; 866 case 9: 867 return "GreaterThan"; 868 case 10: 869 return "GreaterOrEqualThan"; 870 case 11: 871 return "NotNull"; 872 case 12: 873 return "Between"; 874 } 875 }, 876 877 //Get field 878 getResultField_Text: function (value, settings, record, layerGUID, advancedSearchGUID) { 879 880 var result = "-"; 881 882 if (value != null && value.toString() != "") { 883 switch (settings.FieldInterpretationType) { 884 case "Boolean": 885 result = (value == true || value == 1) ? "Da" : "Nu"; 886 break; 887 case "Int": 888 result = (settings.AllowNumberFormat) ? this.formatNumber(value, 0) : value.toString(); 889 break; 890 case "Double": 891 result = this.formatNumber(value, settings.NumberOfDecimals); 892 break; 893 case "String": 894 result = value; 895 break; 896 case "Date": 897 result = moment(value).format("DD.MM.YYYY"); 898 break; 899 case "Time": 900 result = value.length==20?moment(value.replace("Z","")).format("H:mm"): moment("1990-01-01T" + value).format("H:mm"); 901 break; 902 case "DateTime": 903 result = moment(value).format("DD.MM.YYYY H:mm"); 904 break; 905 } 906 907 if (settings.RelatedFeature != null && record.data[settings.RelatedFeature.FeatureID] != null && 908 record.data[settings.RelatedFeature.FeatureID] != "" && record.data[settings.RelatedFeature.FeatureID] != 0) { 909 result = "<a title='" + meAdvSearch.Feature_Tooltip 910 + "' href='javascript:meAdvSearch.showFeatures(\"" + advancedSearchGUID + "\",\"" + layerGUID + "\",\"" + 911 settings.Field + "\",\"" + record.data[settings.RelatedFeature.FeatureID].toString() 912 + "\", true);'>" 913 + " <img src='img/pinRed.png' style='width:15px;' /> " + result 914 + "</a>"; 915 } 916 } 917 return result; 918 }, 919 920 /********************************************************************************************/ 921 922 /********************************************************************************************/ 923 /******************* Main functions used to show Map Features ******************************/ 924 /********************************************************************************************/ 925 926 //Show related feature inside the map 927 showFeatures: function (advSearchGuid, layerGUID, relatedField, featureID, selectResults) { 928 929 $event.notify("advancedSearch_BeforeShowFeature", { advSearchGUID: advSearchGuid }, this); 930 if (this.cancelEvent) { 931 this.cancelEvent = false; 932 return; 933 } 934 935 var tabSettings = this.getTabSettings_ByGuid(advSearchGuid); 936 var relatedFeatureSettings = this.getRelatedFeature_Details(tabSettings, relatedField); 937 938 //Create the layer related to the current avd search (set the cql filter in order to show only the needed features) 939 //and add it to the map 940 //set the load end event in order to fit the search results 941 this.createLayer(layerGUID, advSearchGuid, relatedField, relatedFeatureSettings, featureID, selectResults); 942 }, 943 944 //Create layer used to show the advSearchFeatures 945 createLayer: function (layerGUID, advSearchGuid, relatedField, relatedFeatureSettings, featureID, selectResults) { 946
947 //Deactivate current tab (will be reactivated when the feature is retrieved) 948 var tabPnl = Ext.getCmp(this.TabPanelID); 949 tabPnl.config.deactivateTab(tabPnl, advSearchGuid); 950 951 //Destroy the layer related to the current Adv Search 952 this.destroyLayer(layerGUID); 953 954 //Get CQL Filter Expression - used to retrieve only one feature (the needed one) 955 var format_filter = new OpenLayers.Format.CQL(); 956 var filterExp = ""; 957 if (!$.isArray(featureID)) { 958 filterExp = relatedFeatureSettings.Layer_featureID + "='" + featureID.toString() + "'"; 959 } 960 else { 961 for (var i = 0; i < featureID.length; i++) { 962 filterExp += (i > 0 ? " OR " : "") + relatedFeatureSettings.Layer_featureID + "='" + featureID[i].toString() + "'"; 963 } 964 } 965 var filter_compute = format_filter.read(filterExp); 966 967 //Create and add layer to the map 968 //It is used OpenLayers.Strategy.Fixed because the layer should be loaded only once and it should not depend 969 //on the map bounding box 970 var layerConfig = relatedFeatureSettings.Layer; 971 var url = _mapControl.main.configUrl(_mapControl.main.url.proxy) + "&_layerGuid=" + layerConfig.GUID; 972 var layer = new OpenLayers.Layer.Vector(layerGUID, { 973 strategies: [new OpenLayers.Strategy.Fixed()], 974 protocol: new OpenLayers.Protocol.WFS({ 975 version: "1.1.0", 976 srsName: layerConfig.projection, 977 url: url, 978 featurePrefix: layerConfig.namespace, 979 featureType: layerConfig.tableName, 980 features: layerConfig.geometryName, 981 featureNS: layerConfig.namespace, 982 outputFormat: "JSON", 983 readFormat: new OpenLayers.Format.GeoJSON(), 984 geometryName: layerConfig.geometryFieldName 985 }), 986 filter: filter_compute, 987 projection: new OpenLayers.Projection(layerConfig.projection), 988 attribution: "", 989 }); 990 layer.visibility = true; 991 layer.setOpacity(1); 992 layer.GUID = layerGUID; 993 layer.advancedSearchGUID = advSearchGuid; 994 layer.tooltip = layerConfig.tooltip; 995 layer.relatedLayers = []; 996 layer.idFieldName = layerConfig.idFieldName; 997 layer.mobileTooltip = layerConfig.mobileTooltip; 998 layer.zoomLevel = relatedFeatureSettings.Zoom; 999 layer.AdvSearch_RelatedField = relatedField == null ? "" : relatedField; 1000 layer.RelatedToAdvSearch = true; 1001 layer.selectResults = selectResults; 1002 1003 _mapControl.SetLayerStyles(layerConfig, layer); 1004 1005 //When the layer is loaded => show the form 1006 layer.events.register("loadend", layer, function (evt) { 1007 1008 //used to check if the feature has an empty geometry 1009 if (this.features.length == 1 && this.features[0].geometry != null) { 1010 this.features[0].geometry.calculateBounds() 1011 } 1012 1013 if (this.features.length == 0 || (this.features.length == 1 && (this.features[0].geometry == null 1014 || this.features[0].geometry.bounds == null))) { 1015 Ext.Msg.alert('', (this.features.length==1 && (this.features[0].geometry ==null ||this.features[0].geometry.bounds == null))? meAdvSearch.EM_FEATURE_GEOMETRY_NOT_FOUND : 1016 meAdvSearch.EM_FEATURE_NOT_FOUND, Ext.emptyFn); 1017 } 1018 else { 1019 1020 for (var i = 0; i < this.features.length; i++) { 1021 this.features[i].isAdvSearchResult = true; 1022 this.features[i].advSearchResult_RelatedField = this.AdvSearch_RelatedField; 1023 this.features[i].advancedSearchGUID = this.advancedSearchGUID; 1024 } 1025 1026 _mapControl.FitFeatures(this.features, 1.2, this.zoomLevel, false); 1027 _mapControl.featureSelection.ClearSelection(); 1028 1029 if (this.selectResults) {
1030 _mapControl.featureSelection.SelectFeature(this.features[0]); 1031 } 1032 } 1033 1034 //Reactivate current tab 1035 var tabPnl = Ext.getCmp(meAdvSearch.TabPanelID); 1036 tabPnl.config.activateTab(tabPnl, this.advancedSearchGUID); 1037 1038 }); 1039 1040 // Add layer to the map and set its right index 1041 _mapControl.map.addLayers([layer]); 1042 var layerIndex = this.getLayerIndex(relatedFeatureSettings.AddAfterMapLayer); 1043 if (layerIndex != null) { 1044 _mapControl.map.setLayerIndex(layer, layerIndex); 1045 } 1046 1047 //Add the temporary layer to the highlight control 1048 if (_mapControl.featureHighlight) { 1049 _mapControl.featureHighlight.AddLayer(layer); 1050 } 1051 1052 //Add the temporary layer to the tooltip control 1053 if (_mapControl.tooltip) { 1054 _mapControl.tooltip.AddLayer(layer); 1055 } 1056 1057 //Add the temporary layer from the featureSelection control 1058 if (_mapControl.featureSelection) { 1059 _mapControl.featureSelection.AddLayer(layer); 1060 } 1061 1062 1063 }, 1064 1065 //Destroy layer related to a certain adv search 1066 destroyLayer: function (layerGUID) { 1067 1068 var layer = _mapControl.GetLayerByGuid(layerGUID); 1069 if (layer) { 1070 1071 _mapControl.featureSelection.ClearSelectionByLayer(layerGUID); 1072 1073 //Remove the temporary layer from the highlight control 1074 if (_mapControl.featureHighlight) { 1075 _mapControl.featureHighlight.RemoveLayer(layer); 1076 } 1077 1078 //Remove the temporary layer from the tooltip control 1079 if (_mapControl.tooltip) { 1080 _mapControl.tooltip.RemoveLayer(layer); 1081 } 1082 1083 //Remove the temporary layer from the featureSelection control 1084 if (_mapControl.featureSelection) { 1085 _mapControl.featureSelection.RemoveLayer(layer); 1086 } 1087 1088 //Remove the temporarylayer from the map and destroy it 1089 _mapControl.map.removeLayer(layer); 1090 1091 } 1092 }, 1093 1094 //Get layer Index 1095 getLayerIndex: function (relatedLayerGUID) { 1096 1097 //if the "related layer" was not added to the map, then the result layer should remain 1098 //the last layer 1099 var relatedLayer = _mapControl.GetLayerByGuid(relatedLayerGUID) 1100 if (relatedLayer == null || relatedLayerGUID == null || relatedLayerGUID == "") { 1101 return null; 1102 } 1103 //The layer must be added after the related layer and other layers related to adv searches 1104 var layerIndex = _mapControl.map.getLayerIndex(relatedLayer); 1105 for (var i = layerIndex + 1; i < _mapControl.map.layers.length; i++) { 1106 if (_mapControl.map.layers[i].RelatedToAdvSearch == null || 1107 !_mapControl.map.layers[i].RelatedToAdvSearch) { 1108 return i; 1109 } 1110 } 1111 1112 return layerIndex + 1; 1113 }, 1114 1115 /********************************************************************************************/ 1116 /******************* Main functions used to define the Search Control **********************/ 1117 /********************************************************************************************/ 1118 1119 //Get tab settings by tab guid (advSearch guis) 1120 getTabSettings_ByGuid: function (guid) { 1121 1122 for (var i = 0; i < this.TabSettings.length; i++) { 1123 if (this.TabSettings[i].GUID == guid) { 1124 return this.TabSettings[i]; 1125 } 1126 } 1127 1128 return null; 1129 }, 1130 1131 //Get related feature details 1132 getRelatedFeature_Details: function (tabSettings, relatedField) { 1133 1134 if (relatedField == null || relatedField == "") { 1135 return tabSettings.Results.RelatedFeature; 1136 } 1137 1138 for (var i = 0; i < tabSettings.Results.Fields.length; i++) { 1139 if (tabSettings.Results.Fields[i].Field == relatedField) { 1140 return tabSettings.Results.Fields[i].RelatedFeature; 1141 } 1142 } 1143 }, 1144 1145 //Get the number of columns inside a table 1146 getColumnCount: function (table) { 1147 var ColCount = 0; 1148 table.find("tr").eq(0).find("th,td").each(function () { 1149 ColCount += $(this).attr("colspan") ? parseInt($(this).attr("colspan")) : 1; 1150 }); 1151 1152 return ColCount; 1153 }, 1154 1155 //Return numbers as formated strings 1156 formatNumber: function (x, nrDigits) { 1157 x = Math.floor(x * Math.pow(10, nrDigits)) / Math.pow(10, nrDigits); 1158 var parts = x.toString().split("."); 1159 parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); 1160 return parts.join("."); 1161 }, 1162 1163 /********************************************************************************************/ 1164 1165}); 1166
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.