Daniel Smedegaard Buus
2007-Mar-25 16:34 UTC
Javascript disappears from my view partials when they''re rendered as response to ajax calls.
Hey people :) I''m having some serious trouble understanding what''s going on with my application ATM. I am creating a manager for tree structures with drag-and-drop functionality and such. It''s very generic, so it makes no assumptions about the objects it works on (apart from the existence of ids and parent_ids in the objects). It sort of wraps around partials that are specific to the models that go in the tree, one partial for viewing, and one for when you''re creating new model instances inside the tree. That means I have a create link on nodes (that are saved and thus have an id) that creates a preset child node of the current node by assigning the current node''s id value to the child node id, then renders the forementioned partial that is used to edit the actual data fields of the object in the node. Because I want a generic approach, I don''t want to make any assumptions about how these partials are implemented, and I tried to put as little demand as possible on what they needed to be able to do. So far, the only thing I absolutely need to know ("I" being the tree, or more precisely, the parent node of the soon-to-be child node that has just been rendered after the user clicked the "create new child node of this node" link) is when the child node''s editor has saved the new child node successfully. I need to know that, so that I can add, e.g. a "create new child node" link to the child node that has just been saved. I figured I''d do that using javascript callbacks, since everything is ajax anyway, so existing nodes stay pretty much the same "internally" (inside their surrounding divs) even if new leaf nodes are added or nodes are moved around. So, I thought that for new nodes, I''d generate and pass on a javascript callback function which was to be called by the editor partial after it had saved the node successfully and thus caused it to have a unique id, and be allowed to have its own child nodes. However, and this is where it gets weird, I cannot seem to get any kind of javascript to render in my views when the views are rendered as a response to an ajax request, like link_to_remote, or remote_function. Put simply, if I refresh my page, as in a regular GET html request, this causes the root nodes to be drawn in a "standard" way (index.rhtml iterates over nodes, and renders the partial ''tree_node'' for each), then I can inspect the DOM in firebug and confirm that all script portions of the partial view are rendered correctly, e.g. <script type="text/javascript">alert(''hello'');</script> This not only alerts ''hello'', the script tags and contents are also visible in firebug. But, if I then expand one of these root node, which means triggering a link_to_remote that causes the exact same view partial to be rendered into a "children" div, the scripts "disappear". Depending on where I put the scripts in the partial, I might get an alert box greeting me, but the script is nowhere to be found in firebug regardless. And, if I actually define a callback and try to call it, either from a nested partial, or by typing it into the address line of the browser, I simply get the response that it isn''t defined... I am totally stomped! Please, please, someone help me find out what''s going on here... I''m frustrated beyond what''s healthy. Cheers and thanks in advance for any pointers, Daniel --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Long
2007-Mar-25 18:26 UTC
Re: Javascript disappears from my view partials when they''re rendered as response to ajax calls.
Daniel Smedegaard Buus wrote:>[snip]> > However, and this is where it gets weird, I cannot seem to get any > kind of javascript to render in my views when the views are rendered > as a response to an ajax request, like link_to_remote, or > remote_function. > > Put simply, if I refresh my page, as in a regular GET html request, > this causes the root nodes to be drawn in a "standard" way > (index.rhtml iterates over nodes, and renders the partial ''tree_node'' > for each), then I can inspect the DOM in firebug and confirm that all > script portions of the partial view are rendered correctly, e.g. > <script type="text/javascript">alert(''hello'');</script> >I wonder if you have the evalScripts option turned ON in your AJAX call. Check the prototype API for more detail. http://www.prototypejs.org/api/ajax/updater -- Long http://MeandmyCity.com/ - Free online business directory for local communities http://edgesoft.ca/blog/read/2 - No-Cookie Session Support plugin for Rails --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hi, Is the disappearing script contained within the partial that''s being re-rendered? If so, move it to a page level. I was doing the same kinda thing when partials being rendered / re-rendered contained javascript needed to do app-specific stuff. Hope this helps! Shawn -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Daniel Smedegaard Buus
2007-Mar-26 08:02 UTC
Re: Javascript disappears from my view partials when they''re rendered as response to ajax calls.
On Mar 25, 8:26 pm, "Long" <long...-bJEeYj9oJeDQT0dZR+AlfA@public.gmane.org> wrote:> > I wonder if you have the evalScripts option turned ON in your AJAX call. > Check the prototype API for more detail. > > http://www.prototypejs.org/api/ajax/updater >Hi Long, thanks for your reply :) It does seem like a possibility. I just don''t know how to test for that? Or how to turn it off... Do you know? Cheers, Daniel :) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Daniel Smedegaard Buus
2007-Mar-26 08:07 UTC
Re: Javascript disappears from my view partials when they''re
On Mar 26, 5:54 am, Shawn <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> Hi, >Hi Shawn, thanks for writing back :)> Is the disappearing script contained within the partial that''s being > re-rendered? >Yes, it is.> If so, move it to a page level. I was doing the same kinda thing when > partials being rendered / re-rendered contained javascript needed to do > app-specific stuff. >I think that would fix it, yes. Only thing is, I need the context to be that of the current node. The call is different for each node... But, it really _should_ be just one function, taking two parameters, the div to reload, and the id of the node content object to use for that operation. I think I''d better work towards doing what you say, and getting that script down at page level. That would also save a lot of memory and bandwidth.> Hope this helps! >I''ll try it out and see if I can make it work! Thanks for the tip :) Will report back! Daniel :)> Shawn > > -- > Posted viahttp://www.ruby-forum.com/.--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Conrad Taylor
2007-Mar-26 08:13 UTC
Re: Javascript disappears from my view partials when they''re rendered as response to ajax calls.
Hey, if you post the relevant code, then people within this group can better assist you. For example, view, partials, and other relevant code. -Conrad On 3/26/07, Daniel Smedegaard Buus <danielbuus-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > > > On Mar 25, 8:26 pm, "Long" <long...-bJEeYj9oJeDQT0dZR+AlfA@public.gmane.org> wrote: > > > > I wonder if you have the evalScripts option turned ON in your AJAX call. > > Check the prototype API for more detail. > > > > http://www.prototypejs.org/api/ajax/updater > > > > Hi Long, thanks for your reply :) > > It does seem like a possibility. I just don''t know how to test for > that? Or how to turn it off... Do you know? > > Cheers, > Daniel :) > > > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Daniel Smedegaard Buus
2007-Mar-26 08:27 UTC
Re: Javascript disappears from my view partials when they''re rendered as response to ajax calls.
On Mar 26, 10:13 am, "Conrad Taylor" <conra...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hey, if you post the relevant code, then people within this group can > better assist you. For example, view, partials, and other relevant > code. >Alright :) Here goes, but I''m in the middle of making that js function generic, so it''s not all kosher there ;) Also, note that I pass along :update, :partial, and optionally :partial_on_failure on my remote requests. This is because I need to update more than one thing when rendering the results (I''ve created a status console div that pops up with error messages for models, and notices and warnings) - I handle these params myself, and shouldn''t be considered equivalent to those normally placed in the options hash for remote requests. Here''s the code: <% # Get the controller name from the locals hash (if someone initialized us), from the params (if we called ourselves), # or from the controller that was called which resulted in this view being rendered. controller_name ||= params[:poly_tree_controller_name] || request.parameters[''controller''] || raise("I need to know what controller to query when doing stuff with the tree nodes!") # Get the node from the locals hash, or look for one instantiated in the controller: node_instance_name = controller_name.singularize.sub(/^.+\//, '''') node = node || instance_variable_get("@#{node_instance_name}") || raise("I need a node to start rendering the tree!") # Get the class for the node: node_class = Kernel.const_get(node.class.to_s) # Did we get a parent_content_id via params? parent_content_id = params[:poly_tree_parent_content_id] # Also, when rendering children, we actually send the parent, then state that we want the children. Let''s remember the parent''s id: parent_node_id = node.id # Check if we''re supposed to render the children rather than the node itself: expanded = (params[:poly_tree_expanded] && params[:poly_tree_expanded] == ''true'') # If we are, we throw the children in an array, otherwise we just through this node in an array: nodes = expanded ? node.children : [node] # Get a content_partial and create_partial from the locals hash (if someone initialized us), # from the params (if we called ourselves), or try defaults in the appropriate view directory: content_partial ||= params[:poly_tree_content_partial] || "/ #{controller_name}/tree_node" create_partial ||= params[:poly_tree_create_partial] || "/ #{controller_name}/edit" # Is this an unsaved model? model_is_unsaved = node.id.nil? # Is this create mode? create_new_after_render (params[:poly_tree_create_new_after_render] && params[:poly_tree_create_new_after_render] == ''true'') # Render whichever nodes we''re supposed to render: nodes.each { |node| content_element_id = model_is_unsaved ? "new_child_node_#{Time.now.to_f.to_s.gsub(/ \./,'''')}_of_#{node_instance_name}_#{node.parent_id}" : "tree_node_for_#{node_instance_name}_#{node.id}" %> # HERE''S ME CURRENTLY EDITING THIS FUNCTION, SO EXPECT THINGS TO BE BROKEN ;) <%= ("function #{reload_function}(target_element_id, model_id) {" + (remote_function(:url => { :controller => controller_name, :action => :show, :id => ''___model_id___'', :poly_tree_expanded => ''false'', :poly_tree_content_partial => content_partial, :poly_tree_create_partial => create_partial, :update => ''___target_element_id___'', :partial => ''/ tree_node'' }, :before => "Element.show(''#{content_element_id}_activity_indicator'')", :success => "Element.hide(''#{content_element_id}_collapse_button'');Element.show(''#{content_element_id}_expand_button'');", :complete => "Element.hide(''#{content_element_id}_activity_indicator'')")) + ";}").gsub(/___model_id___/, "'' + model_id + ''").gsub(/ ___target_element_id___/, "'' + target_element_id + ''").in_javascript_tags %> <div id="<%= content_element_id %>" class="tree_node"> <%= # This one tags this node as having a parent. Later, after this item is deleted, we can use javascript to check for the existance of this id. # Knowing that our siblings will be tagged with the same id, if we get a positive, then we know that siblings still exist, if not, we know that # the parent is now childless and should not be show expand/ collapse buttons anymore. ''<div id="'' + parent_content_id + ''_child"></div>'' if parent_content_id %> <div class="tools"> <!-- Delete button --> <span id="<%= content_element_id %>_delete_button"<%= '' style="display:none;"'' if model_is_unsaved %>> <%= link_to_remote( icon_for_backend_list_delete, :url => { :controller => controller_name, :action => :delete, :id => node.id, :poly_tree_expanded => params[:poly_tree_expanded], :poly_tree_content_partial => content_partial, :poly_tree_create_partial => create_partial, :update => content_element_id, :partial => ''/nothing'', :partial_on_failure => ''/tree_node'' }, :before => "Element.show(''#{content_element_id}_activity_indicator'')", :complete => "if ($ (''#{parent_content_id}_child'') == null) { Element.hide(''#{parent_content_id}_collapse_button''); };" ) %> </span> <!-- Expand button --> <span id="<%= content_element_id %>_expand_button"<%= '' style="display:none;"'' unless node.children.size > 0 %>> <%= link_to_remote( icon_for_backend_list_expand, :url => { :controller => controller_name, :action => :show, :id => node.id, :poly_tree_expanded => ''true'', :poly_tree_content_partial => content_partial, :poly_tree_create_partial => create_partial, :poly_tree_parent_content_id => content_element_id, :update => "#{content_element_id}_children", :partial => ''/tree_node'', :insert_at => ''top'' }, :before => "Element.show(''#{content_element_id}_activity_indicator'')", :success => "Element.show(''#{content_element_id}_collapse_button'');Element.hide(''#{content_element_id}_expand_button'');Element.show(''#{content_element_id}_expanded_create_button'');Element.hide(''#{content_element_id}_collapsed_create_button'');", :complete => "Element.hide(''#{content_element_id}_activity_indicator'')") %> </span> <!-- Collapse button --> <span id="<%= content_element_id %>_collapse_button" style="display:none;"> <%= link_to_remote( icon_for_backend_list_collapse, :url => { :controller => controller_name, :action => :show, :id => node.id, :poly_tree_expanded => ''false'', :poly_tree_content_partial => content_partial, :poly_tree_create_partial => create_partial, :update => content_element_id, :partial => ''/tree_node'' }, :before => "Element.show(''#{content_element_id}_activity_indicator'')", :success => "Element.hide(''#{content_element_id}_collapse_button'');Element.show(''#{content_element_id}_expand_button'');", :complete => "Element.hide(''#{content_element_id}_activity_indicator'')" ) %> </span> <!-- Create button when expanded --> <span id="<%= content_element_id %>_expanded_create_button" style="display:none;"> <%= link_to_remote(''expanded_create'', :url => { :controller => controller_name, :action => :create, :poly_tree_expanded => ''false'', :poly_tree_content_partial => content_partial, :poly_tree_create_partial => create_partial, :poly_tree_parent_content_id => parent_content_id, :update => "#{content_element_id}_children", :partial => ''/tree_node'', :partial_on_failure => ''/nothing'', :insert_at => ''top'' }, :before => "Element.show(''#{content_element_id}_activity_indicator'')", # We show the activity indicator in our parent. :complete => "Element.hide(''#{content_element_id}_activity_indicator'')", # Afterwards, we remove this intermediate DIV element. :with => "''#{node_instance_name} [parent_id]=#{node.id}''") %> </span> <!-- Create button when collapsed --> <span id="<%= content_element_id %>_collapsed_create_button"< %= '' style="display:none;'' if model_is_unsaved %>"> <%link_to_remote( ''collapsed_create'',#icon_for_backend_list_create, :url => { :controller => controller_name, :action => :show, :id => node.id, :poly_tree_expanded => ''true'', :poly_tree_content_partial => content_partial, :poly_tree_create_partial => create_partial, :poly_tree_parent_content_id => content_element_id, :poly_tree_create_new_after_render => ''true'', :update => "#{content_element_id}_children", :partial => ''/tree_node'', :insert_at => ''top'' }, :before => "Element.show(''#{content_element_id}_activity_indicator'')", :success => "Element.show(''#{content_element_id}_collapse_button'');Element.hide(''#{content_element_id}_expand_button'');Element.show(''#{content_element_id}_expanded_create_button'');Element.hide(''#{content_element_id}_collapsed_create_button'');", :complete => "Element.hide(''#{content_element_id}_activity_indicator'')") %> </span> <!-- Cancel button when creating --> <span id="<%= content_element_id %>_cancel_create_button"<%= '' style="display:none;'' unless model_is_unsaved %>"> <%= link_to_function( icon_for_backend_close, "Element.remove(''#{content_element_id}''); if ($ (''#{parent_content_id}_child'') == null) { Element.hide(''#{parent_content_id}_collapse_button''); Element.show(''#{parent_content_id}_collapsed_create_button''); Element.hide(''#{parent_content_id}_expanded_create_button''); };") %> </span> <%activity_indicator("#{content_element_id}_activity_indicator") %> </div> <div class="content"> <% if model_is_unsaved %> <%= render :partial => create_partial, :locals => { node_instance_name.to_sym => node, :after_save_id_callback_function => callback_function_name } %> <% else %> <%= render :partial => content_partial, :locals => { node_instance_name.to_sym => node } %> <% end %> </div> <% unless model_is_unsaved %> <div id="<%= content_element_id %>_children" class="children"> </div> <% end %> </div> <% } %> <% # Here we check if we''re supposed to automatically create a new node after an expansion. # - That''s how the "create new" button works when a node is collapsed, it expands the node # with an instruction about creating a new node after it''s had its children expanded into view. # # What we do is that we call the create function on the controller, telling it to use # whatever create partial has been determined for rendering, and to insert the results # at the top of our parent''s children element, then to remove the intermediate element # we create to perform this action. if create_new_after_render content_element_id "new_child_node_caller_#{Time.now.to_f.to_s.gsub(/ \./,'''')}_for_#{node_instance_name}_#{parent_node_id}" %> <div id="<%= content_element_id %>" style="display:none;"> <script type="text/javascript"> <%= remote_function(:url => { :controller => controller_name, :action => :create, :poly_tree_expanded => ''false'', :poly_tree_content_partial => content_partial, :poly_tree_create_partial => create_partial, :poly_tree_parent_content_id => parent_content_id, :update => "#{parent_content_id}_children", :partial => ''/tree_node'', :partial_on_failure => ''/nothing'', :insert_at => ''top'' }, :with => "''#{node_instance_name} [parent_id]=#{parent_node_id}''", # This is the preset values to make sure the created node has the right parent. :before => "Element.show(''#{parent_content_id}_activity_indicator'')", # We show the activity indicator in our parent. :complete => "Element.hide(''#{parent_content_id}_activity_indicator'');Element.remove(''#{content_element_id}'')") # Afterwards, we remove this intermediate DIV element. %>; </script> </div><% end %> --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Daniel Smedegaard Buus
2007-Mar-26 09:58 UTC
Re: Javascript disappears from my view partials when they''re
On Mar 26, 10:07 am, "Daniel Smedegaard Buus" <danielb...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I''ll try it out and see if I can make it work! Thanks for the tip :) > > Will report back! >Okay, so this actually worked out great. It''s a better approach anyway, and it took it one step farther, splitting the partial in two, a _tree partial which is the one you''d call giving it one or more root nodes, and a _tree_node partial, that the _tree partial calls initially, and each node can call individually afterwards when expanding, creating, etc. The _tree partial contains (in a few hours ;) all major javascript function, and the _tree_node partials will then call those javascript functions with the appropriate options. This should be faster and use less memory and bandwidth. The right way to go either way :) Thanks all, for your tips and efforts :) Daniel --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---