- Создать JavaScript-файл или добавить в Header Definition:
function initializeGoogleMaps(){ try{ Ext.BLANK_IMAGE_URL = '/i/1px_trans.gif'; // Create namespace if doesn't already exist Ext.namespace('Ext.ux'); Ext.ux.GMapPanel = Ext.extend(Ext.Panel, { initComponent : function(){ var defConfig = { plain: true, zoomLevel: 3, yaw: 180, pitch: 0, zoom: 0, gmapType: 'map', border: false }; Ext.applyIf(this,defConfig); Ext.ux.GMapPanel.superclass.initComponent.call(this); }, afterRender : function(){ var wh = this.ownerCt.getSize(); Ext.applyIf(this, wh); Ext.ux.GMapPanel.superclass.afterRender.call(this); if (this.gmapType === 'map'){ this.gmap = new GMap2(this.body.dom); } if (this.gmapType === 'panorama'){ this.gmap = new GStreetviewPanorama(this.body.dom); } if (typeof this.addControl == 'object' && this.gmapType === 'map') { this.gmap.addControl(this.addControl); } if (typeof this.setCenter === 'object') { if (typeof this.setCenter.geoCodeAddr === 'string'){ this.geoCodeLookup(this.setCenter.geoCodeAddr); }else{ if (this.gmapType === 'map'){ var point = new GLatLng(this.setCenter.lat,this.setCenter.lng); this.gmap.setCenter(point, this.zoomLevel); } this.gmap.addControl(this.addControl); } if (typeof this.setCenter === 'object') { if (typeof this.setCenter.geoCodeAddr === 'string'){ this.geoCodeLookup(this.setCenter.geoCodeAddr); }else{ if (this.gmapType === 'map'){ var point = new GLatLng(this.setCenter.lat,this.setCenter.lng); this.gmap.setCenter(point, this.zoomLevel); } this.gmap.addControl(this.addControl); } if (typeof this.setCenter === 'object') { if (typeof this.setCenter.geoCodeAddr === 'string'){ this.geoCodeLookup(this.setCenter.geoCodeAddr); }else{ if (this.gmapType === 'map'){ var point = new GLatLng(this.setCenter.lat,this.setCenter.lng); this.gmap.setCenter(point, this.zoomLevel); } this.gmap.addControl(this.addControl); } if (typeof this.setCenter === 'object') { if (typeof this.setCenter.geoCodeAddr === 'string'){ this.geoCodeLookup(this.setCenter.geoCodeAddr); }else{ if (this.gmapType === 'map'){ var point = new GLatLng(this.setCenter.lat,this.setCenter.lng); this.gmap.setCenter(point, this.zoomLevel); } this.gmap.addControl(this.addControl); } if (typeof this.setCenter === 'object') { if (typeof this.setCenter.geoCodeAddr === 'string'){ this.geoCodeLookup(this.setCenter.geoCodeAddr); }else{ if (this.gmapType === 'map'){ var point = new GLatLng(this.setCenter.lat,this.setCenter.lng); this.gmap.setCenter(point, this.zoomLevel); } if (typeof this.setCenter.marker === 'object' && typeof point === 'object'){ this.addMarker(point,this.setCenter.marker,this.setCenter.marker.clear); } } if (this.gmapType === 'panorama'){ this.gmap.setLocationAndPOV(new GLatLng(this.setCenter.lat,this.setCenter.lng), {yaw: this.yaw, pitch: this.pitch, zoom: this.zoom}); } } GEvent.bind(this.gmap, 'load', this, function(){ this.onMapReady(); }); }, onMapReady : function(){ this.addMarkers(this.markers); this.addMapControls(); this.addOptions(); }, onResize : function(w, h){ if (typeof this.getMap() == 'object') { this.gmap.checkResize(); } Ext.ux.GMapPanel.superclass.onResize.call(this, w, h); }, setSize : function(width, height, animate){ if (typeof this.getMap() == 'object') { this.gmap.checkResize(); } Ext.ux.GMapPanel.superclass.setSize.call(this, width, height, animate); }, getMap : function(){ return this.gmap; }, getCenter : function(){ return this.getMap().getCenter(); }, getCenterLatLng : function(){ var ll = this.getCenter(); return {lat: ll.lat(), lng: ll.lng()}; }, addMarkers : function(markers) { if (Ext.isArray(markers)){ for (var i = 0; i < markers.length; i++) { var mkr_point = new GLatLng(markers[i].lat,markers[i].lng); this.addMarker(mkr_point,markers[i].marker,false,markers[i].setCenter, markers[i].listeners); } } }, addMarker : function(point, marker, clear, center, listeners){ Ext.applyIf(marker,G_DEFAULT_ICON); if (clear === true){ this.getMap().clearOverlays(); } if (center === true) { this.getMap().setCenter(point, this.zoomLevel); } var mark = new GMarker(point,marker); if (typeof listeners === 'object'){ for (evt in listeners) { GEvent.bind(mark, evt, this, listeners[evt]); } } this.getMap().addOverlay(mark); }, addMapControls : function(){ if (this.gmapType === 'map') { if (Ext.isArray(this.mapControls)) { for(i=0;i this.addMapControl(this.mapControls[i]); } }else if(typeof this.mapControls === 'string'){ this.addMapControl(this.mapControls); }else if(typeof this.mapControls === 'object'){ this.getMap().addControl(this.mapControls); } } }, addMapControl : function(mc){ var mcf = window[mc]; if (typeof mcf === 'function') { this.getMap().addControl(new mcf()); } }, addOptions : function(){ if (Ext.isArray(this.mapConfOpts)) { var mc; for(i=0;i this.addOption(this.mapConfOpts[i]); } }else if(typeof this.mapConfOpts === 'string'){ this.addOption(this.mapConfOpts); } }, addOption : function(mc){ var mcf = this.getMap()[mc]; if (typeof mcf === 'function') { this.getMap()[mc](); } }, geoCodeLookup : function(addr) { this.geocoder = new GClientGeocoder(); this.geocoder.getLocations(addr, this.addAddressToMap.createDelegate(this));; }, addAddressToMap : function(response) { if (!response || response.Status.code != 200) { Ext.MessageBox.alert('Unable to Locate Address','Unable to Locate the Address you provided'); }else{ place = response.Placemark[0]; addressinfo = place.AddressDetails; accuracy = addressinfo.Accuracy; if (accuracy === 0) { Ext.MessageBox.alert('Unable to Locate Address', 'Unable to Locate the Address you provided'); }else{ point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]); if (typeof this.setCenter.marker === 'object' && typeof point === 'object'){ this.addMarker(point,this.setCenter.marker,this.setCenter.marker.clear,true, this.setCenter.listeners); } } } } }); Ext.reg('gmappanel',Ext.ux.GMapPanel); } catch(err){} } function showAddress(address){ var mapwin = new Ext.Window({ layout: 'fit', title: 'Map', closeAction: 'hide', width:800, height:600, x: 40, y: 60, items: { xtype: 'gmappanel', region: 'center', zoomLevel: 12, gmapType: 'map', mapConfOpts: ['enableScrollWheelZoom','enableDoubleClickZoom','enableDragging'], mapControls: ['GSmallMapControl','GMapTypeControl','NonExistantControl'], setCenter: { geoCodeAddr: address, marker: {title: address} } } }); mapwin.show(); }
- Добавить в HTML Header страницы:
где, &GOOGLE_MAPS_API_KEY. - значение ключа для конкретного хоста<!---script src="http://maps.google.com/maps?file=api&v=2&sensor=true&key=&GOOGLE_MAPS_API_KEY." type="text/javascript"-->
- Добавить в onload body вызов данной функции или использовать метод onReady фреймворка ExtJS:
Ext.onReady(function(){ Ext.BLANK_IMAGE_URL = '/i/1px_trans.gif'; // Create namespace if doesn't already exist Ext.namespace('Ext.ux'); //Здесь последовательность вызовов функций, например: initializeGoogleMaps(); makeComboboxis(); });
- Добавить вызов JavaScript-функции по нажатию на кнопку или ссылку:
например для "Москва, Пресненская набережная 10":javascript:showAddress(адрес);
javascript:showAddress('Москва, Пресненская набережная 10');
суббота, 6 марта 2010 г.
Интеграция Oracle Application Express и Google Maps
пятница, 5 марта 2010 г.
Application Express: функция для ввода только чисел в TEXTFIELD в определённом диапазоне значений
- Создать JavaScript-файл или добавить в Header Definition:
function limitNumber(elementName,minNum,maxNum) { var t_field=document.getElementById(elementName).value; if (isNumeric(t_field)){ if (!((parseInt(t_field) <= maxNum) && ((parseInt(t_field) >= minNum)))) { var temp=document.getElementById(elementName).value.substring(0, document.getElementById(elementName).value.length-1); document.getElementById(elementName).value=temp; } } else { var temp=document.getElementById(elementName).value.substring(0, document.getElementById(elementName).value.length-1); document.getElementById(elementName).value=temp; } }
- Создать или изменить на странице Apex Item типа TEXTFIELD и указать в свойстве Element->HTML Form Element Attributes следующее значение:
например для TEXTFIELD c именем P150_PROBABILITY, минимальный значением 1 и максимальным значением 100:onkeyup="limitNumber('имя_данного_textfield',min_значение,max_значение)" onkeydown="limitNumber('имя_данного_textfield',min_значение,max_значение)"
onkeyup="limitNumber('P150_PROBABILITY',1,100)" onkeydown="limitNumber('P150_PROBABILITY',1,100)"
Application Express: функция для ввода только числовых значений в TEXTFIELD
- Создать JavaScript-файл или добавить в Header Definition:
function checkOnlyNumbers(evt) { evt = (evt) ? evt : window.event var charCode = (evt.which) ? evt.which : evt.keyCode if (charCode > 31 && (charCode < 48 || charCode > 57)) { return false; } else { return true; } }
- Создать или изменить на странице Apex Item типа TEXTFIELD и указать в свойстве Element->HTML Form Element Attributes следующее значение:
onkeydown="return checkOnlyNumbers(event)" onkeyup="return checkOnlyNumbers(event)"
Application Express: функция для ограничения длины вводимых данных для TEXTAREA
Данная функция предназначена для ограничения вводимых данных в TEXTAREA, т.к. стандартными средствами Apex 3.2 эту валидацию выполнить нельзя.
- Создать JavaScript-файл или добавить в Header Definition:
function limitText(elementName,limitNum) { var t_field=document.getElementById(elementName); if (t_field.value.length > limitNum) { t_field.value = t_field.value.substring(0, limitNum); } }
- Создать или изменить на странице Apex Item типа TEXTAREA и указать в свойстве Element->HTML Form Element Attributes следующее значение:
например для TEXTAREA c именем P115_DESCRIPTION и максимальной длинной 2000 символов(для латиницы, для кирилицы в двое меньше):onKeyUp="limitText('имя_данной_textarea',максимальная длинна)" onKeyDown="limitText('имя_данной_textarea',максимальная длинна)"
onKeyUp="limitText('P115_DESCRIPTION',2000)" onKeyDown="limitText('P115_DESCRIPTION',2000)"
Рекомендации при разработке Apex-приложений
- Понимание архитектуры Apex и связанных технологий:
- Oracle RDBMS - PL/SQL
- DHTML = HTML+CSS+JavaScript+Ajax
- Логика отображения(View Layer) должна быть только в:
- Templates
- CSS
- Item Formatting
- Избегать, где это возможно использования PL/SQL для генерации HTML
- Вынести все пользовательские JavaScript-функции в отдельный файл и минимализировать и упаковать
- Перенести анонимные PL/SQL процедуры в БД (нет необходимости в компиляции каждый раз) и отладка из отдельно от Apex. * передавать значения в процедуры как параметры * использовать переменные связывания
- Использовать схему пэйджинга(pagination scheme) "X to Y" взамен "X to Y of Z"
- Постоянно производить диагностику производительности вновь созданных страниц и переодически приложения в целом (возможно использование средств автоматического тестирования Web-приложений, например, Oracle Application Testing Suite).
Рекомендую ознакомиться со статьёй Майка Хичва - Оценка производительности, в которой Вы найдёте пояснение некоторых рекомендаций
Подписаться на:
Сообщения (Atom)