jQuery click and the onclick attribute

by Aaron Powell 27. August 2010 04:35

Note: This may be a bit of an example of “doing it wrong”, but I don’t care :P

Yesterday I was having a look at a bug for a client in which we have a search control on a page which does an AJAX search, reloading the whole page.
Obviously that was a bit of a problem, the dynamic search results were being trashed by the full postback.

It was a very basic form, with a text input box for keywords and a button which you could click if you wanted to do the search. When clicking the button everything was fine, but when hitting Enter in the textbox the whole page refreshed.
After doing a few tests I noticed something interesting, the AJAX was working, the search results were loaded client side but then immediately the page posted.

So I went on the hunt for the keyboard event which was on the textbox and I found this:

$(function() {
	$('.searchKeywords).keypress(function(e) {
		if(e.which == 13) {
	                e.preventDefault();
                	if ($(".searchKeywords").val() != "") {
        	            $(".KeywordSearchFilter").click();
	                }
		}
	});
});

Nothing odd there, that’s perfectly fine for handling the keypress event and then doing the search, so my next assumption is that the button is having a problem.

I started digging around to see if I could find where the buttons click event handler was being registered.
But no joy, nothing, nada, zip.
No jQuery click handler is being registered.

Ooooook… So I had a look at the source for the button itself and found this:

<input type="submit" name="..." value="Go" onclick="SearchHelper.searchByKeyword(null);;return false;WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("...", "", true, "SearchKeyword", "", false, false))" id="..." class="submit KeywordSearchFilter">

I’ve trimmed out the control names so it’s a bit easier to read

Crap, see the problem? The click events are registered in the onclick attribute of the button!

Well first off I was surprised that jQuery actually fired the onclick attributes events, but it is a problem that it wasn’t acknowledging the return false statement.

So I had 2 options in front of me:

1) Refactor the code so that it was registering the event using jQuery

2) Find some funky way to do this

 

Option 1 was not really viable, this search control is a super class of a common search control and I didn’t want to break any other parts of the site, sure our tests would cover it *cough cough :P* but it’s quite a large site and with only a few weeks left here I don’t want to cock anything up.

So it’s option 2, time to work out some funky way around it!
Since onclick is just an attribute, I thought “can I just access it and grab the methods out”? I don’t see why not, jQuery must be doing something like that itself.

And since it’s just a set of functions, could I invoke it?

Well it turns out that I could! And this is what I now have in the codebase:

$(function() {
	$('.searchKeywords).keypress(function(e) {
		if(e.which == 13) {
	                e.preventDefault();
                	if ($(".searchKeywords").val() != "") {
        	            $(".KeywordSearchFilter").attr('onclick')();
	                }
		}
	});
});

I tested this in IE8, Firefox and Chrome and it worked in all three browsers!

Hey, it may not be the best solution, but hey, it worked! :P

Categories: jQuery | JavaScript

TheFARM needs senior .Net developer!

by Shannon Deminick 5. August 2010 05:50

TheFARM is currently looking for a talented and passionate senior .Net developer. Someone that has a minimum of 4 years ASP.Net development experience, stays up to date with the latest technologies, and actually loves to program. Skill set should include:

  • Expert knowledge of .Net from v2 up to v4
  • Experience with common patterns and practices including Dependency Injection
  • JavaScript, JQuery, AJAX, and everything else to do with client side web programming… yes, you’ll still have to write some CSS and HTML
  • ASP.Net MVC 2+
  • We are an Umbraco CMS development agency so if you’ve used it before, it would be of huge benefit, otherwise be prepared for extensive training
  • … and lots, lots more ;)

If you think you would be suitable for this role, we would love to hear from you! Please email us your CV/Resume to: Work@thefarmdigital.com.au

Tags: , ,

ClientDependency now supporting MVC

by Shannon Deminick 6. April 2010 18:38

I’m please to announce that the ClientDependency framework now supports MVC! It’s very easy to implement using HtmlHelper extension methods. Here’s some quick examples:

Make a view dependent on a CSS file based on a path defined as “Styles”

<% Html.RequiresCss("Content.css", "Styles"); %>

Make a view dependent on jQuery using a full path declaration:

<% Html.RequiresJs("/Js/jquery-1.3.2.min.js"); %>

Rendering the Style blocks and defining a global style path:

<%= Html.RenderCssHere(new BasicPath("Styles", "/Css")) %>

Rendering the Script block (no global script path defined):

<%= Html.RenderJsHere() %>

There’s still a provider model for MVC but it uses a slightly different implementation from Web Forms. The same compositeFiles provider model is used but instead of the fileRegistration provider model that is used in Web Forms, a new mvc renderers provider model is used. A renderer provider is similar to the Web Forms fileRegistration providers but instead of registering the markup in the page using the page life cycle, a renderer provider is used to render out the html block necessary to embed in the page.

All of the functionality that existed in Web Forms exists in MVC. You can make as many views that you want dependent on as many of the same or different client files that you want and the system will still sort by position and priority and remove all duplicate registrations. Rogue scripts & styles still get processed by the composite file provider in MVC. Currently however, if you place user or composite controls on your views that have Client Dependencies tagged with either the control or attribute method used in Web Forms, these will not be registered with the view and output with the renderer. 

MVC pages have been added to the demo project as examples so have a look! You can download the source HERE

For full details and documentation go HERE

sIFR vs. cufón: Text replacement and you

by James Diacono 31. March 2010 10:40

There are two reasons I use dynamic text replacement:

  1. Plain text in a browser window is never as smooth as it is in the design (except in Safari),
  2. The designs I'm given almost always use fancy (non-web based) fonts for headings, intro text etc.

Currently I subscribe to two solutions, both client-side: sIFR and cufón. If you want a quick answer to "what should I use?" then here it is: if you want replacement for long sentences and headings, use sIFR. If you want replacement for a few words on a button or in a menu, use cufón. If you want to know more, read on...

sIFR

How sIFR works

sIFR uses javascript to dynamically embed a Flash object in the place of specified HTML text elements. The Flash object is essentially an empty SWF (compiled Flash file) which includes the characters of the font you want to use. When javascript embeds the SWF in the HTML, it passes the SWF arguments such as text-content, font-size, color, rollover behaviour and many more. Some of these properties javascript takes from the CSS applied to the text, and some are overridden by sifr-config.js, which is a human-readable config file containing additional formatting tweaks.

How to use sIFR

  1. Download the source (only sifr.js, sifr-config.js and sifr.css are actually needed).
  2. Generate a font SWF from a True Type Font file. You can do this manually with Adobe Flash (like this) but it is easier to use this online generation tool.
  3. Link to sifr.css in the head of your HTML page.
  4. Link to both scripts in the head of your HTML page, first sifr.js, then sifr-config.js
  5. Edit sifr-config.js to read in the font SWF you created and use CSS selector syntax to select the HTML text elements you want to replace.
  6. Tweak away in sifr-config.js until the text looks right when sIFR is both enabled and disabled, in case the user is missing Flash (iPhones don't have Flash as of early 2010!).

cufón

How cufón works

cufón is entirely javascript and works in all major browsers (including IE6). You still need to generate a font file, but this is output to a javascript file similar in size to the equivalent sIFR SWF font file. cufón looks at selected blocks of text and replaces each word with a dynamically generated image (using the HTML <canvas> tag), or in IE's case, a VML object (Vector Markup Language). As a consquence of this, increasing the text size of the page either doesn't affect cufón-replaced text or expands the image, blurring it. Except in IE, which scales the text perfectly.

How to use cufón

  1. Download the source (all you need is cufon-yui.js)
  2. Generate a font file from a True Type Font. You are unfortunately dependent on this online generator.
  3. Link to cufon-yui.js in the head of your HTML page. Beneath it, link to any font files you've generated.
  4. You may also want to create another file, cufon-config.js, to hold selector information much the same way as sifr-config.js does.
  5. Populate cufon-config.js with what HTML text elements you want to replace.

Legality

Font foundaries are seemingly run by people who are very freaked out that their fonts are going to leak for free. Hence, the vast majority of fonts can't legally be embedded directly into the CSS (what, you didn't know about that? It's been around a while in some form or another - the @font-face directive allows you to supply the font file for obscure font-families - but it's only legal with open source fonts).

Because sIFR uses Flash, and Adobe has a cordial agreement with the font foundaries in Switzerland (or wherever) which allows anyone to embed pretty much any font in a .swf, sIFR is totally legal. cufón... cufón not so much. Although both supply a compiled/obfuscated font resource in .swf/.js format respectively, and are basically the same from the font foundaries' point of view, they haven't got around to adding "Allows embedding using javascript methods" to their fonts' terms of use agreements. And I wouldn't count on it...

