tag:blogger.com,1999:blog-63639243989071498302024-02-01T22:39:05.958-06:00Doug Gault's Blog...A bunch of stuff about MAC, Oracle, ApEx, Wine, Food, Life, Travel, Madness, Mayhem, and whatever else I can sling in here.Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.comBlogger39125tag:blogger.com,1999:blog-6363924398907149830.post-82412291103537950652017-05-24T15:58:00.001-05:002017-05-24T17:15:54.681-05:00Things I have done in my life.Maybe its the fact that I'm coming up on my 50th birthday. Maybe its that I'm kind of at a crossroads in my career. Maybe its because I'm a sappy sentimentalist that just like to nostalgically recount his experiences.<br />
<br />
What ever it is that drove me, a few months ago I started writing down the things I have accomplished in my life. As the weeks moved on I'd think of something else and write it down. To date I've compiled quite a list and going over it, I feel very proud of what I've done. Hopefully this list will continue to grow.<br />
<br />
I'm not sharing this to brag. Some of the things I would definitely not brag about. I'm sharing this to encourage people to create their own lists. You may be surprised at what’s on it. If not, get out of your comfort zone and live life! Stop thinking <strong>What if?</strong> and start thinking <strong>Why Not!</strong><br />
<strong><br /></strong>
<br />
<div>
<strong><em><span style="text-decoration: underline;">Thing I have done in my life </span></em></strong></div>
<ul>
<li>Lived on another continent </li>
<li>Loved unconditionally</li>
<li>Risked everything to do something that I didn't know whether I could do </li>
<li>Given up everything for love</li>
<li>Become a recognized expert in a technical field </li>
<li>Built and sold a company</li>
<li>Completely failed and rebuilt my life </li>
<li>Sold everything I own, twice </li>
<li>Written a book (4 actually)</li>
<li>Lived completely outside of my comfort zone</li>
<li>Learned a martial art </li>
<li>Seen the remains of an incarnation of Buddha </li>
<li>Prayed with a Buddhist monk, baptist minister, catholic priest and a shaman</li>
<li>Seen someone I love die </li>
<li>Met and conversed with celebrities </li>
<li>Dined in the UK Houses of Parliament</li>
<li>Learned about wine </li>
<li>Visited 4 of 7 continents (working on the other 3)</li>
<li>Learned another language </li>
<li>Felt true passion </li>
<li>Stood up for what I believed regardless of the cost </li>
<li>Performed a completely selfless act </li>
<li>Left a relationship I knew to be “safe" because I knew it wasn't right for me</li>
<li>Changed several peoples perception about what it means to be gay</li>
<li>Helped raise a child </li>
<li>Sabotaged something good in my life because I didn’t think I deserved it</li>
<li>Been poorer than most people can imagine </li>
<li>Earned more money than I thought I ever could </li>
<li>Escaped small town midwest life to become a world citizen</li>
<li>Been plucked from death by an unseen force </li>
<li>Been a professional dancer </li>
<li>Mastered a musical instrument </li>
<li>Sung in front of thousands of people </li>
<li>Been brought to tears by beauty</li>
<li>Been completely and utterly rejected </li>
<li>Built something from scratch </li>
<li>Cooked a meal of 4 star restaurant quality</li>
<li>Owned over 30 cars </li>
<li>Rescued an animal</li>
<li>Killed for my dinner </li>
<li>Celebrated my birthday twice by crossing the international date line </li>
<li>Skied a double black diamond </li>
<li>Taken drugs </li>
<li>Married the person I love </li>
<li>Considered taking my own life </li>
<li>Written poetry</li>
<li>Longed for something so much it made me physically ill </li>
<li>Disappointed my parents</li>
<li>Cut my family out of my life </li>
<li>Lost friends to AIDS </li>
<li>Come close to death </li>
<li>Cruised the Caribbean </li>
<li>Seen an Alaskan glacier calve </li>
<li>Hiked where few people have ever walked </li>
<li>Been diagnosed with a life threatening illness </li>
<li>Lied to feel more popular </li>
<li>Been so scared I could not move</li>
<li>Had a panic attack </li>
<li>Shared a rare intimate and personal moment with a complete stranger </li>
<li>Had an unrequited love</li>
<li>Been physically abused in a relationship </li>
<li>Been beaten up and bullied at school</li>
<li>Worked in a factory</li>
<li>Spoken in front of hundreds of people</li>
<li>Taught people my skills</li>
<li>Laughed till I cried</li>
<li>Contributed to Open Source Projects</li>
<li>Stolen food when I had no money to pay for it.</li>
<li>Broken my shoulder</li>
<li>Seen a Psychic</li>
</ul>
<strong><em>LIVED WITHOUT REGRETS!</em></strong>Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com2tag:blogger.com,1999:blog-6363924398907149830.post-8376028778148349662016-04-04T09:27:00.000-05:002016-04-04T09:31:19.048-05:00Warning APEX Users of Form Changes on Navigation away from the page.It has come to my attention the the link back to this article that originally appeared on the Enkitec.com web site is broken. Knowing that people still find this useful, I've copied it here so that it can be easily found and referenced.<br />
<br />
<hr />
<br />
It's a common problem. A user spends time entering data into a form and then, for some reason, clicks a button or tab that will navigate away from the form without saving his data. Wouldn't it be nice if there were a way to warn the user that the data hasn't been saved, and that they may lose their work?Well, there actually is a way to do this in JavaScript, and you don't have to do a lot of work yourself. Here's how...<br />
<br />
The following JavaScript is the key for Standard APEX Forms. You can include it either in the HTML HEADER of the page, or in an HTML Region on the page: <br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><script type="text/javascript"></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br />
</span> <span style="font-family: "courier new" , "courier" , monospace;">function onChangeinit() { </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br />
</span> <span style="font-family: "courier new" , "courier" , monospace;">// This function sets up those fields in <strong>STANDARD APEX FORMS</strong> </span><br />
<span style="font-family: "courier new" , "courier" , monospace;">// which should trigger the "Are You Sure" Popup box upon </span><br />
<span style="font-family: "courier new" , "courier" , monospace;">// navigating away from the page. </span><br />
<span style="font-family: "courier new" , "courier" , monospace;">// First set up the array of elements in the form </span><br />
<span style="font-family: "courier new" , "courier" , monospace;">// This method uses JavaScript to create an array of elements. </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br />
</span> <span style="font-family: "courier new" , "courier" , monospace;">var fields = document.getElementById('wwvFlowForm').elements; </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br />
</span> <span style="font-family: "courier new" , "courier" , monospace;">// Now loop through the array and assign the on-change event</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">// The onchange function sets the value of a JavaScript variable </span><br />
<span style="font-family: "courier new" , "courier" , monospace;">// to '1' to show that something has changed. </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br />
</span> <span style="font-family: "courier new" , "courier" , monospace;">for (var i=0; i<fields.length; i++) {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> $x(fields[i]).onchange = function () {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> window.unsaved=1;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> } </span><br />
<span style="font-family: "courier new" , "courier" , monospace;">} </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">// Now Set up the UNSAVED variable </span><br />
<span style="font-family: "courier new" , "courier" , monospace;">// and the function that checks it on UNLOAD. </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">window.unsaved = ''; </span><br />
<span style="font-family: "courier new" , "courier" , monospace;">window.onbeforeunload = function() { </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> return window.unsaved ? 'There may be unsaved changes to your data.' : undefined; </span><br />
<span style="font-family: "courier new" , "courier" , monospace;">} </span><br />
<span style="font-family: "courier new" , "courier" , monospace;">// And you're done. </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"></script> </span><br />
<br />
For APEX Tabular Forms, the code needs to change just a bit to cover all the iterations of the fields on the page: <br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><script type="text/javascript"></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br />
</span> <span style="font-family: "courier new" , "courier" , monospace;">function onChangeinit() {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br />
</span> <span style="font-family: "courier new" , "courier" , monospace;">// This function sets up those fields for a <strong>TABULAR FORM</strong> </span><br />
<span style="font-family: "courier new" , "courier" , monospace;">// which should trigger the "Are You Sure" Popup box upon navigating</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">// away from the page.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br />
</span> <span style="font-family: "courier new" , "courier" , monospace;">// First set up the array of elements in the form</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">// This method uses JavaScript to create an array of elements.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br />
</span> <span style="font-family: "courier new" , "courier" , monospace;">var fields = document.getElementById('wwvFlowForm').elements;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br />
</span> <span style="font-family: "courier new" , "courier" , monospace;">// Now loop through the array and see if the id matches the format f99_9999</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">// If it does, assign the on-change event.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">//</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">// The onchange function sets the value of a JavaScript variable</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">// to '1' to show that something has changed.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br />
</span> <span style="font-family: "courier new" , "courier" , monospace;">for (var i=0; i<fields.length; i++)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> if (fields[i].id.match('^f[0-9]{2}_{1}[0-9]{4}$'))</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> $x(fields[i]).onchange = function () {window.unsaved=1;}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br />
</span> <span style="font-family: "courier new" , "courier" , monospace;">// Now Set up the UNSAVED variable</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">// and the function that checks it on UNLOAD.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">window.unsaved = '';</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">window.onbeforeunload = function() {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> return window.unsaved ? 'There may be unsaved changes to your data.' : undefined;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br />
</span> <span style="font-family: "courier new" , "courier" , monospace;">// And you're done.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"></script></span><br />
<br />
The onChangeinit JavaScript function needs to be run whenever the page loads. To do that, we call it by placing the following JavaScript in the Execute when Page Loads attribute at the page level.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">onChangeinit();</span><br />
<br />
Finally, we want to provide a way to short circuit this for instances where we want them to be able to press a button without getting the message. The most common example of this would be the SAVE button. Again, you can include it either in the HTML HEADER of the page, or in an HTML Region on the page.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><script type="text/javascript"> </span><br />
<span style="font-family: "courier new" , "courier" , monospace;">function preSubmit() { </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // Call this before any action where you want the user </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // to be able to navigate without the warning message. </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // For instance, add this to the BUTTON ATTRIBUTES of the </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // SAVE button of your form. </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br />
</span><span style="font-family: "courier new" , "courier" , monospace;"> window.unsaved=''; </span><br />
<span style="font-family: "courier new" , "courier" , monospace;">} </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"></script></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br />
</span> The last thing to do is edit any buttons that we want to be able to submit the page without being warned and make sure they call the preSubmit JavaScript function. <br />
<br />
To make this change to SUBMIT buttons, edit the button and do the following:<br />
<br />
• In the Action When Button Pressed region, change the Action to Redirect to URL<br />
• in the URL Target enter the following:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">javascript:preSubmit();apex.submit('<</span><button_name><span style="font-family: "courier new" , "courier" , monospace;">>');</span> <br />
<br />
Make sure the that <<button_name>> in the code above is actually the name of the button that you’re editing. That way when the apex.submit JavaScript function is called, it will be as if the user pressed the button.<br />
<br />
For the DELETE buttons, edit the button and do the following:<br />
<br />
• In the Action When Button Pressed region, change the Action to Redirect to URL<br />
• in the URL Target enter the following: <br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> javascript:preSubmit();apex.confirm(htmldb_delete_message,'<</span><button_name><span style="font-family: "courier new" , "courier" , monospace;">>');</span> <br />
<br />
Again, make sure the that <<button_name>> in the code above is actually the name of the button that you’re editing.<br />
<br />
That's it. That's all there is to it. The nice thing about this is that it will even catch changes made by other JavaScript. <br />
<br />
</button_name></button_name></button_name></button_name>Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com3tag:blogger.com,1999:blog-6363924398907149830.post-69161016574963470942016-01-08T13:26:00.001-06:002016-01-08T13:29:09.118-06:00Beginning Oracle Application Express 5 is OUT!<p>After a few grueling months, late nights, long weekends and some cursing into my sleeve, it’s finally out.</p>
<p>Beginning Oracle Application Express 5 is the updated version of the book which not only includes an all new guided tour of the APEX 5 Page builder, but also takes you through developing an entire system from soup to nuts. </p>
<p>My thanks to all the people at A-Press for being patient while the initial versions of APEX 5 were still being released. (FYI - Writing a book against beta and early adopter versions isn’t the smartest decision!). Also thanks to my technical reviewer Warren Capps. Again he was an invaluable resource and caught things that I would not have thought about.</p>
<p>I hope that this book helps not only guide those new to Oracle APEX, but also helps some of those that want to get fast tracked on APEX 5.0.</p>
<p>The book can be found at the <a href="http://www.apress.com/9781484204672">APRESS Site</a> or on <a href="http://smile.amazon.com/Beginning-Oracle-Application-Express-5/dp/1484204670/">Amazon</a>.</p>
<p>Enjoy</p>
<p> </p>
<p><img style="display: block; margin-left: auto; margin-right: auto;" title="9781484204672.jpg" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWy4eYYR2FEYzHVqbkgCR87g-LozeLRwFSvFE4UJu280v_g40EeqI5lmb3pKgW_t9aCiDB79skTbXoBDANgL3NAgXeG8z7CubCLPF7rk1Qoprtbn_GQhOVZZ-PChVJa7X9YSHfx0_FgBI/?imgmax=800" alt="9781484204672" width="420" height="600" border="0" /></p>Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com10tag:blogger.com,1999:blog-6363924398907149830.post-65637603389312365202015-10-16T08:59:00.000-05:002015-10-16T08:59:02.309-05:00Google Chrome+ OS X + VMWare Fusion 8.0.1 = No BuenoAs those who read my blog know, I recently started a new job with Oracle. A very large part of what i do means being connected internally through the Oracle VPN. Having been a consultant for many MANY years, I’ve come to the realization that putting a fence around VPN is a good idea wherever possible.<br />
<br />
So instead of installing the VPN, Proxies, and the required software on my iMac, I created an OS X based VM using VMWare Fusion 8.0.1. This worked great! I could have my VPN up and running and access what I needed to without affecting all the things that were running perfectly on my desktop.<br />
<br />
That was until yesterday morning. I woke up, went through emails, switched over to my VM, startup up Chrome and was greeted with this:<br />
<br />
<img alt="Bad Chrome" border="0" height="251" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiReADWgQJVPOayldfmMjQHoETlu2z3zsFXB7E01jI5SXpcFADBYObQ_CE1xZvqA6U_QX7X6JeVIog1KQDs5PL628ECua4bTN2g-_pj6TWWVr9E81kH3M2jGTJjPzBrJjpoxoikxQLkKZk/?imgmax=800" style="display: block; margin-left: auto; margin-right: auto;" title="badchrome.png" width="300" /><br />
<br />
I had no idea what was going on, and really didn’t even know what to search for. However, I did know it was working the day before and being a VM, I just restored a snapshot. Hurray. Everything was working again … Until this morning.<br />
<br />
Once again I started up chrome and it greeted me with the snowed out display. This time I knew I had to solve the problem. I couldn’t revert to a snapshot everyday and lose all the work I’d done the prior day. That would get me nowhere.<br />
<br />
After some searching, cursing, more searching and a couple cups of caffeine, I finally found something on the Chromium forums at Google. According to <a href="https://code.google.com/p/chromium/issues/detail?id=542873&colspec=ID%20Pri%20M%20Stars%20ReleaseBlock%20Cr%20Status%20Owner%20Summary%20OS%20Modified">this thread</a>, it’s a problem with Chrome using it’s in-built hardware acceleration with VMWare 8.0.1. so that feature has to be turned off. But to turn it off you have to run chrome, navigate to its settings (which is displayed as a web page), uncheck a box and then restart Chrome. No easy task when you can’t ready anything chrome says.<br />
<br />
However you can start Chrome from the command line and apply run-time settings to it. Open a Terminal window and type the following:<br />
<br />
<div style="font-family: Menlo; font-size: 11px; line-height: normal; margin: 0px;">
open -a “Google Chrome" --args --disable-gpu</div>
<div style="font-family: Menlo; font-size: 11px; line-height: normal; margin: 0px;">
<br /></div>
Then navigate to the <b>Preferences</b> section of Chrome, scroll to the bottom and click <b>Show advanced settings...</b><br />
<br />
<b> <img alt="" src="data:image/png;base64,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" /></b><br />
<br />
Scroll down until you find the SYSTEM area and uncheck Hardware Acceleration.<br />
<br />
Restart Chrome and you’ll be back on track!<br />
<br />
Not sure if this bug affects any other OS’s besides OS X, but just in case ...Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com0Fort Worth, TX, USA32.7554883 -97.330765831.901301300000004 -98.62165929999999 33.609675300000006 -96.0398723tag:blogger.com,1999:blog-6363924398907149830.post-64689467798736639402015-09-25T08:30:00.001-05:002015-09-25T08:38:02.713-05:00A CHANGE IN DIRECTIONHaving just re-read quite a few of my previous blog posts (especially the last two), I can see that over the last while I’ve been a bit restless and unsettled.<br />
<br />
Looking back over my career recently I realized that I've been doing consulting for probably 20+ of my 28 year tenure. I don't regret any part of it as it's taken me all over the world, introduced me to some amazing people and given me hundreds of memorable work and personal experiences.<br />
<br />
But if I look at the last 10 years, the things that I've most enjoyed have not been consulting. For instance:<br />
<ul>
<li>My stint as Lead Architect at <b>TXI</b> (where I initially came in contact with HTMLDB) actually kept me from getting out of IT all together.</li>
<li>My time as Product Development Director for <b>Hotsos</b> was amazingly rewarding as I not only got to help create something from scratch, but got to manage and work with a great team of smart people for an extended period of time and was introduced to various different programming languages and technologies.</li>
<li>Working with Scott Spendolini at <b>Sumneva</b> to help create eSERT and eFramework was much the same. We were able to see a need, fill it, support it and watch it grow and succeed.</li>
<li>Working with the Enkitec team to help harden and productize a few of their offerings.</li>
</ul>
My next obvious question was where to go. And after thinking long and hard about that and examining all the options available to me, one option stuck out in my mind as the next logical step. Over the 28 years I've been working <b><i>with</i></b> Oracle technology, I've never actually worked <b><i>for</i></b> Oracle itself. And the prospect of doing so was very interesting to me.<br />
<br />
So I decided to explore and reach out to a select group of people I knew inside of Oracle who might know of opportunities that I might be a fit for. As it turns out, <a href="http://michaelhichwa.blogspot.com/">Mike Hichwa</a> had just the thing.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2cMp8XimrKXEbMQyJj0etZw0oK6UK6Fr7Hv-O-x9uuWhIL1tB9quKdbsQ1Pr86TBjBT6WSTeMfo3wLc27Sy5FUXuO9EZSwdTGktTK_lqKRTiwdC7LLbvxcFZxLs9QQV5JVF3Xz3nH1dw/?imgmax=800" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img alt="NewImage" border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2cMp8XimrKXEbMQyJj0etZw0oK6UK6Fr7Hv-O-x9uuWhIL1tB9quKdbsQ1Pr86TBjBT6WSTeMfo3wLc27Sy5FUXuO9EZSwdTGktTK_lqKRTiwdC7LLbvxcFZxLs9QQV5JVF3Xz3nH1dw/?imgmax=800" title="NewImage.png" width="320" /></a>Starting October 5th, I’ll join Mike’s group and be working on Oracle’s Cloud solutions. I’ll initially be working on a number of Back-Office APEX applications that help monitor and maintain the various cloud offerings and communicate between operations, account managers and customers. From there I’m sure that Mike and <a href="http://krisrice.blogspot.com/">Kris Rice</a> have a list as long as their arms of things they’ll want me to jump in to.<br />
<br />
While I see joining Oracle as a huge opportunity, it also means a number of things that I’ll have to leave behind:<br />
<br />
First, I’ll be leaving my friends and long time business partners, <a href="http://spendolini.blogspot.com/">Scott Spendolini</a> and <a href="http://wphilltech.com/">Tim St. Hilaire</a>, behind to continue with <a href="http://www.sumnertech.com/">Sumner Technologies</a> alone. I have no doubt that they will continue to make a success of whatever they attack. But it will be weird to be moving in a different direction for the first time in what seems like forever.<br />
<br />
Second, joining Oracle means giving up being an ACE Director. The <a href="http://www.oracle.com/technetwork/community/oracle-ace/index.html">ACE Program</a> has helped me in ways that I cannot express. It helped me focus my energies, become a better ambassador for Oracle, and allowed me to meet and socialize with people that I might now have otherwise been able to. I’ll not only miss the <a href="https://apex.oracle.com/pls/apex/f?p=19297:3:108923068669526">ACE Members</a>, but the lovely people who administer the program. It’s been fun y’all!<br />
<br />
Lastly, by joining Oracle so close to OOW, it means that headcount was already set and approved so I won’t be seeing any of you at OOW this year. Maybe next year and probably at the demo grounds!<br />
<br />
I’m really looking forward to starting my new adventure and will endeavor to blog as much as I can about my experiences and what I’m learning and doing.<br />
<br />
Good luck to Scott and Tim at Sumner as well. Success for everyone! <br />
<br />
<br />
<br />Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com6tag:blogger.com,1999:blog-6363924398907149830.post-20405782874679381472015-06-01T11:53:00.001-05:002015-06-01T16:34:14.403-05:00Coming Full Circle.<p>In <a href="http://douggault.blogspot.com/2015/04/the-road-not-taken.html">April’s blog</a> post, I alluded to the fact that the future had a number of changes in store and that I wasn't exactly sure what shape those changes would take. Since April, a lot has happened; avenues have been explored, opportunities have been entertained, and decisions have been made. It’s been a very interesting few weeks, but I believe that the end result has been worth the time investment.</p>
<p>So it is with great pride and more than just a bit of nostalgia that I’d like to announce that <a href="http://spendolini.blogspot.com/">Scott Spendolini</a>, <a href="http://wphilltech.com/">Tim St.Hilaire</a> and I have re-launched <a href="http://www.sumnertech.com">Sumner Technologies</a>; the original company that Scott and I ran together way back in the day.</p>
<p>We’re going to be focusing out efforts on the following areas: </p>
<ul>
<li>APEX Consulting </li>
<li>APEX Education</li>
<li>Security Reviews</li>
<li>APEX Architecture</li>
<li>Health Checks</li>
<li>Oracle Database Cloud Technology </li>
</ul>
<div>We’re also going to be working on bringing some SaaS offerings to market, but that will have to wait for a different blog post.</div>
<div> </div>
<div>I’m excited to start this new chapter of the story and especially excited to be able to provide the types of hard-hitting offerings that can really make a difference to companies using or looking to use APEX. </div>
<div> </div>
<div>Come visit the web site, and connect with us on social media! Hope to see you all at KSCOPE15.</div>
<div> </div>
<div> <a title="View 'Sumner-Logo' on Flickr.com" href="https://www.flickr.com/photos/douggault/17731010303"><img title="Sumner-Logo" src="https://farm9.staticflickr.com/8823/17731010303_e522dfa547.jpg" alt="Sumner-Logo" width="341" height="123" border="0" /></a></div>
<p>Web: <a href="http://www.sumnertech.com">http://www.sumnertech.com</a><br />LinkedIn: <a href="https://www.linkedin.com/company/sumnertech">https://www.linkedin.com/company/sumnertech</a><br />FaceBook: <a href="https://www.facebook.com/sumnertech">https://www.facebook.com/sumnertech</a> <br />Twitter: <a href="https://twitter.com/sumnertech">@sumnertech</a> </p>
<p> </p>
<p>PS. Many thanks to the crew at <a href="http://www.studiocufflink.com">Studio Cufflink</a> for the incredible re-branding job they did for us. Incredible work and amazingly professional, even after a bit of a false start on our part. If you need brand Identity work - USE THEM!</p>Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com2tag:blogger.com,1999:blog-6363924398907149830.post-73204581002212712012015-04-20T09:37:00.001-05:002015-04-20T09:37:01.952-05:00The Road Not Taken <p>In June 2012, <a href="http://spendolini.blogspot.com/">Scott Spendolini</a> and I signed the papers whereby <a href="www.enkitec.com">Enkitec</a> acquired the assets of Sumneva. We announced this big news at <a href="http://odtug.com/">ODTUG</a> KSCOPE and it was met with quite a lot of interest and more than a few congratulatory beers. Our goal was to step away from the day-to-day trappings of running your own business (i.e. Accounting, Sales, Paying the electric bill, etc) and focus our core skills in APEX.</p>
<p>During the next two years we hired another person (<a href="http://wphilltech.com/">Tim St. Hilaire</a>) to work with us on expanding our APEX based product suite, continued to work on eSERT, expanded our training offering, and built a world-class consulting team with many of the brightest APEX minds in the US. While not without its challenges, work under the Enkitec umbrella was challenging and rewarding.</p>
<p>However, hovering in the background, just under the surface, the entrepreneurial itch never really went away.</p>
<p>Almost 2 years to the day later, Enkitec announced that it was being purchased by Accenture. Again, we announced publicly at ODTUG KSCOPE, and again the announcement was met with a flurry of questions and more congratulatory beers. The year that followed was an interesting one and again, not without it’s challenges. The APEX team grew. The focus on Consulting was accentuated as Training and Product became less important.</p>
<p>The major change we saw was that the size of engagement we were being pulled into were moving up the scale from reasonably large to huge. There was more to do than ever, and as Practice Directors, that meant being involved at the top level of trying to keep the practice focused and moving forward. No small task but working with such talented people, it was undeniably exciting.</p>
<p>And yet, still waiting in the background, a bit less quietly, a bit more insistent, the entrepreneurial itch was calling. And here I am, once again just before KSCOPE, making another life changing decision. It was a hard one to make, but I have learned over the years to trust my instinct and follow the call of that annoying little itch. </p>
<p>What’s next is still a little unclear. There are a number of opportunities to explore and likely by the end of this week, I’ll have a better understanding of what the future holds. Until then I’ll be spending time on the APEX 5.0 Beginner book, to be sure. Which means getting in-depth with APEX 5. </p>
<p>What I do know is that, “... knowing how way leads on to way, I doubt if I should ever come back…"</p>
<p>Let the adventure begin!</p>Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com2tag:blogger.com,1999:blog-6363924398907149830.post-33855081583821470772014-04-28T09:23:00.001-05:002014-05-08T09:52:49.313-05:00ORCLAPEX-DFW First Meetup.Calling all APEX Fanatics in the DFW area, there's a new Meetup for you: <a href="http://www.meetup.com/orclapex-dfw">ORCLAPEX - DFW</a>. <a href="http://www.meetup.com/ORCLAPEX-DFW/events/178992762/">Here's a link to our first event!</a><br />
<h2>
Grass Roots Explosion</h2>
As <a href="http://www.danielmcghan.us/">Dan McGhan</a> mentioned in his blog <a href="http://www.danielmcghan.us/2014/04/orclapex-nyc-first-meetup.html">here</a>, Oracle APEX meet up groups are popping up all over the world. This is a grass roots effort lead by people who are passionate about APEX and want to share their knowledge and encourage others to do the same.<br />
Each group is independent and may run things a little bit differently to suite the way the local group wants to work, but all the groups will be sharing ideas, experiences and we hope to benefit from things that work in other geographies. Who knows.. Maybe at some point we’ll be able to have a ORCLAPEX-GLOBAL meet up! (KSCOPE anyone?)<br />
As it sits now there are # Meetup groups that have been formed or are in the process of forming. They are:<br />
<ul>
<li><a href="http://www.meetup.com/orclapex-msp" target="_blank">ORCLAPEX-MSP</a> for the Minneapolis, St. Paul area led by <a href="http://rimblas.com/blog/author/admin/">Jorge Rimblas</a></li>
<li><a href="http://www.meetup.com/orclapex-nova/" target="_blank">ORCLAPEX-NOVA</a> for the Northern Virginia area led by <a href="http://spendolini.blogspot.com/">Scott Spendolini</a></li>
<li><a href="http://www.meetup.com/orclapex-mtl" target="_blank">ORCLAPEX-MTL</a> for the Montreal area of Cadana led by <a href="http://insum-apex.blogspot.com/">Francis Mignault</a></li>
<li><a href="http://www.meetup.com/orclapex-NYC/" target="_blank">ORCLAPEX-NYC</a> for the New York City area led by <a href="http://www.danielmcghan.us/">Dan McGhan</a></li>
<li><a href="http://www.meetup.com/orclapex-vienna/" target="_blank">ORCLAPEX-VIENNA</a> for the Vienna Austria area led by <a href="http://www.oracle-and-apex.com/">Peter Raganitsch</a></li>
</ul>
<h2>
ORCLAPEX-DFW Meeting Agenda</h2>
Our first meeting will be pretty loosely structured so that we can discuss what we want to achieve with the group and how we’d like it structured going forward. However we did want to make sure that we had some real APEX content that might be interesting so here’s the agenda<br />
<div>
<ul>
<li>5:30pm - Come on up for food, drinks, and socializing </li>
<li>5:45pm - Announcements - We don’t expect much in terms of announcements for our first meeting, but just in case...</li>
<li>6:00pm - Intro to Oracle Application Express 5.0 - We’ll have a look under the covers of APEX 5 and discuss what this means for us as developers </li>
<li>6:30pm - Lightning Demos and Q&A - Anyone who has something cool to share can get up and spend 5-10 minutes showing us what they’ve done with APEX</li>
<li>7:00pm - All good things must come to an end… </li>
</ul>
<div>
For convenience sake, and to keep things Central in the DFW area, the meetings will be held (at least initially) in the Enkitec Irving offices at 5605 North MacArthur Blvd, Suite 600, Irving Texas 750803</div>
To join the DFW Meetup Group go sign up and RSVP to the event!<br />
Hope to see all you DFW APEX FANATICS there!</div>
Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com2tag:blogger.com,1999:blog-6363924398907149830.post-83885130490988431142014-02-04T11:13:00.001-06:002014-02-04T11:13:19.472-06:00You don't have to wait for APEX 5 for FullCalendar Integration<p>One of the MANY nice things that is coming in APEX 5.0 is the native integration of the jQuery based FullCalendar, known in the APEX 5.0 Builder as the CSS Calendar. While the native integration will be nice, you shouldn't have to wait for APEX 5.0 for this functionality.</p>
<p>Enter the Enkitec FullCalendar plugin. We integrated FullCalendar into our website quite some time ago to enable us to display our Education and Conference calendars. Recently I've taken the basis for that code and created a plug-in that works with APEX 4.1 and 4.2.</p>
<p>The plugin allows the developer to decide the following:</p>
<ul>
<li>The jQuery UI Theme to be used to render the calendar</li>
<li>What the header of the Calendar contains and where</li>
<ul>
<li>Navigation</li>
<li>Title</li>
<li>View</li>
</ul>
<li>Which calendar views, in addition to MONTH, the end user sees (Week and/or Agenda/Day)</li>
<li>Whether or not the day is considered an "All-Day" event</li>
<li>Styling for each individual event</li>
<ul>
<li>Either <strong>event_color</strong> and <strong>text_color</strong> or a <strong>CSS Class</strong> to be assigned.</li>
</ul>
<li>Tool Tip text to display when an end user hovers over the event in the calendar</li>
<li>Hight & Width of the Calendar</li>
<li>Which day should be considered the first day of the week</li>
</ul>
<p>While there are still things I want to do to this plug-in, I thought I’d go ahead and release it so that the APEX community could start using it now. </p>
<p>Will the plug-in continue to be developed once 5.0 is finally released? I suppose that depends on whether the APEX team implements the same of better functionality than what I’ve managed to do so far. </p>
<p>In the mean time you can download the plug-in from here: <a href="http://www.enkitec.com/products/plugins/fullcalendar">http://www.enkitec.com/products/plugins/fullcalendar</a></p>Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com9tag:blogger.com,1999:blog-6363924398907149830.post-35419218969394552682013-09-10T09:45:00.001-05:002013-09-10T12:12:06.121-05:00APEX Printing in Depth - OOW Sunday Symposium<p>If you're going to <a href="http://www.oracle.com/openworld/register/packages/index.html?src=7328809&Act=187">Oracle Open World</a> and will be there for the ODTUG Sunday APEX Symposium, then you're in for quite an interesting set of sessions. When discussing what would be a good topic for this year's set of presentations, we wanted to focus on an area within APEX from which everyone could gain some benefit. Although there are many different topics we could have addressed, the one that kept coming to the forefront, and the one that we <em><strong>knew</strong> </em>everyone would have some interest in was generating printable PDF's from APEX.</p>
<p>If you've been in the APEX world for any length of time, you know that "Printing Ain't Easy". Although there are a number of potential solutions to the print problem they all come with their benefits and caveats. This years symposium is aimed at presenting four of the possible solutions, how to implement them and the features, benefits and drawbacks of each. </p>
<p>Here's the Schedule:</p>
<ul>
<li>09:15 - <a href="https://oracleus.activeevents.com/2013/connect/sessionDetail.ww?SESSION_ID=10238">Options for Oracle Application Express: Oracle Business Intelligence Publisher</a> [UGF10238] - <a href="https://twitter.com/RoelH">Roel Hartman</a> </li>
<li>10:30 - <a href="https://oracleus.activeevents.com/2013/connect/sessionDetail.ww?SESSION_ID=10240">Options for Oracle Application Express: Jasper Reports</a> [UGF10240] - <a href="https://twitter.com/sthilaire">Tim St.Hilaire</a></li>
<li>11:45 - <a href="https://oracleus.activeevents.com/2013/connect/sessionDetail.ww?SESSION_ID=10239">Options for Oracle Application Express: FOP and Oracle Application Express Listener</a> [UGF10239] - <a href="https://twitter.com/dgault_apex">Doug Gault</a></li>
<li>14:15 - <a href="https://oracleus.activeevents.com/2013/connect/sessionDetail.ww?SESSION_ID=10237">Options for Oracle Application Express: PL/PDF</a> [UGF10237] - <a href="https://twitter.com/sspendol">Scott Spendolini</a></li>
<li>15:30 - <a href="https://oracleus.activeevents.com/2013/connect/sessionDetail.ww?SESSION_ID=10241">Printing Options for Oracle Application Express: Q&A Panel</a> [UGF10241] - Roel Hartman, Tim St.Hilaire, Doug Gault, Scott Spendolini, <a href="https://twitter.com/martindsouza">Martin D'Souza</a></li>
</ul>
<p> All presentations will take place <strong>Sunday, September 22 in Moscone West - Room 2005.</strong></p>
<p>If you interested in generating PDF reports from APEX, then these sessions are not to be missed.</p>Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com0tag:blogger.com,1999:blog-6363924398907149830.post-16546404825620750542013-03-19T09:11:00.001-05:002013-03-19T09:11:36.094-05:00Your Days Are Numbered … (for early-bird KSCOPE registration)<p><a href="http://kscope13.com/">KSCOPE 13</a> is coming up quickly, and so is the deadline for early-bird registration.</p>
<p>If you haven't ever been, KSCOPE is, dare I say, the <strong><span style="text-decoration: underline;">best technical Oracle conference</span></strong> in the country, and potentially the world. Especially if you're interested in <a href="http://apex.oracle.com/i/index.html">Oracle APEX</a>. Along with excellent in-depth APEX coverage the agenda include coverage of: </p>
<ul>
<li>ADF & Fusion Middleware</li>
<li>Developer's Toolkit</li>
<li>Oracle Core Database </li>
<li>.NET</li>
<li>Business Intelligence</li>
<li>Essbase</li>
<li>And Many, MANY more…</li>
</ul>
<p>The conference runs from Saturday, <strong>June 22 though Thursday June 27</strong>, and will give you an opportunity to wish me a Happy Birthday on June 23. </p>
<p>If you register on or before March 25th, you can save $300 on <a href="http://kscope13.com/registration">registration</a>!</p>
<p>Do yourself and your career a favor and get to New Orleans this year for KSCOPE!</p>
<p>I hope to see you there!!</p>Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com0tag:blogger.com,1999:blog-6363924398907149830.post-89940408988821129772013-03-14T15:36:00.001-05:002013-03-14T15:36:57.974-05:00Of Multiple screens and Mac Menus<p> </p>
<p><img style="float: left;" title="image.jpeg" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhP2Jceg2O0ATrwsGdzXiWY3czWDa392beOVA9OoSYnLH9vwdh_Sjs52U4yWVM5E2nKcYML4xUlJnTaAqwaBn1c474W2_6raaY2mZvMi2hniSjaE7kZCCAF2ObDNEbVeHveEAoMosjEYDs/?imgmax=800" alt="Computer" width="450" height="600" border="0" /></p>
<p>Those who know me probably know I've been a Mac convert for a number of years. At home I have several Macs for various purposes, but at work I have a MacBook Air and a 27" Cinema Display that I use to do most of my work. </p>
<p>I've always had a problem with the fact that the Mac menu bar always stayed hovering down on the main screen of the Mac, forcing me to break concentration from my work, move my mouse down to the lower screen, click the menu and then navigate back up.</p>
<p>Yes, I know that you can change the position of the menu to which ever one you want, but that doesn't solve the problem completely. What if what I'm working on is in the bottom screen and I've moved the menu bar to the top.</p>
<p><a href="http://www.binarybakery.com/product.php?app=menueverywhere">MenuEverywhere</a> to the rescue!</p>
<p>I stumbled across this little gem on MacUpdate while searching online for a solution to my mad mouse scrolling problems. </p>
<p>MenuEverywhere give you lots of options including duplicating the menu bar on secondary screens, attaching an apps menu bar to the app itself (a la WINDOZE), allowing a pop-up menu bar based on a shortcut or button, etc.</p>
<p>It also give you full control over look and feel, fonts, styles and so on.</p>
<p>Now, I don't have to break concentration to get to the working menu that I need.</p>
<p>All is now right with the world again.</p>
<p> </p>Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com1tag:blogger.com,1999:blog-6363924398907149830.post-76513681713513745182013-03-07T12:38:00.001-06:002013-03-07T12:41:42.625-06:00APEX and Exadata is in my future.Since joining forces with Enkitec, I've managed to stay blissfully unaware of some of the things that they're best known for. Namely being top of the food chain when it comes to knowing what's what about Exadata.<br />
<br />
However, that's about to change!<br />
<br />
A couple of the larger clients we worked with while we were still Sumneva have become so successful that they're working to migrate their systems, including their APEX applications, to Exadata platforms.<br />
<br />
Now this in itself isn't a big deal. We all know that APEX runs inside the database and that it doesn't care what the underlying hardware platform is. Exadata machines run Oracle, so it's a no-brainer really.<br />
<br />
The fun comes in when you start to think about the Exadata Secret Sauce, which in a nut shell has everything to do with the storage nodes and very little to do with the server nodes running the database. Those storage nodes are what provide the extreme speed and scalability to the Exadata platform and therefore anything that runs on them.<br />
<br />
Understanding the underpinnings and how they can be used to help system performance can be extremely useful when taking a system that runs in a traditional oracle environment and migrating them to Exadata. Since most people are running APEX in a traditional environment, the data structures and queries have been written based on that knowledge.<br />
<br />
And so starts my education about the technology behind Exadata and how differently (if at all) things need to be done in terms of database and query structure.<br />
<br />
Along the way we're looking at writing a few tools/products that are aimed squarely at the Exadata world, covering things from sizing to migration to performance and beyond.<br />
<br />
I'll be sharing what I learn about Exadata with regards to its relation to APEX et al as I move forward.
<br />
<br />
Exciting times!
Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com2tag:blogger.com,1999:blog-6363924398907149830.post-18490456050175079292012-10-23T18:57:00.001-05:002016-04-04T09:32:34.925-05:00Warning a user that the form has changed - Tabular Form Style.<br />
Quite some time ago, I wrote a quit tip about <a href="http://douggault.blogspot.com/2016/04/warning-apex-users-of-form-changes-on.html">How to Warn a User That the Form Has Changed</a>. The gist of the post was this:<br />
<blockquote class="tr_bq">
"It's a common problem. A user spends time entering data into a form and then, for some reason, clicks a button or tab that will navigate away from the form without saving his data. Wouldn't it be nice if there were a way to warn the user that the data hasn't been saved, and that they may lose their work? "</blockquote>
The original solution used JavaScript to do the following:<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>•<span class="Apple-tab-span" style="white-space: pre;"> </span>create and set a flag at the page level<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>•<span class="Apple-tab-span" style="white-space: pre;"> </span>register an onchange event against all of the fields in the APEX form that sets the flag any time a value is changed<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>•<span class="Apple-tab-span" style="white-space: pre;"> </span>register with the page onbeforeunload event to check to see if the flag had been set and pop-up a warning if it has been<br />
<br />
The original script worked well for a standard form but I had never tested it agains a tabular form. Well, someone else had, and let me know that it really didn’t work.<br />
<br />
As you can imagine, there are a lot of moving parts in a tabular form, especially now with APEX 4. The original script would have registered onchange events against every item on the form whether it was user editable or not. That obviously would’t work for a tabular form as there are some JavaScript events that fire and change some of the hidden items.<br />
<br />
After thinking about this for bit, I finally realized that instead of registering onchange events against every item on the tabular form, only the items that are user editable should be registered. If you look at the editable items, the id of each will conform to the following format: <span style="font-family: "courier new" , "courier" , monospace;">f99_9999</span><br />
<br />
So the key was to register only those items who’s id conforms to that format. To do that the JavaScript match function and regular expressions can be used for this purpose.<br />
<br />
The following JavaScript is the key. You can include it either in the HTML HEADER of the page, or in an HTML Region on the page:<br />
<br />
<pre class="brush:xml"><script type="text/javascript">
function onChangeinit() {
// This function sets up those fields which should
// trigger the "Are You Sure" Popup box upon navigating
// away from the page.
// First set up the array of elements in the form
// This method uses JavaScript to create an array of elements.
var fields = document.getElementById('wwvFlowForm').elements;
// Now loop through the array and see if the id matches the format f99_9999
// If it does, assign the on-change event.
//
// The onchange function sets the value of a JavaScript variable
// to '1' to show that something has changed.
//
for (var i=0; i<fields.length; i++)
if (fields[i].id.match('^f[0-9]{2}_{1}[0-9]{4}$'))
{
$x(fields[i]).onchange = function () {window.unsaved=1;}
}
}
// Now Set up the UNSAVED variable
// and the function that checks it on UNLOAD.
window.unsaved = '';
window.onbeforeunload = function() {
return window.unsaved ? 'There may be unsaved changes to your data.' : undefined;
}
// And you're done.
</script>
</pre>
<br />
The <b>onChangeinit</b> JavaScript function needs to be run whenever the page loads. To do that, we call it by placing the following JavaScript in the <u>Execute when Page Loads</u> attribute at the page level.<br />
<br />
onChangeinit();"<br />
<br />
Finally, we want to provide a way to short circuit this for instances where we want them to be able to press a button without getting the message. The most common example of this would be the SAVE button. Again, you can include it either in the <b>HTML Header</b> of the page, or in an <b>HTML Region</b> on the page.<br />
<br />
<pre class="brush:xml"><script type="text/javascript">
function preSubmit() {
// Call this before any action where you want the user
// to be able to navigate without the warning message.
window.unsaved='';
}
</script>
</pre>
<br />
The last thing to do is edit any buttons that we want to be able to submit the page without being warned and make sure they call the preSubmit JavaScript function. <br />
<br />
To make this change to SUBMIT buttons, edit the button and do the following:<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>•<span class="Apple-tab-span" style="white-space: pre;"> </span>In the <u>Action When Button Pressed</u> region, change the <u>Action</u> to <b>Redirect to URL</b><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>•<span class="Apple-tab-span" style="white-space: pre;"> </span>in the <u>URL Target</u> enter the following: <span style="font-family: "courier new" , "courier" , monospace;">javascript:preSubmit();apex.submit('SUBMIT');</span><br />
<br />
Make sure the that ‘SUBMIT’ in the code above is actually the name of the button that you’re editing. That way when the apex.submit JavaScript function is called, it will be as if the user pressed the button.<br />
<br />
For the DELETE buttons, edit the button and do the following:<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>•<span class="Apple-tab-span" style="white-space: pre;"> </span>In the <u>Action When Button Pressed</u> region, change the <u>Action</u> to <b>Redirect to URL</b><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>•<span class="Apple-tab-span" style="white-space: pre;"> </span>in the <u>URL Target</u> enter the following: <span style="font-family: "courier new" , "courier" , monospace;">javascript:preSubmit();apex.confirm(htmldb_delete_message,'MULTI_ROW_DELETE');</span><br />
<br />
Again, make sure the that ‘MULTI_ROW_DELETE’ in the code above is actually the name of the button that you’re editing.<br />
<br />
Once all of these things are put together, this should work nicely with tabular forms.<br />
<br />
Hope this help some of you out, and as always comments are encouraged.<br />
<br />Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com12tag:blogger.com,1999:blog-6363924398907149830.post-64278896548863107062012-10-09T12:08:00.000-05:002012-10-09T12:08:19.852-05:00Using APACHE ANT to build APEX projects.At Oracle Open World 2012, <a href="http://spendolini.blogspot.com/">Scott Spendolini</a> and I did a presentation entitled “Developing Commercial APEX Applications”. One of the topics that seemed to get a lot of attention and a number of questions was automating our build process using ANT. Several people requested a copy of the ANT script, so instead of sending it out individually, I’ve decided to include it here and walk though it.<br />
<br />
First of all I must confess that I am, by no stretch of the imagination, an expert in building ANT scripts, so there are likely better ways to do some of the things that I’ve done. If you find that to be the case and you care to share your knowledge and experience, I invite you to share that knowledge in the comments section.<br />
<br />
Second, and this may go without saying, but you’ll need to have the <a href="http://ant.apache.org/">ANT</a> executables installed on the server you’re going to use to build your projects.<br />
<br />
<a href="https://www.dropbox.com/s/po4yxsfu6on0oc4/build.xml">Here is a link</a> to download the entire file, but lets go through it piece by piece.<br />
<br />
<pre class="brush:xml"><?xml version="1.0"?>
<project name=“SERT BUILD" basedir="."></pre>
<br />
The above preamble basically sets the XML version you’re adhering to and gives the whole project a name and sets the base directory for any work that is to be done.<br />
<br />
<pre class="brush:xml"><!--The following TASKDEF is needed to include the ANT-CONTRIB libraries -->
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
</pre>
<br />
The ANT-CONTRIB library is an extension to the basic ANT commands. It gives you the ability to do things like FOR and FOREACH loops, IF statements, TRYCATCH and a few others. I use it to loop through lists of files and performa actions on them. Not absolutely necessary, depending on what you’re doing, but very useful.<br />
<br />
You can find more info about the ANT-CONTRIB library and download it <a href="http://ant-contrib.sourceforge.net/">here</a>.<br />
<br />
<pre class="brush:xml"><!-- Define a macro that will be used to wrap the PL/SQL files -->
<macrodef name="wrapfile">
<attribute name="file" />
<sequential>
<!-- The first step wraps the file with an output name of *.*.tmp -->
<exec executable="wrap">
<arg value="iname=@{file}" />
<arg value="oname=@{file}.tmp" />
</exec>
<!-- The second step moves the *.*.tmp file back to the original file name-->
<exec executable="mv">
<arg value="@{file}.tmp" />
<arg value="@{file}" />
</exec>
</sequential>
</macrodef>
</pre>
<br />
Above is a macro definition that I wrote to wrap PL/SQL or SQL scripts. When you define a macro, you can then call that definition later in the script to perform repetitive actions. This is much like defining and calling a PL/SQL Function for repetitive tasks.<br />
<br />
For this to work you actually have to have the Oracle directory where the WRAP command resides in the path of the user that will be running the build. As a word of warning, I found out that the version of WRAP that comes with the Oracle Client for some reason didn’t work. I had to have a full install of the database software (even if I didn’t have a database created) for the build to work properly. I didn’t spend a lot of time tracking this down, but I suspect that it had to do with some library or something that was missing or inaccessible do to some path being out of whack.<br />
<br />
<pre class="brush:xml"><!-- This target sets up the base properties-->
<!-- These items can be changed by using the -D option on the command line -->
<target name="properties">
<property name="wd" value="./work" />
<property name="sv_version" value="000000"/>
<property name="sv_parse_as" value="SV_SERT_APEX"/>
</target>
</pre>
<br />
This is the first of the “Targets” in the file. A Target is basically something that will (either conditionally or unconditionally) get executed as part of the build. The properties target defines the variables that are going to be used during the build process. In my case I have the following:<br />
<ul>
<li><b>wd</b> - The working directory where the build will take place. </li>
<li><b>sv_version</b> - The version of the software we’re going to build. It defaults to 000000, and will most likely be passed in on the command line.</li>
<li><b>sv_parse_as</b> - The parse as schema that will be used to replace placeholders in the scripts. Again, can be overridden on the command line.</li>
</ul>
You can replace any of these values on the command line by using the -D option. Well talk more about how to call it from the command line later.<br />
<br />
<pre class="brush:xml"><!-- This target deletes the working directory and then recreates it.-->
<target name="setup" depends="properties">
<echo message="Deleting the old working directory..." />
<delete dir="${wd}" />
<echo message="Creating the new working directory ..." />
<mkdir dir="${wd}" />
</target>
</pre>
<br />
The <b>setup</b> target sets up the working directory by cleaning it up (deleting it) if it already exists then creating it so that we can actually do some work in it. You’ll notice in line 2 the target tag has a depends attribute that tells ant that the <b>properties</b> target should be executed before this target runs. The depends clause is a nice safety net to make sure that all dependancies have been met before executing the current target.<br />
<br />
<pre class="brush:xml"><!-- This target does the SVN Check out -->
<target name="co" description="Checks out the most recent source to the working directory" depends="setup">
<echo message="Checking out the sumnevaSERT Repository to the local working directory" />
<exec executable="svn" dir="${wd}">
<arg line="co http://svn.codespaces.com/my/repository/path --username myUsername --password myPassword”/>
</exec>
</target>
</pre>
<br />
The <b>co</b> target is used to check all of the current source files out of the source code repository. In our case we’re using SVN so the command-line version of the SVN client needs to be installed on the build machine in order for this to work. You’ll see on line 4 we’re setting up the executable (svn) and telling and the working directory. The next line is providing the command line arguments to the svn command. Obviously the repository URL and the Username and Password are fictional. You’ll need to fill those in for yourself.<br />
<br />
One thing to note. I started off using my personal credentials for the SVN repository in the script. But because the script ended up being on several machines, we decided to create a “build” user that had read only access to the repositories to use in the build scripts.<br />
<br />
<pre class="brush:xml"><!-- This target does the replacement of the @VERSION@ variable in all the files -->
<target name="replace_all" description="replaces all instances of @SV_VERSION@ with the current build version" depends="setup">
<replace dir="${wd}" token="@SV_VERSION@" value="${sv_version}" summary="yes" />
<replace dir="${wd}" token="@SV_PARSE_AS@" value="${sv_parse_as}" summary="yes" />
</target>
<!-- This target does the replacement of the @VERSION@ variable in all the files EXCEPT the APEX application-->
<!-- It’s used to create an install file that maintains the @SV_VERSION@ Tags in the app, so we can move development to a new server -->
<target name="replace_clone" description="replaces specific instances of @SV_VERSION@ with the current build version" depends="setup">
<replace dir="${wd}" token="@SV_VERSION@" value="${sv_version}" excludes="${wd}/app/*" summary="yes" />
</target>
</pre>
<br />
The previous two build targets( <b>replace_all</b> and <b>replace_clone</b>) walk through the code tree and do replaces in all the source files, searching for the token listed and replacing each occurrence with the value provided. The first target replaces all occurrences, wherever they’re found, of both the @SV_VERSION@ and @SV_PARSE_AS@ variables. this would be used in a production build. The second target is used to create a clone of the code that would be in the development environment just in case we had to move it to a new server, which we had to do a couple times do to moving platforms, DB versions and APEX versions.<br />
<br />
<pre class="brush:xml"><!-- This target wraps all of the appropriate PL/SQL FILES-->
<target name="wrap" description="Wraps the appropriate PL/SQL files" >
<echo message="Wrapping all of the PKB files found in the working directory" />
<for param="file">
<fileset dir="${wd}/TRUNK" includes="**/*.pkb" />
<sequential>
<wrapfile file="@{file}" />
</sequential>
</for>
<echo message="Wrapping PL/PDF Certification Key" />
<for param="file">
<fileset dir="${wd}/TRUNK" includes="**/plpdf_cert_b.sql" />
<sequential>
<wrapfile file="@{file}" />
</sequential>
</for>
<echo message="Wrapping any SPECIFIC PKS files." />
<for param="file">
<fileset dir="${wd}/TRUNK" includes="**/sv_license_core.pks" />
<sequential>
<wrapfile file="@{file}" />
</sequential>
</for>
</target>
</pre>
<br />
The <b>wrap</b> target does what you’d expect. It uses the aforementioned <i><b>wrapfile</b></i> macro to apply the Oracle Wrap functionality to obfuscate all of the package bodies (*.pkb) in our code set. It also wraps a few sensative files that we want to keep private. You’ll notice the use of the for and sequential commands. These are available because of the ANT-CONTRIB library we included earlier.<br />
<br />
<pre class="brush:xml"><!-- This target ZIPS the files-->
<target name="zip" description="ZIPS the files for the user" >
<echo message="ZIPPING the final release..." />
<zip destfile="release_${sv_version}.zip">
<zipfileset dir="${wd}/TRUNK/app" prefix="sert/app" />
<zipfileset dir="${wd}/TRUNK/cfg" prefix="sert/cfg" />
<zipfileset dir="${wd}/TRUNK/ctx" prefix="sert/ctx" />
<zipfileset dir="${wd}/TRUNK/ins" prefix="sert/ins" />
<zipfileset dir="${wd}/TRUNK/license" prefix="sert/license" />
<zipfileset dir="${wd}/TRUNK/logger" prefix="sert/logger" />
<zipfileset dir="${wd}/TRUNK/pkg" prefix="sert/pkg" />
<zipfileset dir="${wd}/TRUNK/syn" prefix="sert/syn" />
<zipfileset dir="${wd}/TRUNK/tbl" prefix="sert/tbl" />
<zipfileset dir="${wd}/TRUNK/vw" prefix="sert/vw" />
<zipfileset dir="${wd}/TRUNK/doc" includes="*.pdf" prefix="sert/doc" />
<zipfileset dir="${wd}/TRUNK/plpdf" prefix="sert/plpdf" />
<zipfileset dir="${wd}/TRUNK" includes="ins.sql" prefix="sert" />
<zipfileset dir="${wd}/TRUNK" includes="ins_beta.sql" prefix="sert" />
<zipfileset dir="${wd}/TRUNK" includes="ins_admin.sql" prefix="sert" />
<zipfileset dir="${wd}/TRUNK" includes="unins.sql" prefix="sert" />
</zip>
</target>
</pre>
<br />
Once everything is wrapped and ready to roll, we need to zip it up in a nice little package. Here we’re using the <b>zip</b> target to tall ant which files we want to include in the zip. Line 4 indicates the name of the zip file to be created. Lines 5 through 20 indicate which files to include in the zip file.<br />
Examine the following example:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"><zipfileset dir="${wd}/TRUNK/cfg" prefix="sert/cfg" /></span><br />
<br />
The dir property tells where to look for the files and the prefix property says what the path should be within the zip file. So you effectively have full control of the directory structure that will be created when the file is unzipped.<br />
<br />
In our case we didn’t want to include everything that was in our source tree as there are some things that are really there just for us. By using multiple zipfileset directives, we selectively choose which files to include.<br />
<br />
<pre class="brush:xml"><!-- This target deletes the working directory-->
<target name="teardown" depends="properties">
<delete dir="${wd}" />
</target>
</pre>
<br />
The <b>teardown</b> target simply deletes the working directory after we’re done with it. This is the last of the real grunt work.<br />
<br />
Everything from here out is merely a set of “empty” targets that do no real work of their own. They simply reference the things that need to happen in their depends clause and echo out some information for the user.<br />
<br />
<pre class="brush:xml"><!-- This target BUILDS the full release set-->
<target name="release" description="Full Release Build" depends="properties,co,replace_all,wrap,zip,teardown">
<echo message="Full Build Complete..." />
</target>
</pre>
<br />
The first empty target is the full production build and is called <b>release</b>. The depends clause references all the things that should be executed and in which order. In the case of the production build, we see that it will perform the following tasks:<br />
<ol>
<li>PROPERTIES</li>
<li>CO</li>
<li>REPLACE_ALL</li>
<li>WRAP</li>
<li>ZIP</li>
<li>TEARDOWN</li>
</ol>
Since the <b>co</b> target depends on the <b>setup</b> target, we don’t have to call it specifically in the list.<br />
<br />
<pre class="brush:xml"><!-- This target BUILDS the full release set without wrapping-->
<target name="nowrap" description="Full Release Build - No Wrapping of PL/SQL" depends="properties,co,replace_all,zip,teardown">
<echo message="Unwrapped Build Complete..." />
</target>
</pre>
<br />
The second empty target (<b>nowrap</b>) creates a zip file that is basically the same as previous release target, but notice that it does not do the wrapping of the PL/SQL code. We use this target to create test build so we can debug any issues we may find while testing.<br />
<br />
<pre class="brush:xml"><!-- This target BUILDS the full release set-->
<target name="clone" description="Full Release Build - No Wrapping of PL/SQL" depends="properties,co,replace_clone,zip,teardown">
<echo message="CLONE Build Complete..." />
</target>
</project>
</pre>
<br />
The last empty target (<b>clone</b>) creates the clone that I spoke of above. It only processes a small subsection of the replacement variables and leaves the remainder intact. Again, this is for cloning a development environment. You may not need this.<br />
<br />
Once your script it’s done it’s as simple as executing a simple command line call.<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">ant <target> -D variable_name=value</span><br />
<br />
For instance, to do a full release build based on the targets in my build.xml file:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">ant release -D sv_version=020100</span><br />
<br />
While we don’t have automated builds using something like Maven or Hudson, it would be entirely possible. I hope this has been of some help to those of you who were interested.<br />
<br />
DDoug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com2tag:blogger.com,1999:blog-6363924398907149830.post-41381378467436909782011-06-23T15:24:00.000-05:002011-06-24T09:54:03.397-05:00'Growl' style notification messages for APEXA question was asked in <span style="text-decoration: underline;"><a href="http://forums.oracle.com/forums/thread.jspa?threadID=2191306">this thread</a></span> on the APEX forums that got me itching to do a science experiment.<br />The basic question was this:<br /><br />"Is it possible to produce 'Growl' style notifications in place of the standard APEX Success and Failure messages?"<br />In short the answer is an unequivocal 'Yes', and here's how:<br /><br />First, unless you're a JavaScript whiz and can write your own, you'll need to search out some sort of JavaScript library that provides the Growl style notification. After a quick Google search I found this page...<br /><br /><span style="text-decoration: underline;"><a href="http://webtoolkit4.me/2009/08/13/jquery-growl-likenotification-systems/">http://webtoolkit4.me/2009/08/13/jquery-growl-likenotification-systems/</a></span><br /><br />I chose to search for jQuery related notification systems because of the fact that jQuery is already integrated into APEX 4 and that would mean that there would be less in terms of external JavaScripts for me to load and manage.<br /><br />After looking at the individual option there, I chose to work with <em><strong>Gritter</strong></em> for a number of reasons.<br /><ol style="list-style-type: decimal"><li>I liked the look and feel of it's output. To me it felt the most like what I am used to seeing from Growl.</li><li>The JavaScript is very light. In total it's about 400 lines long un-minified. Much of that is white space and comments which means that minified it's going to be minute.</li><li>It pushes most of the heavy lifting back onto jQuery, where it should be, and the author doesn't try to over engineer the solution.</li></ol>You can choose what ever library you wish, but in this example I'll be using Gritter.<br /><br />The first thing you need to do is put the Gritter JavaScript where it can be accessed by APEX. As a general rule of thumb, it's a very bad habit to get into to put your own code into the /i/ directory provided by Oracle. So we create a directory on our web server to hold all of our custom code, normally named /c/. Inside this directory I created a directory to hold the gritter objects. I ended up with the following directory entries:<br /><br />/c/gritter/js<br />/c/gritter/css<br />/c/gritter/images<br /><br />The next thing to do is to include these scripts into your application. I wanted to see if I could completely replace the standard way APEX handles SUCCESS and FAILURE messages, so I want these scripts to be available on every page. There are two ways I could do this: I could create an After Header region on Page Zero that loads the scripts, or I could edit the page template and insert the script calls there.<br /><br />To make things as quick and easy as possible to load and troubleshoot, I chose to create a Page Zero region as follows:<br /><br />Region Name: <strong>GRITTER - INCLUDES<br /></strong>Region Type: <strong>HTML Text</strong> <br />Template Type: <strong>No Template</strong><br />Display Point: <strong>After Header</strong> <br /><br />and include the following code:<br /><br /><link href="/c/gritter/css/jquery.gritter.css" type="text/css" rel="stylesheet" /><br /><script src="/c/gritter/js/jquery.gritter.min.js" type="text/javascript"></script><br /> <br />After loading the scripts and doing a few tests, I found out a few things...<br /><br /><ol style="list-style-type: decimal"><li>You can use JavaScript in the Success and Failure message of any validation or process and it will be executed. News to me and something I'll file away for later use!</li><li>This isn't scalable as you'd have to change every message within your application to a JavaScript call.</li><li>Because of the way JavaScript deals with nested quotes within strings, life gets extremely interesting when the message you're trying to relay to the end user contains either single or double quotes.</li></ol>To make this work at the application level without forcing the developer to use JavaScript for every message we need to go a step higher and look at the templates. If you're unfamiliar with APEX templates you may not know that within a page template there are two sub-templates for the Success and Notification (failure) messages. By editing these areas within your page template you can move the handling of the JavaScript up so that the developers don't have to worry about it. They can treat the success and failure messages as they always have.<br /><br />To alter the template, navigate to the shared components for the application, click on Templates and edit the page template that you’re using throughout your application. In most cases there will probably only be one template that you’re using, but for more complex applications there may be 2 or 3 you need to edit. You really only need to edit the templates that are used on pages you want to use the growl notification. In my case, there was just one.<br /><br />Once you edit the template, you’ll need to scroll down to the <em><strong>Subtemplate</strong></em> region. This is where the <span style="text-decoration: underline;"><strong>Success Message</strong></span> and and the <span style="text-decoration: underline;"><strong>Notification</strong></span> (Fail) message templates are defined. <br /><br />In the Picture below you’ll see the code in both regions that replaced the original code included in the template. <br /><br /><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguHe8Y8JUcx8illSTzZnFu1JNlRf2BrjCNXAm8XqXxELpl-ipoBCBcWdP46LHv0t1vRNDu5XtDmZ81Ai5Dx8XD9iRSdATsLjbL4dCVdGiMzq0wDIELPBrrrGnH5Zx-_5rttQrcokXVCTo/" alt="PastedGraphic-2011-06-23-15-24.jpg" width="490" height="335" /><br /><br />In both cases, the first thing the code does is create a DIV, giving it an ID that we can grab ahold of later and sets its CSS style to “display:non”. This will keep the DIV from displaying until the Gritter script styles it. The contents of the DIV is the appropriate message template replacement variable, #SUCCESS_MESSAGE# and #MESSAGE#.<br /><br />The next bit of code is a call to a piece of JavaScript code that we’ll talk about in just a moment. The first call, to growlSuccess takes two parameters. First is the ID for the DIV so the script can get a handle on it, and the second is the duration for how long the notification should be displayed. In this case, 5000 is about 5 seconds. The second call, to growlSticky only takes one parameter, the ID of the DIV. This function creates a “sticky” notification that the user will need to dismiss. The reason I created this one is because you want to make sure the end user sees and acknowledges the any error message.<br /><br />The last piece of the puzzle is the javascript that kicks off the Gritter script. Again, I chose to implement this on Page Zero.<br /><br />Region Name: <strong>GRITTER - JavaScript<br /></strong>Region Type: <strong>HTML Text</strong> <br />Template Type: <strong>No Template</strong><br />Display Point: <strong>After Header</strong> <br /><br />And the code in this region is as follows.<br /><br /><script type="text/javascript"><br /><br /> function growlSuccess(vRegion, vLength){<br /> // Get the message out of the DIV created by the page template<br /> var vMessage = document.getElementById(vRegion).innerHTML;<br /> // Instantiate the gritter message.<br /> $.gritter.add({<br /> // (string | mandatory) the heading of the notification<br /> title: 'SUCCESS',<br /> // (string | mandatory) the text inside the notification<br /> text: vMessage,<br /> // (bool | optional) if you want it to fade out on its own or just sit there<br /> sticky: false, <br /> // (int | optional) the time you want it to be alive for before fading out<br /> time: vLength<br /> }); <br /> return false;<br /> }<br /><br /> function growlSticky(vRegion){<br /> // Get the message out of the DIV created by the page template<br /> var vMessage = document.getElementById(vRegion).innerHTML;<br /> // Instantiate the gritter message.<br /> $.gritter.add({<br /> // (string | mandatory) the heading of the notification<br /> title: 'MESSAGE',<br /> // (string | mandatory) the text inside the notification<br /> text: vMessage,<br /> // (bool | optional) if you want it to fade out on its own or just sit there<br /> sticky: true, <br /> // An image to place inside the gritter notification<br /> image:'#IMAGE_PREFIX#menu/info_32.gif'<br /> });<br /> return false; <br /> }<br /><br /></script><br /><br />This is the definition of the two functions that we called in the template code. The comments in the code should document what it’s doing fairly well. But the main thing to understand are is the call to gritter.add. This is the “magic” code that creates the Gritter “floating message”. <br /><br />Referencing the Gritter documentation, you’ll see that there are quite a number of options that I’m not using. I wanted to keep things fairly simple just to make sure I wasn’t fighting against complexity in the early stages. I did go an extra step and put an image inside the <em><strong>sticky</strong></em> message type that is used for Notifications, to differentiate it from the Success Message.<br /><br />Here’s the end result...<br /><br /><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFH0pvzQp14r2eSqE4CMQZqgUNqYsMYf6rL8laY-jTrx38CdAjGoZ_i8PK_Xz64N8zQ37aG3VLl8iBJi7twKf8DhnakT5lrxOO5LWHSugEYjnZS6OK7POibO01U03kkERtQR5uqh_b8w8/" alt="PastedGraphic1-2011-06-23-15-24.jpg" width="548" height="140" /><br /><br />Hopefully this not only answers the question, “Is it possible”, but also shows you that there is way more to APEX than meets the eye. You can use JavaScript in a number of places that you wouldn’t expect. I’m continually pleasantly surprised at the flexibility of APEX. <br /><br /><br /><strong>EDIT (6/24/11)</strong> - Patrick Wolfe, completely independently, has created a Dynamic Action plugin that does much the same thing (see the demo <a href="http://apex.oracle.com/pls/apex/f?p=654321:401:0">here</a>). The reason I went down this path is because the DA Plugin isn’t easily implemented for the APEX Success and Failure message. Anyway. Interesting that two people solved a strikingly similar problem and came up with much the same solution! <br /><br /><br /><br />Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com5tag:blogger.com,1999:blog-6363924398907149830.post-63447431389087312882011-06-22T15:16:00.000-05:002011-06-22T15:16:27.155-05:00It's been quiet... Too Quiet!You have probably noticed that this blog has been very quite for the last few months... Well, there is a reason for that.<br />
<br />
Apart from the <a href="http://www.sumneva.com/apex/f?p=15000:410:0::NO::TRACKBACK:sumnevas_doug_gault_contributes_to_two_new_apex_books">books</a> that I've been involved in writing, we at <a href="http://www.sumneva.com/">Sumneva</a> been working feverishly to put the finishing touches on our first product, <b>sumnevaSERT</b>. And today, we release it into the wild.<br />
<br />
And with all of scary security breaches that have happened recently, the release couldn't have come at a better time.<br />
<br />
For those of you who aren't familiar, <b>sumnevaSERT</b> is a simple yet powerful tool that outlines potential security risks in any Oracle APEX application and provides recommendations on how to mitigate them. You can the Sumneva news post about it <a href="http://www.sumneva.com/apex/f?p=15000:410:0::NO::TRACKBACK:introducing_sumnevasert">here</a>, and get more information about it <a href="http://www.sumneva.com/sert">here</a>. Or<br />
<br />
You can also come and see us at <a href="http://www.kscope11.com/">ODTUG KScope11</a>. We'll have a booth in the exhibition hall and will be giving a vendor presentation on securing your APEX applications.<br />
<br />
Now that the release is out in the wild, hopefully I'll have a bit more time to finish some half completed blog posts and get back out into the world a bit more.<br />
<br />
But keep an eye out, because <b>sumnevaSERT</b> is just the beginning. We plan to continue to support our mission to make developing secure and performant APEX applications even easier.<br />
<br />
Watch this space!Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com0tag:blogger.com,1999:blog-6363924398907149830.post-63874543256815734222011-06-10T12:45:00.000-05:002011-06-10T12:45:11.562-05:00Oracle Author Podcast.<span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;">I recently had the pleasure of co-authoring the APress book, <a href="http://www.apress.com/9781430231479">Beginning Oracle Application Express 4</a>. It was both a trying and rewarding experience, but I'm glad I did it.</span><br />
<span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"><br /></span><br />
<span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;">A couple weeks ago I also participated in creating a <a href="http://feedproxy.google.com/~r/OracleAuthorPodcasts/~3/RxkrKygPElk/10131468_AppXprss_4_061011.mp3">Podcast</a> about the book. </span><br />
<span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"><br /></span><br />
<span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;">Here's some information about it...</span><br />
<span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"><br /></span><br />
<blockquote>
<span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;">A conversation with Patrick Cimolini, Martin D'Souza, and Doug Gault; Authors of Beginning Oracle Application Express 4. David Peake, Principal Product Manager for APEX, chats with some of the authors of the book. They will discuss various aspects about the book including the main reason for the book, who the book is focused towards, and some behind the scenes information about it's writing.</span></blockquote>
<br />
<blockquote>
</blockquote>
<blockquote>
</blockquote>Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com0tag:blogger.com,1999:blog-6363924398907149830.post-12677237252648238942011-05-07T08:35:00.001-05:002011-05-07T08:36:17.797-05:00APEX 4.1 Early Adopter Available.The APEX team has once again surpassed expectations and has released the Early Adopter version or APEX 4.1 on <a href="http://tryaxpexnow.com/">http://tryaxpexnow.com</a>.<br />
<div>
<br /></div>
<div>
A list of what's new appears in the <a href="http://apex.oracle.com/pls/apex/f?p=52663">Feature Description</a> application, but both <a href="http://joelkallman.blogspot.com/">Joel Kallman</a> and <a href="http://www.blogger.com/"><span id="goog_1914651215"></span>David Peake<span id="goog_1914651216"></span></a> warn that there is likely to be more in the final production release.</div>
<div>
<br /></div>
<div>
After having a look at the features, here are some that really stand out to me:</div>
<div>
<br /></div>
<div>
<ul>
<li><b>Declarative Support for Buttons to Trigger Dynamic Actions </b>- The initial version allows you to use any IMAGE or HTML button to trigger dynamic actions. Theme based buttons will currently only work in Theme 21, but I'm sure that will be expanded for the production release.</li>
<li><b>Dynamic Lists</b> - The ability for a list to be based on a SQL statement or a PL/SQL function returning a SQL statement is huge. This will make it way easier to create menuing systems (even CSS based tabs) based on dynamic content stored in tables or gleaned from meta data.</li>
<li><b>Improved Error Handling </b> - The features listed here are two-fold.</li>
<ul>
<li><b>Settable Error Display Location for Processes</b> - For OnSubmit type page processes you can now set the "Error Message Display Location" to either a "Separate Error Page" or "Inline in Notification".</li>
<li><b>New Error Handling Function</b> - A new function has been provided that allows developers to modify or log any errors which occur in apex. (I wonder if they used <a href="http://tylermuth.wordpress.com/2009/11/03/logger-a-plsql-logging-and-debugging-utility/">Tyler Muth's Logger Package</a>). <a href="http://www.inside-oracle-apex.com/">Patrick Wolf</a> is slated to let us know more soon!</li>
</ul>
<li><b>Plugin Enhancements</b> - There are several plug-in enhancements but the ones that caught my eye were</li>
<ul>
<li><b>Adding Plug-in Support for Authorization Schemes </b></li>
<li><b>Increased number of custom attributes to 15</b></li>
<li><b>New Plugin Attribute type Checkbox</b></li>
</ul>
<li><b>Enhanced Tabular Forms - </b>APEX 4.0 introduces HUGE leaps forward in Tabular forms and that theme has been continued in APEX 4.1.</li>
<ul>
<li><b>Validations</b> - Tabular forms now support all validation types. Bind Variable syntax, substitution syntax and Column name are now available depending upon what type of validation you're implementing.</li>
<li><b>Processes </b> - Processes can now be defined for tabular forms as well. These processes allow for easier processing of the each row's items without having to deal with the <b><i>apex_application g_f0X</i></b> arrays.</li>
<li><b>Use of ROWID </b> - You're now allowed to use ROWID as the primary key for Automatic DML Processing in tabular forms.</li>
</ul>
<li><b>Consistency of Item Based Buttons</b> - Item based buttons have now been brought in line and now offer the same behavior has Region based buttons.</li>
</ul>
<div>
While I can't wait to get my hands on some of the new features, this also means that there will need to be some updates to our <a href="http://www.sumneva.com/training">training material</a>... *Sigh*, it never ends! </div>
</div>Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com1tag:blogger.com,1999:blog-6363924398907149830.post-60206215749836197282010-03-31T18:21:00.000-05:002010-03-31T19:11:38.848-05:00Beginning Oracle Application Express 4That’s the title of the book I’ve agreed to write for <a href="http://www.apress.com">APRESS</a>, or at least the working title.<br /><br />The book will be aimed at new comers to <a href="http://apex.oracle.com/">Application Express</a>, introducing them to the environment via the development of a full system and using as many of the new features as possible. However, I’m hoping that it will be useful for people who have dipped their toes in the waters of 3.2 and want to get up to speed on what 4.0 has to offer. The book is due to hit shelved early next year, so it’s a ways off. But as APEX 4 is still only in Early Adopter, that’s probably a good thing.<br /><br />This is the first time I’ve attempted anything like this, and I’m taking it on with more than just a little trepidation. However my good friends, and business partners <a href="http://spendolini.blogspot.com">Scott Spendolini</a> and <a href="http://jes.blogs.shellprompt.net/">John Scott</a> (Co-Authors of the APRESS book <span style="text-decoration: underline;"><strong><a href="http://www.apress.com/book/view/159059827x">Pro Oracle Application Express</a></strong></span>) assure me that it’s a wonderful experience that I will cherish for the rest of my days! (Actually John said that the two best days are the day you start it and the day you finish, and I believe that to be closer to the truth!)<br /><br />I’m going to be blogging about my experience. Both about writing the book and about some of the things I learn along the way. So watch this space for more on the book and my travels along the APEX 4.0 path.<br /><br />Wish me luck! <br /><br />Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com8tag:blogger.com,1999:blog-6363924398907149830.post-89208646282311627712010-03-05T09:01:00.000-06:002010-03-05T09:39:45.850-06:00Sumneva Education Slots Still Available.There are still slots available on many of the Sumneva Education Courses world wide. The training will be covering APEX 3.2.1, but there will definitely be an opportunity to ask questions about the differences in APEX 4.0 and we might even have time to show you some of the highlights.<br /><br /><span style="color: rgb(252,82,63);"><strong>Brussels, Belgium (Public Classroom)</strong></span><br /><a href="http://www.sumneva.com/apex/f?p=15000:310:0::NO::P310_TRAINING_SESSION_ID:701">Introduction to Oracle APEX I</a> <span style="color: rgb(252,83,0);"></span> - 08-MAR-2010<br /><a href="http://www.sumneva.com/apex/f?p=15000:310:0::NO::P310_TRAINING_SESSION_ID:702">Introduction to Oracle APEX II</a> - 11-MAR-2010<br /><a href="http://www.sumneva.com/apex/f?p=15000:310:0::NO::P310_TRAINING_SESSION_ID:703">Advanced Oracle APEX</a> - 15-MAR-2010<br /><br /><span style="color: rgb(252,82,63);"><strong>Manchester, UK (Public Classroom)</strong></span><br /><a href="http://www.sumneva.com/apex/f?p=15000:310:0::NO::P310_TRAINING_SESSION_ID:701">Introduction to Oracle APEX I</a> - 22-MAR-2010<br /><br /><span style="color: rgb(252,82,63);"><strong>Alexandria, VA USA</strong></span><br /><a href="http://www.sumneva.com/apex/f?p=15000:310:0::NO::P310_TRAINING_SESSION_ID:701">Introduction to Oracle APEX I</a> - 12-APR-2010<br /><a href="http://www.sumneva.com/apex/f?p=15000:310:0::NO::P310_TRAINING_SESSION_ID:702">Introduction to Oracle APEX II</a> - 15-APR-2010<br /><br /><span style="color: rgb(252,82,63);"><strong>Americas (OnLine)</strong></span><br /><a href="http://www.sumneva.com/apex/f?p=15000:310:0::NO::P310_TRAINING_SESSION_ID:701">Introduction to Oracle APEX I</a> - 22-MAR-2010<br /><a href="http://www.sumneva.com/apex/f?p=15000:310:0::NO::P310_TRAINING_SESSION_ID:702">Introduction to Oracle APEX II</a> - 31-MAR-2010<br /><a href="http://www.sumneva.com/apex/f?p=15000:310:0::NO::P310_TRAINING_SESSION_ID:644">Intermediate Oracle APEX</a> - 12-APR-2010<br /><a href="http://www.sumneva.com/apex/f?p=15000:310:0::NO::P310_TRAINING_SESSION_ID:645">Troubleshooting and Debugging APEX</a> - 21-APR-2010<br /><br /><span style="color: rgb(252,82,63);"><strong>Discounts</strong></span><br />Qualified companies can receive up to 10% off the cost of their booking. <a href="mailto:info@sumneva.com">Contact us</a> to find out if your company qualifies. <br /><span style="color: rgb(252,82,63);"><strong>Questions or want private on-site training?</strong></span><br />Should you have any questions about the courses, technical requirements or want to discuss private on-site training, please send us a note at <span style="text-decoration: underline;"><a href="mailto:info@sumnertech.com">info@sumnertech.com</a></span> or call us at (703) 879-4615 Americas / +44 113 386 9296 Europe . We look forward to seeing you soon!<br />Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com0tag:blogger.com,1999:blog-6363924398907149830.post-32349519026502013582010-03-03T19:31:00.000-06:002010-03-04T16:05:13.091-06:00Refreshing Flash Charts with AJAX.<span style="color: rgb(252,83,0);"><strong>NOTE: </strong></span>This post makes use of internal APEX JavaScript that is not part of the standard public API’s. Therefore it is likely not supported, so use at your own risk!<br /><br />--------------------------<br /><br />Yesterday, I ran across <a href="http://forums.oracle.com/forums/thread.jspa?messageID=4139943#4139943">this post</a> on the OTN APEX Forums. The problem was basically this.<br /><br />Say you have a chart which you want to refresh each time someone changes a select list value. Sure you could have a select list with submit, but that would cause a redraw of the entire page and, depending on what else might be on that screen, could potentially incur some wait time on behalf of the user. <br /><br />Another way to do this would be to use the chart’s Asynchronous Refresh feature, but this would cause the chart to refresh on a set interval, not on an event. And to make this worth your while, the interval would have to be so small (seconds) that you would instigate an unnecessary amount of network traffic.<br /><br />So how <em><strong>do</strong> </em>you get a chart to refresh asynchronously? Lets have a look<br /><br />First, what I’ve done is to create a simple chart that selects the employees and their salaries from the EMP table. Along with it I created the select list upon which it will depend.<br /><br /><span style="color: rgb(252,83,0);"><strong>Select List SQL<br /></strong></span><br />select null link, ENAME label, SAL value1<br />from "SUMNEVA"."EMP"<br />where deptno like decode(:P2_DEPT_NO,'%null%','%',:P2_DEPT_NO)<br /><br /><span style="color: rgb(252,83,0);"><strong>Select List SQL<br /></strong></span><br />select DNAME display_value, DEPTNO return_value <br />from DEPT<br />order by 1<br /><br /><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjf63tm89vpgttyF-_WtA247PhGcx3IC8PtMEKHViHJOtnmsMay0EnHCoB-IDcYDmwgzvDLtSJ9-Hb3YfqqolWWzBD9uQTcJUdmuLc-OY6Okvt_-cnz7tx-G3OuR_stSsO0vr7uE0s4KKk/" alt="PastedGraphic2.211Fch1GOGvR.jpg" width="439" height="325" /><br /><br />If this were a select list with submit, then everything would work fine as the newly selected value for the department would get set in session state and the chart would redraw using that value when the page was refreshed. However i want to bypass the page submit and make the chart refresh without redrawing the entire screen. How can this be done? <br /><br />We can find the initial clues by looking at what APEX does internally when you turn ASYNCHRONOUS REFRESH on for a chart.<br /><br />Looking at the chart region’s SOURCE in the REGION DEFINITION tab, shows us that APEX uses a number of replacement variables, including #CHART_NAME# and #CHART_REFRESH#. <br /><br /><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoK_qM6ssUFNxn0y5gIkStb-ZTRmtdmP1AHXq729f7CuS3dhEBvHWfvh1oppPb01-Z5Fk5E2K878n7yUol5-hYfFKjPG3dlN9_uLZtzGTLbOHEYJqDyezHohd_-EF8he5ZJY5g-gyJhCI/" alt="PastedGraphic3.AxFtSjJyjwb6.jpg" width="445" height="235" /><br /><br />It’s the second of these that initially caught my attention. If you turn Asynchronous Refresh on for the chart and run the page, you can then view the source to see the javascript that is inserted in place of the #CHART_REFRESH# Variable. <br /><br /><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIhPhZzxkIkbB79ggId1VD5IeYUPPasrJNQIDnVS68MQ0NCMZzi2MSjhCkxSWXA2_PagWSRt8KzufGpoACuxYI57t5_qdv2uhjgh0QqnKhdSQNTa561l5uM8sMnJgj1rIq2Qgr0XRVW3M/" alt="PastedGraphic4.vEh8qFlWzfUf.jpg" width="446" height="123" /><br /><br />I won’t go into the details of what this is doing, but the code that does the “heavy lifting” is<br /><br />apex_RefreshChart (2, '10588887924364140363', 'en-us');<br /><br />After tracking down the definition of this function, now now that the method has the following signature.<br /><br />apex_RefreshChart (A, D, C);<br /><br />A = Current Page Number<br />D = Name of the chart with the initial ‘c’ removed<br />C = Language <br /><br />So we could potentially use this function to our own ends, but to do that we need to know the value of #CHART_NAME#, which is only in context as the chart source is being rendered to the page. What this means to us is that what ever JavaScript function we create needs to be created as part of the rendering of the chart itself. <br /><br />Editing chart SOURCE in the REGION DEFINITION tab, I added the following JavaScript function below the #CHART_REFRESH# replacement variable.<br /><br /><script type="text/javascript"><br />function myRefreshChart(){<br /> var chartName = '#CHART_NAME#';<br /> chartName = chartName.substring(1);<br /> apex_RefreshChart(&APP_PAGE_ID., chartName, 'en-us');<br />}<br /></script><br /><br />The function basically creates a variable for the chart name and strips off the first character. (This is required for the call to apex_RefreshChart as that function actually prepends the ‘c’ back on to the name parameter). It then calls the apex_RefreshChart function.<br /><br />Now it would be tempting to think that we could just hook this script to the on_change event for the select list, but there is a problem with that. The chart series query depends on the value of P2_DEPT_NO that is <em>in session state</em>, and if we’re not submitting the page, then the session state value for the item won’t change. <br /><br />To force the change, we can use APEX’s standard AJAX toolkit; htmldb_get(). <br /><br />As with any AJAX function you need the following things. <br /><br /><ol style="list-style-type: decimal"><li>Application Item(s) to pass values to the process </li><li>An Application Process </li><li>A JavaScript function to execute the AJAX call</li><li>An event that initiates the function</li></ol>First we create an Application Item called AJAX_DEPT_NO that will be used to pass the value the user chose in the select list.<br /><br />Then we create an Application Process called SET_DEPT_NO that does just that.<br /><br /><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-YXtVxExX1uj7NCWc8za1-ho5vZhGTjqHo2oxi1NgcG9rrtNExEv0E8SVNaQhotpndgJUafAsOSBthiRM_JgnVyTwmPI2ixsmyOnvfiVQOM0K_fpwq56PDLciAE6rT_BvAH05qtUC96g/" alt="PastedGraphic5.ofvPSzE57SuC.jpg" width="483" height="244" /><br /><br />Now we need to create the Javascript that will do the AJAX call and then call the myRefreshChart() function. You could easily do this in the HTML HEADER, but I like to put these things in their own HTML REGION with a render sequence of AFTER HEADER.<br /><br /><script type="text/javascript"><br />function selectChanged(filter)<br />{<br /> var get = new htmldb_Get(null,$v('pFlowId'), 'APPLICATION_PROCESS=SET_DEPT_NO',0);<br /> get.add('AJAX_DEPT_NO', filter.value);<br /> var ret = get.get();<br /><br /> myRefreshChart();<br />}<br /></script><br /><br />If you’re used to using AJAX in APEX, then none of this should be of any surprise to you. We’re using htmldb_Get to call the application process and to send the current value of the select list (represented in the function by the <em>filter</em> variable).<br /><br />Once the application process is complete we then run the myRefreshChart() function to tell the chart to refresh it’s data.<br /><br />The last thing we need to do is to put an on_change event on the select list and have it call the selectChange function indicated above. Edit the select list and in the ELEMENT region, enter the following in the <strong>HTML Form Element Attributes</strong>.<br /><br /><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimBaWJOE62CWquhx4UVCrEOnwopXoTlEOomwPqkf18kD9jo2fYJHEsfN195mJ0TODO7pKkpipSmfuid_g_cLlPjYL9UMDIxKh0yoPuqigswmrHen4ABpj0dhmTuqNLclZl33H_B0qpQ9s/" alt="PastedGraphic6.dKBCJtih1T05.jpg" width="506" height="131" /><br /><br />This calls the selectChanged JavaScript function each time the select list changes and passes it a reference to the select list itself. <br /><br /><span style="color: rgb(252,83,0);"><strong>Put it all together ...<br /></strong></span><br />Once everything is in place, we can now run the page and see that every time the select list changes, the graph updated without refreshing the page.<br /><br />You can see an example of this in the <a href="http://apex.oracle.com/pls/apex/f?p=18570:2:">Sumneva workspace</a> on <a href="http://APEX.ORACLE.COM">APEX.ORACLE.COM</a> <br /><br /><br />Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com9tag:blogger.com,1999:blog-6363924398907149830.post-17356783299408996392010-02-15T10:11:00.001-06:002010-02-15T10:47:59.718-06:00Headed to RMOUGAll my bags are packed, and ready to go....<br /><br />IN about 2 hours I’ll be stepping out the door to head to the <a href="http://www.rmoug.org/">Rocky Mountain Oracle user Group</a> (RMOUG). Both <a href="http://spendolini.blogspot.com/">Scott Spendolini</a> and I will be presenting there on behalf of <a href="http://www.sumneva.com/">Sumneva</a>.<br /><br />Scott will be presenting <em><strong>Troubleshooting Oracle Apex </strong></em>on Tuesday, and I’ll be presenting <em><strong>Performance Tuning APEX Applications</strong></em> and <em><strong>Replicating NetFlix Drag & Drop With APEX </strong></em>on Wednesday and Thursday respectively.<br /><br />If you’re going to be there, please swing by and say ‘Hi’.Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com0tag:blogger.com,1999:blog-6363924398907149830.post-92221769482276099882010-02-09T17:18:00.006-06:002010-02-09T17:39:38.457-06:00Warning a user that the form has changed he navigates away without saving.For those of you who haven't visited the new Sumneva.com site, here's an excuse.<br /><br />We've added a <a href="http://www.sumneva.com/apex/f?p=15000:1300:0::NO:::">Tips & Tricks</a> section on the Support tab where we will be sharing little tid-bits of information that we learn as we work with APEX. Our goal is to try to continually add new entries and make this a repository of useful information.<br /><br />I just posted my first tip - "<a href="http://www.sumneva.com/apex/f?p=15000:1310:0::NO::P1310_TIP_ID:121">Warning a user that the form has changed.</a>"<br /><br />Watch for more of these as time goes on, or you can follow <a href="http://twitter.com/sumneva">@sumneva</a> on Twitter to be notified of new Tips & Tricks.<br /><br />EnjoyDoug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com0tag:blogger.com,1999:blog-6363924398907149830.post-42874477454576699962010-02-09T07:08:00.002-06:002010-02-09T07:15:52.845-06:00APEX @ Your Oracle User Group - Mach IIIn <a href="http://jes.blogs.shellprompt.net/2010/02/09/apexyour-oracle-usergroup/">this post</a>, my new business partner (more on that in another post) <a href="http://jes.blogs.shellprompt.net/">John Scott</a> mentioned that if you wanted him to speak at your Oracle User Group meeting about APEX, he'd be very happy too.<br /><br />Not to miss out on any of the fun I think that I can speak for all four of us at <a href="http://www.sumneva.com">Sumneva</a> and say that if you need someone to speak about APEX at a User Group, or other technical related gathering, then do not hesitate to ask.<br /><br />The four of us are dedicated to furthering the APEX cause and would be more than happy to help spread the message.Doug Gaulthttp://www.blogger.com/profile/16786329323466667017noreply@blogger.com0