Words about stuff, and things related to stuff

Quick jQuery email address obfuscator

Here's a quick little jQuery script I created just now. Don't give your email address to spam bots! Instead, try this.


view plain print about
1<a href="/contact"><span class="no-script">Contact Us</span><span class="obfuscate">com/mydomain//me</span></a>
(Use your email address in the format above, where your original address is me@mydomain.com)


Force HTTP:// prefix in url form inputs w jQuery

Here's a quick n' dirty way to make sure any URL in a form input starts with "http://"

view plain print about
1$('form input.url').keyup(function(){
2        if (
3            ($(this).val().length >
6) && ($(this).val().substr(0,7) != 'http://')
4            || ($(this).val() == '')
5            ){
6            $(this).val('http://' + $(this).val());    
7        }
8    });

This ensures that the contents of the input will start with http://. The length > 6 is a bit of a hack, but if you delete everything in the field, or start typing over 6 chars (i.e. long enough to look for http:// at the beginning of the string), the prefix gets inserted for you. I am also loading my input with value="http://", but this could also be done w/ the function above by triggering it on page load rather than just on keyup for the specified input.

Fast easy 'current link' highlighting with CFML and jQuery

First the snippet (watch for line wrapping when copy/pasting this):

view plain print about
1// current link highlighting
2 $('#topLinksNav a[href="<cfoutput>#listLast(cgi.script_name,'/')#</cfoutput>"]').first().addClass('currentLink').parents('li').addClass('currentLink');
3// make sure top level link for this element is also highlighted
4 $('#topLinksNav ul').has('.currentLink').siblings('a').addClass('currentLink');

This finds any link with an 'href' attribute matching the name of your current page, e.g. "pagename.cfm" , and adds a class of 'currentLink' (note this is in a site where all pages are in the root directory - obviously this needs to be changed to match your site structure, but the same idea applies).

A sample of the ul/li menu structure I'm using is below.

Then you just need a CSS rule for the '.currentLink' class, perhaps

view plain print about
1#topLinksNav li.currentLink{
2 set some background color here
7#topLinksNav >
li > a.currentLink{
8 set a highlighted text color here only for top level links

Here's the sample menu structure for the syntax above something like

view plain print about
1<ul id="topLinksNav">
3<a href="index.cfm">Top Level Page</a>
4 <ul>
5 <li>
6 <a href="subpage1.cfm">Secondary Menu Page</a>
7 </li>
8 <li>
9 <a href="subpage2.cfm">Secondary Menu Page</a>
10 </li>
11 </ul>
12 </li>
14<a href="contact.cfm">Top Level Page</a>
15 <ul>
16 <li>
17 <a href="subpage1.cfm">Secondary Menu Page</a>
18 </li>
19 <li>
20 <a href="subpage2.cfm">Secondary Menu Page</a>
21 </li>
22 </ul>
23 </li>

Delay loading of ajax content with jQuery

I needed a function that would take the input of a form, show a loading graphic for a few seconds, and then load some content from an ajax page with jQuery load().

The loading is easy, but i had to experiment a little to get the right syntax for the 'wait a few seconds' part.

Here's what i came up with... this is all part of a function that runs 'onclick' from a link.

var loadingGraphic = '<img src="loading.gif">';
var gameContent = 'ajaxpage.cfm';



this puts the loading graphic in place immediately with html(), and then waits 2 seconds before running the load() function to replace the contents via ajax. 

Persist form values on reload w/ jQuery & ColdFusion

A designer friend presented me with a somewhatlong and complicated HTML form. It is a survey/contest entry for employees of a specific industry, with dozens of fields which include regular text inputs, text areas, and radio buttons.

My task is to create a routine to submit this form via e-mail and store the contents in the database. ColdFusion makes that easy with the built-in #form# scope. And for validation, I simply made his HTML < form > into a <cfform>, and all of the <input> and < textarea > elements into <cfinput> and <cftextarea>, adding 'required="true"' and a validation rule and/or message for each. Whipping up a quick server-side validation for the required fields was also a snap with CF.

Then it occurred to me - if there is in fact some error with the user submission, we will return the user to the form showing an error message at the top of the page.

However, unless we somehow persist the values that were entered, the form will be blank, and the user will no doubt be a little frustrated. This is a long form!

one method would be to create <cfparam> values for each element in the form, and then give each input the a value like value='#form.thisFieldName#" - that's common practice, and works great, but I don't want to do the tedious work. Also, I will be passing this form back to the designer, and don't want him to have to create the default value if he decides to change the names of any inputs, or at other input to the form.

So, I came up with this.

Assuming you already have jQuery in your page, this little block of code will loop through all of the posted values in the ColdFusion form scope, then, using jQuery, will assign the given value to any form element with a matching "name" attribute, allowing us to easily re-populate all the form fields in the page, in one fell swoop with javascript.

Since i only had input / textarea / select / radio button inputs, this just handles those types, but could easily be ammended to include checkboxes and more.

<!--- if form scope exists --->
<cfif isDefined('form.fieldnames')>
    <cfsavecontent variable="hcode">
    <script type="text/javascript">
    <cfloop list="#form.fieldNames#" index="ff">
    <cfset rawVal = form[ff]>
    <cfset ffVal = jsStringFormat(form[ff])>
    //end jQuery
<cfhtmlhead text="#hcode#">

Yes, this makes a big long looped jQuery script in the head of the user's page. But in this instance, it is working perfectly, with no noticeable slowing of page load, or other drawbacks that i can see.

jQuery Masked Input: change masking based on a selected value with unmask()

Along with standard jQuery form validation, the jQuery masked input plugin provides a really nice way to preformat user-entered text. For example, a phone number might be masked so that it always ends up in the format "(999) 555-1234", even if the user just types in 9995551234 .

There are a number of ways this can be applied to a form, including the formatting of credit card numbers. Along with jQuery's validation methods for minlength and maxlength, you may also want to make sure the values entered are numeric only, or perhaps break up the user-entered data into hyphenated blocks, i.e. "9999-1234-1234-1234". This works really well and from what I can tell, helps cut down on errors due to mistyped card numbers.

However, not all credit cards use the same format. Amex is 13, Visa and others 16... and I believe there are some 14 or 15 digit variations.  The brilliant and thoughtful masked input plugin provides two solutions to this issue:

1) Variable (flexible) masking
With a recent release, you can now add a ? character to imply optional trailing digits
So, for an input that should accept 13-16 characters, like a credit card number:
The same works for the CCV code, which can be either 3 or 4 digits

