Thursday, 20 December 2012

Turning you ASP.Net Hyperlinks into images buttons using CSS and jQuery

First of all I’m no big jQuery or CSS geek I know a little and I search the net Smile

I was building a site for a client who wanted Image buttons not text links and you should know me if you have read past posts I believe Dynamic Data is about changing as little as possible in the pages I like to do it all if possible using the Metadata, so I thought is there a way of doing this using pure CSS, there is sort of but you are still left with the text of the hyperlink, that is where jQuery came in, and then I thought I need to add a CSS class to each button and again jQuery came to my aid. so here we go.

Note: I am using the latest Web Essentials by Mads Kristensen and using LESS for my style sheets, you are really missing out if you have VS2012 and are not using this experimental add-in for VS2012.

Note: If you don't have VS2012 the you can use Mindscape’s Web Workbench which offers SASS, LESS and CoffeeScript

So the first job is to somehow automatically add the CSS class to each of the buttons that we want to swap to image button.

function NAC_ReplaceHyperLinkWithImageButton() {
// array of button commands/names to affect
var toMatch = ["Details", "Edit", "Delete", "Update", "Cancel", "Insert", "Select", "New"];
// commands/names to replace
var toReplace = { "New": "Insert" };
$(document).ready(function () {
$("TABLE.DDDetailsTable a, TABLE.DDGridView a")
.each(function () {
// get the inner text
var innerText = $(this).text();
if ($.inArray(innerText, toMatch) > -1) {

// do replacement of commands to Replace
var found = toReplace[innerText];
// check there is a match in the lookup table
if (typeof found !== "undefined")
innerText = found;

// get the embedded text
$(this).addClass(innerText);

// add a tooltip
$(this).attr('Title', innerText);

// remove the hyperlinks text
$(this).text('');
}
});
});
}
// run script
NAC_ReplaceHyperLinkWithImageButton();
// bind script to AJAX bits
Sys.Application.add_load(NAC_ReplaceHyperLinkWithImageButton);

Listing 1 – jQuery for the swap out

So first of all we have an array this contains ALL the button names (the display text) that we want to affect, next we hook into the jQuery Read event then we are selecting command buttons List, Details, Edit and ListDetails pages using these two selectors:

"TABLE.DDDetailsTable a, TABLE.DDGridView a"

after that I am using the jQuery inArray function to check if the buttons text is one we want to affect. Then having gotten the innerText form the hyperlink we add the CSS class, then finally we remove the text so only the icon will show.

jQuery is so cool mixed with CSS.

ReplaceHyperlinkWithIcons

Figure 1- hyperlinks replace with buttons

Now people say LESS is more and in this case it is.

table.DDGridView a.Cancel,
table.DDDetailsTable a.Cancel
{
    width: 20px;
    height: 20px;
    display: inline-block;
    background-repeat: no-repeat;
    background-position: center center;
    background-image: url('../images/Cancel.png');
}

    table.DDGridView a.Cancel:hover,
    table.DDDetailsTable a.Cancel:hover
    {
        background-image: url('../images/Cancel-h.png');
    }

        table.DDGridView a.Cancel:hover:active,
        table.DDDetailsTable a.Cancel:hover:active
        {
            background-image: url('../images/Cancel-a.png');
        }

    table.DDGridView a.Cancel.aspNetDisabled,
    table.DDDetailsTable a.Cancel.aspNetDisabled,
    table.DDGridView a.Cancel.aspNetDisabled:hover,
    table.DDDetailsTable a.Cancel.aspNetDisabled:hover,
    table.DDGridView a.Cancel.aspNetDisabled:active,
    table.DDDetailsTable a.Cancel.aspNetDisabled:active
    {
        background-image: url('../images/Cancel-d.png');
    }

Listing 2 – the CSS

above in Listing 2 is the CSS for the Edit button as you can see we cover hyperlinks with a CSS class of “Edit” and we have three states normal hover and active that is when we click. Now for the LESS

/* ==== button mixin ==== */
.Button (@Name)
{
a.@{Name}
{
width: 20px;
height: 20px;
display: inline-block;
background-repeat: no-repeat;
background-position: center center;

background-image: url('../images/@{Name}.png');

&:hover
{
background-image: url('../images/@{Name}-h.png');

&:active
{
background-image: url('../images/@{Name}-a.png');
}
}
// link fix
&.aspNetDisabled,
&.aspNetDisabled:hover,
&.aspNetDisabled:active
{
background-image: url('../images/@{Name}-d.png');
}
// link fix
}
}

table.DDGridView,
table.DDDetailsTable
{
.Button(Cancel);
.Button(Delete);
.Button(Details);
.Button(Edit);
.Button(Update);
.Button(New);
.Button(Select);
.Button(Insert);
}

Listing 3 – LESS

In Listing 3 we have a MIXIN called Button and we pass in the name of the button we want, no repeating the same code and if you need to add an extra button it’s easy.

The only thing left is for me to add this to NuGet as a simple to apply package and you are away.

Updated: Package now available from NuGet here Replace ASP.Net Hyperlink With Image Button You will need to add a reference in you master page to the CSS and the JavaScript files which will be added to the Style and Scripts folder respectively.

Adding the NuGet package to an existing Dynamic Data site

Right Click the “References” node of the Web Application Project

Adding NuGet Package

Figure 1 – Adding NuGet Package to Project

Find the “Replace Hyperlink With Image Button” NuGet Package

Figure 2 – Find the “Replace Hyperlink With Image Button” NuGet Package

AddingScriptToHead

Figure 3 – Add the Style sheet and jQuery references to the head of the Master page 

Note: the highlighted sections, you will need to add a ~/ and ../ to the start od the CSS and Script links.

AddScriptToEndOfMasterPage

Figure 4 – Add a script tag just before the end of the BODY tag

Note: you can add your scripts and Style sheets your own way with bundling and minifying this is just an example.

Happy coding.

V1.0.4 now on NuGet you disabled icons if a link’s Enabled property is set to “false”;

Replace Hyperlink With Disabled Icons

Hopefully no more changes now.

Warning another change: v1.0.8 now has better icons and supports disabled buttons including removing the onclick event of the Delete button.

7 comments:

Anonymous said...

Not working

Anonymous said...

Not working

Stephen J. Naughton said...

have you tried the latest version from NuGet?

Steve

Unknown said...

Hi Steve

I have added the buttons.css in the head of the Masterpage and added the Javerscript in the bottom of the page as per instructions, but unfortunately it does not appear to work, am I missing something else? Just as of a matter of interest I have managed to bootstrap DynamicData with Bootswatch which gives you 14 different themes, you might want to take a look at it, it makes it a bit more interesting, and you can view it in different devices.

Unknown said...

Hi Steve

I have tried to install this great little add-on, but not having a lot of luck, added the buttons.css to the head in the Masterpage, and then added the script to the bottom of the page, but it does not appear to be working, am I missing something?, I'd love to get this working as I have also bootstraped DynamicData as well, so I am hoping this will finish it off nicely for me.

Oh and by the way it was version 1.1.3

Any help as always would be most appreciated.

Kind Regards
Ron

Stephen J. Naughton said...

Hi email me direct and well try too resolve this,I added the nugget package to a new project did the mods to the master page and all worked fine.

Steve

Unknown said...

Hi Steve

For everyone's information it was my fault, whilst adding bootstrap i deleted the table classes and replaced them with new classes, when i re-added them it worked perfectly as you would expect.

My appologies.