Friday, December 30, 2011

Duplicate CFArgument Gotcha!

Today I was debugging a component which returned a query for a paginated display.

This component has the page number and limit passed in, but also has default values set in the CFArgument tags.

At some point during development (probably while copy-pasting a bunch of cfargument tags for quick editing of names and default values) one of the arguments was left twice.

At appeared something like this:

<cfcomponent ...>
<cffunction name="queryrecs" access="public" output="No" returntype="query">
<cfargument name="someid" type="numeric" required="No" default="0">
<cfargument name="something" type="string" required="No" default="">
<cfargument name="somethingelse" type="string" required="No" default="">
<cfargument name="anotherthing" type="string" required="No" default="">
<cfargument name="page" type="numeric" required="No" default="1">
<cfargument name="limit" type="numeric" required="No" default="10">
<cfargument name="limit" type="numeric" required="No" default="10">

<cfset var pagerecs = "">
<cfquery name="pagerecs">
select ...
from ...
where ...
LIMIT #arguments.limit# OFFSET #(arguments.page-1)*arguments.limit#
</cfquery>
<cfreturn pagerecs />
</cffunction>
</cfcomponent>


Notice the two limit arguments. This is really bad. When the method is called and the "limit" parameter passed in the first cfargument tag catches the passed in "limit" parameter and the second "limit" cfargument tag overwrites the passed in set value in the ARGUMENTS scope to the default value.

It's just something to be mindful of when things aren't working as expected.

That's a wrap!

Saturday, December 17, 2011

Focus Text Input at the End of the Value [SOLVED CROSS BROWSER]

I just saved the world! It didn't notice, so I have to blog about it.

I discovered a super simple, fully cross-browser compatible, solution to focusing a text input at the end of the current value.

I needed to do this as part of the application I am currently working on. The html block, including the search input field, are returned form an ajax call and replace the existing HTML within the specified block. After the ajax call returns and replaces the content it needs to focus the input field at the end of the input value.

Moving the cursor, cross-browser friendly, is always messy. I had been dealing with character codes to clear the field on escape and to submit on the enter key, so I get this idea, 'Why not append the 'character' from the key code for the "END" key onto the input value after focusing it?' If that worked, someone would have done it before. In theory this would be done by appending String.fromCharCode(35) to the current value. Would that move the cursor to the end? I try it, it doesn't work.

My next idea was to just set the value as the "END" key. My thought was that it's not a visible character, so maybe it's a more of an instruction key, so-to-speak, and won't mess things up. I try it, it blanks out the value - not what I wanted, but it was worth a try.

So then I try saving the original value in a variable, then set the value to "END" key (clearing the input as before), then re-set the value to the original value. 'This is nuts!' I'm thinking to myself, 'Why am I even trying this?' but I try it anyway. It worked, wait, what??? Yes, it worked!!! I couldn't believe it. I had to test it a hundred times. It's working solid. Unbelievable. I even put the cursor in the middle of the word and hit enter (triggering the ajax) and it replaces the content block, focuses the input, and the cursor appears at the end right where I want it. This is too cool. I'm in Firefox, I re-test it in Chrome, Safari, both work. This is crazy-good news! I'm thinking, but it's sure to fail in IE, everything cool always fails in IE. I'm on my macbook pro, so I load up my Virtualbox with multiple IE's installed on an old Windows XP instance and I test my code. Low and behold, it works in IE7 and in IE8. I'm astonished! Litterally, my jaw dropped, followed by that irresistible smile of success.

I'm still not entire sure *why* it's actually working. The 'END' key must be sticky in some manner so that when the value is replaced it's inserted in front of the cursor. It doesn't make perfect sense that the cursor would stay at the end of the string following the value being reset by javascript while the input is in focus. There's a lot going on there. But something about it being sticky to the end, and not at a specific character position, is my only guess as to 'why' this works. I'm just flipping happy that it does - and fully cross-browser compatible to boot!

Here's my code sample:

var $t = $("#myinput")  //cache the target so we're not parsing for it multiple times
v
ar oldv = $t.val();  // remember the original value
$t.focus().val(String.fromCharCode(35)).val(oldv);
  // focus it, set as 'END' key, reset to original

That's it. A simply awesome solution.

Friday, December 9, 2011

Prevent Railo's Default FLEX Integration From Generating WEB-INF Directories in Every Web Subdirectory

I recently upgraded to a new AWS server and started from scratch with Apache + Tomcat + Railo 3.3. This comes with a short vertical learning curve in regards to learning Tomcat set-up woes and new railo server.xml default settings. The last of which was the biggest surprise and confusingly new issue until I learned how easy it was to resolve.

