Browsing "Older Posts"

APEX-AT-WORK no image

Vorsätze fürs neue Jahr

Von Tobias Arnhold → 12.31.2011
Neben den zahlreichen Softwareprojekten, werde ich mich auch weiterhin mit neuen Spezialgebieten auseinandersetzen.

Ganz oben auf der Liste steht die Integration von mobilen APEX Applikationen. Details zum Vorhaben findet ihr hier: http://www.apex-at-work.blogspot.com/2011/12/mobile-apex-applikationen-mit-jquery.html

Außerdem habe ich vor die Plugin App zu erweitern. Durch eine entsprechende Berechtigungsverwaltung wird der Zugriff individuell einstellbar sein. Das Ganze wird natürlich durch neue Plugins unterstützt.

Als Letztes, will ich mich mit der raphaeljs Library auseinandersetzen. Ziel ist es, eine ähnliche Methode wie Matt Nolan zu entwickeln, um in APEX Applikationen die visuelle Bearbeitung noch besser abbilden zu können.

Ps.: Wie ihr sicher gesehen habt, habe ich noch etwas an dem Feinschliff meines Blogs gearbeitet. Ich hoffe das neue Design mit geänderten Inhalten kommt gut an. :)

Das wärs für dieses Jahr. Guten Rutsch euch allen!
APEX-AT-WORK no image

Kurze Info

Von Tobias Arnhold → 12.21.2011
Blog Update
Wie ihr sicher schon gesehen habt, habe ich mein Blog Layout überarbeitet. Ziel war es, die Inhalte besser darzustellen und unnötigen Ballast über Bord zuwerfen. Außerdem habe ich den Fokus jetzt mehr auf die deutschsprachige APEX Community gesetzt.
Nur keine Angst, ich werde natürlich auch weiterhin ab und an Posts in Englisch erstellen.

APEX Community Beitrag
Die Plugin App hat einen netten Beitrag auf der APEX Community Seite erhalten:
http://www.oracle.com/webfolder/technetwork/de/community/apex/index.html

Präsentationen zum Thema Plugins
Im März werde ich aller Voraussicht nach, jeweils in Dresden und in Mannheim einen Vortrag über die Plugin App halten. Ich hoffe die DOAG Regionalveranstaltungen werden wieder gut besucht sein. :) Wie immer gibt es einen kostenlosen Zugang zum Download der Anwendung. 

Weihnachten
Zum Schluss, wünsche ich allen ein besinnliches Weihnachtsfest und einen guten Rutsch ins neue Jahr!
APEX-AT-WORK no image

Mobile APEX Applikationen mit jQuery Mobile - Wichtige Links

Von Tobias Arnhold → 12.06.2011
Ich habe vor die Plugin App mit einer entsprechenden mobilen Version zu erweitern. Dazu benötige ich allerhand Hintergrundwissen und das trage ich in dem Blogpost hier zusammen. Starten tue ich mit den wichtigsten Links zur mobilen APEX Entwicklung. Weitere Details werden folgen...


Links zur Entwicklung von mobilen APEX Anwendungen mit jQuery Mobile
M. Sewtz - Getting Started with Mobile in APEX - Part 1 
M. Sewtz - Getting Started with Mobile in APEX - Part 2
APEX Community (P. Raganitsch) - Oracle APEX für mobile Endgeräte
T. Harsono - Oracle APEX 4.1 on Android Phone (Youtube Video)
B. Spendolini - a few thoughts on mobile development....
B. Spendolini - Build your first mobile app with APEX Presentation.
All Things Oracle - Oracle APEX on your Smartphone

APEX Beispielapplikationen:
Sujay - Businessbeispiele
M. Sewtz - Simple Beispielanwendung
P. Raganitsch - Komplexere Beispielanwendung
Jaydip Bosamiya - Komplexere Beispielanwendung

Generelle Links:
jQuery Mobile - Offizielle Homepage
Miami Coder - Interesting jQuery Mobile Tutorials


Advanced ways using the Authorization Schemes inside APEX

Von Tobias Arnhold → 12.05.2011
The standard way to check the authorization is to select the correct scheme inside the security area:


What are authorization schemes and how do you create them?
http://docs.oracle.com/cd/E17556_01/doc/user.40/e15517/sec.htm#BABEDFGB
http://apps2fusion.com/at/64-kr/399-security-using-authorization-in-apex


There are a couple of hidden ways to check the authorization schemes differently to the standard way.

To check more then one authorization scheme with pl/sql use this hint from Denes Kubicek:
http://deneskubicek.blogspot.com/2009/05/checking-authorization-scheme-within.html

To check authorization schemes inside SQL follow this solution:
http://www.oracle.com/webfolder/technetwork/de/community/apex/tipps/repo-2/index.html

For those who do not understand German. Just create a simple function which let you use the authorization scheme function inside a sql statement:
create or replace function 
 my_check_auth(p_security_scheme in varchar2)
 return number is
begin
  if apex_util.public_check_authorization(p_security_scheme) 
  then
    return 1;
  else 
    return 0;
  end if;
end;
 

select 
  'VALID_USER' as return_val
from my_table
where col1 = 'NEW'
and (my_check_auth('AUTH_VALID_USER') = 1  
     or my_check_auth('AUTH_NEW_USER')
     )
APEX-AT-WORK no image

Plug-in Bookmark

Von Tobias Arnhold → 12.04.2011
A couple of days ago I released a new simple plug-in. A dynamic action plug-in which allows you to bookmark the current or any other page by running a generic javascript code which works with most common browsers.

The plug-in can be downloaded here:
http://apex-plugin.com/oracle-apex-plugins/dynamic-action-plugin/bookmark_153.html

Example page:
http://apex.oracle.com/pls/apex/f?p=65560:9

How to use it:
 - set up a new Dynamic Action
 - Event: "Page Load"
 - Action: Bookmark
  - Set up the effected element by using the jQuery logic
    - ID: #P1_YOUR_BUTTON
    - Class: .my_button
  - URL Definition: "Current Page" or "Manually Defined URL"
    - If "Manually Defined URL" then set the URL and the name of the new bookmark


Freier Community Zugang für Die Plugin App

Von Tobias Arnhold → 11.30.2011
Nachdem die erste Präsentation sehr erfolgreich verlaufen ist und das Feedback sehr positiv war. Möchte ich nun die Anwendung für den Rest der APEX Community zum testen freischalten.

Zugang: http://apex.oracle.com/pls/apex/f?p=65600

Anmeldung: demo / demo

Wer mehr über die Anwendung erfahren möchte kann direkt Kontakt zu mir aufnehmen oder verfolgt einfach die nächsten DOAG Regionaltreffen, ich werde dort noch einige ähnliche Vorträge zum Thema halten.


Mir kamen auch schon einige neue Ideen für die nächste Version der Anwendung und werde bald mit der Entwicklung beginnen.

Falls jemand ein paar Anmerkungen zum Logbuch selbst hat, bin ich gern für Erweiterungswünsche offen. Denn auch die neuen Plugins müssen ja irgendwo ihren Platz finden. :)
APEX-AT-WORK no image

Oracle Select: Compare two comma separated lists for matching words

Von Tobias Arnhold → 11.17.2011
This a simple solution to compare two comma separated lists inside a select where clause:
/* 
Table name: TBL_WITH_COMMA_LIST
Columns:
twc_id; twc_list
1     ; 0815,9999,1212,1222,1111,9988
2     ; 0815,8888,2121,2111,2222,8899
3     ; 0110,9112,1211

Parameter: :v_list
0815,9988,1111
*/ 

select tw.twc_id, tw.twc_list, REGEXP_COUNT(tw.twc_list,REPLACE(:v_list,',','|')) ret_val
from TBL_WITH_COMMA_LIST tw
where REGEXP_COUNT(tw.twc_list,
                   REPLACE(:v_list,',','|')
                   ) > 0;
/*
Result:
twc_id; twc_list;                    ; ret_val
1     ; 0815,9999,1212,1222,1111,9988; 3 
2     ; 0815,8888,2121,2111,2222,8899; 1

Info: v_list can only contain 512 bytes 
*/
APEX-AT-WORK no image

"Die Plugin App" - Live Präsentation + Download Zugang am 29.11.2011

Von Tobias Arnhold → 11.14.2011
Leider kann ich nicht bei der diesjährigen DOAG Konferenz dabei sein. Ich hätte zwar liebend gern die vielen APEX Entwickler wieder getroffen, aber es soll nicht sein. :(

Das kann nur heißen, nach vorne schauen und die nächsten Projekte in Angriff nehmen.

Am 29.11.2011 halte ich in Wiesbaden bei dem regionalem DOAG Treffen der Rhein-Main Gruppe die erste DOAG Präsentation über die Plugin Applikation. Das bedeutet, das jeder der kommt die inzwischen auf 30 Plugins angewachsene Applikation sieht und vor allem einen Eindruck erhält, wie aktuelle APEX Plugins eine Anwendung verbessern können.

Details zum Treffen:
http://www.doag.org/termine/termine.php?tid=418033#19:00  

Wichtig: Jeder Teilnehmer erhält einen Online Zugang, über den er sich die Applikation downloaden kann.

Ich freue mich auf das Treffen und bin gespannt wie viele die Applikation wirklich sehen wollen. :)

