Tag Archives: javascript

Having fun with HTML 5 History API – part three

Part 1 – Description of the problem
Part 2 – simple history replacement
Part 3 – additional history items – this article

As we’ve seen in the previous parts, we can alter the history of the current page navigation by replacing the current URL with a new one (this freedom has limits, of course, and we can’t alter the protocol or the host). For women is very important to show off a nice makeup. You can get a smooth makeup with advises from makeup professionals.

What we’ll explore in this part is creating new history items while not leaving the page. In order to achieve this, we’ll make use of

history.pushState( ... )

and an event called popstate :

window.addEventListener('popstate', function () { /* ... */ });

First we’ll need to replace all replaceState calls to pushState calls. The parameters stay the same:

function loadModels(make, pushState, onSuccess) {
    $.ajax({
        cache: true,
        type: 'GET',
        url: '@Url.Action("GetModelsByMake")',
        data: { 'makeId': make },
        success: function (data) {
            if (pushState)
                history.pushState(null, null, "/Home/Selector?mkId=" + make);
            var models = $("#SelectedModel");
            models.empty();
            models.append($("<option></option>").attr("value", "").text(" -- please select a model -- "));
            $.each(data, function (key, val) {
                models.append($("<option></option>").attr("value", val.Id).text(val.Text));
            });
            $('#divModel').show();
            if (onSuccess)
                onSuccess();
        },
        error: function (xhr, ajaxOptions, error) {
            alert(error);
            $('#divModel').hide();
        }
    });
}

// ...

function modelChanged() {
    var makeId = getParameterByName("mkId", document.location.href);
    var modelId = $("#SelectedModel").val();
    if (!modelId)
        history.pushState(null, null, "/Home/Selector?mkId=" + makeId);
    else
        history.pushState(null, null, "/Home/Selector?mkId=" + makeId + "&mdId=" + modelId);
}

Read more »

Having fun with HTML 5 History API – part two

Part 1 – Description of the problem
Part 2 – this article (simple history replacement)
Part 3 – additional history items

As we saw earlier in part 1, hitting the back button into a page with filled in fields will not restore (all) the values, but merely the ones that exist at the time of the page loading. In some cases, for example cascading dropdowns, will not be shown or exist at all at the time of the page load.

What we will accomplish in this part is to push into the query string (without reloading the page!) the selected make and the selected model (where applicable).

We are going to make use of

history.replaceState(...)

function. There is a W3C standard available for this function (and others).  Note that this is supported on all browsers, but only the recent versions.

To do so we need a few things:

  • A function to parse (a) query string; sadly JavaScript does not have anything built in, not even jQuery is of much help..
  • Change the URL upon changing of selection
  • Restore selection from the URL – including cascading

Great! Let’s start.

Upon a bit of searching around which turned into stackoverflowing, I reached the most voted question on this matter called ‘How can I get query string values in JavaScript?‘.

I really looked for a quick-simple-and-standards-compliant-and-so-on solution but the best I could scavenge was this:

function getParameterByName(name, url) {
    if (!url) url = window.location.href;
    name = name.replace(/[\[\]]/g, "\\$&");
    var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
        results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, " "));
}

Ugly but it works.

Read more »

Having fun with HTML 5 History API – part one

Part 1 – this article
Part 2 – simple history replacement
Part 3 – additional history items

Have you ever come across a web page with a few fields, let’s say cascading drop downs, you know like these:

… and after carefully filling in the fields you submit, and you are taken to the next page. Only to find out that you made a mistake and you push the back button in your browser. Guess what, now (almost) all your fields are reset and you have to begin all over again. Frustrating.

Apart from that, I have noticed that “infinite scrolling” has really taken off in a lot of sites, some news site (for example this one – at least at the time of the writing) even change the URL as you scroll down into the next article.

And then I wondered, how could I use this gimmick into solving the first issue (i.e. losing fields information after pressing back) and I came up with two possible solutions to this. I will showcase a small PoC for each one in the next two parts.

First let’s consider the following minimal web project (ASP.NET MVC but since this is about JavaScript, the back end doesn’t really matter) with two drop-downs. The first dropdown will let you choose a make of automobiles and the second one will let you choose a model from that particular make. In the end you press continue and you are directed to a new page:

01

Read more »

Local meetup – AngularJS intro

Lately I’ve been toying with AngularJS and I wanted to share my findings in a short practical presentation. I will be building a small SPA (single page application) with AngularJS and run through the most commonly used directives and features of the framework.

If you are in Bucharest on 8th of December, after work (19:00) drop by and have a look 🙂 The presentation will be in the ADCES group, the location being Electronic Arts (AFI Park 2).

Entrance is free, just register on this event either via Facebook or via Meetup. Hope to see you there 🙂

PS: Did I tell you that we’re having beers afterwards? 😉

Building Client (JavaScript) Custom Validation in ASP.NET MVC 4 using jQuery

Introduction

I was recently asked by some students of mine how exactly is client custom validation done in ASP.NET MVC (4). I did this once before unobtrusive validation and jQuery in ASP.NET MVC 2.0 but then I lost contact with the implementation details.

In ASP.NET MVC 4 (this started in MVC 3) there is jQuery unobtrusive validation that works hand-in-hand with Data Annotations (a set of validation attributes that can decorate properties or even (view)model classes). I just remembered that you need to create a ValidationAttribute subclass and also implement IClientValidatable on it. Also you must decorate a property of the (View)Model with this attribute.

On the client side you need to write JavaScript code that provides a validation adapter and a validation function.

Let’s suppose we’d want to create an URL shortening service and on the “Add URL” page we’d have three fields :
– Original URL (textbox)
– Use custom slug (checkbox)
– Custom slug (textbox)

The “Original URL” textbox would be mandatory and the input format should be of a fully-qualified URL (for example “http://blog.andrei.rinea.ro” :P)

The custom slug textbox would be mandatory ONLY if the “Use custom slug” checkbox would be checked. This is the tough part since validating this field requires knowledge of another field’s value (the checkbox in this case). And by tough I mean having to write actual code because there is no out-of-the-box validator for this (not on the server-side nor on the client-side).

This small tutorial will asume that you have knowledge of the ASP.NET MVC platform and C#. I will not go into detail on matters such as what is the MVC pattern, what is the controller, view etc.

 

Implementation – server side

Let’s start by creating a new ASP.NET MVC 4 web project (select “Internet site” template).
We’ll create a UrlController controller with an action called Add :

using System.Web.Mvc;

namespace MVC4_jQuery_Unobtrusive_Custom_Validation.Controllers
{
    public class UrlController : Controller
    {
        [HttpGet]
        public ActionResult Add()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Add(AddUrlViewModel userInput)
        {
            if (ModelState.IsValid)
            {
                // store the data
                // ...
                return RedirectToAction("Index", "Home");
            }
            return View();
        }
    }
}

Read more »