A collection of computer systems and programming tips that you may find useful.
 
Brought to you by Craic Computing LLC, a bioinformatics consulting company.

Showing posts with label jquery. Show all posts
Showing posts with label jquery. Show all posts

Friday, February 8, 2013

Jquery snippet to disable / enable links on a page

Here are two approaches to hiding all the anchor (a) tags on a page while retaining the html that was contained within the tags. They both use Jquery.

Approach #1 - Remove all the 'a' tags while retaining their content - no way to retrieve the links, etc.

This lets you effectively disable all the links without losing any text. Using the .html() call instead of simply .text() means that any images or other formatting is preserved.

    $("a").each(function() {
      var t = $(this).html();
      $(this).replaceWith(t);
    });

Approach #2 - Reversibly Hide and Show the tags

Replace the 'a' tags with 'span' tags and store the original tag pair in a custom data attribute

Custom data attributes all have the prefix 'data-' followed by a unique name. You can store arbitrary data in these. With this approach I am storing the original 'a' tag pair and its contents.

In the example, my custom data attribute is called 'data-craic' and note that the 'span' tags are given a unique class (I'm using 'hidden-link') that allows you to identify them

To hide/disable the links:

  $("a").each(function() {
    // Get the html within the 'a' tag pair
    var t = $(this).html();
    // Get the entire tag pair as text by wrapping in an in-memory 'p' tag and fetching its html
    var original_tag = $(this).clone().wrap('<p>').parent().html();
    // Replace the 'a' tag with a 'span' - put the original tag in the data attribute
    $(this).replaceWith("<span class='hidden-link' data-craic='" + original_tag + "'>" + t + "</span>"); 
  });

To show/enable the links:

  $(".hidden-link").each(function() {
    // Retrieve the original tag from the data attribute
    var original_tag = this.dataset.craic;
    // Replace the 'span' with it
    $(this).replaceWith(original_tag);
  });

At least in my use cases I have not had to encode the original 'a' tag pairs but base64 encoding might be a good idea to avoid any possible unintended consequences.

Custom data attributes are extremely useful and were the perfect to solution to this problem

You can find a self contained web page with these scripts at https://gist.github.com/craic/4987192


Monday, January 28, 2013

JSON versus JSONP Tutorial

I recently found myself a bit confused on how to convert a JQuery $.getJSON() call to use JSONP (JSON with Padding).

JSONP is a way to get around the Same Origin Policy restriction when a script in one domain wants to fetch JSON data from a server in a different domain.

The approach is simple enough but I had trouble finding a clear explanation. So I wrote up a simple example in both JSON and JSONP with server and client code.

The live demo is at http://json-jsonp-tutorial.craic.com and all the code is on Github at https://github.com/craic/json_jsonp_tutorial

I hope that you find it useful...


Thursday, November 1, 2012

Tutorial on JS/JQuery Bookmarklets

I recently needed to implement a JavaScript bookmarklet for a new project. There are many web resources available but even so I had a bit of a learning curve to contend with.

In the hope of lessening that burden on future users, I've written up a tutorial on two types of bookmarklets with simple, annotated examples and posted all the code on our Github page.


The simplest form of bookmarklet is a chunk of JS code contained in the Bookmarklet URL that invokes some action. This is a direct approach - you select some text, you click the bookmarklet and you get a result. If you want to repeat the process with some other text on the page then you have to click the bookmarklet link again.

However, for many applications you need to invoke an action multiple times on a single page - looking up words in a dictionary would be a good example. Having to click on a Bookmarklet link every time is not a good solution. Instead you want to modify the behaviour of the page by injecting a custom JS script. A bookmarklet can be used to initiate this. So you end up with three scripts, two of which are slightly modified, general purpose scripts.


The bulk of the code for this second approach comes from how-to-create-a-jquery-bookmarklet, written by Brett Barros of latentmotion.com, with some code input from Paul Irish.

To fully benefit from the tutorial, you should download the project, run 'bundle install' and 'rackup -p 4567' to set up a local Sinatra server, then point your browser to http://localhost:4567



Wednesday, August 8, 2012

Simple Example of How to Show / Hide Divs using JQuery

Here is a simple example of how to use JQuery to show or hide divs by clicking a link within a HTML page. You could make this even more minimal but I think this version gives you the simplest explanation.

I use this to embed comments in pages that I want to show to a client. When they are visible, the client gets to see my rationale for designing the page a certain way. But by clicking a 'Hide Comments' link, the client can see the final page design.

Clicking on the 'Hide Comments' link makes a 'Show Comments' link appear, and vice versa.

You can see the test page in its entirety at this github gist: https://gist.github.com/fa1782bd47872f4c98d6

Within the body of the page, each comment is entered in a div (or paragraph) block with the class 'comment'

At the top of the page are two links with '#' as the target and with the div ids of 'show-comments' and 'hide-comments' respectively.

In the Head of the page you need to include the JQuery library and then you create your custom script. This has three components:

The first defines the action taken when the Hide Comments link is clicked. All divs with class 'comment' and the Hide Comments link are hidden and the Show Comments link is shown.
  jQuery('#hide-comments').click(
    function() {
      jQuery('.comment, #hide-comments').hide();
      jQuery('#show-comments').show();
    }
  );

The second component implements the reverse action when the Show Comments link is clicked. Now, all divs with class 'comment' are displayed along with the Hide Comments link. The Show Comments link is hidden.
  jQuery('#show-comments').click(
    function() {
      jQuery('.comment, #hide-comments').show();
      jQuery('#show-comments').hide();
    }
  );
Finally the Show Comments link is hidden when the page is loaded.


You could do this with a single show/hide comments link. You would update the Javascript to use the 'toggle()' function instead of show()/hide() and you would update the text of the link as appropriate.

Monday, November 14, 2011

Captain Beefheart Song Titles

Here is a silly project that I knocked out last week - a generator of Fake Captain Beefheart Song Titles

It was inspired by a comment on Gideon Coe's radio show on BBC 6 Music where he wondered if such a thing existed - it didn't - so I wrote one!

The 'algorithm', if you can call it that, combines words from real Beefheart song titles and a list of others that sound (to me) like they could be. The structure of the real titles is relatively simple with most of them following a few simple patterns. Some of the generated titles don't work but every so often it'll spit out a good one.

The site is built with Ruby and Sinatra, with some jQuery thrown in for the scrolling effect. It serves as a nice example if you are learning Sinatra. You can find the code at Github and the application is hosted on Heroku.

It's just a bit of fun, but writing a small, self-contained application like this is a great way to learn new technologies. Giving yourself a short time frame in which to develop and deploy a complete application is a great exercise in efficiency.



Friday, November 11, 2011

When jQuery $.ajax() keeps returning the same value on Internet Explorer


I just mentioned this in my last post, but it is important enough that I'm going to give it its own post!

If you have jQuery Ajax calls, such as $.ajax() , $.get(), etc., that are continually fetching data from a remote server, you may find this works on Firefox, Chrome, etc. but in Internet Explorer it keeps returning the same value.

IE has cached the first return value and thinks that you are making identical requests so it just uses the cached value and never contacts the server.

Turn off caching by adding a call to ajaxSetup  at the start of your script block and set cache to false.

<script>

  $.ajaxSetup ({  
     cache: false  
  });
[...]
</script>


The fix is simple once you realize it but it took me a while to figure it out this morning. 


Debugging JavaScript is painful at the best of times. It's worse when you throw AJAX into the mix. So take small steps and test on multiple platforms right from the start. I need to learn that lesson.





Latest version of jQuery on Google APIs


If a web page uses the jQuery library it usually makes sense to link to copy hosted on an external content delivery network (CDN). You don't have to keep an updated copy on your site, the client may already have this copy cached, and the CDN has high bandwidth connections. Google, Microsoft and jQuery themselves offer CDN hosted jQuery.

I use the Google version and call it with this line:

 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script>

That is fine, but what happens when a new version comes out? 

In these cases some sites will offer a 'latest' url that automatically points to the most recent version.

Google does not do that - but they offer something similar, and which might be slightly better.

If I want version 1.7.0 and nothing else then I use the link given above. 
If I want the latest version in the 1.7 series then I use:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>

And if I want the latest version in the 1 series then I use:

 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

Note that you don't always want to use the most general form. New releases are not necessarily back compatible. But you have the choice. 
   
And note that you no longer need to include type="text/javascript" in the script tag anymore - it's the default.



Friday, March 18, 2011

Tandem Select jQuery Plugin

A standard HTML multiple Select menu allows the user to select multiple options using Command-Click. But when the list of options is long, requiring the user to scroll, it becomes cumbersome and prone to errors.

An effective solution is to use two select menus in tandem, with buttons allowing options to be swapped between the two.

I'm pleased to announce the release of a new jQuery plugin that makes tandem selects simple to set up and easy to customize.

Tandem Select consists of a JavaScript function that leverages the jQuery library, a CSS file and template HTML code.

More information and live demos can be found on the Project Page and the software can be downloaded from the GitHub repository.




Friday, March 4, 2011

simple-tooltip Ruby Gem for tooltip help

I'm pleased to announce the release of my first Ruby Gem: simple-tooltip

Simple Tooltip helps you make tooltip help available in your Rails 3 applications.

This is often done using a JavaScript plugin which produces a small popup window containing a short text string. That works great in many applications but often the help content that you want to provide is more extensive and you many want to include richer formatting, such as links to other web pages.

Simple Tooltip acts as a Rails Generator which will create a Tooltip model in your application along with a database table, a controller and views. You create help records using a web interface using plain text, html, Textile or Markdown formatting. The help records are stored in the database and retrieved using the unique, informative titles that you give them.

In your web pages you include a Tooltip helper that refers to the title of the relevant tooltip. Depending on how you set it up, when you hover over a tooltip icon or click on it, a popup window will appear displaying your help.

This is much richer and more flexible than the basic solutions available from JavaScript alone.

More than that, if the audience for your application is not just English-speaking, you can create multiple instances of each tooltip with content in each target language, identified by a two letter locale string. If a user has a non-English locale defined in your application, Simple Tooltip will look for content in the matching locale and display that. For content longer than single sentences, this is a more practical internationalization solution than I18n functionality built into Rails 3, which is more focused on shorter strings.

The gem is available at https://rubygems.org/gems/simple-tooltip.

The code is available at https://github.com/craic/simple_tooltip and is made freely available under the MIT license.



 

Tuesday, December 21, 2010

Per Page Inclusion of JavaScript in Rails view pages

I use various jQuery plugins in my Rails views but I don't want to download all that code in pages that don't use them. Furthermore I want to minimize the chance of namespace conflicts between different blocks of code.

A simple way to do this is to add these lines to your application.html.erb file after the main JS includes:
<%= yield :custom_javascript_includes %>
and then add a block similar to this in each view template that needs custom JS.
<% content_for :custom_javascript_includes do %>
<%= javascript_include_tag "your_custom_plugin.js" %>
<script type="text/javascript">
// Your custom JavaScript code
</script>
<% end %>
In this example I'm including a specific file from the public/javascripts directory and then adding some custom JS code that might define some events or trigger some action on page load.

Here is a real example that uses the facebox jQuery plugin which provides 'light box' functionality. This code is placed at the top of my 'show' template.
<% content_for :custom_javascript_includes do %>
<%= javascript_include_tag "facebox.js" %>
<script type="text/javascript">
jQuery(document).ready(function($) {
$('a[rel*=facebox]').facebox({
loadingImage : '/images/facebox_loading.gif',
closeImage : '/images/facebox_closelabel.gif'
});
});
</script>
<% end %>
You can take this further by also including custom stylesheets linked to these plugins in the same block. That can result CSS and JS includes being interspersed in the resulting HTML file which some people may not like, but I don't think there are any practical drawbacks to it.

The big win is that you keep your custom JS code right there in the same file as your HTML. If that JS code is substantial you could move it into a partial that resides in your views directory, as opposed to having it separated in the public/javascripts directory.

For high performance production sites you should weigh the benefits of this approach in terms of clarity with the performance benefit of stashing all your JS code in a single file and minifying it.


 

Thursday, March 11, 2010

Raphaël Live

Raphaël is an amazing JavaScript Library for creating Vector Graphics in browsers. It was created by Dmitry Baranovskiy. It is goes further than HTML Canvas in that any object is accessible in the DOM and so can be made in to buttons, dragged around the canvas, etc. You need to know about it!

To help my exploration of the library I built a simple in-browser environment with a drawing canvas and the CodeMirror code editor so that I could try out Raphaël calls and see the results immediately. That worked out really well for me and so today I've released a more developed version of the tool, along with a range of code examples.

Raphaël Live allows you to load in code examples into the editor, run them, see the results, modify the attributes, etc., re-run them and thereby learn how to use the library.

The tool is freely distributed. You can use it on the craic.com site, or download you own version from GitHub.

Hope that you'll check it out...



Archive of Tips