Jquery blog editor

By sarah

The next step in my blog engine project is to use the attribute contentEditable that I talked about in my last post together with jquery to add different elements to the page. Depending on what button the user clicks, the correct markup is added to the page, which is then editable. My code looks like this:

$('#controls ul li a').click(function () {
var markup = $(this).attr('href');
if (markup == 'hr') {
$('section[role=main]#detail #movable').append('<' + markup + ' />');
} else if (markup == 'blockquote') {
$('section[role=main]#detail #movable').append('
<' + markup + ' contenteditable="true">"Click to edit"
');
} else if (markup == 'ul' || markup == 'ol') {
$('section[role=main]#detail #movable').append('
<' + markup + ' contenteditable="true"><li>Click to edit</li>
');
} else {
$('section[role=main]#detail #movable').append('
<' + markup + ' contenteditable="true">Click to edit
');
}
$('section[role=main]#detail .editable').unbind();
bindHover()
return false;
});

I then want to add a toolbar when hovering over these editable areas on the page,that disappears when you move the mouse away. My code for this is as follows:

$('section[role=main]#detail .editable').mouseenter(function () {
if (!$(this).hasClass("active")) {
if ($('.top-bar', $(this)).length == 0) {
$(this).prepend('
<ul><li><a href="#" class="move">Move</a> <li><a href="#" class="delete">Delete</a></li> ');
$('.top-bar ul li a.delete', $(this)).click(function () {
$(this).closest('.editable').remove();
});
}
}
}).mouseleave(function () {
if (!$(this).hasClass('active')) {
$('.top-bar', $(this)).remove();
}
});

In extension of this functionality, I want the toolbar to remain visible when the area is clicked and include extra styling options. Here is my code:

$('section[role=main]#detail .editable').click(function () {
if (!$(this).hasClass("active")) {
$('section[role=main]#detail .editable').removeClass('active');
$('section[role=main]#detail .editable .top-bar').remove();
$(this).addClass("active");
$(this).prepend('
<ul class="styling"><li><a href="#" class="bold">B</a></li><li><a href="#" class="italic">I</a></li><li><a href="#" class="link">Link</a></li></ul><ul><li><a href="#" class="move">Move</a></li><li><a href="#" class="delete">Delete
</li></ul>');
$('.top-bar ul li a.delete', $(this)).click(function () {
$(this).closest('.editable').remove();
});
}
});

Finally here is how it all works together.

And so February begins...

By Editor

It was a mere month ago when the Christmas holiday was upon us and we were frantically rushing around shops making the decision to buy gifts and get drunk or pay rent! 

Now it is all in the past, and a sparkly new year is upon us - and speeding past!

This year we have some amazing things to celebrate...

Of course the top of our list is our birthday - we are 10!! We have a bunch of exciting stuff planned throughout the year and we will be celebrating every month!

Also on the calendar is the Queen's Jubilee and the Olympics, not quite as thrilling but a few more bank holidays to celebrate.

How has your year gone so far? Hoping for a better February than January?  

 

Further webGL

By lyle

So after the last blog i wanted to get some proper 3d shapes going on. They can be seen here http://demo.creative-jar.com/webgl3d/ (don't forget about using chrome). Again they're nothing special or fancy, but it's a step forwards from where i was. The next step from here is to try and get textures working and possibly some keyboard input.

ContentEditable and Hyperlinks

By jason

This week I was trying to replicate "hyperlink" functionality using a ContentEditable area, rather than a <textarea>. Stupidly, I thought the process of finding a user's currently selected text and surrounding it with a link would be fairly easy... it turned out to be fairly tough.

My function would use the window.getSelection() to get the user's current selection, and then call getRangeAt(0).cloneRange() to create a copy of the "Range" object for that selection. The range object tells the browser where the selection starts and where the selection ends.

I would pull the selected text out into a string object by calling .toString() on the Range object itself. Then I could modify that string to include an <a> tag surrounding it, with the appropriate link. The next step was the most difficult to figure out, the process is as follows:

  1. Create a new text node, using document.createTextNode and passing in the modified string.
  2. Call "insertNode" on my range object, passing the text node as a parameter.
  3. Call "removeAllRanges()" on the selection object, to remove any existing ranges.
  4. Call "addRange" on the selection object, passing in my modified range object.

This resulted in the selected text being replaced with my linked version in every browser except... Firefox. Bit of a strange one, really, and Googling the issue didn't seem to shed much light. My next step is to find a Firefox friendly fallback for if the normal method fails.

ContentEditable = “truly awesome”

By sarah

Recently I’ve been collaborating on a blog engine with a designer (Simon) and back-end developer (Jason). Using Simon’s built WYSIWYG editor ( see previous post ) as a starting point we are aiming to create a user friendly blog that can be edited ‘on the fly’.

So the html5 attribute ‘contenteditable’ is fundamental in our development allowing us to avoid the use of form textareas to input text. This quick demo shows that by adding ‘contenteditable=”true” to the element the user can directly edit the text inside. Such an easy bit of work for a massive chunk of our editor.

context.isPointInPath()

By Ben

Continuing on my journey of learning the in's and out's of HTML5's Canvas, I found myself needing to detect whether a point on my canvas was within the region of one of my multiple objects already drawn on the canvas.

At first I thought I was stuck with the only option of having to loop through each of the objects, calculating all of the co-ordinates that the object covers and then seeing if any of them tally up with another my point of interest. I hope that makes sense, it definitely took me a while to even come up with that solution. However, as I began down this route I thought there must be a better way, something I'm missing.

After some googling, I came across isPointInPath(), a function within the Canvas API which, in short, allows you to check if a co-ordinate (passed into the function) is within the current path being drawn. Perfect! The only issue is that I have been drawing my object's through the use of methods such as .drawRect() which, from what I could tell anyway, could not be used within a path. This therefore meant that I needed to redraw my object's.

In the code below, I check to see if a point is within the current path, and therefore change the colour of the object I am about to draw. This is it in it's simplest form, but you could use it to do alot more, especially when bringing mouse interactions into a Canvas piece.

context.beginPath();
            
context.moveTo(100, 100);
context.lineTo(200, 100);
context.lineTo(200, 200);
context.lineTo(100, 200);
                                    
context.fillStyle = "rgb(0, 0, 0)";
context.fill();
                    
if(context.isPointInPath(250, 250)) {
    var blockColour = "rgb(255, 0, 0)";
}
else {
    var blockColour = "rgb(0, 255, 0)";
}
                    
context.closePath();
                    
context.fillStyle = blockColour;
context.fillRect(250, 250, 5, 5);

You can also see though that I am drawing a 5x5 rectangle, starting at the co-ordinate I passed into the isPointInPath function. This means though that whilst the starting point is not in the path, another point within the rectangle could be. This leaves me the next challenge to see if I can check if any point within a path is within a point within another path. I do like to give myself challenges, don't I?

In the following demos, you can see an example of the above code in action; a point being within the path and another point being outside the path.

Multiple dynamic Partial Views in MVC3

By jason

I thought I’d write a blog around a piece of interesting functionality I developed for a new blog engine that I am currently involved with.

The requirement was to take a flat list of posts and output a dynamic, magazine style layout with was broken down into multiple rows, with each row having a varying number of posts. This needed to be a random arrangement, so that each time the blog was visited, the layout would be different and make for a more interesting user experience.

This was going to be using MVC3, so the first step was to create a database table called BlogRow. This contained all of the row variations that existed within the system, the two most important columns being “ViewName” (which stored the name of the partial view instance for that particular row type) and “NumberOfPosts” (which stored the number of posts this row required to display).

When the page began rendering, you’d start with a flat list of 24 posts, retrieved in reverse chronological order from the database. Then you’d follow this process:

  1. Get a random BlogRow instance from the database (where NumberOfPosts for that row is higher than the remaining posts in the flat list)
  2. Slice the required NumberOfPosts out of the flat list (so slicing 4 would leave you with 20 in the flat list)
  3. Create a model for that particular partial view, consisting of a List of Post objects and the name of the partial view for that Blog Row
  4. This process continues until you have no posts remaining in the flat list of posts, at which post, a model which consists of a List of Lists of Posts (confusing, right?) is sent to the main View for the front of the blog

There were a couple of pieces of extra logic around this (for example, a row consisting of a single post is only used if there’s only one post left in the list at the end), but I won’t go into all of those now. The page also stored it’s layout in the user session, preventing the layout from changing constantly for a single user every time they refreshed the page.

I couldn’t find many instances of people using a dynamic number of Partial Views/Partial View Models within a single view, so it took a bit of planning to put something together, but I ended up with a pretty effective solution.

Dragdealer

By sarah

For a recent project I was required to create a scrollable map that also acted as a slideshow of content. I was pointed in the direction of an online script called dragdealer.js. On first view this seemed to have all the features I needed and would be easily customizable to the design I was working from.

So I started editing the markup to create my 3x4 grid but immediately hit a problem with my slides not scrolling to the coordinates I had set. With little explanation to the script online I eventually realized that I would need a grid of equal slides horizontally and vertically, so I reworked my coordinates. The drawback of this was I would have to use extra markup to create these empty slides.

So my code then looked like this; with steps being the number of slides horizontally/vertically.

var canvasMask = new Dragdealer('canvas', { x: 1, y: 0, vertical: true, steps: 5, loose: true });

var slideCoordinates = [[1, 0], [2, 0], [3, 0], [1, 1], [2, 1], [3, 1], [1, 2], [2, 2], [3, 3], [1, 3]];

However at this point my dragging functionality still wasn’t working correctly. After a lot of trial and error I worked out this formula.

x = x / (steps -1) & y = y /( steps-1)

So..

var canvasMask = new Dragdealer('canvas', { x: 0.25, y: 0, vertical: true, steps: 5, loose: true });

var slideCoordinates = [[0.25, 0], [0.5, 0], [0.75, 0], [0.25, 0.25], [0.5, 0.25], [0.75, 0.25], [0.25, 0.5], [0.5, 0.5], [0.75, 0.5], [0.25, 0.75]];

Take a look at my demo

Looking at webGL

By lyle

I've been looking into making 3d shapes in browser using webGL. I've been working through some lessons at http://learningwebgl.com/blog/ and so far i've got to lesson 3. As you can see http://demo.creative-jar.com/webgl/. It's not too fancy at the moment but it's a start. The next step is to do some proper 3d stuff. Oh, and to view the demo you will probably need chrome.

Mobile Detection Testing

By candice

Since my last post on mobile browser detection I’ve had a play with the code, fixed the map overlap issue that I had a couple of posts ago, and have been putting my colleagues here to work giving me a good set of results from testing.
 
So, what caused the map to overlap on some phones and not others? The media query selecting the CSS to use. It would appear having followed some guidance on http://www.html5rocks.com/en/mobile/mobifying.html which showed an example calling ‘handheld’ in the query. Given that this was focused purely for mobile phones at the time I felt it was reasonable to assume I should put this in. However many phones don’t recognise this value in the media query and so the mobile css was not picked up. Cleansing my media query to be based on screen size alone meant that it was picked up by any device falling within the media query’s values.
 
So, now I had a website which would display the map correctly, now I just wanted to test the redirects. I setup the following URLs will separate instances of the redirect:
 
Server Side Mobile Detection Redirect
 
Client Side Mobile Detection Redirect
 
The results are in and they make for interesting reading:
  • Samsung Galaxy SII | Android | OS 2.3.3 | Google Android
    Outcome: Page redirects on each URL, map displays correctly, can move around map

  • Samsung Omnia 7 | Windows Phone 7.5 | IE 9
    Outcome:  Page redirects on each URL, map displays correctly, cannot move around map

  • HTC Mozart | Windows Phone 7.5 | IE - Latest on WP7
    Outcome: Didn’t redirect. Phone was set to view websites not mobile versions so phone ignored the redirect. When phone was set to view mobile sites the redirect worked on both occasions.

  • HTC Trophy 7 | Windows Phone 7.5 | IE – latest version on WP7
    Outcome: Page redirects on each URL, map displays correctly, cannot move around map

  • iPhone 3GS | OS 4.1 | Safari
    Outcome: Page redirects on each URL, map displays correctly, can move around map. This particular user discovered they could use Street View too! 

  • iPhone 3GS | iOS 5.0.1 | Safari
    Outcome: Site loaded, map loaded, nothing overlapped and was able to move around the map per the normal Google Maps app. 

  • iPhone 4S | iOS 5.0.1 | Safari
    Outcome: Redirected but would not load map. Had javascript enabled.

  • iPhone 3GS | latest OS | Safari
    Outcome: Redirected but would not load map. Had javascript disabled. Enabled and tried again but would still not load the map.
The interesting thing here is that the iPhone, regardless of model, appeared to be a bit hit and miss! While the idea of creating a mobile website, there are limitations and sometimes they’re not even down to a specific phone and/or configuration.

Mobile Apps developed to the mobile platform of choice certainly have their place. Apps are there for users to perform actions that might otherwise be available on a normal website in a mobile environment. Browsing stripped back information on mobile websites makes sense, and there will undoubtedly be some simple functions that can be performed logically on a mobile website, but there are some that clearly cannot.