I've used RJS in the past for RoR projects and felt terribly constrained by what it could do. However, using Javascript alone felt/feels ugly and hack-y. This is particularly true when writing Javascript that manipulates Rails automagically generated from variable names. I haven't seen much talk about RJS in the blogosphere recently. Is RJS being used in new RoR projects or have people decided that it's not effective? Is it still being actively developed and its function-coverage expanded? I'd appreciate some insight into the current state of affairs.
So, who's using RJS (and how is it working out for you) and who's using javascript?
I recommend writing straight javascript. I believe that - yes - RJS is going out of style. One reason for this is the popularity of the sexy jQuery library. Another is the model of RJS - in that it is a ruby wrapper around javascript, and so for any javascript library you need to use, you will need a corresponding ruby wrapper library, which means more grunt work somebody's going to have to do(and another gem you'll have to depend on). Also, although the idea of making a request and receiving back executable javascript is nice, I believe there are many who don't like this style, or at least don't think it's appropriate for certain situations. I personally have learned javascript and have come to like it a lot, and I recommend you give it a try.
I like using RJS for simple tasks, like:
page["post_#{#post.id}"].replace :partial => #post
page["post_#{#post.id}"].highlight
Yes, you could do this directly with the link_to_remote function, but that just clutters up your view with code, or with an update_page in the controller, but that is ugly.. the rjs allows you to write more clearly understandable code that's uncoupled from any javascript library (since there are things like jrails out there, or you can just override the Rails' methods yourself.)
If you have a really complex javascript function for your application, you'd probably be better served by writing the javascript yourself, since at that point, you won't want to rely on the abstractions that Rails provides.
By RJS, I assume you are referring to RJS templates. The whole concept is that you are generating JavaScript that will be run in a JS eval function in the browser as an AJAX return. How exactly is it that you "felt terribly constrained by what it could do"? You can mix Ruby and JS in the RJS files in a variety of ways, and it isn't any more constraining than other ERB type formats. It's a very powerful way to make AJAX calls do more than update a single <div> (they can even update two <div>s).
I have a feeling you are really meaning to ask about using the JavaScript/Prototype/Scriptaculous Helpers. Is that so?
RJS was never intended to be a flat-out replacement for JavaScript, and you shouldn't decide which tool is right for the job based on what you think you see some other kid doing on the blogosphere.
I personally do not like the js generated by the helpers, so I usually opt to not use them. However, there are times when they are quite convenient.
There is also a Jquery replacement, Jrails, if your not a Prototype fan.
But, I have to agree with NSD. Why would you let what others do ultimately lead your path. If you don't like the way the helpers work or they are not doing it for your project, don't use them. Or if it's missing something, write your own. And perhaps in that, you can ignite some intrest.
As for investing time, it's knowledge.
Related
[Disclosure: This question is slightly related to my previous question.]
As you can see, a few suggested that I learn JavaScript / jQuery / Node.js. From what I've read, (a) jQuery is a JS library that makes coding in JavaScript (that works across all browsers in one go) easier, (b) Node.js is a basically a server-side JavaScript environment, (c) Javascript is the root programming language of the aforementioned ones, and is client-side.
I have also read many questions regarding the same on SO, but for someone (like me) who has nil knowledge of any kind of programming, somethings aren't clear.
(1) Basically, my goal is to write a (real-time) live blogging/commenting application for my blog. This, I have learnt, requires a client-side scripting language like JavaScript. So, the question is, can I build such an application with (a) jQuery alone (b) Node.js alone?
(2) If the answer to (1) is YES: Do you think going with the server-side option - - Node.js would be better? (as jQuery definitely doesn't work on JS-disabled browsers, I don't know about Node.js.) Please advise.
(3) When I got a book for XHTML, the book got me started with HTML, and gradually took me into XHTML. So, there was no confusion between HTML and XHTML. Would that be the case with (a) jQuery and (b) Node.js too?
EDIT: (4) There's one problem with JS. Some users may have JS disabled in the browser. Is there any other client-side scripting alternative as good as JS? (Just asking)
That is, in order to learn, (a) jQuery or (b) Node.js should I first learn, JS or can I start with a beginner's jQuery or Node.js book right away? Which would be the right way?
I really need your advise here, as I am totally new to programming (and have very little time to study), and I am pretty excited of what's ahead.
(I used (a) jQuery and (b) Node.js whenever possible to denote that you consider them separately, and not think that I will be learning both. I can only choose one, at least for now.) Thanks.
DECISIONS! DECISIONS! For someone who may come here in the future searching for the same... From the answers it's clear that one can start with jQuery, and end up learning pure JS through practice (building applications, solving issues etc). It seems the learning curve, that way, would be longer?! (Because you end up having problems, keep trying to solve them, maybe lose confidence... blah! blah! blah!) Still that's good. What I've chosen is the straight forward way - JS first (until I feel like I've got some hold), and then go go jQuerying! I hope I am not wrong in my conclusion. :) {Thanks #Greg Pettit and #Pete Wilson}
Node.js and jQuery perform two different roles. One facilitates server-side JavaScript, the other provides an abstraction library for client-side JavaScript. It's not one or the other. The question has to be branched into two directions:
What server-side technologies do I want to use? Is PHP+MySQL (a known commodity) going to do what I want on the server side? Should I use something I'm already familiar with (ASP or whatever)? Or do I like the projected performance benefits and scalability of Node.js to jump into that? Does Node.js have mature enough Database classes to actually use it for my purpose?
On the client-side, do I want to write everything with 'pure' JavaScript, or do I want to use a framework? If I use a framework, should I use jQuery because it seems to be the most widely-known, or do I research other frameworks that might do what I want? Furthermore, should I look into web application frameworks like Kendo UI or jQuery UI or piece it together with a JavaScript framework?
At some point, someone is going to tell you if you don't know JavaScript at all that you should start with pure JavaScript so that frameworks don't corrupt you. Me, I say phooey. You want to get stuff done. You don't want to spend your hours jumping through hoops when you could be just getting stuff done.
If you jump right into a framework (say, jQuery) instead of learning JavaScript properly, there are things that you will learn eventually anyhow. Before too long you'll realize that you didn't need to use $(this).attr('id') when you could've just used this.id. But it doesn't matter, because the former worked until you learned the better way.
I'm a former educator and very much in support of seeing results quickly, because it will propel you to learn more. Just because you start with jQuery doesn't mean you'll forever ignore 'pure' JavaScript. If you are an intelligent problem-solving kind of person, eventually 'pure' JavaScript will find you, and you'll begin to identify the right time to use it, and the right time to use a framework.
You should definitely start with learning Javascript first. I would read Eloquent Javascript to learn javascript at first. Then, learn jQuery and then node.js. For jQuery, I would say you should read jQuery in Action to learn jQuery.
For most web-applications, you need a server-side part. For the application you want to do, you need client-side Javascript. You'll have to do both parts.
For the server-side part, you can use whatever you please, whether it's Node.js, or PHP + the myriad PHP web frameworks, or anything else that can respond to HTTP requests.
Node.js and jQuery serve completely different purposes, it's unlikely you'll find a book that deals with both, and if you do, there's no "smooth" progression between the topics I can imagine.
jQuery does make use of certain idiosyncracies of Javascript (rebinding this), some of its nontrivial features (anonymous functions), and introduces several patterns on top (using literal objects for named/optional function arguments), so I'd recommend looking into JS at the moderately advanced level rather than just muddling though.
You should read javascript the good parts by Douglas Crockford, make a hello world with pure node.js then use express.js + socket.io or now.js. and mongodb for data persistence
Well it goes without saying to learn library of any language you need to learn the laguage first. But how you want to learn it is your choice, some people prefer to start with the library first then traverse bottom up to cover the basics of the language, while some other likes to get their hands dirty with basics of language before trying out advanced syntaxes and libraries.
To add to it I should also mention jQuery and Node.js are totally different things and have different learning curve too.
Node.js is more of a concept to enable javascript run at server side with asynchronus programming inbuilt. To learn node you will be learning some server level APIs like file streaming, logging, file system operations, callback etc which are typically server level tasks.
Whereas to learn jQuery you would learn how javascript operate of doms and events, css , ajax etc on a webpage to alter those pages dynamically.
From application/website building point of view I would say to get started you need very little knowledge of nodejs but more knowledge of JQuery.
PS: If you are looking to build an website today in 2017 I would suggest to avoid jQuery altogether and go for client frameworks like angular/react.
I have been a user of jQuery (and some of its minor plugins) for a while. The Javascript code I've developed over the years could be described best as... messy. It used a ton of global variables and functions here and there, didn't use standard ways of organizing the code, nor any design patterns whatsoever.
I am currently building the new version of a website, and I have completed doing the backend with PEAR::MDB2 and Smarty templates. The rest is just homebrew PHP with some classes.
Now I am at the point where I'll add the Javascript layer on top of the website to improve the user-friendliness of some features. (while making sure everything degrades gracefully) I want to write better, cleaner, more organized Javascript than I used to, so I did a little research. I read Stefanov's Object-Oriented Javascript to have a better grasp on some concepts I knew only loosely about (prototypes, constructors, etc.) as well. Now I'm stuck at a point where I wonder which Javascript frameworks I should use, and how to organize it all.
After conducting my research, I understood Cappuccino & Objective-J, and Sproutcore were not what I was looking for. To quote Cappucino's about page:
Cappuccino is not designed for building web sites, or making existing sites more "dynamic". We think these goals are too far removed from those of application development to be served well by a single framework. Projects like Prototype and jQuery are excellent at those tasks
So there's that. Then I found out about Coffee Script, which is more of a one-to-one "compiler" and wouldn't help me with the actual organization of my code.
I also stumbled on some articles that give guidelines:
Using Inheritance Patterns to Organize Large jQuery Applications
A JavaScript Module Pattern
I also found out about Backbone.js, Shoestring, JavaScriptMVC, Google Loader, jQuery Tools, jQuery UI. I don't really know what to do of all this... The things I know:
I don't want to invest too much time in learning something too complex, I want to keep things simple and flexible as much as possible (that is why I don't use Symfony on the backend, for example), yet clean and organized.
I want to use jQuery, the question is, what should I use with it? (that is compatible too)
Right now, I'd use jQuery and jQuery Tools and "organize" all that in a simple namespace/object literal with simple properties and methods and also, since the site is localized, I just plan on using the simple vsprintf (as I do on the backend) with key:value pairs loaded from an object literal provided by the backend. JavaScriptMVC seems interesting, but I fear it would bring way too much complexity for a project that is fairly small sized. That is where I need your advice! Thank you very much in advance.
Ok, my attempt at an answer:
There is no 'best' to way to do it. You now know what's there and I think you might have a preference for yourself for what you want. In that case, pick a framework and learn it inside-out. (sorry to burst your bubble, but each framework has a learning curve, some steep, some very easy, but in the end to use it well you have to invest in it. Just do it, you won't be sorry).
You of course have an preference for clean code, so you might take some considerations into account. You also say you have a preference for jQuery, which is fine, but there are some limitations (as also pointed out in the link provided by eskimoblood).
There are some nice lectures / and tutorials with advice on how to structure your code in jQuery:
How to manage large jquery apps
On Large jQuery apps
Essential Javascript and jQuery patterns (free ebook)
Some style guides:
Jquery core UI Styleguide
Google Closure Javascript Style Guide
Tools for checking your code
JSLint
JSHint (a more forgiving/practical fork)
Closure Linter (haven't tried it yet, but intend to)
Standard works (javascript)
Everything by Douglas Crockford
Quirksmode
There might be more.. perhaps more people can contribute, but I also think that you've almost reached the end of what you can learn before getting your hands dirty. Many of these guides are written in a very generic way, but the interesting thing is that javascript is called upon in many specific situations. It might be useful to just post some of the code that you regard as "messy" and we can help you figure out how to do it better. Good luck!
You should watch the video and read the links in this article and then you should ask yourself again if jquery is the right tool. Maybe you will use dojo, that is much better for larger projects or you take a look at backbone and where you can stay with jquery. After all both of them are more "javascriptish" then something like sproutcore, cappuciono or even GWT. And also much easier to understand when you come from jquery.
One framework that is to consider is definitely ReactJS from Facebook. This framework is pretty slick in many ways.
First thing you have to know is that it is a view framework. It can be used server-side to do the pre-rendering of pages, but it really shines on client side. Since it's a view framework, it can be used with backbone or any other "back-front"-end framework.
One of the main point of React is its rapidity. It keeps a virtual DOM in memory and virtualize all the webpages events. So the virtuals event are used to keep events browser agnostics.
The virtual DOM kind of make programming a dynamic site as if you were programming an old static website. You can just shoot the whole HTML to render to the view engine (as if you were "re-rendering" the whole page) and it will manage the DOM operations. It does a diff between the new virtual DOM and the current virtual DOM and only inserts nodes that needs to be inserted. This way you reduce the number of DOM ops and thus increase your render speed by a lot.
A good place to start is this tutorial which shows how to use "Flux" (the web flow designed by Facebook for its site) in order to realize a Todo application!
Coming from Java, I'm wondering if a Java best practice applies to JavaScript.
In Java, there's a separation of interface and implementation, and mixing them up is considered a bad practice. By the same token, it is recommended to hide implementation details of your library from end developers.
For example, log4J is one of the most popular logging libraries out there but it is recommended to write code to the slf4j library or the Commons Logging library that "wraps" log4j. This way, if you choose to switch to another logging framework such as logback, you can do so without changing your code. Another reason is that you, as a user of a logging library, how logging is done is none of your concern, as long as you know what logging does.
So back to JavaScript, most non-trivial web applications have their own custom JavaScript libraries, many of which use open source libraries such as jQuery and dojo. If a custom library depends on, say jQuery, not as an extension, but as implementation, do you see the need to add another layer that wraps jQuery and makes it transparent to the rest of JavaScript code?
For example, if you have the foo library that contains all your custom, front-end logic, you'd introduce the bar library that just wraps jQuery. This way, your foo library would use the bar library for jQuery functions, but it is totally oblivious to jQuery. In theory, you could switch to other libraries such as dojo and google web toolkit without having a big impact on the foo library.
Do you see any practical value in this? Overkill?
Although it makes sense from a theoretical standpoint, in practice I'd say it's overkill. If nothing else for these two reasons:
Anything that adds to the size of
the request (or adds more requests)
is bad - in web world, less is more.
If you're using say jQuery, the
chances of you switching to
something like Mootools is (imho) slim to none. From what I've seen, the top libraries each aim to solve different problems (at least in the case of Mootools and jQuery - see this great doc for more info on that). I'd assume that you'd incur a tremendous amount of headache if you were to try to implement a middleware library that could easily switch between the two.
In my experience and being a Java developer myself, sometimes we tend to take the whole "abstraction" layer pattern too far, I've seen implementations where someone decided to completely abstract a certain framework just for the sake of "flexibility" but it ends up making things more complicated and creating more code to maintain.
Bottom line is you should look at it on a case by case basis, for example you wouldn't try to create an abstraction layer on top of struts, or on top of JPA, just in case you then go to a different framework (which I've rarely seen done).
My suggestion is, regardless of the framework you are using, create objects and components that use the framework internally, they should model your problem and be able to interact between them without the need of any specific framework.
Hope this helps.
There are a lot of good answers here, but one thing I don't see mentioned is feature sets. If you try to write a library to wrap the functionality provided by, say, jQuery, but you want to be able to easily swap out for something like prototype, you have a problem. The jQuery library doesn't provide all the features prototype provides, and prototype doesn't provide all the features jQuery provides. On top of that, they both provide their features in radically different ways (prototype extends base objects -- that's damn near impossible to wrap).
In the end, if you tried to wrap these libraries in some code that adds 'abstraction' to try to make them more flexible, you're going to lose 80% of what the frameworks provided. You'll lose the fancy interfaces they provide (jQuery provides an awesome $('selector') function, prototype extends base objects), and you'll also have to decide if you want to leave out features. If a given feature is not provided by both frameworks, you have to either ditch it or reimplement it for the other framework. This is a big can of worms.
The whole problem stems from the fact that Java is a very inflexible language. A library provides functionality, and that's it. In JavaScript, the language itself is insanely flexible, and lets you do lots of crazy things (like writing a library, and assigning it to the $ variable). The ability to do crazy things lets developers of javascript libraries provide some really creative functionality, but it means you can't just find commonalities in libraries and write an abstraction. I think writing javascript well requires a significant change in perspective for a Java developer.
Someone wise once said "premature optimization is the root of all evil." I believe that applies in this case.
As others have expressed, you don't want to abstract for the sake of flexibility until you have an actual need for the abstraction. Otherwise you end up doing more work than necessary, and introducing unnecessary complexity before it is required. This costs money and actually makes your code more brittle.
Also, if your code is well organized and well tested, you should not be afraid of major changes. Code is always changing, and trying to anticipate and optimize for a change that may or may not come will almost always get you in more trouble than it saves you.
Acknowledgement: I should give credit to Agile programming and my practice and readings on the topic. What I've said comes directly from my understanding of Agile, and I've found it to be an extremely good razor to cut out the extra fat of my work and get lots done. Also none of what I've said is actually JavaScript specific... I'd apply those principles in any language.
There are good arguments calling this development practice - wrapping in order to switch later - into question in any language.
A good quote by Oren Eini, from his writeup on wrapping ORMs:
Trying to encapsulate to make things
easier to work with, great. Trying to
encapsulate so that you can switch
OR/Ms? Won’t work, will be costly and
painful.
This is definitely something that is done in enterprise environments.
Take for example a company that has their own custom javascript framework that is used on all of their projects. Each of the projects decide to use their own framework (jQuery, Dojo, Prototype) to add functionality to the underlying modules of the company framework. Employees that move between projects can now easily do so because their API with working the project's codebase is still the same, even though the underlying implementation could be different for each project. Abstraction is helpful in these situations.
It is overkill. Javascript is not Java and is not in any way related to Java. It is a completely different language that got J-a-v-a in the name for marketing reasons.
If you are concerned with availability of add-on libraries, then choose a framework with a large ecosystem. In an enterprise environment you will be further ahead by standardising on a vanilla off-the-shelf uncustomised web framework that you can upgrade every year or so tracking the rest of the world. And then supplement that with a SMALL in-house add-on library which you will, of course, have to maintain yourself, not to mention training any new programmers that you hire.
Since you are talking about Javascript in the client (web browser) it is more important that you limit the complexity of the things that people do with it. Don't build huge amounts of client side code, and don't make stuff that is so brittle that another programmer can't maintain it. A web framework helps you both keep the linecount down, and keep your own code reasonably simple.
It is not a question of Javascript best practice, because that would be different for server-side JS such as Rhino or node.js.
Adapter pattern is not a common solution in this case. The only example I know to use this pattern is extjs. Javascript projects are usually too small and they aren't worth the effort you would make by creating such an abstraction layer.
The common solution for this problem is that you try to use multiple frameworks together for example with jquery.noConflict.
I've done this before, and can talk a bit about the experience of writing a library/toolkit wrapper.
The plan was to move from Prototype to some other library. Dojo was the first choice, but at the time I wasn't sure whether that's the library to move everything to (and by everything I mean ~5MB of Prototype-happy JS). So coming from a world of clean interfaces, I was set to write one around Prototype and Dojo; an awesome interface that would make switching out from dojo a breeze, if that was in fact necessary.
That was a mistake that cost a lot of time and effort for a few reasons. The first one is that although two libraries can provide the same functionality, (a) their API will almost always be different, and most importantly (b) the way you program with one library will be different.
To demonstrate, let's take something as common as adding a class-name:
// Prototype
$("target").addClassName('highlighted');
// Dojo
dojo.addClass("target", "highlighted");
// jQuery
$("target").addClass("highlighted");
// MooTools
$('target').set('class', 'highlighted');
Pretty straight-forward so far. Let's complicate it a bit:
// Prototype
Element.addClassName('target', 'highlighted selected');
// Dojo
dojo.addClass("target", ["highlighted", "selected"]);
// jQuery
$("target").addClass(function() {
return 'highlighted selected';
});
// MooTools
$("target").set({
"class": "highlighted selected"
});
Now after choosing an interface for your version of the addClass you have two options: (1) code to the lowest common denominator, or (2) implement all of the non-intersecting features of the libraries.
If you go with the 1st -- you'll loose the "personality" / best qualities of each of the library. If you go with #2 -- your addClass' code will be at 4 times larger than the ones provided by any of the libraries, since for example when Dojo is included, you'll have to write the code for the function as the first param (jQuery) and the Object as the first param (MooTools).
Therefore, although it is theoretically possible, it isn't practical, but is a very nice way to understand the intricacies of the libraries out there.
my rails applications (all 2.3.5) use a total mix of inline javascript, rjs, prototype and jquery. Let's call it learning or growing pains. Lately i have been more and more infatuated with unobtrusive javascript. It makes your html clean, in the same way css cleaned it up.
But most examples i have seen are small examples, and they put all javascript(jquery) inside application.js
Now i have a pretty big application, and i am thinking up ways to structure my js. I like somehow that my script is still close to the view, so i am thinking something like
orders.html.erb
orders.js
where orders.js contains the unobtrusive javascript specific to that view. But maybe that's just me being too conservative :)
I have read some posts by Yehuda Katz about this very problem here and here, where he tackles this problem. It will go through your js-files and only load those relevant to your view. But alas i can't find a current implementation.
So my questions:
how do you best structure your unobtrusive javascript; manage your code, how do you make sure that it is obvious from the html what something is supposed to do. I guess good class names go a long way :)
how do you arrange your files, load them all in? just a few? do you use content_for :script or javascript_include_tag in your view to load the relevant scripts. Or ... ?
do you write very generic functions (like a delete), with parameters (add extra attributes?), or do you write very specific functions (DRY?). I know in Rails 3 there is a standard set, and everything is unobtrusive there. But how to start in Rails 2.3.5?
In short: what are the best practices for doing unobtrusive javascript in rails? :)
I do not think there is one best practice, but I'll let you know what I do.
I have a series of js files each for with their own purpose in the public/javascripts/ directory. Some examples could be utility.js chat.js shopping_basket.js and so on.
I use asset packager and define one big fat collection for all my general use functionality and another for admin only functionality. Round trips to the server cost way too much. I basically include all the js in on first page load minified into one blob (in general)
I allow basic $(document).ready hooks inline in the pages, and keep them really short.
Data that my js files needs to access is rendered inline with the page. (Usually in the DOM, sometimes as vars - Eg. var xyz = 100)
I will usually develop my controllers with javascript off (and make sure it all works), then I turn it on and sprinkle a few if request.xhr? where needed.
Keep in mind, Rail 3.1 introduces a built-in best practice, see: http://guides.rubyonrails.org/asset_pipeline.html - on a personal note I have had performance and configuration issues with the new pipeline, however many others have had great success with it.
I recently documented how I have been managing javascript in Ruby on Rails. I basically break things down into many small, granular files, each with an appropriate namespace and then merge them all into a single file for production using asset_packager.
I found this post while trying to solve the same problem, but none of the existing solutions struck me as the right one. I wrote up my approach here. I love Rails' convention over configuration, so I wanted the same approach to including Javascripts that are applicable only to a particular action page. If nothing else, it's at least another approach to add to your options.
Hey guys. There has been a lot of activity lately on the jQuery Dev Group about prototypal inheritance and plugin namespacing, and I want to see who has the best answer for it.
Group link:
http://groups.google.com/group/jquery-dev/browse_thread/thread/620c6a18a16d9665
Questions:
What do you guys think should be done about this and why?
Do you agree with any opinions there? Why or why not?
Why it is important:
If jQuery did decide to implement something like this into the core, this is a huge decision that will affect a lot of people and may affect how they use/extend jQuery and if they continue to use jQuery. It may convert a lot of people to jQuery.
I think what sets jQuery apart from libraries like prototype is that it concentrates on features such as fast DOM selection, traversal and manipulation rather than adding 'flavor' to javascript.
Problem with Prototype is it puts a ruby hat on javascript and it ends up getting bloated with features you probably never end up using.
I have worked in projects where people overuse prototype Classes to implement everything as a class where it simply wasn't needed. People who move from Java or C# (or even Ruby) like to do everything their way - which is often not needed.
I think that this is important step for jQuery. Of cause jQuery is very dom centric lbrary. And that is why it achieves so much attention over the world, but it is hard to build complex solutions basing on it only. You can not use all the benefits of OOP and so you must to have all the code in a head - all of your programmers must. I suppose jQuery is the most easy solution - thats why everybody likes it, but now it wants to be enterprise solution.
I think this can make enterprise client side development faster and that is great:)