Shaun Mccran

My digital playground
 
14
A
P
R
2010

Handling JavaScript event model differences in Internet Explorer and Firefox

A few weeks ago I created an inline editing system for a Content Management System. It allowed a user to click on a page element and edit it inline. The updated data was then submitted through an AJAX request.

I have recently discovered an issue with some of the JavaScript code that I wrote in the event handling routine.

[More]

 
23
M
A
R
2010

What does "Invalid Label" mean in a JSON response, and how can I fix it?

I recently build an application that returned a JSON object of data based on a select field value. Whilst I was building this I encountered an error using the JavaScript eval() function on my JSON response. I am using the eval() function to parse a string from my JSON response, but firebug is showing a JavaScript error of "Invalid Label".

This is the code:

view plain print about
1function(data){
2    jsonResponse = eval(data);
3    var src = jsonResponse.DATA;
4    });

After having a Google around it appears that the eval function is interpreting the first item in the JSON response as a label, rather than data. By changing the code like this:

view plain print about
1jsonResponse = eval("(" + data + ")");

We are forcing eval to recognise the data as variable data. Now the JSON to string translation works.

 
16
M
A
R
2010

Validating checkboxes using the JQuery validate plug-in

I have recently spent some time building a dynamic XML driven form generator. The last element of this was the checkbox form element. All my other fields were being validated as either required, or needing a certain length using the JQuery Validation plug-in. ( http://jquery.bassistance.de/validate/)

This article explains how I put together a checkbox validation routine using the Validate plug-in.

[More]

 
11
M
A
R
2010

JavaScript Library conflicts when using more than one at the same time

Whilst building a new piece of functionality I have been trying to combine a JQuery carousel plug-in and the lightview prototype plug-in. This threw up an unexpected issue. Both libraries map the dollar ($) as their shortcut indicator. JQuery uses "$" as a shortcut as a replacement for "jQuery" and Prototype uses "$" as well.

It turns out that there is a JQuery command for exactly this issue. Wherever you include the JQuery library reference add another script code. The noConflict function maps which character you tell it as the short name for "JQuery".

view plain print about
1<s/cript src="http://www.google.com/jsapi" type="text/javascript"></script>
2<s/cript type="text/javascript" charset="utf-8">
3    google.load("jquery", "1.3");
4</script>
5
6<s/cript>
7    jQuery.noConflict();
8    var J = jQuery;
9</script>

Just remember to change your references to JQuery from "$" to "J", or whatever you assign it to.

view plain print about
1J(document).ready(function(){
2code
3});

Now both the Libraries can load into different namespaces.

 
07
M
A
R
2010

Tracking single page sites with Google analytics code

If you have a framework that controls the URL in some way then you may have an issue when it comes to Google Analytics tracking. In this blog entry I will examine how to alter your GA tracking so that you can specify custom URL values to track. I will then apply this to a FuseBox framework.

Traditionally Google Analytics code tracks each page impression by capturing the URL and all values of the Query string, storing it in a cookie and sending it back to the Google search engine through a JavaScript call. When all your site / applications pages are "index.cfm" it may prove difficult to generate useful Analytics information.

In this example I am using a FuseBox framework. If you are unfamiliar with this, the premise is that all the templates use "index.cfm" and then pass through two parameters. The first is the component to use as a controller (we will use public.cfc) and the second value is the function name to call within that controller. So our URL may look like this:

view plain print about
1www.mysite.com/index.cfm?go=public.login

[More]

 
23
F
E
B
2010

Creating a pop up floating div with JQuery

This entry will deal with how to create a displayed / collapsible floating div, using JQuery. When I build a web platform I often like to include small sections of text alongside the functionality, just to provide the users with a little guidance on what is going on. Rather than having these inline, where they can often interfere with the content and display, I like to add them to a 'help' div that I float inside the framework. First we include the JQuery library from Google, and our link. It doesn't go anywhere, but we will attach a JQuery event to it.
view plain print about
1<s/cript type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
2
3<a href="javascript:void(0);" id="help">Pop me up</a>
4<div>stuff</div>
Next we create our JQuery function, attached to the 'help' div. This adds a div to the document with whatever content you have set in it. There is also a 'close' link in the floating div that calls the close function.
view plain print about
1<s/cript>
2 $(function() {
3 $("#help").live('click', function(event) {
4 $(this).addClass("selected").parent().append('<div class="messagepop pop">Content<p><a class="close" href="/">Cancel</a></p></div>');
5 $(".pop").slideFadeToggle()
6 return false;
7 });
8
9 $(".close").live('click', function() {
10 $(".pop").slideFadeToggle();
11 $("#contact").removeClass("selected");
12 return false;
13 });
14 });
15
16 $.fn.slideFadeToggle = function(easing, callback) {
17 return this.animate({ opacity: 'toggle', height: 'toggle' }, "fast", easing, callback);
18 };
19</script>
Lastly we add some styling and positioning to tie the whole lot together. This gives the pop up div its shape and style. I've positioned the floating div on top of the calling function text.
view plain print about
1<style>
2a.selected {
3 background-color:#1F75CC;
4 color:white;
5 z-index:100;
6}
7
8.messagepop {
9 background-color:#FFFFFF;
10 border:1px solid #999999;
11 cursor:default;
12 display:none;
13 margin-top: 15px;
14 position:absolute;
15 text-align:left;
16 width:394px;
17 z-index:50;
18 padding: 25px 25px 20px;
19 top: 0px;
20 left: 0px;
21}
22}
23
24label {
25 display: block;
26 margin-bottom: 3px;
27 padding-left: 15px;
28 text-indent: -15px;
29}
30
31.messagepop p, .messagepop.div {
32 border-bottom: 1px solid #EFEFEF;
33 margin: 8px 0;
34 padding-bottom: 8px;
35}
36</style>
You can see an example functionality here.

 
16
F
E
B
2010