So in short, use cufón. Go on, it's young and fresh and rad! Push the font foundaries to legalise it! But remember: you read that in a blog post...I'm not going to be your lawyer if they come after you.

Comparison

sIFR cufón
Core file-size (not including fonts) 30KB 18KB
Independent of Flash ×
Resizes nicely ×
Cursor-selectable text ×
Doesn't flicker on load ×
Independent of online font-generator ×
Online font-generator supports Open fonts (.otf) ×
Supported in all browsers
Degrades gracefully
Legal ×
Categories: Flash | JavaScript

jQuery fade bug in IE – background transparent PNG image

by Shannon Deminick 26. March 2010 08:20

(I’ve found a ‘solution’ to this… see bottom of post)

Problem

I’ve been trying to figure this out for the whole day today and have finally succumbed to the realization that I’m pretty sure I’ve found a bug in jQuery, even the latest version.

The example link is below. The mark-up is very simple and all that is being done is:

  • Create a box with a single pixel semi transparent PNG image
  • Call either fadeIn or fadeOut on any HTML element on the page… suddenly (and strangely) the box magically has a semi transparent gradient on it!

So if anyone out there know how to fix this, I’m all ears. I’m about to go searching on the net for an alternative fade in/fade out library that doesn’t produce these results but would obviously like to just use the built in jQuery methods.

Click here to see the bug and source! (You’ll have to view in IE 7/8 to see the bug)

Before fade out on the black box:

image

After fade out on the black box:

image

 

VERY STRANGE!!!!

Solution

I knew this had to be an issue with IE’s stupid DXImage transform stuff but didn’t really want to go down the route of fiddling with it but in the end, had to do it. And also had to add a stupid little hack to target IE directly.

Step 1:

Create a IE conditional div wrapper around everything under body:

<!--[if IE]><div id="ieWrap"><![endif]—>

(the rest of the page html goes here)

<!--[if IE]></div><![endif]—>

Step 2:

Target the elements in CSS for IE that have the background PNG transparent image:

#ieWrap .productView .productThumbnail a
{
	background-image: none;
	filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='grey_overlay.png',sizingMethod='scale');
}

Click here for solution

And, a day later i found out this isn’t working as expected in IE 7… great… so figured out i had to add: width:100% to the style with the DXImageTransform.

Tags: , ,

ASP.Net Client Dependency Framework RC1 Released!

by Shannon Deminick 18. March 2010 17:13

With the community feedback, bug reports, patches, etc… I’ve managed to find time to upgrade this library to a release candidate status. We do use this framework in many production websites but it was great to hear from other in regards to specific bugs that were found relating to particular environments. These bugs have all been fixed up and this library is looking very stable.

You can download the binaries here.

Better yet, I’ve put together a near complete documentation library on CodePlex here !!

I still think the best way to learn about this project is to download the source code from CodePlex here and have a look at the demo web application included.

Moving forward, the next phase for this library is to add MVC support and another file registration provider called PlaceholderProvider which will give you even more granular control over where dependencies can be rendered in your markup. MVC support should be fairly straight forward and we’ll include a demo project for this as well.

Well definitely be releasing a final version soon after the next Umbraco 4.1 release candidate is released (which will hopefully be fairly soon!)

Happy day! Any and all feedback, bug reports and patches are definitely appreciated!

Client Dependency Framework Beta Released

by Shannon Deminick 29. September 2009 07:06

I’ve posted a new Beta release on CodePlex, you can get it here: http://clientdependency.codeplex.com/Release/ProjectReleases.aspx. On the releases tab includes a sample web site that has most of the functionality that you can do so please download it for a documentation reference.