2) Change the mask based on a user selection
Also introduced in a recent version, we now have the "unmask()" function.

So, to change the masking format based on the selection of another field - in this case, the type of credit card - is very easy.

In my form, I have a select box with the id of #cardType, which allows the user to select the type of card, and the options have values such as 'visa,amex,disc', etc.

To adjust the masking based on the user's card type, we simply need to grab the value of the dropdown when it is changed - if the value is 'amex' , set the mask for 13 digits, and 4 for the ccv (amex standard). If otherwise, set it to 16 and 3 digits. }

Here's my code, using unmask():

    // change mask for cc type
        var ctype = $(this).find('option:selected').attr('value');
            // amex masking
        } else {
            // standard masking

Once again a superbly elegant and simple solution via jQuery.
From here, you can easily edit these rules to allow for specific masks based on other values.




jQuery AJAX get() function cached in IE

From the 'how the heck were we supposed to know this?' department, a little tidbit I'd like to share, perhaps saving some poor, frustrated developer from the same type of mystifying madness:

jQuery "get()" operations are cached in IE unless you pass in a unique URL !

By cached, I mean, you can have a remote page with a query or other function, which responds to a unique set of values being passed in, and it will work fine in Firefox, but in IE, you'll get the same results from the remote page, even if the response is unique (like query results that have changed, for the same record), unless the values you are passing in via get() are also unique (i.e. you haven't looked up that particular record yet).

So, before you go banging your head on the floor and screaming out 'why oh why can't i find the problem, let alone the solution?!?' (not that i would ever do that), read this post, which i found via a quick Google search for 'jquery get IE cache' : http://www.sitecrafting.com/blog/ajax-ie-caching-issues/ 

I only had the presence of mind to run that search once i got my ajax results to display as an alert on the calling page, and deduced that the displayed content was based on the first values passed in, while all other updates and requests were ignored.

