model.js

I’m working on a quick alternative to heavy frameworks like ExtJS and Backbone called model.js, it’s more or less just a simple library/script at the moment. It allows you to pass in JSON objects to create classes in which all class objects begin with a nice event model. It’s design to be tiny and relatively simple.

UPDATE: model.js now has a home -> modeljs.org

GitHub: model.js

Here’s a quick example: Continue reading

jQuery & Multi-touch: Getting Started

It’s been about a month since my last update, well I have some fun treats for everyone this time.  Let’s enter the world of mobile & touch devices.  Over the past month I’ve been working on some touch devices and have released a couple scripts to accelerate development on such devices.

There are a few things to keep in mind:

  • Touch events are treated as the same event for each touch.
  • Touch events do not coincide with mouse events, except on mobile devices.
  • Currently, no stable release of a desktop browser supports touch events.
  • IE10 will not support touch events as standardized by W3C.  (read more)

Well, now that you know [some] of what you’d be dealing with, you may understand why multi-touch platforms could be potentially cumbersome.  Web pages have been designed with one “pointer”, the mouse, in mind.  With one pointer you don’t have to manage touch events around multiple pointer inputs – so what happens when you start porting drag & drop code to multi-touch interfaces?  You get interference from other pointers.

Solution #1: jqTouchEvents

Well, I’ve got a simple solution for all of this called jqTouchEvents.  jqTouchEvents is a jQuery library designed to accelerate development of multitouch applications by allowing touch events to take exclusive control of an interacting element.  What does this mean?  You can prevent elements from responding to more than one touch event at a time.

Here’s a drag & drop example:

$(document).ready(function(){
	var startPoint, startPosition;
	var $dragElement = $('.dragElement');
 
	var processMove = function(touch) {		
		$dragElement.css({
			marginLeft: (touch.pageX - startPoint.pageX) + startPosition.left,
			marginTop: (touch.pageY - startPoint.pageY) + startPosition.top
		});
	}
 
	$dragElement.exclusiveTouch({
		anyEl: true, // Invoke move and end for the touch holding the element exclusively regardless of the target
		start: function(touch) {
			// Grab starting touch point
			startPoint = {pageX: touch.pageX, pageY: touch.pageY};
 
			// Grab current position of element
			startPosition = $dragElement.offset();
		},
		move: processMove,
		end: processMove // Call again when touch ends, for precision
	});
});

Solution #2: clickTouch.js

This is an easy one, if you want the mouse to act like a touch input, I’ve create a script for that called clickTouch.js.  It only needs to be included in your project and initialized.  You can also pass the boolean “true” if you wish to block all mouse events and only invoke touch events from the mouse.

Usage:

$(document).ready(function(){
	clickTouch.init(true);
});

 

Stay tuned, I’ll have more coming soon…

Native Browser Wrapper with HTML5 & CSS3

This blog is due for an update and I’ve got a good one finally.  There’s this open-source project called OpenWebKitSharp that’s so heavily underrated, it’s ridiculous.  Apparently it’s run by GT Web Software, which is surprising — I don’t mean to undercut them, but their projects are great, they just don’t look like much at first glance.  They have something truly valuable to many developers on their hands and I don’t think they even realize it.