Newest changes & additions

  • Namespace and codebase changes/steamlining
  • Proper versioning added
    • Versioning is done on a global basis in the config
    • Old versions are retained and can still be accessed from the Client Dependency URL that was previously used (if necessary)
    • Versioned composite files names are prefixed with the version number (i.e. version 2 files will be prefixed with '2_') so it's easy to figure out which files are old
    • The composite file map also reflects which composite file sets are under a specific version
  • Provider model extended to support 2 types of providers:
    • File Registration Providers
      • Still comes with 2 providers: page header provider and a lazy loading JavaScript client based provider
    • Composite File Providers:
      • Comes with the standard provider: CompositeFileProcessor
      • You can implement your own provider to customize the way that files are combined, compressed, minified, etc... if the standard provider isn't exactly what you are after
  • Forced providers! You can now force a dependency to use a particular provider. This can be useful if you want to ensure that a particular script or stylesheet is rendered on to the page differently. For example, you may want to ensure that a script is lazy loaded (using the lazy load provider) but the rest are rendered in the page header.
  • Utility methods added to the ClientDependencyLoader for more dynamic implementations
  • A test website is included in the release which doubles as documentation, it includes:
    • Standard page header provider example
    • Forced providers example
    • Lazy load provider example
    • Dynamically registering dependencies in your code behind
    • Registering dependencies with attributes and via aspx controls

Things //TODO:

I’ve finished off versioning so at least i can cross that off from the previous list. But there’s still more to do:

  • Implement functionality for jQuery CDN
    • This will be a new control/attribute to easily include jQuery in your project
    • You will have the option to select which CDN you want to use (Microsoft or Google), or you can supply an address (like your own CDN/web server)
    • Though this framework will be included in Umbraco 4.1, we’ll be leaving this functionality out of the Umbraco build as we realize that there are quite a few installs that operate behind a firewall that won’t have access to the CDN.
  • Implement skeleton for Microsoft AJAX 4 CDN
    • Again, this will be another new control/attribute to easily include Microsoft’s new brand of AJAX with their CDN solution
  • Add support for MVC
  • Support for JS/CSS Minification with options to disable per dependency
    • The reason this hasn’t been implemented yet is that I’ve found a lot of scripts/stylesheets break with minification so we need to be able to turn this on/off on a per file basis
  • Some more documentation/examples in the example web application

ASP.Net Client Dependency Framework Released

by Shannon Deminick 15. September 2009 12:35

Repository/Download

  • CodePlex Home: http://clientdependency.codeplex.com
  • The repository has the latest new version, the alpha release version is OLD so best to get the latest codebase from the Source Control tab!

History

I’ve been busy in the Umbraco core putting in place a new Client Dependency framework for version 4.1. I thought since this could benefit many other people/projects that I’d take it out of the Umbraco core and make it its own standalone project. Currently in Umbraco v4, there’s already a Client Dependency framework that you may have come across if you’ve decided to go deep within the core code. It was developed for Umbraco Canvas (live editing) by Ruben (and Niels I think) to be able to tag controls as being dependent on CSS/JavaScript files to be lazy loaded into the client’s browser to enable live editing of the page. I thought the idea was great and wanted to combine it with a bunch of work that we had done in the office already to make a library that everyone can use. So what does it do???

Features

Most of the features can be enabled/disabled in the configuration section. By default, they’re all enabled.

  • Make your controls dependent on client files by:
    • Attributing your controls
    • Using the JSInclude or CSSInclude web controls
    • Dynamically registering them in code
  • Provider Model so you can choose how you would like your JS and CSS files rendered
    • Comes with 2 providers: page header provider and a lazy loading JavaScript client based provider (the original lazy loader by Ruben… nice work!… slightly modified though)
    • You can explicitly tell the engine which provider you would like a particular script/stylesheet to be rendered out by if you require this. An example could be that you want one script in particular to be rendered in the page header, but another script to be lazy loaded.
  • Combining and compressing JavaScript and CSS files
  • Resolving the correct URL paths in CSS files while they are being combined so you don't have to worry about this
  • Combining external JS and CSS files
  • OutputCaching of the combined/compressed composite files
  • Saving of the combined/compressed composite files for increased performance when applications restart or when the Cache expires (persistent compression/combination)
  • Creation of an XML file map to tell you which saved composite files are for which real files
  • Easily clearing the cache
  • Tagging client files with priorites
  • Tagging client files with path names so you don't have to worry about moving files around in your project, worrying about absolute vs. relative paths, or running your application in a virtual folder

This library isn’t the answer to all of your compression needs, but it is a good start or addition to something your already using. Most other compression libraries out there are module based which can do page compression, script/css compression/combination, etc… and are all a really good idea. The compression/combination part of this library is just a really good bonus on top of what it is actually made for which is making your controls dependent on client files without worrying about duplication and having full control over how you want them rendered in your page (i.e. Provider model)

