find a location for property in a new city
Showing posts with label jQuery. Show all posts
Showing posts with label jQuery. Show all posts

Friday, 11 January 2013

Add rel="nofollow" to all external links with one line of jQuery

You may want to change all external links on a page to do something different such as add a target="_blank" to each one or add rel="nofollow" to every external link. This post will show you how this can be done in one line of jQuery!

SEO SEO SEO... How tiresome a concept... Anyway, people make their living with it apparently and while that is the case I get all kinds of weird requirements like this. This time I had to add rel="nofollow" to all external links for latest whim of an SEO consultant.

Since SEO requirements seem to chop and change fairly unpredictably I wanted to add rel="nofollow" to all external links in the quickest and least interfering way possible. I managed it with one line of jQuery so that is fairly innocuous and I can just remove it if it needs to be undone at some point. This can be used to add target="blank" to also.

Add rel="nofollow" to all external links

$("div.content a[href^='http']:not([href*='mysite.co.uk'])").attr("rel", "follow");

Add target="_blank" to all external links

$("div.content a[href^='http']:not([href*='mysite.co.uk'])").attr("target", "_blank");

Hope this helps you spend as little time on this as possible :)

Update:

I did some reasearch into whether adding a nofollow in this way will work on Google and came to the conclusion that it probably wont. Colin Asquith commented similar thoughts. So this should probably be considered if using this for adding rel="nofollow" to links but technically this is a good way of going about it or anything similar like adding target="_blank" for example.

Follow britishdev on Twitter

Thursday, 10 May 2012

Set maxlength on a textarea

It's annoyed me for quite a while that you can set a maximum length on an <input type="text" /> but not on a textarea. Why? Are they so different?

I immediately thought I was going to have to write some messy JavaScript but then I learned that HTML5 implements maxlength on text areas now and I'm only considering modern browsers! Wahoo!

Then I learnt that IE9 doesn't support it so JavaScript it is...

JavaScript textarea maxlength limiter

What I have done that works well is bind events keyup and blur on my text area to a function that removes characters over the maxlength provided. The code looks like this:

$('#txtMessage').bind('keyup blur', function () {
    var $this = $(this);
    var len = $this.val().length;
    var maxlength = $this.attr('maxlength')
    if (maxlength && len > maxlength) {
        $this.val($this.val().slice(0, maxlength));
    }
});

Conclusion

It works quite well because if the browser already supports maxlength on a textarea there will be no interruption because the value of the textarea will not go over that maxlength.

The keyup event doesn't fire when the user pastes text in using the mouse but that is where the blur event comes in. Also, an enter click makes a new line on a textarea so the user has to click the submit button (blurring the textarea).

Beware though that this is for usability only; a nasty user could easily bypass this so ensure you are checking the length server side if it is important to you.

Follow britishdev on Twitter

Wednesday, 18 April 2012

jQuery - Don't use bind and definitely don't use live!

If you use jQuery you have almost certainly used the .click(fn) event. You may know that just calls .bind('click', fn). You may have used live(). You may know that live() is weird and buggy and inefficient. You may have heard you should not use it in favour of .delegate(). You may have heard of the new .on(). But which is better? bind vs live vs delegate vs on?

Take the following html:

<div id="myContainer">
    <input type="button" id="myBtn" value="Click me!" />
</div>
<script type="text/javascript>
    $('#myBtn').click(doSomething);
</script>

I have a button that has a javascript function called doSomething attached to it. This works fine until I dynamically replace the inner HTML of the div myContainer with a new button (with same ID etc). doSomething will no longer be attached to the new myBtn button so it will not be called when the button is clicked.

FYI, $('#myBtn').click(doSomething); is just shorthand for writing $('#myBtn').bind('click', doSomething);

So you can change the JavaScript code above to $('#myBtn').live('click', doSomething); and it will still work even when the button is brought in or generated dynamically. Up until now I have found that the live function uses magic to just make it all work even after ajax abuse and therefore it is better.

However, recently (in a more complex implementation) I found it was causing some undesired behaviour so I had a dig into it. Turns out live() is buggy and badly performing and has actually been deprecated as of jQuery v1.7 so do not use live! What should you be using for this type of functionality then?

Well, delegate has been the popular replacement since it attaches the method once to a selected container but still targets the inner element as bind or click would. The importance is two fold:

  1. The functionality is not wastefully attached to each element matched and instead just once to the containing element
  2. Dynamically added items that match the selector will still fire the event since the event is not attached to this element, it is attached to the container that has remained static

In fact live does the same as delegate but it's containing element cannot be defined, it is the whole document which, if you have a deep DOM, finding the originating element using the selector could cause it to search a long way. Lame... In fact, I found bugs with it and there are other details which mean you should use delegate instead. I say should because there is a new cool kid on the block.

So what is better than bind, live and delegate?