Now back to reality, OpenWebKitSharp is just a wrapper for WebKit to be used in [C#] .Net, it’s nothing unexpectedly original except for the fact there’s very little like it.  You have one commercial solution called Awesomium (almost $3k for a license? that insane for new ventures for a medium sized company) and then another called Berkelium (looks great, but interfaces directly with Chromium).

So why do I chose OpenWebKitSharp?

  • No ridiculous licensing.  Though Awesomium may be great to look at for the future, but too costly for a new venture.
  • It interfaces directly with WebKit nighties, I know for a fact the browser itself can’t be easily hijacked.  I’m not saying Berkelium in insecure, but it definitely looks to add another layer rather than creating it’s own rendition of the browser document.
  • I can download the code and have an easily-understood example up and running in minutes.  There’s a solution in their sources prepackaged for Visual Studio.
  • HTML5 & CSS3 Support!  You have all the latest features of the WebKit engine, essentially it’s the same as running Chrome or Safari!
  • It’s simple!
Lastly, why would anyone want this?  It allows a controlled browser environment.  This can be used for a number of applications in which the developer desires to use web technologies to build applications that look and feel native to Windows.  It’s an easy alternative to Adobe Air and other related technologies.

ExtJS 4 Loader Tips & Tricks

The Loader component in ExtJS 4 is great, but there’s a few quirks.  I thought I’d share for anyone else who may be running into issues similar to what I encountered.

Tip #1: Fix “disappearing” breakpoints.

Just because Ext disabled sends and extra parameter (“disableCachingParam” or “_dc”) to prevent caching, just about every browser loses breakpoints on page refresh. You might also want to install some cache clearing tools for your browser too, I could not get my scripts to clear from cache with just a refresh. (even hard refresh wont do)

Ext.Loader.setConfig({
	disableCaching: true
});

Tip #2: Don’t forget to define!

Be sure to define a class for each script you load. I’ve found not doing so can cause Ext to lock up on occassion. It won’t throw an error and it won’t freeze the browser, it will just stop running certain parts of code. This is especially good to know if you wish to auto-load oddly named overrides.

Tip #3: Test your code by auto-loading.

Auto-loading will always create excess http requests over loading one condensed script, but you can still use it for testing code structure. If your code isn’t structured (namespaced) properly it can still work perfectly when included, but will fail to auto-load. Just by testing your code with auto-loading, you can verify all file names and class definitions are correct.

Note: This post was sitting in my drafts awaiting additions for some time, not sure of anything to add, so *post*. ;)

Why I Hate Dreamweaver

I hate Dreamweaver. It seems everyone and their dog can use Dreamweaver these days, and that’s great.  For me, this is all about the fight against Dreamweaver and most IDE’s.  Did I just say most?  I meant just about every IDE out there, especially most mainstream IDE’s like Dreamweaver.

To set things clear, this article is also about the general concept of most IDE’s in general.  Why did I pick Dreamweaver?  Well, apparently Arthur Kay doesn’t think I can possibly out-hate Dreamweaver more than him.  I’m here to prove him wrong and claim my delicious beer.  Yes, Art, I want that beer.  That, oh, so delicious Dreamweaver-free beer.

Now that you understand where I’m coming from, let’s begin. It’s clear, I hate Dreamweaver. Let’s start off with the word “hate”, as defined in the Merrian-Webster dictionary.

\ˈhāt\ : intense hostility and aversion usually deriving from fear, anger, or sense of injury.

That about sums up how I feel; intense hostility. I most definitely feel hostile towards Dreamweaver, I’ve gone through the trouble of expressing how much I hate it in the form of writing. That takes patience, but mostly anger.

So, I hate Dreamweaver, but why?

Continue reading

Injecting jQuery: Just for Fun

I’ve put together a small snippet you can enter at the top of any page. Use it to inject the jQuery library into the page, and optionally run a small script of mine which will create a small debugging tool. It’s like Firebug Lite, except much smaller and less useful.

Just type this into the address bar after you’ve loaded a page:

javascript:var i,s,ss=['http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js','http://extraordinarythoughts.com/toybox.js'];for(i=0;i!=ss.length;i++){s=document.createElement('script');s.src=ss[i];document.body.appendChild(s);}void(0);

Want only jQuery? Use this:

javascript:var i,s,ss=['http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js'];for(i=0;i!=ss.length;i++){s=document.createElement('script');s.src=ss[i];document.body.appendChild(s);}void(0);

ExtJS GridView autoFill & forceFit

It’s no surprise grid layouts can be tricky in ExtJS. After much struggle, I’d like to point out an obvious that isn’t well documented – ExtJS GridPanels scrollbars, and those scrollbars are always accounted for unless configured otherwise.

If you happen to be using autoFill & forceFit with autoHeight, you’ll notice there’s still a gaping void of 10 pixels or so to the side of your columns, this is where scrollOffset comes in. scrollOffset is used to predict where a scrollbar would be, just set it to 0 and enjoy your new, nicely formatted, grid! This also works with Ext.grid.EditorGridPanel, of course.

// Perfect full-width columns!
new Ext.grid.GridPanel{
	autoHeight: true,
	viewConfig: {
		autoFill: true,
		scrollOffset: 0
	}
});

Understanding jQuery Plugins

jQuery Logo

If you’re here, I’m sure it’s no surprise jQuery is an easy library to use. jQuery may be easy, but it still has its quirks and can be difficult for some to grasp beyond basic functionality and concepts. No worries, I’ve got a simple guide here to help break down code, that may seem like overly complex syntax, into simple thoughts and patterns that can be easily understood.

