Thursday, 18 September 2014

Watermarks in ASP.NET MVC 4

...using the jquery.overlabel plugin

1. Stick a DisplayName attribute for the watermark on your model property

[RequiredIf("Mode", UnderOfferModelMode.SetUnderOffer, ErrorMessage = "Please enter a comment")]

[DisplayName("Please enter your comment text here")]

public string UnderOfferComment { get; set; }

2. Add an Html.LabelFor and an Html.TextAreaFor your model property

3. Import the jquery.overlabel.js by including "overlabel" in your require imports

4. Add a line in the document.ready to call the .overlabel() method on the label selector (or use a class selector as I have)

clip_image001

5. In your css then you just need

label.overlabel {

position: absolute;

margin-left: 70px;

margin-top: 10px;

z-index: 1;

color: #999;

}

And you end up with a lovely little unobtrusive watermark that doesn't interfere with your model validation in anyway.

Wednesday, 13 August 2014

Hyperlinks not opening immediately from emails

If this happens then follow the steps below to fix it...

To reset Internet Explorer Settings, follow these steps:

  1. Close all Internet Explorer windows.
  2. Click Start, type inetcpl.cpl in the Search box and then click inetcpl.cpl on the Programs list.
    The Internet Options dialog box appears.

     

    Note for Windows XP, click Start, click Run, type inetcpl.cpl in the Open box, and then click OK.

  3. Click the Advanced tab.
  4. Under Reset Internet Explorer Settings, click Reset. Then, click Reset again.
  5. When Internet Explorer finishes resetting, click Close in the Reset Internet Explorer Settings dialog box.
  6. Start Internet Explorer again.
    Your changes will take effect the next time that you open Internet Explorer.


Tuesday, 12 August 2014

Resharper equivalent for clipboard ring

Assigned Ctrl+Shift+V to ReSharper.ReSharper_PasteMultiple instead as I find this to be a much more useful interface than trying to guess what the last 10 items on your clipboard are.
Plus it supports way more items than just the 10 you get with Visual Studio.
image

Wednesday, 6 August 2014

How to open Visio documents in Visio Viewer when you already have Visio installed

  1. Just delete the HKEY_CLASSES_ROOT\.vsd key from you registry root
  2. Enter the below registry text into a .reg file and double click to add it into your registry
  3. In internet explorer choose File, Open, (select all files filter), and then select your .vsd file, and then allow the activex control to run.
  4. Also to remove the warning from IE each time you open a .vsd file, set the following security option in your Internet options, Advanced dialog...
    image

 

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\.vsd]
@="VisioViewer.Viewer"
"Content Type"="application/vnd.ms-visio.viewer"

[HKEY_CLASSES_ROOT\.vsd\PersistentHandler]
@="{FAEA5B46-761B-400E-B53E-E805A97A543E}"

[HKEY_CLASSES_ROOT\.vsd\shellex]

[HKEY_CLASSES_ROOT\.vsd\shellex\{8895b1c6-b41f-4c1c-a562-0d564250836f}]
@="{21E17C2F-AD3A-4b89-841F-09CFE02D16B7}"

Tuesday, 8 July 2014

Kendo DropDownList popup keep open alternative code using list property

Should you ever have the need to keep a kendo drop down list open using typescript, then the following example is how you should go about it with the latest kendo libraries that we're referencing

Note: The benefits of doing it this way is that you can strongly type all the typescript code, instead of relying on an undocumented extension property called popup off the drop down list control.

Typescript code:

