views:

391

answers:

4

We have a tabbed interface, inside one of these tabs is a privacy form. This privacy form, as well as using an external javascript file for the bulk of its work, also uses inline javascript as it currently relies on dynamic code (in the server side language).

formTabs wrapper (ajax tabs without callback functions)

...
<script type ="text/javscript">
    var messagingTabset = ProjectName.Tabset.init({
        'tabID': 'preferences-tabset',
        'ajaxUrl0': '<%=Url.Action("PreferencesMainForm", "Profile")%>',
        'ajaxUrl1': '<%=Url.Action("ProfileImageForm", "Profile")%>',
        'ajaxUrl2': '<%=Url.Action("InterestsForm", "Profile")%>',
        'ajaxUrl3': '<%=Url.Action("PrivacyForm", "Profile")%>',
        'ajaxUrl4': '<%=Url.Action("PasswordForm", "Profile")%>',
        'ajaxUrl5': '<%=Url.Action("CustomUrlForm", "Profile", new {userId = Model.UserId})%>',
        'defaultAjaxUrl': '<%=Url.Action(Model.PartialName, "Profile")%>'
    });
</script>
...

privacyForm view (more inline javascript with server-side code)

...
<script type = "text/javascript">
    var preferencesPrivacyForm = new ProjectName.AJAX.Form({
        "ajaxFormID": "preferences-privacy-form",
        "actionUrl": '<%= Url.Action("SavePrivacy","Profile") %>',
        "dataReturnType":"json"
    });
</script>
...

Back end developer: "The configuration JavaScript Code for this form should stay in privacyForm view"

Front end developer: "Hmm, I'm sure I"ve read that this is not the way to do this - unreliable, all the JavaScript should be inside the html page that contains the tabs wrapper, inside a callback function of that tabs load. You should really a)provide the logic for me get that dynamic data inside the tabs-wrapper or b) let me grab those dynamic variables via DOM traversal"

Back end developer: "Both of these methods are lots of work for no real pay off! The first example is bad because it means I'm going to have to change the way its built (and works fine). This is probably going to mean duplication. The second example is dodgy as the markup could change, so somebody working on the code might forget to edit the DOM traversal methods in the tabs-wrapper. It's another level of abstraction that we don't need. If you provide me with some evidence about why this is really really bad, than I'll check it out, but otherwise I can't justify putting the time in"

Front end developer: 'Well, I've already wasted a few days, fixing problems with AJAX loaded JavaScript by putting them in callbacks of their wrappers, but yeah now you think about it, a good reference on this kind of thing would be really nice, because you are right, at the moment, the application is running without any problems.'

This is one of many examples throughout a large application where we are loading inline JavaScript with Ajax.

Should I be convincing the back-end developer that we should be using callbacks, or am I missing something?

+3  A: 

I would recommend reading Dale Carnegie's How to Win Friends and Influence People.

It seems developers constantly get into this situation, where they know what is the best thing to do, but they get no buy in from other developers or management.

This book is definitely worth reading; an absolute MUST read for this profession.

Meiscooldude
This is a really unexpected answer that I think is great. I will be checking out this book. Hope you don't mind me simplifying the question title to a more technical focus. +1
Dr. Frankenstein
+5  A: 

It isn't really "bad" as long as it serves a purpose (for example, it loads content from other websites like the WordPress dashboard), but making all the extra calls to the server is a waste of resources unless you absolutely have to do it.

Usually, the simplest answer is the most correct one. In this case, it means not adding all the extra overhead to avoid slightly recoding a back-end.

Aaron Harun
A: 

It's not clear from the example why you would need AJAX in the first place. Why not just put

<script type ="text/javscript">
    var userId = "<<<<= userId >>>>"
</script>

directly into the HTML head? It is faster for the user, easier on the server, and you avoid all sort of pains with timing and error handling for failed requests.

Tgr
I've updated the code to show a bit more of a real life example, cheers.
Dr. Frankenstein
Thanks, but it doesn't make it any more clear why you would need the AJAX call. The standard way to pass dynamic data to javascript is to set a javascript variable in the header, which then you can refer anywhere else. You get rid of the extra HTTP request and the associated delay that way. You only need an AJAX call if you can't figure out at page load time what data you will need.
Tgr
I'm using MVC so unfortunately this does not apply
Dr. Frankenstein
I fail to see what this has got to do with MVC. You have some way (MVC or not) of putting user data into HTTP responses. You might chose to put the user id into the original HTTP response (the HTML code of the page) or in a latter response (the XML/JSON/whatnot code of the AJAX result). The two types of response manipulation are identical from a structural point of view; if you can use MVC for one, you can use it for another.
Tgr
+1  A: 

This is the core of the argument with why unobtrusive Javascript (UJS) is good. I never understood its merit because I did not know how to solve problems without inline Javascript. I eventually learned.

First of all, UJS is good because it separates your front end code as follows:

  1. HTML - pure HTML is for structuring your information.
  2. CSS - CSS is used to style your document and lay it out.
  3. Javascript - Javascript is used to define the behaviour of your page.

To make them work together, the HTML file loads in external CSS files to define styles and external Javascript files to define behaviour. Furthermore, you need well-known symbols in your HTML (such as id's, class names and tags), your CSS (id and class rules), so that your Javascript can manipulate the structure, layout, and styling according to implement the behaviour.

With a Javascript framework such as jQuery, you can dynamically bind javascript handlers to events on your various HTML DOM objects. This lets you avoid doing it inline within the HTML.

I have worked with code that is is cleanly separated (structure, style/layout, behaviour), and code that is a dog's breakfast of HTML, CSS, and Javascript, including HTML/JS code that was dynamically generated using ERB. Both were difficult to understand for different reasons. The first one was hard because I had to understand what was in each of the files, while the mixed code was hard to understand because I had to figure out what was JS, what was HTML, what was CSS, what initialized when, and what was generated. However, once I rode the learning curve, evolving the cleanly separated code was less work and easier to test.

For generated Javascript (e.g. with ERB), you can usually structure the code where you have static javascript driven by some user-specific or context-specific data. As suggested by a previous person, you can just set the values for that data in the HEAD section and then go with static Javascript files. You could also use an AJAX call to grab that same data from the server.

From a short-term business perspective, the back end guy is right. If it works, don't fix it. From the view of the medium-term, it will cost your team more to evolve and maintain your code if you don't cleanly separate your HTML, CSS, and Javascript with UJS. From your business perspective, it will be painful for you to maintain and evolve the code as it is today. From the business perspective of the back-end guy, it will cost him more if he does anything other than what works today. i.e. Your team leader and architect needs to balance the various business perspectives to determine which way to structure your code.

Jay Godse
Thanks for this, though I'm not sure what this specifically has to do with unobtrusive javascript as I understand it - http://icant.co.uk/articles/seven-rules-of-unobtrusive-javascript/. This question is more concerning the importance of callbacks in javascript, apologies if I have not have not worded it quite correctly.
Dr. Frankenstein