Monthly Archives: February 2012

A javascript selection script

I wanted a lightweight and cross browser plugin to be able to handle selections in a text area (for my griffin.editor plugin). Didn’t find a suitable one despite asking at stackoverflow.com. I created my own. It’s stand alone and only 2,6kb (uncompressed).

Usage:

//jQuery is not required but supported.
var selection = new TextSelector($('#mytextarea'));
selection.replace('New text');

// you can change selection:
selection.select(1,10); // select char 1 to 10

// get selection information
console.log("Start char: " + selection.get().start);

// check if anything is selected
selection.isSelected();

// get the text
var text = selection.text();

Code at github


Introducing griffin.editor – a jQuery textarea plugin

I’ve tried to find a jQuery editor plugin which works out of the box without configuration. The WMD editor used by stackoverflow.com looked nice but I couldn’t find a version that I got running. My main issue with most editors was that I didn’t figure out how to configure custom image and link dialogs. I’ve therefore done my own.

Highlights:

  • Markdown (currently the only format supported)
  • Preview pane (see generated HTML live)
  • Syntax highlighting (live), using highlightjs or google prettify
  • Expanding textarea (which also goes back to original size on blur)
  • jQueryUI dialogs for links/images
  • Access keys (default browser modifier or CTRL if activated)
  • Plug & Play (just include additional scripts to activate features)

The basic setup looks like this:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<head>
  <title>Editor demo</title>
  <script type="text/javascript" src="scripts/jquery-1.6.2.min.js"></script>
  <script type="text/javascript" src="scripts/jquery.markdown-0.2.js"></script>
  <script type="text/javascript" src="../Source/textselector.js"></script>
  <script type="text/javascript" src="../Source/jquery.griffin.editor.js"></script>
  <script type="text/javascript" src="../Source/jquery.griffin.editor.markdown.js"></script>
  <style type="text/css">
   .editor .area { width: 600px; height: 200px; }
   .editor .toolbar { padding: 0px;  }
 </style>
</head>
<body>
<div class="editor">
	<div class="toolbar">
		<span class="button-h1" accesskey="1" title="Heading 1"><img src="../Source/images/h1.png" /></span>
		<span class="button-h2" accesskey="2" title="Heading 2"><img src="../Source/images/h2.png" /></span>
		<span class="button-h3" accesskey="3" title="Heading 3"><img src="../Source/images/h3.png" /></span>
		<span class="button-bold" accesskey="b" title="Bold text"><img src="../Source/images/bold.png" /></span>
		<span class="button-italic" accesskey="i" title="Italic text"><img src="../Source/images/italic.png" /></span>
		<span class="divider">&nbsp;</span>
		<span class="button-bullets" accesskey="l" title="Bullet List"><img src="../Source/images/bullets.png" /></span>
		<span class="button-numbers" accesskey="n" title="Ordered list"><img src="../Source/images/numbers.png" /></span>
		<span class="divider">&nbsp;</span>
		<span class="button-sourcecode" accesskey="k" title="Source code"><img src="../Source/images/source_code.png" /></span>
		<span class="button-quote" accesskey="q" title="Qoutation"><img src="../Source/images/document_quote.png" /></span>
		<span class="divider">&nbsp;</span>
		<span class="button-link" accesskey="l" title="Insert link"><img src="../Source/images/link.png" /></span>
		<span class="button-image" accesskey="p" title="Insert picture/image"><img src="../Source/images/picture.png" /></span>
	</div>
	<textarea class="area">Hello world</textarea>
</div>
<script type="text/javascript">
	$(function(){
		$('.editor').griffinEditor();
	});
</script>
</body>
</html>

All of that is required. (Just a simple copy/paste). The idea is that you should easily be able to customize it’s layout. The script generates the following layout:

Basic layout

Dialogs

The basic setup uses browser dialog boxes:

Dialog box

Not so sexy. Include jQueryUI and the integration script:

  <link rel="stylesheet" href="Styles/jquery-ui-1.8.16.custom.css">
  <script type="text/javascript" src="scripts/jquery-ui-1.8.16.custom.min.js"></script>
  <script type="text/javascript" src="../Source/jquery.griffin.editor.dialogs.jqueryui.js"></script>

.. to automatically reconfigure the plugin to use jQueryUI:

Using jQueryUI for dialogs

You can use your own dialogs by implementation the following function:

$.griffinEditorExtension.imageDialog = function(options)
{
    //options.title & options.url contains info specified in the editor

   // invoke when done
   options.success({ title: 'Some title', url: 'Some url';}) when you are done
}

Same goes for the link dialog.

Preview pane

