views:

32

answers:

1

i've been playing with MVC for a while now, but since the project i'm on is starting to get wind in its sails more and more people are added to it. Since i'm in charge of hacking around to find out some "best practice", i'm especially wary about the possible misuses of javascript and would like to find out what would be the best way to have our views and partial views play nicely with javascript.

For the moment, we're having code that looks like this (only simplified for example's sake)

<script type="text/javascript">
    function DisableInputsForSubmit() {
        if ($('#IsDisabled').is(':checked')) {
            $('#Parameters :input').attr('disabled', true);
        } else {
            $('#Parameters :input').removeAttr('disabled');
        }
    }
</script>

<%=Html.SubmitButton("submit", Html.ResourceText("submit"), New With {.class = "button", .onclick = "DisableInputsForSubmit(); if ($('#EditParameters').validate().form()) {SetContentArea(GetHtmlDisplay('SaveParameters', 'Area', 'Controller'), $('#Parameters').serialize());} return false;"})%><%=Html.ResourceIcon("Save")%>

Here, we're saving a form and posting it to the server, but we disable inputs we don't want to validate if a checkbox is checked.

a bit of context

  • Please ignore the Html.Resource* bits, it's the resource management helpers
  • The SetContentArea method wraps ajax calls, and GetHtmlDisplay resolves url regarding an area, controller and action
  • We've got combres installed that takes care of compressing, minifying and serving third-parties libraries and what i've clearly identified as reusable javascript

My problem is that if somebody else defines a function DisableInputsForSubmit at another level (let's say the master page, or in another javascript file), problems may arise.

Lots of videos on the web (Resig on the design of jQuery, or Douglas Crockford for his talk at Google about the good parts of javascript) talk about using the namespaces in your libraries/frameworks. So far so good, but in this case, it looks a bit overkill. What is the recommended way to go? Should i:

  • Create a whole framework inside a namespace, and reference it globally in the application? Looks like a lot of work for something so tiny as this method
  • Create a skeleton framework, and use local javascript in my views/partials, eventually promoting parts of the inline javascript to framework status, depending on the usage we have? In this case, how can i cleanly isolate the inline javascript from other views/partials?
  • Don't worry and rely on UI testing to catch the problem if it ever happens?

As a matter of fact, i think that even the JS code i've written that is in a separate file will benefit from your answers :)

+1  A: 

As a matter of safety/best practice, you should always use the module pattern. If you also use event handlers rather than shoving javascript into the onclick attribute, you don't have to worry about naming conflicts and your js is easier to read:

<script type="text/javascript">
(function() {
    // your button selector may be different
    $("input[type='submit'].button").click(function(ev) {
        DisableInputsForSubmit();

        if ($('#EditParameters').validate().form()) {  
            SetContentArea(GetHtmlDisplay('SaveParameters', 'Area','Controller'), $('#Parameters').serialize());
        } 
        ev.preventDefault();
    });

    function DisableInputsForSubmit() {
        if ($('#IsDisabled').is(':checked')) {
            $('#Parameters :input').attr('disabled', true);
        } else {
            $('#Parameters :input').removeAttr('disabled');
        }
    }
})();
</script>

This is trivially easy to extract into an external file if you decide to.

Edit in response to comment:

To make a function re-usable, I would just use a namespace, yes. Something like this:

(function() {

    MyNS = MyNS || {};

    MyNS.DisableInputsForSubmit = function() {
        //yada yada
    }

})();
Gabe Moothart
Ok, but then if i need to promote something (let's say DisableInputsForSubmit) to framework status, i'd just use a basic namespace pattern? What would you recommend for good/easy usage?
samy
Thanks for the edit :) too bad we can't upvote twice :p
samy