You should use .on(). All the cool kids are doing it. Want me to name drop users of on? Well, ME! Perhaps more famous in the JavaScript world is jQuery, and they use it! If you look at the jQuery library bind, live and delegate all just call on as of jQuery v1.7+

So my JavaScript code above should change to:

Bind and click are still fine in my opinion as nice little shortcuts but only when using it them to attach a function to one specific element and only when you are not attaching to dynamic objects. If you are attaching to, say, multiple <li>’s in a <ul> you should use on() instead to attach the event to the <ul> and target the event to the <li>’s. This way there is only one function and multiple references to it rather than creating the function once for each of the <li>’s.

Follow britishdev on Twitter

Friday, 1 October 2010

ASP.NET MVC IsAjaxRequest() not recognising request from jQuery $.ajax()

If you are finding that an AJAX request from, say, a piece of jQuery AJAX code such as $.ajax() $.get() or $.post() or you own custom AJAX code (you legend) is not registering as an AJAX request when using the IsAjaxRequest() then the problem is probably to do with X-Requested-With.

I used .NET Reflector to have a look at how IsAjaxRequest() works and it is something like this:
return ((request["X-Requested-With"] == "XMLHttpRequest") || ((request.Headers != null) && (request.Headers["X-Requested-With"] == "XMLHttpRequest")));

So that means you need to have a header of "X-Requested-With" set to "XMLHttpRequest" which is usually the case when you are using AJAX libraries like ASP.NET's or jQuery's. You can see if this is the case using Fiddler.

However, interestingly you can also set this as either part of your form POST or even a GET querystring! Such as www.example.com?x-requested-with=XMLHttpRequest (case sensitive). This will also make IsAjaxRequest() return true.

Follow britishdev on Twitter

Monday, 6 September 2010

How to force clients to hard refresh their browser cache

We had this problem when we removed our style sheets and put them into a HttpHandler to serve them all in one single request. The problem was that due to some caching problem, users' needed to refresh their page to receive the updated CSS files. This resulted in confused users looking at a non-styled site featuring trendy black Times New Roman font on a original white background with blue and purple retro links? old skool...

We (as developers) nonchalantly refreshed the page and happily continued, others didn't and we quickly realised that "Oh, they just need to refresh the page" wasn't good enough.

Solution

We needed a way to make the users refresh their browser caches, but how since we have no control over their browsers?

I came up with a bit of JavaScript that will do a hard refresh of the page and use cookies to record that it has been refresh and ensure that it only happens once and doesn't go into an infinite loop.

Here is some code I came up with:
//jquery plugin for cookies
<script type="text/javascript" src="/js/jquery/jquery.cookies.2.0.1.min.js"></script>
<script type="text/javascript">
//give it a new name each time you need to do this
var cookieName = 'refreshv1';
//check client can use cookies
if ($.cookies.test()) {
    //get the cookie
    var c = $.cookies.get(cookieName);
    //if it doesn't exist this is their first time and they need the refresh
    if (c == null) {
        //set cookie so this happens only once
        $.cookies.set(cookieName, true, { expires: 7 });
        //do a "hard refresh" of the page, clearing the cache
        location.reload(true);
    }
}
</script>
Feel free to work with this code but please do not use it without testing or ensuring it is right for your situation. It is merely an idea that worked for me.

Follow britishdev on Twitter

Wednesday, 4 August 2010

IntelliSense for jQuery in Visual Studio 2010

I read this morning in Steve Sanderson's Pro ASP.NET MVC 2 Framework book that it is possible to get IntelliSense when using the popular JavaScript library, jQuery.

Microsoft have decided to implicitly support jQuery by including some of its libraries in their sample MVC project. This is as well as their own AJAX library that comes with a lot of support for ASP.NET Web Forms specific features, which of course you won't be needing in ASP.NET MVC.

Part of their support translates into working with them to provide IntelliSense support to Visual Studio. It is not entirely integrated so will need a touch of set up and here's how to do it:

Let's do it!

First, you need to get the jquery-1.4.1-vsdoc.js file. I got mine by creating a new ASP.NET MVC2 sample web application. You will find it at /Scripts/jquery-1.4.1-vsdoc.js. Copy it from here and put it in your application somewhere sensible.

Then you simply reference the file like so:
<% /* %><script type="text/javascript" src="/js/jQuery/jquery-1.4.1-vsdoc.js"></script><% */ %>

Now you can enjoy such delights as this:

Note

  • You may want to put that reference in your MasterPage so it will work for all pages that use it. It will not work in miscellaneous pages or user controls (unless you add your own reference in those pages).
  • Also note the syntax I used so that users will not download the file as part of their request.
  • This works for VS2010. For VS2008 you may need to download a path that allows Visual Studio to find *-vsdoc.js files automatically

Follow britishdev on Twitter