export class AssignmentDashboard extends Base.HomePageBase {

private filterEventsDdLInitialized = false;

public filterEventsDdlInitialize: () => void = () => {

if (this.filterEventsDdLInitialized === false) {

var filterEventsDdl: kendo.ui.DropDownList = $("#viewEventListFilters").data("kendoDropDownList");

if (!this.isDefined(filterEventsDdl)) {

alert('viewEventListFilters drop down list widget not found');

return;

}

filterEventsDdl.list.on("mousedown", "*", (e: JQueryEventObject) => {

this.lastTarget = <HTMLElement>e.currentTarget;

});

filterEventsDdl.bind("close", (e: kendo.ui.DropDownListCloseEvent) => {

if ($.contains(e.sender.list[0], this.lastTarget)) {

e.preventDefault();

}

this.lastTarget = document.body;

//e.preventDefault(); // comment out for prod. use this to lock ddl during debugging/editing.

});

filterEventsDdl.list.on("click", "input", this.filterOptionChangeHandler);

this.filterEventsDdLInitialized = true;

}

}

CSHTML code:

attach the filterEventsDdlInitialize class method to the e.open event of the drop down in the cshtml… e.g.

.Events(e =>

{

e.Open("$(document).data('assignmentDashboardContext').filterEventsDdlInitialize");

})

e.g.

@(Html.Kendo().DropDownList()

.Name("viewEventListFilters")

.HtmlAttributes(new { style = "width: 240px;" })

.Height(410)

.BindTo(Model.FilterOptionsBinder)

.Text("Events")

.Value("Events")

.Events(e =>

{

e.Open("$(document).data('assignmentDashboardContext').filterEventsDdlInitialize");

})

.Template(tempHolder)

)

Friday, 20 June 2014

Fingerprint css in MVC web sites

http://madskristensen.net/post/cache-busting-in-aspnet

Optimizing for website performance includes setting long expiration dates on our static resources, such s images, stylesheets and JavaScript files. Doing that tells the browser to cache our files so it doesn’t have to request them every time the user loads a page. This is one of the most important things to do when optimizing websites.

In ASP.NET on IIS7+ it’s really easy. Just add this chunk of XML to the web.config’s <system.webServer> element:

<staticcontent>
<clientcache cachecontrolmode="UseMaxAge" cachecontrolmaxage="365.00:00:00" />
</staticcontent>

The above code tells the browsers to automatically cache all static resources for 365 days. That’s good and you should do this right now.

The issue becomes clear the first time you make a change to any static file. How is the browser going to know that you made a change, so it can download the latest version of the file? The answer is that it can’t. It will keep serving the same cached version of the file for the next 365 days regardless of any changes you are making to the files.

Fingerprinting


The good news is that it is fairly trivial to make a change to our code, that changes the URL pointing to the static files and thereby tricking the browser into believing it’s a brand new resource that needs to be downloaded.

Here’s a little class that I use on several websites, that adds a fingerprint, or timestamp, to the URL of the static file.

using System; 
using System.IO;
using System.Web;
using System.Web.Caching;
using System.Web.Hosting;

public class Fingerprint
{
public static string Tag(string rootRelativePath)
{
if (HttpRuntime.Cache[rootRelativePath] == null)
{
string absolute = HostingEnvironment.MapPath("~" + rootRelativePath);

DateTime date = File.GetLastWriteTime(absolute);
int index = rootRelativePath.LastIndexOf('/');

string result = rootRelativePath.Insert(index, "/v-" + date.Ticks);
HttpRuntime.Cache.Insert(rootRelativePath, result, new CacheDependency(absolute));
}

return HttpRuntime.Cache[rootRelativePath] as string;
}
}

All you need to change in order to use this class, is to modify the references to the static files.

Modify references


Here’s what it looks like in Razor for the stylesheet reference:

<link rel="stylesheet" href="@Fingerprint.Tag("/content/site.css")" />

…and in WebForms:

<link rel="stylesheet" href="<%=Fingerprint.Tag(" />content/site.css") %>" />

The result of using the FingerPrint.Tag method will in this case be:

<link rel="stylesheet" href="/content/v-634933238684083941/site.css" />

Since the URL now has a reference to a non-existing folder (v-634933238684083941), we need to make the web server pretend it exist. We do that with URL rewriting.

URL rewrite


By adding this snippet of XML to the web.config’s <system.webServer> section, we instruct IIS 7+ to intercept all URLs with a folder name containing “v=[numbers]” and rewrite the URL to the original file path.

<rewrite>
<rules>
<rule name="fingerprint">
<match url="([\S]+)(/v-[0-9]+/)([\S]+)" />
<action type="Rewrite" url="{R:1}/{R:3}" />
</rule>
</rules>
</rewrite>

You can use this technique for all your JavaScript and image files as well.

The beauty is, that every time you change one of the referenced static files, the fingerprint will change as well. This creates a brand new URL every time so the browsers will download the updated files.

FYI, you need to run the AppPool in Integrated Pipeline mode for the <system.webServer> section to have any effect.