Here, we’ve got a basic plugin layout:

// Shawn Khameneh
// ExtraordinaryThoughts.com
 
(function($) {
	var privateFunction = function() {
		// code here
	}
 
	var methods = {
		init: function(options) {
			return this.each(function() {
				var $this = $(this);
				var settings = $this.data('pluginName');
 
				if(typeof(settings) == 'undefined') {
 
					var defaults = {
						propertyName: 'value',
						onSomeEvent: function() {}
					}
 
					settings = $.extend({}, defaults, options);
 
					$this.data('pluginName', settings);
				} else {
					settings = $.extend({}, settings, options);
				}
 
				// run code here
 
			});
		},
		destroy: function(options) {
			return $(this).each(function() {
				var $this = $(this);
 
				$this.removeData('pluginName');
			});
		},
		val: function(options) {
			var someValue = this.eq(0).html();
 
			return someValue;
		}
	};
 
	$.fn.pluginName = function() {
		var method = arguments[0];
 
		if(methods[method]) {
			method = methods[method];
			arguments = Array.prototype.slice.call(arguments, 1);
		} else if( typeof(method) == 'object' || !method ) {
			method = methods.init;
		} else {
			$.error( 'Method ' +  method + ' does not exist on jQuery.pluginName' );
			return this;
		}
 
		return method.apply(this, arguments);
 
	}
 
})(jQuery);

You may notice the structure I’ve provided is significantly different from others. Plugins can vary depending on usage and needs. Here, it is my goal to explain the concepts in code well enough for you to understand and author a plugin in such a way that suits you best.

So, let’s break it down!
Continue reading

ExtJS Snapping Windows

There’s a really useful feature in Windows 7 that allows windows to be resized just by dragging them to edges of the screen.  Well, I wanted that feature for an ExtJS desktop environment, so here’s my solution for Windows 7 style window dragging.

The following code overrides some functionality in ExtJS and allows windows to be resized in the same manner.

Features:
  • Windows can be dragged when maximized and will resize when dragged.
  • Dragging a window (cursor within 20 pixels) to top of container will maximize it.
  • Dragging a window (cursor within 20 pixels) to left or right of container will resize it to that half of the container.
  • The window ghost will indicate its new size according to placement when dragging.
  • Windows will restore to their original size before being snapped. (Not working in ExtJS 4 version)
  • Adds snapLeft() and snapRight() functions to the Ext.Window component.
  • Unsnapping windows will position them relative to the original cursor position on the title bar. (v2 only)
  • Supports autoloading (v2 only)
Bugs / Quirks:
  • Windows that initialize maximized will restore to 800×400
  • Windows that initialize with resizable = false cannot be dragged when maximized. (Only ExtJS 3.3.1 version)
  • Maximizing a window when snapped to half the screen will make it resize to half of the screen.  (only ExtJS 3.3.1 version when using resize button)
Yeah, the quirks can be easily fixed, I just have no immediate need to fix them.

Continue reading

ExtJS Window Reference & Focus

I’ve got a short & sweet code snippet to provide provide more usable functionality in ExtJS 3.3.1.

This code snippet solves two minor drawbacks in Ext that I felt the need to address:

  1.  To reference a [nested] component’s window in ExtJS, you must explicitly pass a reference to the window or obtain the window component by means not recommended to be practiced in production-level code.
  2. Selecting an item in a list grid does not always give the parent window focus.

To solve this, I’ve created a snippet of code to give each component a property called “ownerWindow” and components containing a “dynamicGrid” will focus the parent window when clicked.

Components that aren’t rendered or have no containing window will default the “ownerWindow” property to false for convenience.

// Shawn Khameneh
// GFX International
// www.gfxi.com
 
Ext.Component.prototype.initComponent = Ext.Component.prototype.initComponent.createSequence(function(){
	this.ownerWindow = this.ownerWindow || false;
});
 
Ext.Component.prototype.afterRender = Ext.Component.prototype.afterRender.createSequence(function(){
	if(!this.ownerWindow) {
		if(this.ownerCt && this.ownerCt.ownerWindow) {
			this.ownerWindow = this.ownerCt.ownerWindow;
			if(this.dynamicGrid || this.root) {
				this.el.on('click', function(){
					this.ownerWindow.show();
				}, this);
			}
		} else {
			this.ownerWindow = this;
		}
	}
});