The preview pane is automatically configured when you add a div with a special id:

<div class="editor" id="myeditor">
//all the editor code
</div>
<div id="myeditor-preview">
</div>

This allows you to place the preview pane wherever you like. The included demo scripts places the preview to the right:

Preview pane

You can also add support for syntax highlighting by including additional script & stylesheet:

  <script src="http://yandex.st/highlightjs/6.1/highlight.min.js"></script>
  <link rel="stylesheet" href="http://yandex.st/highlightjs/6.1/styles/idea.min.css">

The script inclusion will activate those features, no additional configuration is required.

Access keys

The default access key implementation uses the browser specific implementation. For instance Win+Chrome uses ALT+Key to activate it. Hence no additional information in the tooltip:

Default access keys

That can be changed by adding a hotkeys script:

  <script type="text/javascript" src="scripts/jquery.hotkeys.js"></script>

Which reconfigures the tooltips and allows you to use CTRL+key to access the toolbar features. The key is still controlled by the accesskey attribute on the toolbar icons.

Better hotkeys

Summary

The codez & all examples are available at github.


Generic repositories – A silly abstraction layer

This post is all about GENERIC repositories as in Repository, not about all types of repositories. Repositories are a great way to abstract away the data source. Doing so makes your code testable and flexible for future additions.

My recommendation is against generic repositories, since they don’t give you any additional value compared to regular repository classes. “Regular” repositories are usually written specifically for the requirements that your project have.

Let’s look at what generic repositories give you:

You can change OR/M implementation at any time.

Seriously?

  1. If you find yourself having switch OR/M during a project you have not done you homework before you started the project.
  2. The OR/M choice doesn’t matter since you have abstracted away the features of the chosen OR/M

imho you’ll stick with one OR/M during a project and switch for the next one (if you have to switch).

You have to write less code.

Here is a Generic repository (nhibernate implementation) from a SO question:

public interface IRepository<T> : IQueryable<T>
{
  void Add(T entity);
  T Get(Guid id);
  void Remove(T entity);
}

public class Repository<T> : IQueryable<T>
{
  private readonly ISession session;

  public Repository(ISession session)
  {
    session = session;
  }

  public Type ElementType
  {
    get { return session.Query<T>().ElementType; }
  }

  public Expression Expression
  {
    get { return session.Query<T>().Expression; }
  }

  public IQueryProvider Provider
  {
    get { return session.Query<T>().Provider; } 
  }  

  public void Add(T entity)
  {
    session.Save(entity);
  }

  public T Get(Guid id)
  {
    return session.Get<T>(id);
  }

  IEnumerator IEnumerable.GetEnumerator()
  {
    return this.GetEnumerator();
  }

  public IEnumerator<T> GetEnumerator()
  {
    return session.Query<T>().GetEnumerator();
  }

  public void Remove(T entity)
  {
    session.Delete(entity);
  }   
}

Take a look at the methods. All they do is to call methods in nhibernate. You do not win anything by doing so. All you get is an abstraction layer that removes the good things with nhibernate/ef/whatever.

It’s better to create a proper base class and move all repeated (DRY) functionality into it (and therefore still be able to take advantage of the features in your favorite OR/M).

Summary

Did I miss something that a generic repository gives you? Please make a comment.


Repositories, Unit Of Work and ASP.NET MVC

There are a lot of posts discussing repository implementations, unit of work and ASP.NET MVC. This post is an attempt to give you and answer which addresses all three issues.

Repositories

Do NOT create generic repositories. They look fine when you look at them. But as the application grow you’ll notice that you have to do some workarounds in them which will break open/closed principle.

It’s much better to create repositories that are specific for an entity and it’s aggregate since it’s much easier to show intent. And you’ll also only create methods that you really need, YAGNI.

Generic repositories also removes the whole idea with choosing an OR/M since you can’t use your favorite OR/Ms features.

Unit Of Work

Most OR/Ms available do already implement the UoW pattern. You simply just need to create an interface and make and adapter (google Adapter pattern) implementation for your OR/M.

Interface:

    public interface IUnitOfWork : IDisposable
    {
        void SaveChanges();
    }

NHibernate sample implemenetation:

    public class NHibernateUnitOfWork : IUnitOfWork
    {
        private readonly ITransaction _transaction;

        public NHibernateUnitOfWork(ISession session)
        {
            if (session == null) throw new ArgumentNullException("session");
            _transaction = session.BeginTransaction();
        }

        public void Dispose()
        {
            if (!_transaction.WasCommitted)
                _transaction.Rollback();

            _transaction.Dispose();
        }

        public void SaveChanges()
        {
            _transaction.Commit();
        }
    }