New Railo installs, by default, are set up to integrate with FLEX. This should either be an option during installation, or... it should be an option during installation. I had never used the new railo-...-installer.run program, I really liked it a lot, but I really wish it had asked me if I wanted FLEX integration in the process. It's a small thing, but it's always the smallest things that make the biggest difference. It's okay, I'm still a [Railo] believer.

So, to fix this issue, go to the bottom of /opt/railo/lib/railo-server/context/railo-server.xml (or where ever you have your Railo engine installed)

Change:
<flex configuration="xml"/>

To:
<flex configuration="manual"/>

Then you cango to your website root directory and run:
$ ls -alR | grep 'WEB-INF'


That will show all of the 'WEB-INF' directories that you don't need (in your /images, /css, /js, ...) that you should delete with following command:
$ sudo rm -RIf ./css/WEB-INF
$ sudo rm -RIf ./images/WEB-INF
$ sudo rm -RIf ./js/WEB-INF
... etc., etc.


Notes on the above: the 'R' = recursive, the 'I' (capital i, not lowercase L) ignores errors, and the 'f'' means 'force' to ignore 'are you sure' confirmation questions.

Then you can go into the Railo SERVER admin and Restart the server there, or recycle Tomcat and that will regenerate the one and only required 'WEB-INF' in the web root directory.


- UPDATE -
It turns out the above was not the only issue, as it was not completely resolved. After a lot more testing I found that I had also incorrectly set up my Tomcat Virtual Hosts. On this Ubuntu Railo-Tomcat server the Tomcat server.xml is located in /opt/railo/tomcat/conf/server.xml. My site's host xml was not set up correctly - missing the attribute 'autoDeploy' in conjunction with having an unwanted 'appBase' attribute. (See the first and second wrong ways below.)

My first WRING way:
<host name="www.website1.com" appbase="/var/www/website1">
<context path="" docbase="">
...
</host>


My Second WRONG way:
<host name="www.website1.com" appbase="/var/www" autoDeploy="false">
<context path="" docbase="website1">
...
</host>

// this actually worked, but we don't need appBase at all for CFM. the reason the first attempt above was screwing things up is that not setting 'autoDeploy' at all defaulted to 'true'. Setting it to false fixed the WEB-INF in the sub-directories, but it's still not right.

Here is the RIGHT way:
<host name="www.website1.com">
<context path="" docbase="/var/www/website1">
...
</host>



That's today's lesson learned.

Flexible Width Text Link as Buttons with Background Image (SOLVED)

The important part to note in the CSS below is the right margin on the <a> link tag - it's -20px. That beings in the right side so the :hover's work correctly.

When that is done another way the mouse over on one of the ends doesn't work and you get the background image shifting correctly on the end but not under the text. This way makes the link tag cover the entire span tag so both are always triggered on the native :hover state.


THE HTML:

<div class="button-container">
    <span class="button-wrapper">
        <a href="/fr/snapdragon-mobile-processor">Start</a>
    </span>
</div>


THE CSS:

#block-views-training-module-listing-block-2 .views-field-nid .field-content {
    background: url("images/trainmod-start-blank-wide-sprite.png") no-repeat scroll 0 0 transparent;
    display: block;
    float: left;
    height: 30px;
    position: relative;
    /*width: 82px;*/
}
#block-views-training-module-listing-block-2 .views-field-nid a {
    background: url("images/trainmod-start-blank-wide-sprite.png") no-repeat scroll 100% 0 transparent;
    color: #666666;
    display: block;
    font-size: 14px;
    font-weight: 600;
    height: 30px;
    line-height: 30px;
    margin: 0 -20px 0 0;
    padding: 0 30px 0 15px;
    position: relative;
    text-decoration: none;
    /*width: 82px;*/
}
#block-views-training-module-listing-block-2 .views-field-nid .field-content:hover {
    background-position: 0 100%;
}
#block-views-training-module-listing-block-2 .views-field-nid a:hover {
    background-position: 100% 100%;
}


THE BACKGROUND IMAGE:





Thursday, December 8, 2011

Update to Ubuntu Set Timezone Post

Just another reminder on how to quickly set the local timezone on Ubuntu Server.

I had blogged about this previously, but I didn't make it simple enough even for myself, so this is a do-over.


Find your timezone specific file in /usr/share/zoneinfo/America/.

Then run the following three commands:

$ cd /etc
$ mv localtime localtime_orig
$ ln -s /usr/share/zoneinfo/America/tzfilename localtime

Reboot and you're set. Now java defaults to this timezone.