Umbraco Usage

Because there are so many controls in Umbraco and so many client files, its very difficult to keep track of what has already been included in pages, other controls, etc… This library is now part of Umbraco 4.1 codebase and all controls are now using it. There was a lot of hard coding paths to either /umbraco_client or /umbraco folders which is one of the reasons Umbraco won’t run in a virtual folder in IIS. This library solves the hard coded path issue.

What this means for package developers is that they don’t have to worry about whether or not jquery, or other JS/CSS files have been included in the page, they can simply add a client dependency to their controls.

Easier Team Development

If you’re working in a team locally in your office or one that spans between different office, this implementation makes things a whole lot easier for developing controls.

Things //TODO:

  • Need to add versioning
    • This will remove old versioned persistent files saved under any older version
    • Easier to deploy since right now you would need to remove the persisted files to remove the cache
  • Add support for MVC
    • This should be pretty darn easy i think
  • Adding some more providers (i.e. ScriptManager provider, etc…)
  • Documentation

Config

<clientDependency isDebugMode="false">
  <fileRegistration defaultProvider="PageHeaderProvider"
    fileDependencyExtensions="js,css"
    enableCompositeFiles="true">
        <providers>
            <add name="PageHeaderProvider" 
                type="ClientDependency.Core.FileRegistration.Providers.PageHeaderProvider, ClientDependency.Core" />
            <add name="LazyLoadProvider" 
                type="ClientDependency.Core.FileRegistration.Providers.LazyLoadProvider, ClientDependency.Core" />
        </providers>
    </fileRegistration>
    <compositeFiles defaultProvider="CompositeFileProcessor" 										
        compositeFilePath="~/App_Data/ClientDependency"
        compositeFileHandlerPath="DependencyHandler.axd">
          <providers>
            <add name="CompositeFileProcessor" 
                type="ClientDependency.Core.CompositeFiles.Providers.CompositeFileProcessingProvider, ClientDependency.Core" />
          </providers>
    </compositeFiles>
</clientDependency>

Includes/Usage

Implementation is pretty simple…

  • You need a ClientDependencyLoader to do the loading, only one of these can exist on the request (just like the ScriptManager in ASP.Net)
  • You can use CssInclude and JsInclude controls in your User Controls/Pages, etc… to declare that a CSS or JS file is required OR
  • You can use the ClientDependencyAttribute to attribute your composite control classes OR
  • You can programmatically add a dependency by using the ClientDependencyLoader’s methods (there’s a few of these overloaded methods):
    • ClientDependencyLoader.Instance.RegisterDependency("Content.css", 
                     "Styles", 
                     ClientDependencyType.Css);

The FARM adds a nail to the coffin of IE 6

by Shannon Deminick 20. July 2009 10:19

Days until TheFARM drops support for IE6



We are happy to announce that we will cease to support IE 6 development from Oct 31 2009. We will continue to support our clients’ existing websites but any new development will target Firefox 2+, IE 7+, and Web kit browsers (e.g. Safari, Chrome).

IE 6 was released in Aug 2001, it is 8 years old and 2 more browsers have since been released from Microsoft… it’s about time people stop using this horrible, horrible browser. Other larger players including YouTube have also stated that support for IE 6 will stop. We’re hoping that more agencies will adopt this idea and push for clients to finally make the upgrade or switch to a new browser… it’s 8 years old!

Comments are always welcome!

Tags: , , ,

jQuery Vertical Align

by Shannon Deminick 7. April 2009 05:09

UPDATED! (2009-04-29)

An easy way to vertical align elements with one line of code:

$('.innerText').VerticalAlign();  

I've removed the parameters as it turns out if you pass in a negative offset using padding, IE6 throws an error and JavaScript fails to continue executing. If you get the following error in IE6 debugging, it may be due to passing in a negative value to a padding css attribute, or similar:

  • invalid argument jquery J[G]=K

It's fairly easy to structure your html to not require a vertical align offset so it's really not needed anyways.

It also supports a couple of parameters:

  • offset = the number of pixels to offset the vertical alignment
  • usePadding = true/false. the default is false which uses a margin to align, if set to true, it uses padding
$('.innerText').VerticalAlign({offset:-20, usePadding:true})

Get the source:  VerticalAlign.zip (290.00 bytes)

Categories: JavaScript