ASP.NET MVC

I prefer to use an attribute to handle transactions in MVC. It makes the action methods cleaner:

[HttpPost, Transactional]
public ActionResult Update(YourModel model)
{
    //your logic here
}

And the attribute implementation:

public class TransactionalAttribute : ActionFilterAttribute
{
    private IUnitOfWork _unitOfWork;

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        _unitOfWork = DependencyResolver.Current.GetService<IUnitOfWork>();

        base.OnActionExecuting(filterContext);
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        // let the container dispose/rollback the UoW.
        if (filterContext.Exception == null)
            _unitOfWork.SaveChanges();

        base.OnActionExecuted(filterContext);
    }
}

Localizing jQuery plugins

I’ve spent some time to figure out how to localize my jQuery plugins and I’ve just found out a way that works just fine. Disclaimer: I’m not 100% sure of how namespacing works in jQuery so this might not be the correct way.

I’m using the meta header accept-language to control which language to use. It allows me to select the language in my backend (using user settings or whatever) instead of just using the languages defined by the browser. An ASP.NET MVC3 header would look like this in the layout:

<meta name="accept-language" content="@System.Globalization.CultureInfo.CurrentCulture.Name" />

You should be able to do the same thing in PHP or whatever language you use.

Next thing to do is to add the localization structure to your plugin script file:

(function($) {
    //globals
    $.yourPluginName = {
        texts: {
            title: 'Please wait, loading..'
        },
        translations: []
    };
    
    var methods = {
		// your methods here.
	};

    $.fn.yourPluginName = function(method) {

        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not exist on jQuery.yourPluginName');
        }

    };

})(jQuery);

That will make the plugin work if no languages are loaded. The translations will be loaded into the $.yourPluginName.translations array by another script.

We got one thing left to do before we can use the texts in your script. We need to load the correct language. Create another script called jquery.yourpluginnamne.localization.js and load it after$.yourPluginName.texts.anyTextName in your plugin to use the localized strings.


Get an unique session in each browser tab

I got a lot to do at work, hence the silence. I got a lot to blog about, but so little time ;/ I found an interesting question at stackoverflow which this answer is for (also to show you that the blog is not forgotten).

A user wanted to store browser tab specific data which can be a problem since most browsers shares a session between different tabs. The solution is to create a new route which generates a GUID and then
use that guid to fetch and store session information. Keep in mind that you need to routes: One that works for users which just surfed into the site, and one that loads an existing guid.

Here is the route class:

public class GuidRoute : Route
{
	private readonly bool _isGuidRoute;

	public GuidRoute(string uri, object defaults)
		: base(uri, new RouteValueDictionary(defaults), new MvcRouteHandler())
	{
		_isGuidRoute = uri.Contains("guid");

		DataTokens = new RouteValueDictionary();
	}

	public override RouteData GetRouteData(HttpContextBase httpContext)
	{
		var routeData = base.GetRouteData(httpContext);
		if (routeData == null)
			return null;

		if (!routeData.Values.ContainsKey("guid") || routeData.Values["guid"].ToString() == "")
			routeData.Values["guid"] = Guid.NewGuid().ToString("N");

		return routeData;
	}

	public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
	{
		return !_isGuidRoute ? null : base.GetVirtualPath(requestContext, values);
	}
}

Replace the default route in global.asax with it:

/*routes.MapRoute(
	"Default", // Route name
	"{controller}/{action}/{id}", // URL with parameters
	new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);*/

routes.Add("Default", new GuidRoute(
	"{controller}/{action}/{id}", 
	new { controller = "Home", action = "Index", guid = "", id = UrlParameter.Optional }));

routes.Add("GuidRoute", new GuidRoute(
	"g/{guid}/{controller}/{action}/{id}", 
	new { controller = "Home", action = "Index", guid = "", id = UrlParameter.Optional }));

And finally some extension methods to make life easier in the controllers:

public static class ControllerExtensionMethods
{
	public static string GetGuid(this Controller controller)
	{
		return controller.RouteData.Values["guid"].ToString();
	}

	public static void SetGuidSession(this Controller controller, string name, object value)
	{
		controller.Session[controller.GetGuid() + "_" + name] = value;
	}

	public static object GetGuidSession(this Controller controller, string name)
	{
		return controller.Session[controller.GetGuid() + "_" + name];
	}
}

One thing left though: Any browser bookmarks will use an old GUID. Should not be a problem in most cases (unless the user opens the bookmark in multiple tabs = sharing the session between the tabs). Same
thing goes for opening a link in a new tab = shared.