The fix, as that post suggests, is to create a unique url. In this case, i use javascript to append a random number to my function, - in this case, I just use javascript to create a random number right inline, then add that as a meaningles url variable to the page in the get() function:

                           // set up unique url
                            var randomNo = Math.floor(Math.random()*9999999);
                            var urlStr = 'journalLookup.cfm?r=' + randomNo;
                            // run get function using randomized URL
                            $.get(urlStr,{jdate:dateLookup}, function(data){  .... [ function here ]

If this saves you some aggravation, let me know in the comments ... maybe i'll feel better about the time i just wasted chasing this mystery 'feature' in IE!!


How to show changed input and select fields with jQuery

Here are a few quick easy jquery functions that will add a class of 'changed' to any input or select box if it is changed, and will remove that class if the value is reset to the default.

view plain print about
1// inputs
2        $('form.myForm :input').change(function(){
3        var defval = $(this)[0].defaultValue;
4        if ($(this).val()!=defval){
5            $(this).addClass('changed');
6        } else {
7             $(this).removeClass('changed');
8        }
9        }).keyup(function(){
10             $(this).trigger('change');
11        });
13        // select boxes
14        $('form.myForm select').change(function(){
15        var defval = $(this).find('option[defaultSelected=true]').val();
16        if ($(this).val()!=defval){
17            $(this).addClass('changed');
18        } else {
19             $(this).removeClass('changed');
20        }
21        }).keyup(function(){
22             $(this).trigger('change');
23        });

Note in both cases we use keyup (onkeyup) to trigger the 'change' event. This allows the browser to show the changed class as soon as the user changes the value using a keyboard, rather than 'onblur'.

jQuery Cycle slideshow demo with next/back/paging links

This demo uses some of the advanced features of the jQuery Cycle plugin to create a mixed content slideshow (html/text/images) with a visual navigation bar, and next/back arrows

In this setup, the slideshow advances automatically, until somebody clicks one of the links, which stops the automatic action and allows the user to control the advancement of the slides. The Cycle plugin allows for pausing, resuming or stopping the slideshow with a simple click action.

See the demo (includes css/jquery code for easy reuse) http://www.gowestwebdesign.com/demos/jquery-cycle-gallery-next-back-paging/

Thanks to Mike Alsup for the versatile Cycle plugin: http://www.malsup.com/jquery/cycle/

Feel free to use the code for any purpose, and please drop me a comment or link to check out your work. As always, comments/suggestions/fixes are welcome.

jQuery form input defaultValue

When creating a form to accept user info, there are times when functions related to a form input's default value are required. For example, you have a field that says "search here", and when the user clicks in the field, the default value is removed so the user can begin typing. But, if the user leaves the field blank, you might want that default term to return. In regular javascript, we use something like this:

view plain print about
1if(inputName.value == ''){
2inputName.value = inputName.defaultValue

but jQuery doesn't have a built-in method for retrieving that default value. Thankfully, google found me a super easy workaround - this discussion thread holds the key:

view plain print about
1if ($(this).val() == "") {
2 var defVal = $(this)[0].defaultValue;
3 $(this).val(defVal);
4 }

Note the [0] in the defaultValue. As explained in the thread linked above: "If you imagine $(this) as an array of DOM objects within jQuery, then $(this)[0] is a way to access the first (or in this case, only) DOM object. jQuery doesn't have a built in way to retrieve the default value of an input, so we have to nip back into the DOM momentarily in order to retrieve it. "

Marking current menu link with jQuery for CartWeaver categories

Working on a heavily-modified Cartweaver Coldfusion E-Commerce shopping cart site, I have created a database-driven navigation menu containing links to each category. When a user clicks a link, the products in that category are displayed, and the menu link for that category is highlighted via a special 'currentLink' css class.

Now of course I could use CF to add ' class="currentLink" ' to the current category's menu option, but I am not doing this particular menu that way. Besides, it is just as easy with jQuery!

view plain print about
1<cfif cgi.script_name contains 'results.cfm' AND isDefined('url.category') and url.category gt 0>
2<cfsavecontent variable="highlight">
3<script type="text/javascript">
5$('.sideNav li a').removeClass('currentLink');
6$('.sideNav li a[href=results.cfm?category=<cfoutput>#url.category#</cfoutput>]').addClass('currentLink');
7//end jQuery
11<cfhtmlhead text="#highlight#">

Simple enough - if we are on the 'results' page, and a category is defined in the url, remove the 'currentLink' class from all existing menu items, find the one where the 'href' attribute matches the current pagename and category, and add the class back to that link. Done.

The use of cfsavecontent and cfhtmlhead means I can put this right below the code that calls in my custom nav tag, for easy fine-tuning right where i need it (rather than in an external scripts file).

Quick , easy, and done in a flash with jQuery!


Recent Comments

Importing Events Calendar Data into Mura CMS
Jon said: Hi Michael, Thanks for this post - similarly looking to import data from excel spreadsheet into mur... [More]

New TinyMCE lets you paste as plain text automatically
PRR said: I am using tinyMCE 4.2.3 and configured as suggested in this post but when i try pasting in editor i... [More]

Searching and collecting Mura CMS content by Extended Attribute Value with feed.addParam()
Armando Faes said: After a few hours of head banging - finally thanks to this - Once more THANK YOU! [More]

CF Gallery Creator & jQuery Slider Gallery !New and Improved!
Jan Willis said: Okay, I realized that you are calling my root as the Site - not the wwwroot. So, I moved the JS, CS... [More]

CF Gallery Creator & jQuery Slider Gallery !New and Improved!
Michael Evangelista said: @Jan, it has been a long time (6+ years) so my memory of the details is vague, but I think the image... [More]