Controlling show() hide() Divs with a JQuery powered Select field

There are many ways of hiding all your page elements then only showing specific areas based on user selection. One old school way of changing the displayed page content was with a select field that had an onchange event that posted to the same page, but with a URL variable.

I have been testing out a variation on this using the JQuery show() / hide() functions.

We attach an event to the select field, and pass the selected option to a JQuery function, as in the example code below.

view plain print about
1<s/cript type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
2
3<select name="field_data_loc[key]" class="form-select required" id="edit-field-data-loc-key" onChange="showHide(this.value)" >
4<option value="didnotchoose" selected="selected">Choose</option>
5<option value="web">Website</option>
6<option value="file">File to upload</option>
7<option value="url">Url</option>
8</select>

We have a series of DIV's that are named the same as the select field options. All these DIV's will be hidden by default, apart from the "start" div.

view plain print about
1<div id="start">Starting div</div>
2
3<div id="url">url</div>
4
5<div id= "file">file</div>
6
7<div id= "web">web</div>

Lastly we have our JQuery script. Here we have our showHide function. This accepts a DIV id, which is then shown. All other DIV's are hidden.

The last piece of script here simply hides all the DIV's on the page load, so that they are all hidden by default.

view plain print about
1<s/cript language="javascript">
2
3    function showHide(obj)
4        {
5            var showDiv = "#"+obj;
6            $("div").hide();
7            $(showDiv).show();
8        }
9
10    // hide all the divs on start up
11    $('#web').hide();
12    $('#file').hide();
13    $('#url').hide();
14
15</script>

Putting it all together, and making it dynamic based on a list, it looks like this:

view plain print about
1<cfset variables.mylist = "scotland,england,wales,ireland">
2
3<s/cript type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
4
5<cfoutput>
6<select name="field_data_loc[key]" class="form-select required" id="edit-field-data-loc-key" onChange="showHide(this.value)" >
7<option value="didnotchoose" selected="selected">Choose</option>
8
9    <cfloop list="#variables.mylist#" index="variables.index">
10        <option value="#variables.index#">#variables.index#</option>
11    </cfloop>
12
13</select>
14
15<div id="start">Starting div</div>
16
17<cfloop list="#variables.mylist#" index="variables.index">
18    <div id="#variables.index#">#variables.index#</div>
19</cfloop>
20
21<s/cript language="javascript">
22
23    function showHide(obj)
24        {
25            var showDiv = "##"+obj;
26
27            <cfloop list="#variables.mylist#" index="variables.index">
28                $('###variables.index#').hide();
29            </cfloop>
30                $('##start').hide();
31
32            //$("div").hide();
33            $(showDiv).show();
34        }
35
36<cfloop list="#variables.mylist#" index="variables.index">
37    $('###variables.index#').hide();
38</cfloop>
39
40</script>
41</cfoutput>

An example is here.

 
10
F
E
B
2010

Dynamically editing web content inline, using JavaScript and AJAX

Most of us are familiar with the standard method of displaying data in a tabulated fashion, selecting a record, and populating the form that follows. What about editing the content directly into a template that mirrors the actual live version of a page?

This article examines how to edit web content directly inline, and commit it back to a server using an AJAX post request.

The main catalyst for this is that clients that use a content management system do not often have a clear image of how their content will look online. The traditional form layout for entering text does not lend itself well to representing the actual content in the format it is display in.

The aim here is to build a flexible system that allows for inline content editing, and saves it gracefully to a server based database.