Wer die Plugin App noch nicht kennt, der sollte sich die entsprechenden Blog-Post's nochmal anschauen:
Eigene URLs und Bilder im APEX Report abbilden:
http://apex-at-work.blogspot.com/2011/10/eigene-urls-im-report-mit-bilder.html

Die nächsten Plugins für "Die Pugin App":
http://apex-at-work.blogspot.com/2011/09/die-nachsten-plugins-fur-die-pugin-app.html

Logbuch mit neuem Plugin:
http://apex-at-work.blogspot.com/2011/09/logbuch-mit-neuem-plugin.html

Logbuch - Die Plugin App:
http://apex-at-work.blogspot.com/2011/09/logbuch.html
APEX-AT-WORK no image

Loading Icon - Upgrade thoughts

Von Tobias Arnhold → 11.13.2011
During my development I was always troubled that the loading icon plug-in worked fine with before page submit events but never worked when you redirected the page immediately. For example if you used code like this:
<a href="f?p=&APP_ID.:3:&SESSION.::NO::P2_EXAMPLE_ID:#EXAMPLE_ID#">
<img alt="" src="/i/menu/pencil16x16.gif">
</a>
No loading icon would appear. As a manual solution use this code example:
/* Template: */
<img
  src="#IMAGE_PREFIX#magnifying_glass_white_bg.gif" 
  alt="" 
  title="Show sample data"
  style="cursor:pointer;"
  onclick="
   fnc_startLoadIcon('...loading...','/i/my_loading_icon.gif',32,32,8,'#F26300',6);
   window.location='f?p=&APP_ID.:1:&SESSION.::::P2_EXAMPLE_ID:#EXAMPLE_ID#';
   return false;">
I'm thinking to integrate this as an option to the Loading Icon plug-in. I would capture the href element take the href source and transform it so that the loading icon would appear before the page reloads.

Disable CKEditor 3 (Rich Text Editor) inside APEX

Von Tobias Arnhold → 11.09.2011
If you want to disable the "Richt Text Editor" inside APEX and still show everything in the right HTML format. Just add this code snippet inside the "Page Footer Text":
<script>
/* HowtTo: http://cksource.com/forums/viewtopic.php?t=15659 */
$(document).ready( function() {
( function()
{
   var cancelEvent = function( evt )
      {
         evt.cancel();
      };

   CKEDITOR.editor.prototype.readOnly = function( isReadOnly )
   {
      /* Turn off contentEditable. */
      this.document.$.body.disabled = isReadOnly;
      CKEDITOR.env.ie ? this.document.$.body.contentEditable = !isReadOnly
      : this.document.$.designMode = isReadOnly ? "off" : "on";

      /* Prevent key handling. */
      this[ isReadOnly ? 'on' : 'removeListener' ]( 'key', cancelEvent, null, null, 0 );
      this[ isReadOnly ? 'on' : 'removeListener' ]( 'selectionChange', cancelEvent, null, null, 0 );

      /* Disable all commands in wysiwyg mode. */
      var command,
         commands = this._.commands,
         mode = this.mode;

      for ( var name in commands )
      {
         command = commands[ name ];
         isReadOnly ? command.disable() : command[ command.modes[ mode ] ? 'enable' : 'disable' ]();
         this[ isReadOnly ? 'on' : 'removeListener' ]( 'state', cancelEvent, null, null, 0 );
      }
   }
} )();
setTimeout ('CKEDITOR.instances.<YOUR_APEX_ITEM>.readOnly( true )',1000);
});
</script>
The result will look like this:

Eigene URLs und Bilder im APEX Report abbilden

Von Tobias Arnhold → 10.18.2011
Wie bereits Gestern erwähnt, bin ich in den letzten Zügen der Entwicklung für die "Plugin App".

Heute wollte ich aus ein paar hässlichen Buttons ein paar schöne Icons machen.
Ausgangslage
 Zieldarstellung
Dazu habe ich mir einen simplen Report erstellt, der mir jeweils meine Icons mit sicheren URLs ausgibt:
select img from (
 select
  1 as ordby,
  '<a href="' ||
  APEX_UTIL.PREPARE_URL('f?p=' ||
                        v('APP_ID') || 
                        ':1:' || 
                        v('APP_SESSION') || 
                        ':XLSX') ||
  '"><img src="#APP_IMAGES#download_xlsx.png" alt="" title="Download Excel XLSX"/>' as img
 from dual
 union
 select
  2 as ordby,
  '<a href="' ||
  APEX_UTIL.PREPARE_URL('f?p=' ||
                        v('APP_ID') || 
                        ':1:' || 
                        v('APP_SESSION') || 
                        ':EXCEL_XML') ||
  '"><img src="#APP_IMAGES#download_xml.png" alt="" title="Download Excel XML"/>' as img
 from dual
 union
 select
  3 as ordby,
  '<a href="' ||
  APEX_UTIL.PREPARE_URL('f?p=' ||
                        v('APP_ID') || 
                        ':11:' || 
                        v('APP_SESSION') || 
                        ':') ||
  '"><img src="#APP_IMAGES#download_pdf.png" alt="" title="Download PDF"/>' as img
 from dual
 )
order by ordby
Mit APEX_UTIL.PREPARE_URL definieren Sie in SQL und PL/SQL einfach eine sichere URL die Sie in Verbindung mit Session State Protection (SSO) benötigen. #APP_IMAGES# referenziert auf mein hochgeladenes Bild. Da ich auf dem öffentlichen APEX Server arbeite, kann ich meine Bilddateien nicht auf einem Webserver ablegen. Dies wäre aber aus performance und caching Gründen zu bevorzugen. Auf der anderen Seite soll die Applikation später als Download zur Verfügung stehen, dann kann ich die Bilder einfach als Supporting Objects bei der Installation mit integrieren.

Erinnerung: APEX Workshop vom 24.10. bis 26.10.2011

Von Tobias Arnhold → 10.17.2011
Nochmal die Erinnerung:
Vom 24. bis zum 26.10.2011 findet der "Oracle APEX: Knowhow aus der Praxis" Workshop in Bensheim statt. Ich halte am Montag einen Gastauftritt zu APEX Plugins und zeige Ihnen wie Sie das jQuery Sparkline Plugin in ein APEX Plugin umwandeln können:
Beispiel Sparklines
 Das fertige Plugin in Aktion
Details zum jQuery Plugin finden Sie übrigens hier: http://omnipotent.net/jquery.sparkline/

Außerdem zeige ich zum ersten mal die Plugin App Live. Die Anwendung liegt in den Endzügen der Entwicklung und bedarf nur noch kleinerer Anpassungen.
Das letzte Plugin vor dem ersten Release habe ich heute integriert:
Save Before Exit von Skillbuilders.
Dieses Plugin verwende ich zum Beispiel in Kombination mit dem Iframe Plugin, um mehrere Tabular Forms auf einer Seite darstellen zu können die mit Standard APEX Prozessen verwendet werden.
 Aktuell habe ich 29 Plugins in der Anwendung verwendet. Die Startseite verwendet die meisten Plugins : "9"!


Wem das noch nicht an Argumenten reicht, dem sei gesagt: Am dem Sonntag vor dem Kurs soll (so munkelt es) der Formel 1 Weltmeister 2011 seine Weltmeisterfeier im benachbarten Heppenheim haben. Heißt, frühes anreisen sorgt für gute Plätze! ;)

Looking for UILayout plug-in beta tester (APEX 4.1 only)

Von Tobias Arnhold →
I added some fixes to the UILayout plug-in in combination with APEX 4.1 and the Interactive Report appearance.

I'm quite busy with the Plugin App and looking out for some testers. If there is anybody out there then please contact me.

The following issues are fixed under APEX 4.1:

Format options position
Rows Per Page position
Column options

I don't know if it works for all themes? If you know about more issues or even have some improvement ideas please inform me. I will fix it before the final release will come out.

Tobias

Die nächsten Plugins für "Die Pugin App"

Von Tobias Arnhold → 9.25.2011
Die Plugin App hat einen schon recht hohen Reifegrad erreicht. Da ich aber noch bis Ende Oktober Zeit habe, werde ich noch versuchen ein paar weitere Plugins zu integrieren:

Diese Plugins sollen noch kommen:
PicInsideEditBox:
http://apex-plugin.com/oracle-apex-plugins/item-plugin/picinsideeditbox_141.html
Reports 2 PDF:
http://apex-plugin.com/oracle-apex-plugins/process-type-plugin/reports-2-pdf_140.html
SkillBuilders Save Before Exit:
http://apex-plugin.com/oracle-apex-plugins/dynamic-action-plugin/skillbuilders-save-before-exit_43.html
Simple Checkbox:
http://apex.oracle.com/pls/apex/f?p=654321:206:0::::: 
Address(validate, display map)
http://apex-plugin.com/oracle-apex-plugins/item-plugin/addressvalidate-display-map_88.htmlresizeable 
Textarea (memory) 
http://apex-plugin.com/oracle-apex-plugins/item-plugin/resizeable-textarea_80.html

Hier die Liste aller bisher verwendeten Plugins:


Wenn jemand ein tolles Plugin kennt, das hier noch fehlt, dann meldet euch bitte bei mir.

Oracle APEX: Knowhow aus der Praxis

Von Tobias Arnhold → 9.21.2011
Es ist wieder soweit, zwischen dem 24. und dem 26.10.2011 findet der "Oracle APEX: Knowhow aus der Praxis" Workshop in Bensheim statt:


Diesmal mit der Besonderheit, dass ich als Gastredner auftrete!
Ich werde mich mit dem Thema Plugins befassen und Ihnen zeigen, wie Sie solch ein APEX Plugin erstellen und in Ihrer APEX Anwendung verwenden können. Falls jetzt die Frage aufkommt, um was für ein Typ Plugin es sich handelt?
Dann schauen Sie doch einfach mal hier rein:
http://apex-at-work.blogspot.com/2011/09/logbuch-mit-neuem-plugin.html

Außerdem werde ich mein aktuelles Projekt "Die Plugin App" das erste mal Live präsentieren.

Also wir sehen uns beim Workshop!

What happens in 4 years

Von Tobias Arnhold → 9.14.2011
Since 2008 I write about APEX, Javascript and PL/SQL and still like it a lot. It seems that people think that I do right:

If people around the world like it then i will not stop it!

Logbuch mit neuem Plugin

Von Tobias Arnhold →
Bei der Entwicklung der Logbuchanwendung habe ich auch gleich ein kleines aber feines Plugin mit integriert, dass es so nicht als Download zu haben gibt.

Es handelt es sich um das jQuery Sparkline Addon. Es dient zur Anzeige von kleinen Line- oder Bar-Charts direkt im Report. Ach seht einfach selbst:

Wie man sieht ist die Anwendung noch nicht perfekt, aber auf dem richtigen Weg. :)

Wenn jemand Interesse an dem Plugin, dann könnt ihr euch bei mir melden.

Weitere Infos und Bilder folgen...

Ps.:
Die nächste Aufgabe ist die Integration des "Embedded PDF" Plugins zur Generierung von PDF's ohne BiPublisher oder Jasper Reports. Mal sehen was das Plugin so kann.

Logbuch - Die Plugin App

Von Tobias Arnhold → 9.11.2011
Ich arbeite mit ein paar Freunden derzeit an einer Applikation die sich Logbuch nennt und das Ziel hat, möglichst viele APEX Plugins in einer Business Applikation abzubilden.

Ein paar Infos zur Anwendung:
- Ziel der Anwendung ist es, Einträge über eigens definierte Kategorien zu erfassen.
- Die komplette Applikation nutzt nur Standard APEX Funktionalität bei allen DML Prozessen.
- Es werden im Moment über 10 Plugins verwendet und das Ziel ist 15 zu integrieren.
- Neben der normalen Webapplikation für Standard-Workstations mit aktuellem Browser, wird auch eine mobile Variante integriert werden.

Die Anwendung selber ist zu 75% fertig und soll als Beispiel auf regionalen DOAG Veranstaltungen die Nutzung von APEX Plugins näher bringen.

Also haltet die Augen für die kommenden DOAG Events offen.

Hier mal eine Seite in der Anwendung:
APEX-AT-WORK no image

Automatic File Upload filename can't be null

Von Tobias Arnhold → 8.30.2011
I used the automatic file upload feature of APEX and got always an error that either filename or mimetype column of my file table can't be null.

APEX probably saves first in FLOW_FILES and then updates my tables. If I take the column "NOT NULL" limitation away it works fine.

If you want to know how you configure automatic file upload in APEX look here:
File Browser in APEX 4 with BLOB column specified in item source attribute
APEX-AT-WORK no image

Restore package source code

Von Tobias Arnhold →
If you need to restore your changed or dropped package then use this select to retrieve the lost information:http://www.blogger.com/img/blank.gif
select text
 from dba_source
   as of timestamp systimestamp - interval '10' minute
 where name='MY_PACKAGE'
 order by line;

For more information read this blog post of Uwe Hesse:
Retrieve old versions of procedures with Flashback Query

Btw: Have you seen the great blog post from Matt how you can use your own interactive images in APEX: APEX Plugin – Body Chart
APEX-AT-WORK no image

IRR: UILayout issue

Von Tobias Arnhold → 8.17.2011
If you use the UILayout plug-in for APEX with Interactive Reports you will see some issues inside the action menu. The "Rows Per Page" and the "Format" menu will be positioned above the main action menu.

To fix this use the following js snippet with a dynamic action or add it inside your page header:
$('.dhtmlSubMenuS').mouseover(function() {

  $('#apexir_ROWS_PER_PAGE_MENU').css({

    left: $('#apexir_ROWS_PER_PAGE_MENU').position().left + 200 + "px"

  });

  $('#apexir_FORMAT_MENU').css({

    left: $('#apexir_FORMAT_MENU').position().left + 200 + "px"

  });    

});


Create a Dynamic Action which fires on the refresh of your Interactive Report and executes the JS code. Run it also on page load.

I will fix it in one of the next versions of the plug-in.

IRR: Remove single rule

Von Tobias Arnhold → 8.09.2011
If you want to remove easily a single rule inside your interactive report then use this javascript code snippet:

$('a:contains(Vorname ist Null)').parent().parent().remove();

Customized IRR example:
/* Remove Highlight rules */

$('a:contains(MY_RULE1_BLUE)').parent().parent().remove();

$('a:contains(MY_RULE2_GREEN)').parent().parent().remove();

$('a:contains(MY_RULE3_ORANGE)').parent().parent().remove();

/* remove filter */

$('a:contains(My Column filter = \'FILTER\' )').parent().parent().remove();

/* Remove named report */

$('a:contains(Gespeicherter Bericht = \"My filtered report\")').parent().parent().remove();

/* Remove group label text */

$('#apexir_SAVED_REPORTS optgroup[label="Standard"]').attr("label","");

$('#apexir_SAVED_REPORTS optgroup[label="Öffentlich"]').attr("label","");

/* Remove Control Panel Control and make it always active */

$('#apexir_CONTROLS_IMAGE').removeClass('pseudoButtonActive');

$('#apexir_CONTROLS_IMAGE').addClass('pseudoButtonInactive');

/* gReport.toggle_controls($x('apexir_CONTROL_PANEL_CONTROL')); */

$('#apexir_CONTROL_PANEL_CONTROL').hide();
APEX-AT-WORK no image

Check if part of a string has only number values

Von Tobias Arnhold → 8.06.2011
I had the requirement to find out if a part of a string includes only number values:

Table: My_Test_String_Table
Column: T_STR
String 1: TIGER031STD
String 2: TIGERTT1STD
String 3: TIGER999STD

Now I need to find all rows where position 6, 7 and 8 is a number value.

Select:

select * from My_Test_String_Table
where
decode(REGEXP_INSTR (substr(T_STR,6,3), '[^[:digit:]]'),0,'YES','NO') = 'YES';

Returns String 1 and 3!

Take a look into this forum post to find more examples:
http://forums.oracle.com/forums/thread.jspa?threadID=371057
APEX-AT-WORK no image

IRR: Get current report selection

Von Tobias Arnhold →
With Interactive Reports you are able to save several views of one report source.
- Default
- Public
- Private

Your end user can easily choose from those saved reports.
If you need to know which the currently viewed report is then you can use this little js code snippet:
alert(
'ID: ' + 
$('#apexir_SAVED_REPORTS').val() + 
', Text: ' + 
$('#apexir_SAVED_REPORTS :selected').text()
);


Try it inside a dynamic action!
APEX-AT-WORK no image

New Plug-in: Hyphenation for APEX

Von Tobias Arnhold → 7.02.2011
I just released a new plug-in called: Hyphenation for APEX

Unfortunately at the moment it seems only to work with Firefox. I contacted the developers of the original plug-in to find the issue why it doesn't work with IE9 and the standard APEX theme?

Check out this ticket for more information: http://code.google.com/p/hyphenator/issues/detail?id=146

I will update the plug-in as soon as I have a solution.
APEX-AT-WORK no image

How to find duplicate rows?

Von Tobias Arnhold → 6.08.2011
Basically with a single table you do like this:

SELECT COLUMN_A, COLUMN_B, COUNT(*)
FROM MY_TABLE
GROUP BY COLUMN_A, COLUMN_B
HAVING COUNT(*)>1;

If you have a special select and you need to find duplicate rows then do like this:

select count(*), cust_no
(
select
c.cust_no, c.cust_name, s.order_date, s.art_no, s.art_amount
from table_sales s, table_customer c
where c.cust_no = s.cust_no
and s.country_no = 49
and s.order_date = trunc(sysdate-1)
group by
order by 2,3
)
group by cust_no
having count(*) > 1
APEX-AT-WORK no image

Check ob Flash installiert ist

Von Tobias Arnhold → 6.06.2011
Ich habe vor ein paar Tagen ne interessante Frage gestellt bekommen:
"Wie überprüft man in Apex, ob ein Flash Plugin installiert ist?"
Antwort:
Einen Standard-Check gibt es nicht.

Lösungsansatz:
Probiert folgende Erweiterung JavaScript Flash Detection Library (Flash Detect)

Die Datei "flash_detect_min.js" auf eurem Server laden und in den APEX Page Header einbetten.

Auf eurer Startseite erstellt ihr ein Hidden Item: P1_FLASH

Auf der gleichen Seite erstellt ihre eine Dynamic Action die nach dem "Page Load" startet.

Erste TRUE Action: Execute Javascript Code
if(!FlashDetect.installed){
$s('P1_FLASH','TRUE');
}else{
$s('P1_FLASH','FALSE');
}

Zweite TRUE Action: Execute PL/SQL Code
Code: null;
Page Items to Submit: P1_FLASH

Nun könnt ihr auf jeder Seite für die betroffenen Regionen Bedingungen integrieren:
:P1_FLASH = 'TRUE'

Das Ganze könnte auch ein schönes kleines Plug-in sein! :D
APEX-AT-WORK no image

Two ways using string to table in APEX selects

Von Tobias Arnhold → 5.03.2011
First way
This example uses "REGULAR expressions" and the "connect by" clause. Perfect when you select on columns including lists.
Forum entry: http://forums.oracle.com/forums/thread.jspa?messageID=9494074

WITH TABLE1
AS (SELECT 1 my_id, '8092:7054:9237:4232:3333:4023:6781' my_list FROM DUAL
UNION
SELECT 2, '8765:2231:2242:3412:3453' FROM DUAL
UNION
SELECT 3, '2121' FROM DUAL
UNION
SELECT 4, '6565:9121' FROM DUAL)
SELECT my_id,REGEXP_SUBSTR ( my_list, '([^:]+)', 1, lvl)
FROM TABLE1,
(SELECT LEVEL lvl
FROM (SELECT MAX (LENGTH (REGEXP_REPLACE ( my_list || ':', '[^:]'))) mx
FROM TABLE1)
CONNECT BY LEVEL <= mx + 1)
WHERE lvl - 1 <= LENGTH (REGEXP_REPLACE ( my_list || ':', '[^:]'))
AND REGEXP_SUBSTR ( my_list, '([^:]+)', 1, lvl) IS NOT NULL
ORDER BY my_id,lvl;


Second way
This example is based on a nice XML solution. Only needs two lines of code. Easy to use in combination with variables.
Forum entry; http://forums.oracle.com/forums/thread.jspa?threadID=2184251&tstart=0&messageID=9406487

:F_STRING := '8092:7054:9237:4232:3333:4023:6781'

select upper(extractvalue(column_value,'e'))
from table(xmlsequence(xmltype('' || replace(:F_STRING,':','') || '').extract('e/*')));
APEX-AT-WORK no image

ORA-00001, WWV_FLOW_DATA_IDX1, ERR-1029

Von Tobias Arnhold → 4.13.2011
Troubleshooting the following APEX error:

ORA-00001: unique constraint (APEX_040000.WWV_FLOW_DATA_IDX1) violated
ERR-1029 Speichern von Sessioninformationen nicht möglich. session=3642920897355064 item=9815904291046405

This issue often comes in combination with iFrames, item computations, different languages or collections.

First you need to find which item is effected:

Inside APEX Application Builder > Application xxx > Utilities > Application Express Views > APEX_APPLICATION_PAGE_ITEMS
Columns: Select all columns
Filter: Item_ID = 9815904291046405
Copy the generated select and execute it inside your SQL Developer:

select WORKSPACE,APPLICATION_ID,APPLICATION_NAME,PAGE_ID,PAGE_NAME,ITEM_NAME,DISPLAY_AS,DISPLAY_AS_CODE,ITEM_DATA_TYPE,IS_REQUIRED,STANDARD_VALIDATIONS,DISPLAY_SEQUENCE,REGION,REGION_ID,SOURCE_USED,ITEM_DEFAULT,ITEM_DEFAULT_TYPE,LABEL,PRE_ELEMENT_TEXT,POST_ELEMENT_TEXT,FORMAT_MASK,ITEM_LABEL_TEMPLATE,ITEM_LABEL_TEMPLATE_ID,ITEM_SOURCE,ITEM_SOURCE_TYPE,ENCRYPT_SESSION_STATE,SOURCE_POST_COMPUTATION,READ_ONLY_CONDITION_TYPE,READ_ONLY_CONDITION_EXP1,READ_ONLY_CONDITION_EXP2,READ_ONLY_DISPLAY_ATTR,LOV_NAMED_LOV,LOV_DEFINITION,LOV_DISPLAY_EXTRA,LOV_DISPLAY_NULL,LOV_NULL_TEXT,LOV_NULL_VALUE,LOV_QUERY_RESULT_TRANSLATED,LOV_CASCADE_PARENT_ITEMS,AJAX_ITEMS_TO_SUBMIT,AJAX_OPTIMIZE_REFRESH,ITEM_ELEMENT_WIDTH,ITEM_ELEMENT_MAX_LENGTH,ITEM_ELEMENT_HEIGHT,HTML_TABLE_CELL_ATTR_LABEL,HTML_TABLE_CELL_ATTR_ELEMENT,HTML_FORM_ELEMENT_ATTRIBUTES,FORM_ELEMENT_OPTION_ATTRIBUTES,ITEM_BUTTON_IMAGE,ITEM_BUTTON_IMAGE_ATTRIBUTES,BEGINS_ON_NEW_ROW,BEGINS_ON_NEW_CELL,COLUMN_SPAN,ROW_SPAN,LABEL_ALIGNMENT,ITEM_ALIGNMENT,SHOW_QUICK_PICKS,QUICK_PICK_LINK_ATTR,QUICK_PICK_LABEL_01,QUICK_PICK_VALUE_01,QUICK_PICK_LABEL_02,QUICK_PICK_VALUE_02,QUICK_PICK_LABEL_03,QUICK_PICK_VALUE_03,QUICK_PICK_LABEL_04,QUICK_PICK_VALUE_04,QUICK_PICK_LABEL_05,QUICK_PICK_VALUE_05,QUICK_PICK_LABEL_06,QUICK_PICK_VALUE_06,QUICK_PICK_LABEL_07,QUICK_PICK_VALUE_07,QUICK_PICK_LABEL_08,QUICK_PICK_VALUE_08,QUICK_PICK_LABEL_09,QUICK_PICK_VALUE_09,QUICK_PICK_LABEL_10,QUICK_PICK_VALUE_10,ATTRIBUTE_01,ATTRIBUTE_02,ATTRIBUTE_03,ATTRIBUTE_04,ATTRIBUTE_05,ATTRIBUTE_06,ATTRIBUTE_07,ATTRIBUTE_08,ATTRIBUTE_09,ATTRIBUTE_10,CONDITION_TYPE,CONDITION_EXPRESSION1,CONDITION_EXPRESSION2,MAINTAIN_SESSION_STATE,ITEM_PROTECTION_LEVEL,ESCAPE_ON_HTTP_OUTPUT,AUTHORIZATION_SCHEME,AUTHORIZATION_SCHEME_ID,BUILD_OPTION,BUILD_OPTION_ID,ITEM_HELP_TEXT,LAST_UPDATED_BY,LAST_UPDATED_ON,COMPONENT_COMMENT,ITEM_ID,COMPONENT_SIGNATURE
from APEX_APPLICATION_PAGE_ITEMS
where ITEM_ID = 9815904291046405


Investigate the effected item... You may find strange connections to other APEX components?

Forum entry: http://forums.oracle.com/forums/thread.jspa?messageID=9365663
APEX-AT-WORK no image

Handling the 32k problem in APEX charts

Von Tobias Arnhold → 4.03.2011
How to handle more then 32k (32768) characters inside your APEX charts: AnyChart gantt with custom xml and more then 32k

Workaround:

- Create your own chart

Info:
- AnyChart documentation: Set XML As String From TextArea

