Archive for category Javascript
Highcharts- Highlight the last clicked bar
Posted by shawson in Javascript on May 10, 2012
This is handy, only really if you have charts which, on click, have drill down data which pops up, perhaps in a table underneath or something- I basically just wanted to highlight the last clicked column in a column chart;
Check it out on jsFiddle : http://jsfiddle.net/shawson/CkkbF/8/
Recursive jQuery Drop Down Menu’s
Posted by shawson in Javascript, jQuery on March 8, 2012
Following on from my previous post about drop downs, I recently expanded the code to allow for sub menus- as many levels deep as you would like.
The Code:
$(document).ready(function () { // Shawsons' Teeny-Tiny Recursive Drop Downs!
$('.drop-down-menu>li>ul').hide().mouseleave(function () {
$('.highlighted', this).removeClass('highlighted');
$(this).hide();
});
$('.drop-down-menu li>a').mouseenter(function () {
var menu_root = $(this).parent().parent();
$('ul', menu_root).hide();
$('.highlighted', menu_root).removeClass('highlighted');
$('>ul', $(this).addClass('highlighted').parent()).show();
}).mouseleave(function (o) {
if ($(this).parent().has($(o.relatedTarget)).length < 1) {
$('ul', $(this).parent()).hide();
}
});
});
The Markup:
<ul class="drop-down-menu">
<li>Drop Down Menu - Demo Title : </li>
<li><a href="">Menu 1</a>
<ul>
<li><a href="a.htm">a</a></li>
<li><a href="b.htm">b</a></li>
<li><a href="c.htm">c »</a>
<ul>
<li><a href="c-a.htm">c-a</a></li>
<li><a href="c-b.htm">c-b »</a>
<ul>
<li><a href="c-b-a.htm">c-b-a</a></li>
<li><a href="c-b-b.htm">c-b-b »</a>
<ul>
<li><a href="c-b-b-a.htm">c-b-b-a</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="c-c.htm">c-c</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="">Menu 2</a>
<ul>
<li><a href="d.htm">d</a></li>
<li><a href="e.htm">e</a></li>
<li><a href="f.htm">f</a></li>
</ul>
</li>
</ul>
Some CSS:
.drop-down-menu { display:block; }
.drop-down-menu li { float:left; padding: 8px; }
.drop-down-menu>li>a { padding:8px; }
.drop-down-menu li ul
{
position:absolute;
background-color:#fff;
border: 1px solid #999;
border-radius: 0px 7px 7px 7px; -moz-border-radius:0px 7px 7px 7px; -webkit-border-radius:0px 7px 7px 7px;
padding:5px;
width: 50px;
}
.drop-down-menu li ul a {
display:block;
width:50px;
}
.drop-down-menu li ul li ul
{
margin-left:50px;
margin-top: -20px;
}
.drop-down-menu li ul li { float:none; }
.drop-down-menu li ul li a { color:#000; }
.drop-down-menu li ul a.highlighted { background-color:#F68833; }
Demo :
Adding cross browser consistent keyboard short-cuts to your website
Posted by shawson in Javascript, jQuery, Web Standards on February 9, 2012
I wanted to employ keyboard short cuts to a frequently used internal web app used within the company- Pinch o’ the proverbial piss I thought- I’ll just use access keys! I’ve used them before on front facing sites for accessibility- but when I actually came to document these keys for the users I realised that support across different browsers is a mess;
IE Alt + {key}then hit return
Firefox Alt + Shift + {key}
Chrome Alt + {key} (the most sensible implementation, in my opinion)
IE also seems to refuse to aknowlege the links unless they are currently visible, and as the options I was short cutting existed in drop down menus this was no good, as they existing in bulleted lists which are “display:none” until the user mouses-over the menu bar (using my tiny drop down menu code)!
So to get around this I wrote some jQuery which standardises the short cuts- note this is no good for normal accessibility uses as it’s a new key combo which none of the browsers use, so without documentation no one will know- but for my use on an internal system it’s perfect.
I took the decision to make all the short cuts Ctrl+Alt+{key}, and wanted to keep using the accesskey attribute on my links rather than introduce another mechanism for dictating which keys triggered what- I also wanted to ensure if the link had a javascript onclick handler, instead of navigating away, we respect the handler and simply trigger that. Here’s the code;
$(document).keydown(function(e) {
if (e.ctrlKey && e.altKey && e.which >= 65 && e.which <= 122) {
e.preventDefault();
var key = String.fromCharCode(e.which);
var the_link = $("a[accesskey=" + key.toLowerCase() + "]");
if (typeof(the_link) != 'undefined') {
// does this link have a javascript assigned click handler, or do we simply send the user to the links href value?
var events = $.data( $(the_link).get(0), 'events' );
if (typeof(events) != 'undefined') {
if (typeof(events.click) != 'undefined') {
$(the_link).click();
return;
}
}
window.location = $(the_link).attr('href');
}
}
});
Quick & Tiny jQuery Drop Down Menus
Posted by shawson in Javascript, jQuery on January 24, 2012
Note: this has been superseded by the recursive drop down menu script.
The Code:
$(document).ready(function () { // Shawsons' Teeny-Tiny Drop Downs!
$('.drop-down-menu li ul').hide().mouseleave(function () {
$(this).hide();
});
$('.drop-down-menu>li>a').mouseenter(function () {
$('ul', $(this).parent().parent()).hide();
$('ul', $(this).parent()).show();
}).mouseleave(function (o) {
if ($(this).parent().has($(o.relatedTarget)).length < 1) {
$('ul', $(this).parent()).hide();
}
});
});
The Markup:
<ul class="drop-down-menu">
<li>Available Actions : </li>
<li><a href="">Menu 1</a>
<ul>
<li><a href="a.htm">a</a></li>
<li><a href="b.htm">b</a></li>
<li><a href="c.htm">c</a></li>
</ul>
</li>
<li><a href="">Menu 2</a>
<ul>
<li><a href="d.htm">d</a></li>
<li><a href="e.htm">e</a></li>
<li><a href="f.htm">f</a></li>
</ul>
</li>
</ul>
Some CSS:
.drop-down-menu { display:block; }
.drop-down-menu li { float:left; padding: 8px; }
.drop-down-menu li a { padding:8px; }
.drop-down-menu li ul
{
position:absolute;
background-color:#fff;
border: 1px solid #999;
border-radius: 0px 7px 7px 7px; -moz-border-radius:0px 7px 7px 7px; -webkit-border-radius:0px 7px 7px 7px;
padding:5px;
}
.drop-down-menu li ul li { float:none; }
.drop-down-menu li ul li a { color:#000; }
.drop-down-menu li ul li:hover { background-color:#F68833; }
Grouped pagination links function in JavaScript
Posted by shawson in Javascript on November 10, 2011
I just created a JavaScript port of an awesome bit of pagination code I first used years and years ago while working in Classic ASP, originally written by Dave Child who I was working with at the time. The original can be found on this site here.
It’s an awesome script when you have 100′s of pages of data (which probably suggests you need to implement some good filtering and search features to save your poor users..) and presents the links like so..
« Prev 1 2 3 … 7 [8] 9 … 208 209 210 Next »
function BuildGroupedPagination(current_page, total_pages, base_url, seperator)
{
var url = base_url;
var strPages = "";
var intMaxPages = 0;
var intMinPages = 0;
var intPaginI = 0;
if (typeof(seperator) == 'undefined')
{
seperator = " ";
}
if (total_pages > 10)
{
if (total_pages > 3)
{
intMaxPages = 3;
}
else
{
intMaxPages = total_pages;
}
for (intPaginI = 1; intPaginI <= intMaxPages; intPaginI++)
{
if (intPaginI == current_page)
{
strPages += "<strong>[" + intPaginI + "]</strong>";
}
else
{
strPages += "<a href=\"" + url + intPaginI + "\">" + intPaginI + "</a>";
}
if (intPaginI < intMaxPages)
{
strPages += seperator;
}
}
if (total_pages > 3)
{
if ((current_page > 1) && (current_page < total_pages))
{
if (current_page > 5)
{
strPages += " ... ";
}
else
{
strPages += seperator;
}
if (current_page > 4)
{
intMinPages = current_page;
}
else
{
intMinPages = 5;
}
if (current_page < total_pages - 4)
{
intMaxPages = current_page;
}
else
{
intMaxPages = total_pages - 4;
}
for (intPaginI = intMinPages - 1 ; intPaginI <= intMaxPages + 1; intPaginI++)
{
if (intPaginI == current_page)
{
strPages += "<strong>[" + intPaginI + "]</strong>";
}
else
{
strPages += "<a href=\"" + url + intPaginI + "\">" + intPaginI + "</a>";
}
if (intPaginI < intMaxPages + 1)
{
strPages += seperator;
}
}
if (current_page < total_pages - 4)
{
strPages += " ... ";
}
else
{
strPages += seperator;
}
}
else
{
strPages += " ... ";
}
for (intPaginI = total_pages - 2; intPaginI <= total_pages; intPaginI++) {
if (intPaginI == current_page) {
strPages += "<strong>[" + intPaginI + "]</strong>";
}
else {
strPages += "<a href=\"" + url + intPaginI + "\">" + intPaginI + "</a>";
}
if (intPaginI < total_pages) {
strPages += seperator;
}
}
}
}
else
{
for (intPaginI = 1; intPaginI <= total_pages; intPaginI++)
{
if (intPaginI == current_page)
{
strPages += "<strong>" + intPaginI + "</strong>";
}
else
{
strPages += "<a href=\"" + url + intPaginI + "\">" + intPaginI + "</a>";
}
if (intPaginI < total_pages)
{
strPages += seperator;
}
}
}
return strPages;
}
jqZoomage jQuery component
Posted by shawson in Javascript, jQuery on September 10, 2011
I’ve built a simple jQuery plugin for use on a website I’m building and am in the process of submitting it to the jQuery plugins website. It’s a simple zoom panel, allowing your users to mouse over portions of your small image, to see a close up view. Ideal for use on product details page or similar.
Screenshot
Installation
Just add a reference to the script at the bottom of your page (where all your js should be anyway!)- as shown in the demo, this is a basic example;
$(window).ready(function() {
$("#dinky-img").zoomage({
zoomedImageContainer: "#big-img",
zoomedImageUrl: "big-image.gif",
stayActiveOnMouseOut: false,
zoomedImageStartsCentered: true
});
});
There are a couple of styles which are required for the view finder, and the mask which goes over the image (allowing you to customise the look)- add these rules to your style sheet somewhere;
#zoomage-view-finder { border: 1px solid #fff; }
.zoomage-view-finder-surround { background-color:#fff; opacity:0.7; }
As a general point, it’s best to run the script in a $(window).load() rather than the standard $(document).load(), as this ensures that all the images are loaded before the script begins, otherwise the script runs and grabs the width() and height() of the image to work out ratios, but these get returned as 0′s! More info on this can be found on the stack overflow issue about this
Configuration
zoomedImageContainer * Required *
Default Value : “#zoom-image-container”
This is the jQuery selector for the div which will act as the close up view for your image.
zoomedImageUrl * Required *
Default Value : “”
This is the URL of the zoomed image file. I generally use images 3 times larger than the original, however there isn’t a limit. The scale ratio is calculated on load.
stayActiveOnMouseOut
Default Value : false
If this is set to true, the view finder will continue to show in it’s last position even when the mouse pointer is moved off of the image. If false, the view finder will disappear on mouse out.
zoomedImageStartsCentered
Default Value : true
Indicates that, on load, the zoomed image view shows the center of the image.
centerOnMouseOut
Default Value : true
If true, on mouse out, the zoomed view will return to the center of the zoomed image.
Live Demo
You can check out a real life working version of it here!
Tested across all the major modern browsers (IE9/ FF4/ Chrome10)- give me a shout if you spot an issue.
Download
Current Version 1.2 – 2011-09-10
Unminified Development Version
Minified Production Version
Licence
This plugin is available for use under the MIT licence. For more info see http://codeblog.shawson.co.uk/storage/jquery.zoomage/licence.txt
jQuery Plugin Site Link
The official jQuery Plugin catalogue link for this plugin is http://plugins.jquery.com/project/jqZoomage
New Adobe HTML5 Animation tool “Edge”- free tech preview
Posted by shawson in CSS, HTML5, Javascript on August 1, 2011
A real nail in the coffin for Flash, as it’s own parents (Adobe) release a free tech demo version of Edge- A new editor that lets you make flash style animations– without Flash! Instead the animations are scripted using standards html5, JavaScript and CSS3. Having been hand coding stuff like this over the past year (for 8week game and the like) I’m interested to see what kind of code this tool actually spits out! Check it out herel; http://t.co/I46QFYm
Adding minification and obfuscation of your Javascript and CSS to your ASP.net build process using Yahoo YUI Compressor
Posted by shawson in .net, C#.net, CSS, Javascript on July 22, 2011
I’ve just finished integrating Yahoo’s YUI Compressor into the MSBuild process for a new web probject I’m working on, and I thought I would document the process as there doesn;t seem to be a start to finish guide about anywhere.
To start with, let me just explain the structure I use for new Solutions;
C:\_Dev\MyNewWebsite\ C:\_Dev\MyNewWebsite\Artwork\ C:\_Dev\MyNewWebsite\BuildTools\ C:\_Dev\MyNewWebsite\Docs\ C:\_Dev\MyNewWebsite\Source\ C:\_Dev\MyNewWebsite\Source\MyNewWebsite.sln C:\_Dev\MyNewWebsite\Source\MyNewWebsite.Web\ C:\_Dev\MyNewWebsite\Source\MyNewWebsite.Web\Controls\ C:\_Dev\MyNewWebsite\Source\MyNewWebsite.Web\Images\ C:\_Dev\MyNewWebsite\Source\MyNewWebsite.Web\Scripts\ C:\_Dev\MyNewWebsite\Source\MyNewWebsite.Web\Services\ C:\_Dev\MyNewWebsite\Source\MyNewWebsite.Web\Styles\ C:\_Dev\MyNewWebsite\Source\MyNewWebsite.Web\MyNewWebsiteWeb.csproj C:\_Dev\MyNewWebsite\Source\MyNewWebsite.Entities\ C:\_Dev\MyNewWebsite\Source\MyNewWebsite.Entities\MyNewWebsiteEntities.csproj C:\_Dev\MyNewWebsite\Source\MyNewWebsite.Interfaces\ C:\_Dev\MyNewWebsite\Source\MyNewWebsite.Interfaces\MyNewWebsiteInterfaces.csproj C:\_Dev\MyNewWebsite\ThirdParty\
Firstly, download the dot net port of the YUI compressor from codeplex. I then extracted this into a new folder in the BuildTools folder. (there should be 2 dll files and one txt licence file.)
I then created a new MSBuild file called build-minify.xml, in the MyNewWebsite.Web project folder. That file looks like this;
<?xml version="1.0" encoding="utf-8"?>
<!-- http://yuicompressor.codeplex.com/wikipage?title=Sample%20MSBuild.xml%20File&amp;amp;amp;amp;ProjectName=yuicompressor -->
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask
TaskName="CompressorTask"
AssemblyFile="..\..\BuildTools\Yahoo.Yui.Compressor-v1.5.0.0\Yahoo.Yui.Compressor.dll" />
<ItemGroup>
<CssFiles Include="$(SourceLocation)Styles\Fonts.css"/>
<CssFiles Include="$(SourceLocation)Styles\Site.css"/>
<CssIE Include="$(SourceLocation)Styles\IE.css"/>
<CssIE6 Include="$(SourceLocation)Styles\IE6.css"/>
<JsAll Include="$(SourceLocation)Scripts\jquery-1.6.1.min.js" />
<JsAll Include="$(SourceLocation)Scripts\jquery-ui-1.8.14.custom.min.js" />
<JsAll Include="$(SourceLocation)Scripts\json2.js" />
<JsAll Include="$(SourceLocation)Scripts\jqModal-r14.js" />
<JsAll Include="$(SourceLocation)Scripts\jquery.tipsy.js" />
<JsAll Include="$(SourceLocation)Scripts\jquery.scrollTo-1.4.2.min.js" />
<JsAll Include="$(SourceLocation)Scripts\jquery.localscroll-1.2.7.min.js" />
<JsAll Include="$(SourceLocation)Scripts\chinook-alert.js" />
<JsAll Include="$(SourceLocation)Scripts\chinook-validation.js" />
<JsAll Include="$(SourceLocation)Scripts\chinook-rollovers.js" />
<JsAll Include="$(SourceLocation)Scripts\chinook-custom-accordion.js" />
<JsAll Include="$(SourceLocation)Scripts\chinook-vehicle-lookup.js" />
<JsAll Include="$(SourceLocation)Scripts\chinook-sandbox.js" />
<JsAll Include="$(SourceLocation)Scripts\chinook-finance-calculator.js" />
<JsAll Include="$(SourceLocation)Scripts\chinook-apply-now.js" />
</ItemGroup>
<Target Name="Minimize">
<CompressorTask
CssFiles="@(CssFiles)"
DeleteCssFiles="false"
CssOutputFile="Styles/Site.rel.css"
CssCompressionType="YuiStockCompression"
DisableOptimizations="Nope"
EncodingType="Default"
LineBreakPosition="-1"
LoggingType="ALittleBit"
ThreadCulture="en-gb"
IsEvalIgnored="false"
/>
<CompressorTask
CssFiles="@(CssIE)"
DeleteCssFiles="false"
CssOutputFile="Styles/IE.rel.css"
CssCompressionType="YuiStockCompression"
DisableOptimizations="Nope"
EncodingType="Default"
LineBreakPosition="-1"
LoggingType="ALittleBit"
ThreadCulture="en-gb"
IsEvalIgnored="false"
/>
<CompressorTask
CssFiles="@(CssIE6)"
DeleteCssFiles="false"
CssOutputFile="Styles/IE6.rel.css"
CssCompressionType="YuiStockCompression"
DisableOptimizations="Nope"
EncodingType="Default"
LineBreakPosition="-1"
LoggingType="ALittleBit"
ThreadCulture="en-gb"
IsEvalIgnored="false"
/>
<CompressorTask
JavaScriptFiles="@(JsAll)"
ObfuscateJavaScript="true"
PreserveAllSemicolons="true"
DisableOptimizations="false"
EncodingType="Default"
DeleteJavaScriptFiles="false"
LineBreakPosition="-1"
JavaScriptOutputFile="Scripts/chinook.rel.js"
LoggingType="ALittleBit"
ThreadCulture="en-gb"
IsEvalIgnored="false"
/>
</Target>
</Project>
You can create whatever ItemGroups you’d like- then just create a compressor task for each. For a rundown of the settings, check out the link in the comment at the top of the XML there. In the above file I had decided to compress all of my Javascript into a single file called chinook.rel.js, and my fonts and site css file rolled into one file, keeping the ie6 css separate, but still minifying it down.
The next step is to add it to the normal build. I opened the solution in Visual Studio, right clicked my web project and selected properties. Go to “Build Events” and add the following post-build event;
$(MSBuildBinPath)\msbuild.exe $(ProjectDir)build-minify.xml /target:Minimize
Now you can test it out by building your project. The new minified files are dumped out, in my case to the Scripts folder. Now that the files are there, I need a way of telling my release version of the website to use these instead of the raw, human-readable versions; but I still want to continue using the human-readable versions for development.
To achieve this I use pre-processor directives. These are most commonly seen in the c# code behind files, but can also be used in the aspx files. I added the following lines at the bottom of my master page;
<% #if (!DEBUG) %>
<script src="Scripts/chinook.rel.js" type="text/javascript"></script>
<% #else %>
<script src="Scripts/jquery-1.6.1.min.js" type="text/javascript"></script>
<script src="Scripts/jqModal-r14.js" type="text/javascript"></script>
<script src="Scripts/chinook-alert.js" type="text/javascript"></script>
<script src="Scripts/jquery-ui-1.8.14.custom.min.js" type="text/javascript"></script>
<script src="Scripts/chinook-vehicle-lookup.js" type="text/javascript"></script>
<script src="Scripts/chinook-sandbox.js" type="text/javascript"></script>
<script src="Scripts/chinook-finance-calculator.js" type="text/javascript"></script>
<script src="Scripts/jquery.scrollTo-1.4.2.min.js" type="text/javascript"></script>
<script src="Scripts/jquery.localscroll-1.2.7.min.js" type="text/javascript"></script>
<script src="Scripts/jquery.tipsy.js" type="text/javascript"></script>
<script src="Scripts/json2.js" type="text/javascript"></script>
<script src="Scripts/chinook-validation.js" type="text/javascript"></script>
<script src="Scripts/chinook-apply-now.js" type="text/javascript"></script>
<script src="Scripts/chinook-rollovers.js" type="text/javascript"></script>
<script type="text/javascript" src="Scripts/chinook-custom-accordion.js"></script>
<% #endif %>
So if the project is NOT running in debug mode, I import my full chinook.rel.js include which has everything already included, otherwise I manually include all the human readable, separate files.
And that’s pretty much it. Make sure you thoroughly retest your site with your combined java script file, as sometimes minification can cause issues with some code.
Front end web developer coding standards
Posted by shawson in Javascript on May 6, 2011
Well put together, and generally good advice about the finer details of javascript (closures, truthy values) for someone starting out.
Adding Javascript Unit Testing/ Compression to your MSBuild
Posted by shawson in .net, Javascript, Test Driven Development on May 4, 2011
A couple of resources- I shall add to this post as I look into this myself. I basically want to add steps to my project file, so msbuild will run javascript tests (qUnit) and perform minification/ combines all the js source files.
- http://yuicompressor.codeplex.com/
- http://blogs.msdn.com/b/francischeung/archive/2010/02/13/integrating-javascript-unit-tests-with-continuous-integration.aspx
- http://www.testinggeek.com/index.php/testing-tools/test-execution/189-qunit-selenium-continuous-integration
- http://dotnet.geir-sorensen.net/2010/04/10/msbuild-custom-targets/
- http://www.simple-talk.com/dotnet/.net-tools/extending-msbuild/