I will start by saying thank you to Peter-Paul Koch. His article here (http://www.quirksmode.org/dom/cms.html) on making content editable was invaluable, and a lot of this is based on his theory.

We start by setting a value "editing" to false. This is the default for the page, as the user isn't editing anything when the page loads.

view plain print about
1var editing = false;
2
3if (document.getElementById && document.createElement) {
4    var butt = document.createElement('BUTTON');
5    var buttext = document.createTextNode('Save');
6    butt.appendChild(buttext);
7    butt.onclick = saveEdit;
8}
9
10function catchIt(e) {
11    if (editing) return;
12    if (!document.getElementById || !document.createElement) return;
13    if (!e) var obj = window.event.srcElement;
14    else var obj = e.target;
15    while (obj.nodeType != 1) {
16        obj = obj.parentNode;
17    }
18    if (obj.tagName == 'TEXTAREA' || obj.tagName == 'A') return;
19    while (obj.nodeName != 'P' && obj.nodeName != 'HTML') {
20        obj = obj.parentNode;
21    }
22    if (obj.nodeName == 'HTML') return;
23    var x = obj.innerHTML;
24    var y = document.createElement('TEXTAREA');
25    var z = obj.parentNode;
26    z.insertBefore(y,obj);
27    z.insertBefore(butt,obj);
28    z.removeChild(obj);
29    y.value = x;
30    y.focus();
31    editing = true;
32    getId(e)
33}
34
35function getId(e) {
36    var targ;
37    if (!e) var e = window.event;
38    if (e.target) targ = e.target;
39    else if (e.srcElement) targ = e.srcElement;
40    if (targ.nodeType == 3) // defeat Safari bug
41        targ = targ.parentNode;
42    thisTarget = e.target.id;
43    
44}
45
46function saveEdit() {
47    var area = document.getElementsByTagName('TEXTAREA')[0];
48    var y = document.createElement('P');
49    // set the id back to the original value as the real one is destroyed
50    y.setAttribute('id', thisTarget);
51
52    var z = area.parentNode;
53    y.innerHTML = area.value;
54    z.insertBefore(y,area);
55    z.removeChild(area);
56    z.removeChild(document.getElementsByTagName('button')[0]);
57    editing = false;
58    // action the server request, first var is the value, second var is the id
59    saveToServer(y.innerHTML,thisTarget);
60}
61
62function saveToServer(valToCommit,fieldname) {
63    //alert(valToCommit);
64    $.post("view/appeals/act_commitChange.cfm", { newValue: valToCommit, field: fieldname, appeal: intId },
65
66    function(data){
67        alert(data);
68    });
69
70document.onclick = catchIt;

I wont go into massive depth on a line by line basis but Peter's article does break this down a lot. The premise is that there is a function catchit(), which will intercept any click events. It will then check that the event was triggered from a 'P' tag, which is our defining element for editable content. IE any P elements hold editable content. It will then remove the P html container, replacing it with a textarea, and re insert the P tags previous html content using the innerHTML JavaScript function.

In this way we can create editable inline textareas within the framework of our page.

The next step is to create a save function. The function 'saveToServer{)' take several arguments. It needs the value to commit, IE what the amended text string is, and the fieldname. Each 'P' tag has an id that I am matching to a data field. In this way if there are multiple p tags in a display they can each be attributed to a specific storage field in a database.

Because we are destroying the 'P' tag when we create the textarea we need to re assign the id to it when we save. We can do this by using the JavaScript function 'setAttribute'. The setAttribute function is used to set the value of an attribute on an object. It is typically used along with objects returned by document.getElementById to assign a new value to the object's attribute.

view plain print about
1// set the id back to the original value as the real one is destroyed
2y.setAttribute('id', thisTarget);

If we don't do this then the recreated 'P' tag no longer has an id attribute, so will error on any subsequent updates.

Next we use a JQuery Post function to post the values through an AJAX request.

view plain print about
1$.post("commitChange.cfc", { newValue: valToCommit, field: fieldname, appeal: intId },

This will post the values to the cfml CFC "commitChange.cfc", which handles them in a function.

This will allow you to perform seamless inline edits to the display layer, and commit them back to a server, so they are stored in real time.

There is an example of this here. (Minus the storing). You can track the AJAX post using a tool like charles http proxy, or firefox's firebug.

Now, to write a nice JQuery response handler to fade the returned massage in and out.

Previous Entries / More Entries


This content is purely my opinon, any offence or errors are unintentional, please comment your views appropriately
Site Credits
Aggregated by ColdfusionBloggers.org Powered by Coldfusion

Technology & Science Blogs - BlogCatalog Blog Directory Blog Directory & Search engine