HTML Header:http://www.blogger.com/img/blank.gif

<script src="#APP_IMAGES#anychart_intkit.js" language="javascript"></script>

PL/SQL Region:

/* ... */
htp.p('<textarea cols="65" rows="17" id="rowData" style="display:none;">');

/* Write CLOB through a package function */
P_CLOB := MY_PACKAGE.F_APEX_GANTT_COMPLETE ( P_USER );

dbms_lob.open(P_CLOB, dbms_lob.lob_readonly);

P_LENGTH := dbms_lob.getlength (P_CLOB);

while P_LENGTH > 0 loop

/* Read 32000 characters from CLOB */
dbms_lob.read(P_CLOB, P_CLOB_BUFFER, P_POS, P_SET);

/* Write code in APEX */
htp.prn(P_SET);

/* Increase Counter */
P_POS := P_POS + P_CLOB_BUFFER;
P_LOOP := P_LOOP + 1;

/* Resize CLOB length */
P_LENGTH := P_LENGTH - P_CLOB_BUFFER;

end loop;

dbms_lob.close(P_CLOB);

htp.p('</textarea>');
htp.p('<div id="chartDiv"></div>');

htp.p(
'<script type="text/javascript" language="javascript">' || chr(10) ||
'/* Set default swf path */' || chr(10) ||
'AnyChart.swfFile = ''/i/flashchart/anygantt_4/swf/AnyGantt.swf'';' || chr(10) ||
'/* Create new gantt chart */' || chr(10) ||
'var chart = new AnyChart();' || chr(10) ||
'chart.width="2500";' || chr(10) ||
'chart.height="1400";' || chr(10) ||
'/* Get string data from text area */' || chr(10) ||
'var data = document.getElementById(''rowData'').value.toString();' || chr(10) ||
'/* Set data */' || chr(10) ||
'chart.setData(data);' || chr(10) ||
'/* Write chart to "chart" div */' || chr(10) ||
'chart.write("chartDiv");' || chr(10) ||
'</script>');
/* ... */


I created a region plug-in based on the above code to handle the huge charts! :)
APEX-AT-WORK no image

Remove delete icon in SkillBuilders Super LOV

Von Tobias Arnhold → 3.25.2011
Do you like the Super LOV as much as I do? It is just a great plug-in.

Some customers didn't like the delete button to erase the selected value. I could not find any setting to disable this icon.

Workaround:
Add a dynamic action "after page load" which executes some javascript with this little piece of code:
$('.superlov-modal-delete').remove();

That's it.

Customize Interactive report header graphic

Von Tobias Arnhold → 3.22.2011
Create a new image called report_bg_red.gif:

Add this inside your page header to exchange the IRR default image:

.apexir_WORKSHEET_DATA th {
background: url("/i/my_images/ir_styles/report_bg_red.gif") repeat-x scroll 0 0 #AAAAAA;
}

Change "/i/my_images/" with your image directory.

If you want to customize even more CSS watch this blog post of Shakeeb Rahman: http://apex.shak.us/post/1145946801/fully-control-your-interactive-reports-toolbar
APEX-AT-WORK no image

SQL: Count character in column or string

Von Tobias Arnhold → 3.21.2011
Use this sql select to count a special character inside a column or string:

Column selection:

select col, length(col)-length(replace(col,',',''))
from
(select 'col1,col2,col3,col4' as col from dual);

COL LENGTH(COL)-LENGTH(REPLACE(COL,',',''))
------------------- ---------------------------------------
col1,col2,col3,col4 3

String selection

BEGIN
:P1_STRING := 'col1,col2,col3,col4';

select length(:P1_STRING)-length(replace(:P1_STRING,',','')) into :P1_CHAR_CNT from dual;
END;


Watch this thread on Ask Tom: http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:55423584511523
APEX-AT-WORK no image

APEX bug with APEX_ITEM and POPUPKEY_FROM_LOV

Von Tobias Arnhold → 3.17.2011
Try to set two POPUPKEY_FROM_LOVs beside each other with the column ids: 2,3

select
APEX_ITEM.CHECKBOX (1,ac.ac_id) as ac_id,
APEX_ITEM.POPUPKEY_FROM_LOV(2,ac.application_key,'lov_apps',50) as application,
APEX_ITEM.POPUPKEY_FROM_LOV(3,ac.system_key,'lov_systems',50) as system
from app_conf ac;

When you run the page then APEX automatically creates a hidden field for the return value of the "popup lov".

The output looks like that:
column "application": Return column id = 2, Display column id = 3
column "system": Return column id = 3, Display column id = 4

If you set a value for column "system" it saves the "return value" in the "display value"-field of column "application".

Workaround: Use at least two numbers in between to avoid this behavior:

select
APEX_ITEM.CHECKBOX (1,ac.ac_id) as ac_id,
APEX_ITEM.POPUPKEY_FROM_LOV(2,ac.application_key,'lov_apps',50) as application,
APEX_ITEM.POPUPKEY_FROM_LOV(4,ac.system_key,'lov_systems',50) as system
from app_conf ac;

New plug-in "Add favorite"

Von Tobias Arnhold → 3.16.2011
Have you ever looked for a solution to create an "add favorite"-button which let the user bookmark your website. You probably found out that each browser uses an own solution for it. I put it all into a nice little dynamic action plug-in. It supports to load only the "add favorite"-function, bookmark the current APEX page, bookmark any other page you define through the plug-in.

Supported browsers: MS Internet Explorer, Firefox, Opera

Demo: http://apex.oracle.com/pls/otn/f?p=65560:ADD_FAVORITE



I'm still working on the demo and will release all new plug-ins in the next couple of weeks. For all who want those plug-ins before the release then refer to this post: How can we help Japan?

Tobias
APEX-AT-WORK no image

How can we help Japan?

Von Tobias Arnhold → 3.12.2011
To help the suffering people of Japan my applications from now on "cost" a donation (no matter how small or big) via any aid organisation of Your own choice. All You APEX users who are interested in my plug-in example application just have to send me an e-mail (tobias-arnhold@hotmail.de) including a confirmation of Your donation and You are able to get the export of the application "for free". I hope You have understanding and will do this small effort. I am very greatful for Your cooperation.

Plug-in example application: http://apex.oracle.com/pls/otn/f?p=65560:DONATE_TO_JAPAN

The example application also includes the new "Icon Loader" Plug-in

The plug-in will soon be released.

Info: The application can not be downloaded anymore from my workspace on apex.oracle.com

If you want to then feel free to follow my example and either develope your own "donation for application" -site or you can get access to my workspace "APEX_PLUGINS" and integrate your plug-ins there. I will buy it ;O)
APEX-AT-WORK no image

Range Slider Plug-in for APEX?

Von Tobias Arnhold → 3.08.2011
I'm a bit surprised that there is no range slider plug-in for APEX yet. At least I couldn't find one.

There are a couple of nice examples out there in the wild. I'm curios if somebody of you uses such a plug-in in APEX or is developing a plug-in right now?

I saw one blog entry from Paul Brookes: http://peekbee.blogspot.com/2010/02/range-slider-plugin.html
But the plug-in seems not to be released on: http://www.apex-plugin.com/

List of nice slider solutions:
http://www.paciellogroup.com/blog/misc/samples/aria/slider/doubleslider.html
http://jqueryui.com/demos/slider/#range
http://www.noupe.com/javascript/30-javascriptajax-techniques-for-sliders-scrollers-and-scrollbars.html

I also started a forum entry about it:
http://forums.oracle.com/forums/thread.jspa?threadID=2187679&tstart=0

I will let you know if I here anything about it.
APEX-AT-WORK no image

Es sind die kleinen Dinge, die APEX 4 so viel besser machen

Von Tobias Arnhold → 3.07.2011
Ich habe heute eine Frage im APEX Forum beantwortet. Diese recht trivial klingt, aber in der Konstellation doch recht anspruchsvoll wurde.

Ausgangslage:
Ein Entwickler hat zwei Textfelder: P1_FIELD_A, P1_FIELD_B und beide Felder sind im DATE-Format.
Wenn er das Feld P1_FIELD_A verlässt, dann soll das Feld P1_FIELD_B den Wert von P1_FIELD_A erhalten und diesen Wert automatisch um 1 Jahr erhöhen.

Wie gesagt es klingt recht einfach, sofern Sie PL/SQL verwenden dürfen und APEX 4.0 im Einsatz haben!

Kreieren Sie eine Dynamic Action > "Erweitert" > Event: "Lose Focus" > Item: P1_FIELD_A

TRUE Action: "Set Value" > Set Type: "PL/SQL Expression" >
Code: to_char(add_months(to_date(:P1_FIELD_A,'DD.MM.YYYY'),12),'dd.mm.yyyy')
Page Items to Submit: P1_FIELD_A

Affected Elements: Items > Item: P1_FIELD_B

