Showing posts with label css. Show all posts
Showing posts with label css. Show all posts

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.

Monday, 11 January 2010

Required Field Highlighting in Dynamic Data Field Templates

I’ve been using this for some time and thought I should post a small article on it.

RequiredField RequiredFKField

 Figure 1 – Highlighted fields

The idea is to give the user some prior knowledge the some field are required and these are have their backgrounds tinted yellow, so lets look at the code for this:

protected void Page_Load(object sender, EventArgs e)
{
    TextBox1.ToolTip = Column.Description;

    SetUpValidator(RequiredFieldValidator1);
    SetUpValidator(RegularExpressionValidator1);
    SetUpValidator(DynamicValidator1);

    // add 'validationRequired' class to the TextBox
    if (Column.IsRequired)
        TextBox1.CssClass += " validationRequired";
}

Listing 1 – the highlighter code.

It’s the last if statement that does the work if the the column is required then the “validationRequired” class is added to the fields class.

Note: All you need to do is add this code to each Edit field template that has a required field validator.
/* required field class */
.validationRequired
{
    background-color: #FFFEBD;
}

Listing 2 – required field css class

Making ForeignKey Field Template have Required Validation

The next thing I like is to add validation the FK field templates so there is a select [type] as the first entry in the FK field if the field is required and validation is enabled.

<asp:DropDownList 
    ID="DropDownList1" 
    runat="server" 
    CssClass="droplist">
</asp:DropDownList>
<asp:RequiredFieldValidator 
    runat="server" 
    ID="RequiredFieldValidator1" 
    CssClass="droplist" 
    ControlToValidate="DropDownList1" 
    Display="Dynamic" 
    Enabled="false" />
<asp:DynamicValidator 
    runat="server" 
    ID="DynamicValidator1" 
    CssClass="droplist" 
    ControlToValidate="DropDownList1" 
    Display="Dynamic" />

Listing 3 – ForeignKey_Edit.aspx

protected void Page_Load(object sender, EventArgs e)
{
    if (DropDownList1.Items.Count == 0)
    {
        if (!Column.IsRequired || 
            (Column.IsRequired && Mode == DataBoundControlMode.Insert))
        {
            DropDownList1.Items.Add(new ListItem("[Not Set]", ""));
        }

        PopulateListControl(DropDownList1);
    }
    DropDownList1.ToolTip = Column.Description;

    SetUpValidator(RequiredFieldValidator1);
    SetUpValidator(DynamicValidator1);

    // add 'validationRequired' class to the TextBox
    if (Column.IsRequired)
        DropDownList1.CssClass += " validationRequired";
}

Listing 4 – ForeignKey_Edit.aspx.cs

In Listing 3 I have added the standard RequiredFieldValidator and DynamicValidator to the ForeignKet_Edit field template and in Listing 4 I have added the setup for both validators and also changed the if statement that adds the “[Not Set]” entry to the dropdown list; this is make sure the user picks a value when the column is required and it is in insert mode as opposed to just accepting the default value.

Like I said only a short article but neatOpen-mouthed