JavaScript

typeahead – Limit results

Posted on: February 28th, 2014 by taff No Comments

 

I recently started using twitters typeahead for search suggestions. Although it works well out of the box, there were a couple of things I wanted to change. Currently I have typeahead doing two requests, one that retrieves the searchterms other users have used and the other to find relevant products in a database, but to start let's look how to go about limiting the number of results.

Limiting the number of results with typeahead

By default, typeahead limits the number of results to 5. I, however, only wanted the 3 closest results. Limiting the number of results with typeahead is simply achieved using the limit parameter as can be seen in the typeahead example below

jQuery('#Search').typeahead([
{
limit: 3,
remote: '/searchterms.php?q=%QUERY',
name: 'searchterms'
}
]);

The example has three parameters, the limit parameter that tells typeahead how many results to display, the remote parameter which tells typeahead where to get the data from and name which tells typeahead the name of the dataset. The code above limits the results to three. As you can see limiting the number of results with typeahead is a breeze with the correct parameter.

This code needs to be placed inside a document ready function or an equivalent to ensure execution when the page has loaded. It goes without saying but you obviously need to make a script call to typeahead.min.js. In the example above typeahead adds some javascript magic to the input field with the ID Search.

Although not entirely related to limiting the number of results with typeahead, in addition to the remote parameter, there are other ways of retrieving data. For example, if you have a set amount of data that you want to be cached client side, you may want to look into the prefetch parameter. I hope you like this short example of limiting the number of results with typeahead. Look forward to a couple of other examples such as requesting more than one type of data and how to build a custom template without using hogan.

Loop through Input Elements in a DIV Tag with jQuery

Posted on: February 26th, 2014 by taff 2 Comments

 

Occasionally you need to loop through input elements prior to submission so that you can see what exactly is being submitted.
I like to use jQuery, the javascript framework of my choice for this. Although the title describes looping through input elements in a DIV Tag, you can use the following script to equally loop through elements in a FORM tag identically.

The following script will loop through input elements in the DIV tag with the ID nameOfDiv. You can, of course, use a different selector if you need the elements in multiple divs.

var $inputs = jQuery('#nameOfDiv :input');
var values = {};
$inputs.each(function() {
    console.log(values[this.name] = jQuery(this).val());
});
jQuery('#nameOfDiv').submit();

Using the jQuery each function we can loop through all the input elements in our div. For the example, I am simply outputting them into the console window, i.e. Firebug or the Chrome console.

Resize iframe from another domain with easyXDM

Posted on: June 23rd, 2013 by taff No Comments

 

I recently ran into the problem of trying to resize an iframe element to match the height of the content. This does away with extra scrollbars which can create usability issues.
Unfortunately trying to resize iframe from another domain is not an easy task because of the same origin policy. However, there is normally a workaround for all things web and this is the solution I implemented to allow me to resize an iframe from another domain.

Although there are various ways to workaround the entire ajax / same origin policy headache I went with easyXDM and followed the resize iframe based on content example. The example worked as described but I then noticed the dreaded disclaimer "If you plan on navigating the inner window, be aware that this will break the connection and subsequent pages won’t cause the iframe to resize" and indeed this was the case. The suggested workaround was to use an intermediate iframe and an example was provided. Either this wasn't very well documented or I just didn't find it, so here is how I managed to resize iframe from another domain and navigate within it.

Document with the iframe

The document with the iframe had been built using JSF in this example.
The value of my hidden field with the id statisticsURL had been declared in a config file and was something like "http://www.someOtherDomainThanThisOne.com/page1.html"
The message being passed is the height of the content. I added 50 to the total height to ensure that scrollbars were not shown.