Mit APEX 3 sah das noch ganz anders aus!
Statt einfach auf eine PL/SQL Funktion zugreifen zu können, musste diese über Javascript als Application Prozess eingebunden werden. Statt 5 Klicks brauchten Sie 20 Zeilen Code der an verschiedenen Stellen lag.
Ich habe die Aufgabe versucht mit Javascript zu lösen. Verdammt unschön und aufwendig so ganz ohne PL/SQL:

Dazu müssen Sie dem Element P1_FIELD_A folgenden Code unter "HTML Form Element Attributes" zuweisen:

onblur="javascript:fnc_field_b(this)"

Und im Page Header folgte dieser JS Code:

<script>
function fnc_field_b(v_field_a){
/* Input: mm/dd/yyyy */
/* Output: dd.mm.yyyy */
/* Documentation: http://www.javascriptkata.com/2007/04/27/mastering-of-the-date-object-in-javascript/ */
/* http://programming.top54u.com/post/Javascript-Convert-String-to-Date.aspx */

/* Create date object */
var myDate = new Date(v_field_a.value);

/* Add 1 year */
myDate.setDate(myDate.getDate() + 365);

/* Create output string DD.MM.YYYY */
/* Day */
var myStr = (myDate.getDate() < 10 ? "0" + myDate.getDate().toString() : myDate.getDate().toString()) + ".";
/* Month */
myStr = myStr + (myDate.getMonth()+1 < 10 ? "0" + (myDate.getMonth()+1).toString() : (myDate.getMonth()+1).toString()) + ".";
/* Year */
myStr = myStr + myDate.getFullYear().toString();

/* Set value */
$s('P1_FIELD_B',myStr);
}

Dabei ist dieser Code noch nicht einmal inhaltlich vollständig. Javascript kann nur das Format mm/dd/yyyy direkt in Date umwandeln.
Ok und diese:
* MM-dd-yyyy
* yyyy/MM/dd
* MM/dd/yyyy
* MMMM dd, yyyy
* MMM dd, yyyy
Unser beliebtes dd.mm.yyyy ist nicht dabei. Also müsste man dieses via ein paar ausgefeilten String-Funktionen noch umwandeln und unter Umständen noch eine Regular Expressions zum Fehlerhandling hinzufügen.
Javascript unterstützt auch nicht die to_char-Funktion. Weshalb ein recht komplexer Script zu umwandeln benötigt wird. Das Gute an JS ist, dass es unzählige Beispiele im Netz gibt.
Weshalb dieser Part recht einfach zu lösen war (http://www.javascriptkata.com/2007/04/27/mastering-of-the-date-object-in-javascript/).

Nur zur Info: Die meisten anderen Web-Entwickler haben kennen keine Dynamic Action Logik bzw. kennen kein PL/SQL.

Das zeigt nur im kleinem Beispiel warum die Entwicklung von APEX Anwendungen so schnell geht.
Ich vergleiche das immer mit Oracle Forms und Oracle Java Alternativen dazu. Wieso tief in den Programmierschichten graben wenn das Leben doch so leicht sein kann. :)

Den Forum Beitrag finden Sie hier: http://forums.oracle.com/forums/thread.jspa?threadID=2186734&tstart=0

Hide Interactive Report filter dynamically after page load

Von Tobias Arnhold → 2.28.2011
To hide IRR filters always after the page load just use this little JS code inside a dynamic action (event: "Page Load")

/* Hide IRR filter after page load*/
if( $('#apexir_CONTROLS_IMAGE').attr("src") == '/i/minus.gif') {
gReport.toggle_controls($x('apexir_CONTROL_PANEL_CONTROL'));
}

Result:

Interactive Report Header problem with multiple lines

Von Tobias Arnhold →
There is a bug/misbehavior inside the IRR column headers in APEX 4. When you create column names with linebreaks (using the <br> tag) inside then the background color changes to a grey background on the second line.
Workaround: Add this script to your IR region header:
<style>
/* IRR Header Fix */
.apexir_WORKSHEET_DATA th{background-color:#828282!important;}
</style>


Bug view:

Fixed view:


There is a forum entry as well: http://forums.oracle.com/forums/thread.jspa?threadID=1981024
APEX-AT-WORK no image

ORA-20503 im APEX Application Builder

Von Tobias Arnhold → 2.25.2011
Falls Sie auf den Fehler ORA-20503 während der Arbeit im APEX Application Builder treffen, dann wird ihnen dieser Blogeintrag hoffentlich viel Ärger ersparen.

Beispielfälle:

ORA-20503: Die aktuelle Version der Daten in der Datenbank wurde geändert, seit der Benutzer einen Updateprozess eingeleitet hat. Aktuelle Prüfsumme (Checksum) = "CE59A26EB14199C787195DCC947CFC04" Anwendungs-Prüfsumme (Checksum) = "8D8F85130213A161B73628D3D0B3F56E" Zeile der Tabelle WWV_FLOW_FEEDBACK konnte nicht verarbeitet werden.



ORA-20503: Die aktuelle Version der Daten in der Datenbank wurde geändert, seit der Benutzer einen Updateprozess eingeleitet hat. Aktuelle Prüfsumme (Checksum) = "076BC396EB2BA9DEF778E5B684CFA2B5" Anwendungs-Prüfsumme (Checksum) = "3EF59F3E445142B8A971E94C9FFABB59" Fehler beim Verarbeiten von Zeile.

Wahrscheinlich haben Sie mehrere Sprachen in ihrer APEX Umgebung installiert. Beispielsweise: Englisch, Deutsch.

Nun gibt es in APEX 4.0 das Phänomen, dass während der Laufzeit sich die Sprache im Application Builder von Englisch auf Deutsch einfach ändert,
obwohl unter "Home" Englisch als Sprache eingestellt ist.
Der Grund des Problems liegt wohl an ihrer eingestellten "Browser Language", die für gewöhnlich auf Deutsch eingestellt ist.

In diesem Zusammenhang kommt der ORA-20503 Fehler zustande. Ich denke das dies ein Bug in der aktuellen Version ist.
Es ist recht einfach diesen Fehler zu beheben:
- Melden Sie sich am APEX Application Builder an.
- Unter "Home" Startseite (1000) können Sie am rechten Seitenrand die Sprache einstellen "Language"
- Stellen Sie die Sprache auf "Deutsch" um
- Gehen Sie in das Item (bzw. in den fehlerhaften Bereich) und speichern Sie dieses erneut ab.
- Es sollte alles funktionieren!
- Alternativ können Sie auch jederzeit mit einem alternativen Browser die Daten abspeichern, der Fehler bleibt aber in ihrem Standardbrowser existent.

Bei mir trat dieser Fehler bisher nur im Firefox auf. Ich entwickle allerdings auch nur ausschließlich in diesem. :)

Ich hoffe die Sprachsteuerung wird in APEX 4.1 etwas verbessert, so dass weder der ORA-20503 auftritt noch sich einfach die Umgebungssprache ändert.

In den folgenden Forum Beiträgen finden Sie weitere Informationen zum Fehler:
http://forums.oracle.com/forums/thread.jspa?messageID=9299655
http://forums.oracle.com/forums/thread.jspa?messageID=9368275
APEX-AT-WORK no image

Clear the page cache with PL/SQL

Von Tobias Arnhold → 2.24.2011
I just stumbled into a problem where I needed to clear the page cache inside an APEX PL/SQL process.

It is quite easy if you know how:

APEX_UTIL.CLEAR_PAGE_CACHE (160);

-- APEX_UTIL.CLEAR_PAGE_CACHE (
-- p_page IN NUMBER DEFAULT NULL);
-- Description: This procedure removes session state for a given page for the current session.


There are two other similar functions:
CLEAR_APP_CACHE, CLEAR_USER_CACHE

For more information watch the documentation for APEX_UTIL:
http://download.oracle.com/docs/cd/E10513_01/doc/apirefs.310/e12855/apex_util.htm#BABCIAFJ
APEX-AT-WORK no image

Freeze panes example

Von Tobias Arnhold → 2.23.2011
Just saw the nice looking freeze panes example of Andy (ATD) in the Oracle APEX forum.
It is to good to not being mentioned.

Example:
http://apex.oracle.com/pls/otn/f?p=267:47

For more information about the implementation watch this forum post:
http://forums.oracle.com/forums/thread.jspa?threadID=2180543
APEX-AT-WORK no image

Sichere URLs mit einem Application Process erstellen

Von Tobias Arnhold → 2.15.2011
Wenn Sie eine APEX Anwendung mit Session State Protection verwenden, dann muss jeder Request entsprechend ihrer Einstellungen mit einem sicheren Hash-Schlüssel versendet werden. Wie Sie dies während der Laufzeit mit einem Application Process erstellen können, beschreibt dieser Artikel:

Was ist Session State Protection und für was brauch ich diese Funktion in APEX Anwendungen?
SSP schützt vor dem manuellen ändern der Browser URL durch den Endbenutzer, so dass dieser nicht einfach eine falsche ID abfragen oder beliebige Page-/Applikations-Variablen während der Laufzeit ändern kann.
- SSP muss explizit über Shared Components > Session State Protection aktiviert werden.
- SSP kann für jede Seite und jedes Item individuell definiert werden.
- SSP macht die Entwicklung nicht einfacher aber wesentlich sicherer.
- SSP schützt nicht automatisch vor allen feindlichen Attacken gegen eine APEX Anwendung.

Alles wichtige rund um SSP finden Sie in der APEX Dokumentation:
http://download.oracle.com/docs/cd/E17556_01/doc/user.40/e15517/sec.htm#HTMDB12002

Ein paar nützliche Links zum Thema SSP und APEX Sicherheit allgemein:
http://www.oracle.com/global/de/community/tipps/securitytipps/index.html
http://www.talkapex.com/2009/05/apex-page-access-protection-and-session.html
http://dgielis.blogspot.com/2007/03/session-state-protection-and-url.html
http://apps2fusion.com/at/64-kr/400-preventing-url-tampering-using-apex-session-state-protection

Im Normalfall generiert APEX sichere URL's automatisch, sobald SSP aktiviert wurde. Leider ist dies in Verbindung mit manuell erstelltem Code nicht der Fall. Um eigene sichere URL's zu definieren, müssen Sie die URL mit der PL/SQL Funktion apex_util.prepare_url validieren und Sie erhalten die sichere URL als Rückgabewert. Dies funktioniert exzellent bei dynamisch erstelltem PL/SQL Code. Wenn Sie dies über eine Javascript Funktion verwenden möchten, dann brauchen Sie entweder eine Dynamic Action oder einen Application Process Aufruf, der ihnen die sichere URL zurück liefert. Ein Beispielfall könnte ein dynamischer Javascript Baum sein, dieser zur Seiten-Navigation verwendet wird. Die Baum-Daten würden via AJAX dynamisch nachgeladen werden. Bsp: ExtJS in APEX
(Dieses Beispiel zeigt nur ein mögliches Szenario, es enthält kein SSP und kein AJAX.)

Die Frage ist nun: Wie bauen Sie solch einen Prozess!?

Fügen Sie diesen Code ihrem Javascript Prozess hinzu:

/* Call Application Process um eine Secure URL zu erstellen */
v_no_sec_url = 'f?p=25500:8:3521997579041922::NO::P8_E_ID:131'
/* Statt der dargestellten URL wuerden Sie eine Javascript Variable verwenden, diese die URL enthaelt. */

/* Aufruf eines Application Prozess ueber Javascript: http://www.packtpub.com/article/ajax-implementation-apex */
var v_get_sec_url = new htmldb_Get(null, $v('pFlowId'),'APPLICATION_PROCESS=AP_SECURE_URL', $v('pFlowStepId'));

/* Uebergabe Parameter 1 und 2 definieren */
v_get_sec_url.addParam('x01',v_no_sec_url);
v_get_sec_url.addParam('x02','SESSION');

v_sec_url = v_get_sec_url.get(); /* Uebergebe APEX Wert an Javascript Variable */
/* alert(v_sec_url); */

window.location.href = v_sec_url /* Seite mit neuem HREF aktualisieren */

Nun definieren Sie den Application Process - AP_SECURE_URL:

DECLARE
v_part1 varchar2(100);
v_part2 varchar2(1000);
v_url varchar2(1200);
BEGIN
/* Teile URL */
v_part1 := substr(wwv_flow.g_x01,1,instr(wwv_flow.g_x01,'f?p')-1);
v_part2 := substr(wwv_flow.g_x01,instr(wwv_flow.g_x01,'f?p'));

/* Erstelle sichere URL */
/* Hilfe: http://apex.oracle.com/i/doc/AEAPI/apex_util074.htm */
v_url := APEX_UTIL.PREPARE_URL(p_url => v_part2,
p_checksum_type => wwv_flow.g_x02);

/* Return mit Teil 1 und Secure URL */
htp.p(v_part1 || v_url);
END;

Die erstellte URL ist aber nur die halbe Miete. Für jeden AJAX Call (Bsp: Klick auf Baum Subeinträge) muss sichergestellt werden, dass der Endbenutzer die übergebenen Parameter auch wirklich verwenden darf.
Deswegen müssen Sie ein oder mehrere Validierungs-Checks in die Prozedur integrieren:

DECLARE
v_part1 varchar2(100);
v_part2 varchar2(1000);
v_sec_url varchar2(1200);

/* Parameter fuer eigene URL Validierung */
v_url_validation number;
v_url_parameter varchar2(200);
v_url_page varchar2(10);
BEGIN
/* Teile URL */
v_part1 := substr(wwv_flow.g_x01,1,instr(wwv_flow.g_x01,'f?p')-1);
v_part2 := substr(wwv_flow.g_x01,instr(wwv_flow.g_x01,'f?p'));

/* Wichtig: Individuelle URL Validierung fuer uebergebene Parameter */
/* ----------------------------------------------------------------------- */
v_url_parameter := substr(v_part2,
instr(v_part2,':',1,7)+1
);
v_url_page := substr(v_part2,
instr(v_part2,':',1,1)+1,
instr(v_part2,':',1,2)-instr(v_part2,':',1,1)-1
);

if (v_url_parameter in (10,20,30,40,50)
and v_url_page = 10)
or (v_url_parameter in (60,70,80,90,100)
and v_url_page = 10
and :APP_USER = 'TARNHOLD')
then
v_url_validation := 1;
else
v_url_validation := 0;
end if;
/* ----------------------------------------------------------------------- */

if v_url_validation = 1 then
/* Wenn OK, dann erstelle sichere URL */
/* Hilfe: http://apex.oracle.com/i/doc/AEAPI/apex_util074.htm */
v_sec_url := APEX_UTIL.PREPARE_URL(p_url => v_part2,
p_checksum_type => wwv_flow.g_x02);

/* Return mit Teil 1 und Secure URL */
htp.p(v_part1 || v_sec_url);
else
/* Bei Validierungsfehlern (falsche Parameter) auf Anmeldeseite verlinken */
htp.p(v_part1 || 'f?p=' || :APP_ID || ':101');
end if;
EXCEPTION
WHEN OTHERS THEN
/* Bei unbekannten Fehler auf Anmeldeseite verlinken */
htp.p(v_part1 || 'f?p=' || :APP_ID || ':101');
END;

Solch eine Prozedur muss alle nicht erlaubten Fremdeingaben abfangen, um die Sicherheit in ihrer Anwendung zu gewährleisten.
Deswegen zeige ich ihnen eine noch sicherere Beispiel-Prozedur, damit eine mögliche Risikominimierung für feindliche Attacken und der Aufwand dessen deutlich wird, der für eine solche Prozedur notwendig ist:

DECLARE
v_part1 varchar2(100);
v_part2 varchar2(1000);
v_sec_url varchar2(1200);

/* Parameter fuer eigene URL Validierung */
v_url_validation number;
v_url_app varchar2(100);
v_url_page varchar2(100);
v_url_request varchar2(100);
v_url_debug varchar2(3);
v_url_clearcache varchar2(100);
v_url_param_name varchar2(200);
v_url_param_val varchar2(200);
-- v_url_printer varchar2(200);
BEGIN
/* Teile URL */
v_part1 := substr(wwv_flow.g_x01,1,instr(wwv_flow.g_x01,'f?p')-1);
v_part2 := substr(wwv_flow.g_x01,instr(wwv_flow.g_x01,'f?p'));

/* Wichtig: Individuelle URL Validierung fuer uebergebene Parameter */
/* ----------------------------------------------------------------------- */
v_url_app := substr(v_part2,
instr(v_part2,'=',1,1)+1,
instr(v_part2,':',1,1)-instr(v_part2,'=',1,1)-1
);
v_url_page := substr(v_part2,
instr(v_part2,':',1,1)+1,
instr(v_part2,':',1,2)-instr(v_part2,':',1,1)-1
);
v_url_request := substr(v_part2,
instr(v_part2,':',1,3)+1,
instr(v_part2,':',1,4)-instr(v_part2,':',1,3)-1
);
v_url_debug := substr(v_part2,
instr(v_part2,':',1,4)+1,
instr(v_part2,':',1,5)-instr(v_part2,':',1,4)-1
);
v_url_clearcache := substr(v_part2,
instr(v_part2,':',1,5)+1,
instr(v_part2,':',1,6)-instr(v_part2,':',1,5)-1
);
v_url_param_name := substr(v_part2,
instr(v_part2,':',1,6)+1,
instr(v_part2,':',1,7)-instr(v_part2,':',1,6)-1
);
v_url_param_val := substr(v_part2,
instr(v_part2,':',1,7)+1
);
/* TEST
htp.p( 'v_url_app: ' || v_url_app || ' ,v_url_page: ' || v_url_page || ' ,v_url_request: ' || v_url_request
|| ' ,v_url_debug: ' || v_url_debug || ' ,v_url_clearcache: ' || v_url_clearcache
|| ' ,v_url_param_name: ' || v_url_param_name || ' ,v_url_param_val: ' || v_url_param_val
);
*/

