Currently, pages generated by Rails tend to be sprinkled with JavaScript. This happens, because the various helper methods work only locally and simply append to the output. In order to hide the JavaScript away, rendering would probably have to be changed. A way I can think of is that a page-specific script is included in the head of the document and JavaScript code is not written to the main document, but to the script file instead. I''m not yet completely convinced of the value of hiding scripts away and I''m definitely unsure if it would be worth the effort -- regarding implementation and possible execution speed penalty. Do you have any opinions and ideas concerning this topic? Michael -- Michael Schuerig Nothing is as brilliantly adaptive mailto:michael@schuerig.de as selective stupidity. http://www.schuerig.de/michael/ --A.O. Rorty, The Deceptive Self
http://dean.edwards.name/my/cssQuery/ might be a solution i also recently found a promising script (attached) by Richard Cornford posted on http://www.sitepoint.com/blog-post-view.php? id=171578 that might do the trick didnt yet have the time to test though. Daniel:) <code> /** * <p>Title: Initializer.</p> * <p>Description: Common Onload initialisation interface.</p> * <p>Copyright: Richard Cornford 2004</p> * @author Richard Cornford * @version 1.0 */ /** * A global function named - initializeMe - is created that can be used * to arrange the execution of an arbitrary number (but probably * implementation limited to the order of about 1500) of functions from * the - onload - handler of a web page. The intention being to allow an * indefinite number of other scripts to use a common interface for * triggering their onload initialisation functions. * * NOTE: This function must be included before any code that attempts * to use it. * * The - initializeMe - function is called with a reference to a * function object as its first argument, and up to 4 optional * additional arguments:- * * initializeMe(functRef, "idOfElement", "nameOfForm"); * * - The function reference and any additional arguments are stored in a * function stack, the base of which is assigned as to window.onload * handler (or using W3C DOM addEventListener or IE attachEven, if * available) and when the onload event is triggered the execution of * the base of the function stack results in the execution of the * function passed as the first argument, followed by the next function * in the stack (which executes its function argument, And so on until * the stack is excused. The execution of functions passed to the - * initializeMe - function is in the order in which they are passed to * the - initializeMe - function (first in, first executed). * * The function object passed as - funcRef - is called with its first * argument being the (onload) - event - object and the values * originally passed to the call to - initializeMe - as the optional 2nd * to 5th arguments as its 2nd to 5th arguments (in the same order). So, * in the example call to - initializeMe - above, the function object * passed by reference as the first argument would have the pattern:- * * function(event, idString, nameString){ * ... * } * * - and the two string arguments passed to - initializeMe - would be * passed on when it was called during the onload event. * * Note: The - event - object passed to the calls to the - funcRef - * functions is browser normalised with - (ev?ev:global.event) - prior * to the call to the function, so these function do not have to * normalise the event objects themselves, but they also cannot make * decisions about the DOM in use from inferences about their - event - * argument. */ var initializeMe = (function(){ var global = this; var base = null; var safe = false; var listenerType = (global.addEventListener && 2)|| (global.attachEvent && 3)|| 0; function getStackFunc(funcRef, arg1,arg2,arg3,arg4){ var next = null; function l(ev){ funcRef((ev?ev:global.event), arg1,arg2,arg3,arg4); if(next)next = next(ev); return (arg1 = arg2 = arg3 = arg4 = funcRef = null); }; l.addItem = function(d){ if(next){ next.addItem(d); }else{ next = d; } }; return l; }; return (function(funcRef, arg1,arg2,arg3,arg4){ if(base){ base.addItem( getStackFunc(funcRef, arg1,arg2,arg3,arg4) ); }else{ base = getStackFunc(funcRef, arg1,arg2,arg3,arg4); } if(!safe){ switch(listenerType){ case 2: global.addEventListener("load", base, false); safe = true; break; case 3: global.attachEvent("onload", base); safe = true; break; default: if(global.onload != base){ if(global.onload){ base.addItem(getStackFunc(global.onload)); } global.onload = base; } break; } } }); })(); //^^ : The inline execution of the outermost function expression. </code> On Jun 29, 2005, at 3:14 PM, Michael Schuerig wrote:> > Currently, pages generated by Rails tend to be sprinkled with > JavaScript. This happens, because the various helper methods work only > locally and simply append to the output. > > In order to hide the JavaScript away, rendering would probably have to > be changed. A way I can think of is that a page-specific script is > included in the head of the document and JavaScript code is not > written > to the main document, but to the script file instead. > > I''m not yet completely convinced of the value of hiding scripts > away and > I''m definitely unsure if it would be worth the effort -- regarding > implementation and possible execution speed penalty. > > Do you have any opinions and ideas concerning this topic? > > Michael > > -- > Michael Schuerig Nothing is as brilliantly adaptive > mailto:michael@schuerig.de as selective stupidity. > http://www.schuerig.de/michael/ --A.O. Rorty, The Deceptive Self > _______________________________________________ > Rails-spinoffs mailing list > Rails-spinoffs@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs >
http://www.ripcord.co.nz/behaviour/ looks very interesting. Uses css selectors to apply javascript. Chris On 6/29/05, Michael Schuerig <michael@schuerig.de> wrote:> > Currently, pages generated by Rails tend to be sprinkled with > JavaScript. This happens, because the various helper methods work only > locally and simply append to the output. > > In order to hide the JavaScript away, rendering would probably have to > be changed. A way I can think of is that a page-specific script is > included in the head of the document and JavaScript code is not written > to the main document, but to the script file instead. > > I''m not yet completely convinced of the value of hiding scripts away and > I''m definitely unsure if it would be worth the effort -- regarding > implementation and possible execution speed penalty. > > Do you have any opinions and ideas concerning this topic? > > Michael > > -- > Michael Schuerig Nothing is as brilliantly adaptive > mailto:michael@schuerig.de as selective stupidity. > http://www.schuerig.de/michael/ --A.O. Rorty, The Deceptive Self > _______________________________________________ > Rails-spinoffs mailing list > Rails-spinoffs@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs >
On Wednesday 29 June 2005 17:35, Daniel-Philipp Gona wrote:> http://dean.edwards.name/my/cssQuery/ might be a solutionAnother variant: http://www.ripcord.co.nz/behaviour/> i also recently found a promising script (attached) by Richard > Cornford posted on http://www.sitepoint.com/blog-post-view.php? > id=171578 that might do the trickWas there a problem with executing an arbitrary number of scripts after the document has been loaded? I think window.addEventListener(...) does all that''s needed. Anyway, with all these techniques, you have to look at the page/document in its entirety. Otherwise you can''t separated JavaScript from (X)HTML. Rails builds pages in a piecemeal fashion, stuff is just added at the end (modulo layouts). Michael -- Michael Schuerig Airtight arguments have mailto:michael@schuerig.de vacuous conclusions. http://www.schuerig.de/michael/ --A.O. Rorty, Explaining Emotions
On Wednesday 29 June 2005 18:29, Chris McGrath wrote:> http://www.ripcord.co.nz/behaviour/ looks very interesting. Uses css > selectors to apply javascript.Yes, but how do you use this in a Rails context? Michael -- Michael Schuerig Failures to use one''s frontal lobes mailto:michael@schuerig.de can result in the loss of them. http://www.schuerig.de/michael/ --William H. Calvin
> Yes, but how do you use this in a Rails context?As you said, the Rails helpers spit out that icky javascript code. You''ll just have to write new helpers to use these unobtrusive ones instead. Just after taking a quick glance however, there may be nothing more required than setting a unique id or class for your ajaxed elements, setting up your behavior stylesheet, and writing the Ajax.Updater calls yourself. The easiest way is probably to set them up w/ rails first, then copy the generated JS to your behavior sheet. -- rick http://techno-weenie.net
On Wednesday 29 June 2005 19:02, Rick Olson wrote:> As you said, the Rails helpers spit out that icky javascript code. > You''ll just have to write new helpers to use these unobtrusive ones > instead. Just after taking a quick glance however, there may be > nothing more required than setting a unique id or class for your > ajaxed elements, setting up your behavior stylesheet, and writing the > Ajax.Updater calls yourself.Let''s see, if I understand you correctly. I''d have to use custom helpers that don''t write out JavaScript, but do appropriately label elements with ids. The JavaScript code that would have gone into the page is collected in a view-specific script file. Is that what you''re suggesting? With this approach, I don''t see how it would work when the contents of a page are not fixed and it''s not known beforehand which scripts are needed. Also, one has to take extra care in order to keep view code and script file consistent. No unsurmountable obstacles, but I''m still wondering if it''s worth the effort. Michael -- Michael Schuerig Failures to use one''s frontal lobes mailto:michael@schuerig.de can result in the loss of them. http://www.schuerig.de/michael/ --William H. Calvin
> With this approach, I don''t see how it would work when the contents of a > page are not fixed and it''s not known beforehand which scripts are > needed. Also, one has to take extra care in order to keep view code and > script file consistent. No unsurmountable obstacles, but I''m still > wondering if it''s worth the effort.It''s probably not worth the effort, since your application may have an unlimited number of actions. What if you have a listing of blog entries, each with a delete link? It may be possible to do something like this: <a href="#" class="delete_link" id="15" var myrules = { ''.delete_link'' : function(el){ el.onclick = function(){ delete_by_id(this.getAttribute(id)); } } }; I find unobtrusive js great for simple examples. Drop a js file into your page, and all text areas are WYSIWYG widgets. Drop a ''sortable'' class onto a table, and now its headers are sortable. Ajax calls are a lot more complex and frankly, I''d rather just get on with the rest of app personally. -- rick http://techno-weenie.net
I concur. Besides packing any addtional functions you might need in your app in it''s own js file (or files), the built-in functions just generate comparably small calls to prototype.js and the script.aculo.us libs. Also, with the upload-progress patch that is now in trunk, it''s possible to use <script> tags inside Ajax returns that are then executed. A complete seperation of client-side page structure (XHTML), design (CSS) and behaviour/logic (inside .js files) is achievable but comes at the cost of additional effort that IMHO isn''t justifyable. I''d vote for a strict seperation of HTML and CSS, throw in most stuff of "bigger chunks" of client side behavior into .js files, and let the Rails framework do it''s job by inserting events and little "scriptlets" inside the structure to call upon the external funtionality in the .js files. Thomas Am 29.06.2005 um 15:14 schrieb Michael Schuerig:> I''m not yet completely convinced of the value of hiding scripts > away and > I''m definitely unsure if it would be worth the effort -- regarding > implementation and possible execution speed penalty.
With a big disclaimer that I haven''t actually tried this myself, someone on IRC indicated that using this library made it much easier to make forms that gracefully degraded if javascript is not present. Not something everyone worries about I know, but worth bearing in mind. Chris On 6/29/05, Thomas Fuchs <thomas@fesch.at> wrote:> I concur. Besides packing any addtional functions you might need in > your app > in it''s own js file (or files), the built-in functions just generate > comparably small calls > to prototype.js and the script.aculo.us libs. > > Also, with the upload-progress patch that is now in trunk, it''s > possible to use <script> > tags inside Ajax returns that are then executed. > > A complete seperation of client-side page structure (XHTML), design > (CSS) and > behaviour/logic (inside .js files) is achievable but comes at the > cost of additional > effort that IMHO isn''t justifyable. > > I''d vote for a strict seperation of HTML and CSS, throw in most stuff > of "bigger chunks" of > client side behavior into .js files, and let the Rails framework do > it''s job by inserting > events and little "scriptlets" inside the structure to call upon the > external funtionality > in the .js files. > > Thomas > > Am 29.06.2005 um 15:14 schrieb Michael Schuerig: > > > I''m not yet completely convinced of the value of hiding scripts > > away and > > I''m definitely unsure if it would be worth the effort -- regarding > > implementation and possible execution speed penalty. > _______________________________________________ > Rails-spinoffs mailing list > Rails-spinoffs@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs >
On 6/29/05, Chris McGrath <c.r.mcgrath@gmail.com> wrote:> With a big disclaimer that I haven''t actually tried this myself, > someone on IRC indicated that using this library made it much easier > to make forms that gracefully degraded if javascript is not present. > Not something everyone worries about I know, but worth bearing in > mind.It''s not difficult to make your ajax operations backwards compatible. You can easily specify real urls for remote forms and links, so I''m not sure what the fuss was about. Here''s a quick sample of mine. You can override the link href with the html_options hash to point to a real page. link_to_remote(''Show Bid History'', {:url => (url bid_history_url(:guid => @billboard.guid)), {:href => url, :id => ''bid_history_link''}) -- rick http://techno-weenie.net
On 29/06/2005, at 11:14 PM, Michael Schuerig wrote:> Currently, pages generated by Rails tend to be sprinkled with > JavaScript. This happens, because the various helper methods work only > locally and simply append to the output. > > In order to hide the JavaScript away, rendering would probably have to > be changed. A way I can think of is that a page-specific script is > included in the head of the document and JavaScript code is not written > to the main document, but to the script file instead. > > I''m not yet completely convinced of the value of hiding scripts away > and > I''m definitely unsure if it would be worth the effort -- regarding > implementation and possible execution speed penalty. > > Do you have any opinions and ideas concerning this topic?Why not have an app helper duo that uses the Behaviour JS method to include the relevant JS in the head of the document? For example, I use the following helper in views to declare I need a JS file: def require_javascript(javascript) @javascripts ||= [] unless @javascripts.include? javascript @javascripts << javascript end end Then I use the following in the head (which should really go into another helper method): <% unless @javascripts.nil? -%> <% for jscript in @javascripts -%> <%= javascript_include_tag(jscript) %> <% end -%> <% end -%> We could do a similar thing where the javascript helper methods ''require'' JS statements, which then get included in the head. Problems with this approach could be a change in the API (maybe?) and fragment caching. I don''t think putting JS into a separate dynamically served file would be worth it for performance and complexity. -- tim lucas
Tim - that is a nicely clever technique, which decently addresses the thing I like least about Rails. Some background: I''ve been developing component-oriented applications using Tapestry for a long while now and in the past I did some WebObjects (we''ll skip over the *ahem* Struts era). I''ve mostly thought of Rails erb-based templating to be JSP-like where you have helpers that are essentially tag libraries. (sorry if my Java analogies don''t strike a chord). But because views get rendered before layouts, tricks like what Tim shows make it different from the top-down rendering of JSP. In Tapestry, for example, simply using a DatePicker component adds a common DatePicker <script> section to the <head> appropriately with no other consideration for that JavaScript anywhere - and it also adds some instance-specific JavaScript that can hook into onload. All of this just magically hooks in by using the DatePicker component once. And if it is used multiple times in the same page, the common script section is only imported once as it should be. Techniques like what Tim shows will dramatically improve templating and avoid the spaghetti mess of CSS, JavaScript, and HTML all being munged together. The "behavior" techniques of applying scripting to elements based on CSS classes jives with this sort of thing and could really be made into a pretty elegant feature of Rails - though it would require some overhaul of the helpers I suspect to get them to play well - or perhaps an alternate set of helpers that provide these features. Thoughts? Erik p.s. Can we set reply-to for this list to go back to the list? On Jun 29, 2005, at 9:49 PM, Tim Lucas wrote:> On 29/06/2005, at 11:14 PM, Michael Schuerig wrote: > > >> Currently, pages generated by Rails tend to be sprinkled with >> JavaScript. This happens, because the various helper methods work >> only >> locally and simply append to the output. >> >> In order to hide the JavaScript away, rendering would probably >> have to >> be changed. A way I can think of is that a page-specific script is >> included in the head of the document and JavaScript code is not >> written >> to the main document, but to the script file instead. >> >> I''m not yet completely convinced of the value of hiding scripts >> away and >> I''m definitely unsure if it would be worth the effort -- regarding >> implementation and possible execution speed penalty. >> >> Do you have any opinions and ideas concerning this topic? >> >> > > Why not have an app helper duo that uses the Behaviour JS method to > include the relevant JS in the head of the document? > > For example, I use the following helper in views to declare I need > a JS file: > def require_javascript(javascript) > @javascripts ||= [] > unless @javascripts.include? javascript > @javascripts << javascript > end > end > > Then I use the following in the head (which should really go into > another helper method): > <% unless @javascripts.nil? -%> > <% for jscript in @javascripts -%> > <%= javascript_include_tag(jscript) %> > <% end -%> > <% end -%> > > We could do a similar thing where the javascript helper methods > ''require'' JS statements, which then get included in the head. > > Problems with this approach could be a change in the API (maybe?) > and fragment caching. > > I don''t think putting JS into a separate dynamically served file > would be worth it for performance and complexity. > > -- tim lucas > > _______________________________________________ > Rails-spinoffs mailing list > Rails-spinoffs@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs > >
> On Thursday 30 June 2005 03:49, Tim Lucas wrote: >> Why not have an app helper duo that uses the Behaviour JS method to >> include the relevant JS in the head of the document?On Thursday 30 June 2005 04:09, Erik Hatcher wrote:> Techniques like what Tim shows will dramatically improve templating ? > and avoid the spaghetti mess of CSS, JavaScript, and HTML all being ? > munged together. ?The "behavior" techniques of applying scripting to > ? elements based on CSS classes jives with this sort of thing and > could really be made into a pretty elegant feature of Rails - though > it would require some overhaul of the helpers I suspect to get them > to play well - or perhaps an alternate set of helpers that provide > these features.I''m not convinced that this technique works for pages with a dynamic structure. Say, pages where the existence or count of specific elements depends on conditions/loops. AFAICT, CSS selectors are not sufficient to pick out elements in cases like these. Michael -- Michael Schuerig Those people who smile a lot mailto:michael@schuerig.de Watch the eyes http://www.schuerig.de/michael/ --Ani DiFranco, Outta Me, Onto You
Michael Schuerig wrote:>On Thursday 30 June 2005 04:09, Erik Hatcher wrote: > > >>Techniques like what Tim shows will dramatically improve templating >>and avoid the spaghetti mess of CSS, JavaScript, and HTML all being >>munged together. The "behavior" techniques of applying scripting to >> elements based on CSS classes jives with this sort of thing and >>could really be made into a pretty elegant feature of Rails - though >>it would require some overhaul of the helpers I suspect to get them >>to play well - or perhaps an alternate set of helpers that provide >>these features. >> >> > >I''m not convinced that this technique works for pages with a dynamic >structure. Say, pages where the existence or count of specific elements >depends on conditions/loops. AFAICT, CSS selectors are not sufficient >to pick out elements in cases like these. > >Michael > >The technique is good for replacing elements onload via the DOM, or enhancing items etc... But I''d agree that it''s not necessarily a technique that applies itself to It''s always worth keeping in mind though to ensure that the site works without the JS elements. Things like graceful degredation are essential. The JS section of my site has a number of examples of this http://livsey.org/category/web-dev/js/ Most notabley, ''javascript and clean html'' http://livsey.org/2005/03/11/javascript-and-clean-html/ Textarea tools http://livsey.org/2005/01/30/textarea-tools-update/ And the JS multiselect http://livsey.org/2005/02/03/js-multiselect/