<form><input id="statisticsURL" type="hidden" value="#{sessionBean.statisticsURL}" /></form><script type="text/javascript">// <!&#91;CDATA&#91;
   var pageURL = encodeURIComponent($("#statisticsURL").val()); 			
   var transport = new easyXDM.Socket({ 				
      remote: "/iframe-intermediate.html?url="+pageURL, 				
      container: "iframeContainer", 				
      onMessage: function(message, origin){ 					
        message = (Number(message)+50); 					
        this.container.getElementsByTagName("iframe")&#91;0&#93;.style.height = message + "px"; 					
// &#93;&#93;></script>
<div id="iframeContainer"></div>

Intermediate iFrame to allow navigation from within the iframe and still be able to resize

Our intermediate iFrame is hosted at the same domain as our iFrame content i.e. www.someOtherDomainThanThisOne.com
In the example above it is called iframe-intermediate.html but the name plays no role whatsoever. The content of the intermediate iframe is:

<head>
        <script type="text/javascript" src="/path/to/easyXDM.min.js"></script>
        <script type="text/javascript">
            var iframe;
            var socket = new easyXDM.Socket({
                swf : "/path/to/easyxdm.swf",
                onReady : function() {
                    iframe = document.createElement("iframe");
                    iframe.frameBorder = 0;
                    document.body.appendChild(iframe);
                    iframe.src = easyXDM.query.url;

                    var timer;
                    iframe.onload = function() {
                        var d = iframe.contentWindow.document;
                        var originalHeight = d.body.clientHeight || d.body.offsetHeight || d.body.scrollHeight;

                        // We want to monitor the document for resize events in case of the use of accordions and such,
                        // but unfortunately only the window node emits the resize event, and we need the body's.
                        // The only solution then is to use polling..

                        // Lets start the polling if not all ready started
                        if(!timer) {
                            timer = setInterval(function() {
                                try {
                                    var d = iframe.contentWindow.document;
                                    var newHeight = d.body.clientHeight || d.body.offsetHeight || d.body.scrollHeight;
                                    if(newHeight != originalHeight) {
                                        // The height has changed since last we checked
                                        originalHeight = newHeight;
                                        socket.postMessage(originalHeight);
                                    }
                                } catch(e) {
                                    // We tried to read the property at some point when it wasn't available
                                }
                            }, 300);
                        }
                        // Send the first message
                        socket.postMessage(originalHeight);
                    };
                },
                onMessage : function(url, origin) {
                    iframe.src = url;
                }
            });

        </script>
        <style type="text/css">
            html, body {
                overflow: hidden;
                margin: 0px;
                padding: 0px;
                width: 100%;
                height: 100%;
            }
            iframe {
                width: 100%;
                height: 100%;
                border: 0px;
            }
        </style>
    </head>
    <body></body>

iFrame Content Example

This is example content to resize Iframe from another domain. The actual content of the iframe doesn't matter at all as in the example provided on the easyXDM website.

    <head>
        <title>easyXDM</title>
        <style type="text/css">
            html, body {
                overflow: hidden;
                margin: 0px;
                padding: 0px;
                background-color: green;
            }
        </style>
    </head>
    <body>
        <a href="resized_iframe_2.html">resized_iframe_2.html</a>
        <br/>
        Nam nulla nibh, tempus ut dictum eget, euismod vitae metus. Donec vitae nulla nec quam sagittis gravida vel quis eros. Nullam vel est justo. Donec euismod interdum magna, et rutrum libero tincidunt vel. Praesent imperdiet, magna et suscipit facilisis, nulla justo consequat nisl, et mollis elit nunc a est. Sed felis quam, condimentum eget gravida non, semper non quam. Duis vestibulum sem id erat tristique eleifend. Phasellus ante nunc, pulvinar nec facilisis at, hendrerit sed leo. Morbi lacinia nisl id nunc faucibus lacinia. Curabitur adipiscing leo a odio aliquet hendrerit. Nullam laoreet pulvinar suscipit.
    </body>

I spent a while trying to resize iframe from another domain until I finally managed to get it to work, so hopefully these examples will give you a good starter to workaround the same origin policy when you need to resize an iframe.

jquery each last iteration

Posted on: June 22nd, 2013 by taff No Comments

 

Rainer Sturm  / pixelio.de

Rainer Sturm / pixelio.de

I occasionally need to add some extra markup when looping through elements using jQuery each. The following is an example of some Javascript which I used to parse XML data that I received from an AJAX call. To cut down on overhead I don't use jquery .size() but prefered to use the "standard" .length property.

Get the last iteration of an each loop

The idea is simple to get the last iteration in the each loop, we simply find out how many elements we have in our array, loop through them, add one to our "counting" variable or incremental and check to see if we have reached the value of .length.

The example looks like this:

//get the length of our array
var totalLen = $(this).find('filename').length;

var tmpLen = 0;

$(this).find('filename').each(function(){
//add one each time the function is called
tmpLen++;
//add the content of our filename node
str += $(this).text();
//if it's the last element add a full stop, otherwse add a comma.
if(tmpLen<=totalLen){
str += ".";
}else{
str += ", ";
}
});

jQuery – Remove last row from table

Posted on: June 10th, 2013 by taff No Comments

 

Learning how to remove last row from table with javascript is functionality I occasionally implement when the last row contains totals for each column and I need to load more rows of data via ajax. I will delete the last table row then append data then call my total generator function.

If using jQuery I simply use the following to delete the last row from a table:

$('#idOfTable tr:last').remove();

Of late, whenever I use a table to display data I take advantage of the tablesorter plugin as it offers everything I need straight out of the box. The markup required by tablesorter for a table looks like this

<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Column 1</td>
<td>Column 2</td>
</tr>
<tr>
<td>Column 1</td>
<td>Column 2</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Footer 1</td>
<td>Footer 2</td>
</tr>
</tfoot>
</table>

As you can see I use the thead, tbody and tfoot tags. I think these are a good choice anyway so tablesorters requirement makes no difference to me at all.

Remove tfoot with jQuery

If I need to remove the entire tfoot before adding the new table rows it is even easier than the above script to remove a row. I can simply do

$('#idOfTable tbody').remove();

And it's bye bye tfoot.

JQuery colour alternate table rows

Posted on: June 7th, 2013 by taff No Comments

 

Colouring alternate table rows increases readability, thus increasing usability. In particular long table rows with the same background colour being hard to read is a phenomenon that most of us know well from using MS Excel. The same goes for long tables in our browser where, in a worst case, we need to scroll the entire view.

Using jQuery to colour alternate table rows may sound strange when CSS now offers exactly that with the use of a pseudo selector.

Colour alternate table rows with CSS pseudo selector

tr:nth-child(even) {
background-color: #f8f8f8;
}

Unfortunately, and probably not that surprising for most of you, Internet Explorer 8 doesn't like the css solution. I am currently building an MIS for a large company and their browser of choice at the moment is, yes you guessed it, IE8 so I had to resort to a javascript solution. JQuery was already in use so I simply did the following

Colour alternate table rows with jQuery

$("tr:even").css("background-color", "#f8f8f8");

If I for whatver reason have no default background colour for my table rows I can use a short hand version of the if / else conditional like this

$("#idOgTable tbody tr").css("background-color", function(index) {
return index%2==0?"#f8f8f8":"#ffffff";
});

Due to my table setup using thead, tbody and tfoot tags I have the tbody in the selector. I needed this setup to allow me to use the amazing tablesorter plugin to exclude rows when sorting.

I hope you can use the above script to colour alternate table rows with jQuery.

Reset form elements with jQuery

Posted on: November 8th, 2012 by taff No Comments

 

Reset form with jQuery is not as easy as I thought. I was using some jQuery love to send some form values via AJAX to a service when the submit button was clicked. I like to override submits with javascript, it slows down spam when used on contact forms and the like and is very fast to implement. The basic idea is on submit, hide the form and submit the data using the jQuery serialize() method. If the data is successfully submitted offer the user the option of resubmitting the form. If they click on the link, stop hiding the form and reset the fields so as to avoid confusion. I will add a post on how to submit a form with jQuery in the near future, but I am digressing, so back to the example. This was my first attempt and it failed miserably.

//Fails miserably
$("#create_teaser").reset();

After looking online there was quite a bit of talk about creating new jQuery methods and such, which seemed like a bit of an overkill to me.

Example of reset form with jQuery

This solution is about as simple as it gets when you want to reset form elements.

$("#create_teaser")[0].reset();

Reset form elements with Javascript

If you don't have jQuery available then you could just reset a form like this:

document.getElementById('myForm').reset();

which gets the element with the id myForm (in our case the form itself) and resets all the form elements to their original value.

confirm delete prior to execution with javascript

Posted on: November 8th, 2012 by taff No Comments

 

Using javascript to confirm delete action is an important factor before carrying out data deletion. It gives you a second chance if you or the baby you have on your lap click on a delete button or link accidentally. In my opinion you should always have to confirm delete actions prior to execution.

Confirm delete - A javascript example

This is an example of a function to confirm a delete action. It uses jQuery for the selectors and AJAX calls. It also uses the jQuery live method so that content loaded at a later date can still be targeted by using selectors.

$(".deleteTeaser").live("click", function(){
//element ID is equal to the teaser ID: <button class=\"deleteTeaser\" id="12">Delete Teaser</button>
	var buttonID = $(this).attr("id");
	if(confirm("Are you sure you want to delete the teaser with id '"+buttonID+"'?")){
		$.ajax({
			type: "GET",
			url: '/link/to/delete/service/deleteTeaser',
			data: "teaserId="+buttonID,
			success: function (response) {
			  //Response from Service
			  if ($(response).find("status").text() == 'true') {
				//Action on success
			  } 
			}
		});


	}
});

jQuery Validation Plugin – Add custom method

Posted on: November 2nd, 2012 by taff No Comments

 

During my daily use of jQuery I find that I always seem to use the same plugins over and over again. One of these is the jQuery validate Plugin. Out of the box it offers just about everything you need to validate forms prior to submitting them to a database or passing them to a further script for processing.

If however you want to validate a field in a form that requires something out of the usual you can create further methods using the following technique. In this example I'm going to validate to (almost) ensure that a German telephone number is valid. I saw almost because you can't really allow for all eventualities but this is my shot. In my opinion it's better to let the odd wrong phone number through than not allow a real number because it is out of scope.

$(document).ready(function() {
jQuery.validator.addMethod("fonNummer", function(value, element) {
return this.optional(element) || /^([0-9\s\(\)\+\-\/]{9,30})*$/.test(value);
}, "Gültige Telefonnummer?");

//Add the rule to a field with our new method
$("#myform").validate({
rules: {
field: {
required: true,
fonNummer: true
}
}
});

});

You can now use the fonNummer rule in the same way you would any of the built in rules. A great resource for finding regular expressions such as one for validating US phone numbers where you quite often add the extension as either x123 or ext123.

I also use the jQuery validator for simulating a multipage form (why load a new page when only the form changes?). The rules are simply added when the user clicks next (if everything validates). I will go into this in further depth some time in the future.

Travel Cost Calculator

Posted on: November 1st, 2012 by taff

 

Piedmont trip calculatorI built this a few weeks back. It simply involves a little Maths and a bit of JavaScript to add and multiply fields, thus allowing the customer to see at a glance if they aren't better off using this airport by seeing how much it costs for parking, travelling and mileage. To save the user the hassle of repeatedly inputing things like the number of days they are away and their hourly rate, I added some automagical goodness to populate those fields once the equivalent first field had a value.

Everything went well thanks to a careful sprinkling of jQuery (mostly for the selectors). Due to the small amount of jquery required, this could have been the project where I could have finally give jquip (an unbloated jquery alternative)...but it wasn't