if v_url_app IN (:APP_ID,:APP_ALIAS)
AND v_url_request is null
AND v_url_debug = 'NO'
AND (
v_url_page IN ('1','2','3','4','5')
and v_url_param_name is null
and v_url_param_val is null
OR v_url_page = '10'
and v_url_param_name IN ('P10_MFD_ID')
and v_url_param_val IN (1,14,15,16,17,19) /* Koennte auch ein Sub Select sein*/
and length(v_url_param_val)-length(replace(v_url_param_val,',','')) = 0
OR v_url_page = '20'
and v_url_clearcache = '20'
and v_url_param_name IN ('P20_KLT_ID')
and v_url_param_val IN (100,200,300,400,500,600) /* Koennte auch ein Sub Select sein*/
and length(v_url_param_val)-length(replace(v_url_param_val,',','')) = 0
OR v_url_page = '30'
and v_url_clearcache = '30'
and v_url_param_name IN ('P30_KLS_ID,P30_KLS_PAR1')
and substr(v_url_param_val,1,instr(v_url_param_val,',')-1) IN (1000,2000,3000,4000,5000,6000)
and length(v_url_param_val)-length(replace(v_url_param_val,',','')) = 1
)
then
v_url_validation := 1;
else
v_url_validation := 0;
end if;
/* ----------------------------------------------------------------------- */

if v_url_validation = 1 then
/* Wenn OK, dann erstelle sichere URL */
/* Hilfe: http://apex.oracle.com/i/doc/AEAPI/apex_util074.htm */
/* Der Parameter: p_checksum_type sollte fest über die Prozedur gesteuert werden */
v_sec_url := APEX_UTIL.PREPARE_URL(p_url => v_part2,
p_checksum_type => 'SESSION');

/* Return mit Teil 1 und Secure URL */
htp.p(v_part1 || v_sec_url);
else
/* Bei Validierungsfehlern (falsche Parameter) auf Anmeldeseite verlinken */
htp.p(v_part1 || v_part2);
-- htp.p(v_part1 || 'f?p=' || :APP_ID || ':101');
end if;
EXCEPTION
WHEN OTHERS THEN
/* Bei unbekannten Fehler auf Anmeldeseite verlinken */
htp.p(v_part1 || 'f?p=' || :APP_ID || ':101');
END;

Was schließt man daraus: Schönheit kann ganz schön teuer (aufwendig) werden. :) Wer hätte das gedacht.

Fazit: Die Verwendung von SSP mit Standard APEX Funktionalität bietet ohne großes Wissen die meiste Sicherheit. Bei der Verwendung von eigenen Erweiterungen, muss auf die oben beschriebenen Sicherheitsaspekte Wert gelegt werden. Deswegen ist es auch von Vorteil solche Erweiterungen in Plug-Ins auszulagern. Mehr Infos dazu erhalten Sie in meinem letzten APEX Community Beitrag: HowTo: APEX 4.0 Dynamic Action Plugins

Wenn Sie Unterstützung bei APEX Security Themen benötigen, dann können Sie sich natürlich immer an mich (Tobias Arnhold - tobias-arnhold@hotmail.de) wenden. Ein wahrer Kenner auf dem Gebiet "APEX Security" ist Denes Kubicek, dieser auch spezielle Schulungen zum Thema APEX anbietet.
APEX-AT-WORK no image

UILayout: Hide half loaded elements

Von Tobias Arnhold → 2.14.2011
One of the problems of an layout extension is the initialization time.
Normally the UILayout needs a couple of seconds to initialize (1-3). Depending on your server connection, your client hardware and your browser (IE6 is slow, FF 3.6 is fast).

To show a similar loading frame like the ExtJS Loading Icon http://apex.oracle.com/pls/apex/f?p=65555:1 use this trick:

Add the following code to the beginning of your Page Template Body or add a new HTML region (No template) on page 0:

<div style="width: 100%; height: 100%; position: absolute; left: 0pt; top: 0pt; background-color: rgb(255, 255, 255); z-index: 4000; opacity: 0.8; display: block;" id="loadingBackground">
<div style="height: auto;left: 50%;position: absolute;top: 50%;text-align: center; color: #555555;font-size: 18px;font-family:Arial,Helvetica,Geneva,sans-serif;padding:8px;42px;"> ... Loading ... </div>
</div>


After the initialization of the UILaoyut plug-in use the LoadingIcon plug-in with the option "Stop LoadingIcon"

The initialization feels much smoother now.

Example: http://apex.oracle.com/pls/apex/f?p=AAW_PLUGINS:UILAYOUT_PLUGIN
APEX-AT-WORK no image

Hide/Show APEX items and labels with jQuery

Von Tobias Arnhold → 2.02.2011
To hide or show items and labels with jQuery use this syntax:

$('#P1_NAME').hide();
$('#P1_NAME').parent().hide();
$('#P1_COMPANY').show();
$('#P1_COMPANY').parent().show();

Update 06.02.2011:
Peter mentioned right that this example only works when your item label is set to above!

Short way:

$('#P1_NAME').hide().parent().hide();
$('#P1_COMPANY').show().parent().show();

@Jaydip
"I want to remove those hidden item space. Is it possible by using your method?" - No
I guess you would need to move these hidden items to another place and move them back when they are not hidden. With jQuery you could use appendTo(). I don't know if it works or not? But you would need ID's for your regions.
APEX-AT-WORK no image

UILayout plug-in for APEX updated to version 1.2

Von Tobias Arnhold → 1.30.2011
What's new:
- New plug-in for the styling of the UILayout. Styling is now completely supported by either the plug-in or your own CSS files.
- Bug fixes and small improvements inside the initialization plug-in.

Example application: http://apex.oracle.com/pls/apex/f?p=65560:1

Here is the complete documentation:


Update 09.02.2011:
Just released version 1.2.1 which includes some bug fixes for the initialization part.
- APEX had some issues because the div elements were out of the form element.
- Radio button just moved to next then icon when you refreshed the page. Without changing the radio item.

You can download the current version here: UILayout plug-in for APEX 1.2.1 - www.apex-plugin.com/
APEX-AT-WORK no image

UILayout Plug-in update is online

Von Tobias Arnhold → 1.22.2011
A new version of the UILayout plug-in for APEX is online on www.apex-plugin.com: UILayout 1.1 - Update

I added a couple of features. Like sizing, disabling of areas, Dynamic actions during runtime, IR Bug - Solution,...

Hope for some feedback.

Tobias

UILayout Plugin Design Issues

Von Tobias Arnhold → 1.09.2011
I finished the first part of the UILayout Plug-in. For me it is the first plug-in as well. Any feedback is much appreciated.



It handles the initialization of the UILayout and the moving of the APEX template ID's/Classes to the UILayout areas by the plug-in or by the template.

Now I'm thinking about the second part. It will handle the sizing of each area: NORTH, SOUTH, WEST and EAST.

There are 7 settings for each area:
- Display: Yes/No
- Closable: Yes/No
- Resizable: Yes/No
- Slidable: Yes/No
- Size: (Number value like "250" as px)
- Min-Size: (Number value like "150" as px)
- Max-Size: (Number value like "350" as px)

I could either create one plug-in for all areas with comma separated values or create 4 plug-ins for each area one plug-in.

What is more troubling for the end user?

Version 1 - One Plug-in:
Example based on the following logic: NORTH,SOUTH,WEST,EAST
- Display: yes,yes,yes,no
- Closable: no,no,yes,no
- Resizable: no,no,yes,no
- Slidable: no,no,yes,no
- Size: 150,100,400,0
- Min-Size: 0,0,300,0
- Max-Size: 0,0,800,0

For me it looks quite difficult making the correct settings!

Version 2 - Four Plug-ins:
Example based on the NORTH area:
- Display: yes
- Closable: no
- Resizable: no
- Size: 150

Example based on the WEST area:
- Display: yes
- Closable: yes
- Resizable: yes
- Slidable: yes
- Size: 400
- Min-Size: 300
- Max-Size: 800

For me it looks much easier to set it correctly. But the end user would need to install all 4 plug-ins.

What do you think?

By the way you can try the first plug-in here: http://apex.oracle.com/pls/otn/f?p=65560:1

You can download it from apex-plugin.com: http://www.apex-plugin.com/oracle-apex-plugins/dynamic-action-plugin/uilayout-part-1-initialize_77.html

If nobody answers I will probably create 4 similar plug-ins for each area.