Hello, I realise this is a ruby group, but I''ve got this link from scriptaculous so I hope somebody can help. Apologies in advance if this is the wrong place to post this type of question. What I''m doing is reasonably simple in principle, but I''m not quite sure how best to approach it. I have a html page containing some JavaScript that reads nodes from an xml file and for each ''clipping node in the xml the javascript adds a div to my page (it contains some text or an image etc), I want each of these divs to be draggable. So that they can be dragged into the text area on my page which is droppable. Now it works fine in my simple test page where I know at design time what elements will need to be draggable. I just create a variable and stick it in the onload i.e. mydrag_1 = new Draggable(''clipping_1'',{revert:true,ghosting:true}); But as I don''t know how many clippings there will be at design time I can''t get it to work and I''m not sure how to approach it. A couple of things worth mentioning is that the draggable divs are not present for the onload, they appear when a user selects a category from a drop down list, JavaScript then loads the corresponding xml file and adds a div for each clipping to the html page. What I would like is a way of looping through and making all the clipping divs (they each have a unique id) draggable. I will know the ids of all the divs I need to make draggable. I would also like to be able to toggle the dragging on and off (as I have done in my test), this would be useful if a user for example wishes to highlight only a section of the div and not drag the whole div. Below is my working test page with hard coded draggable elements to hopefully give a better understanding of what I want to achive. What I would like to be able to do it enable and disable the draggable divs as I need to: Javascript var mydrag_1; var draggingEnabled; window.onload=function(){ mydrag_1 = new Draggable(''clipping_1'',{revert:true,ghosting:true}); mydrag_2 = new Draggable(''clipping_2'',{revert:true,ghosting:true}); mydrag_3 = new Draggable(''clipping_3'',{revert:true,ghosting:true}); Droppables.add(''docText'', { accept: ''clipping'', onDrop: function(element) { var obj = document.getElementById("docText"); obj.value += element.innerHTML; } }); draggingEnabled = true; } function switchDragging(element) { if (draggingEnabled == true) { disableDragging(); element.innerHTML = ''Enable Block Dragging''; draggingEnabled = false; } else { enableDragging(); element.innerHTML = ''Disable Block Dragging''; draggingEnabled = true; } } function enableDragging() { mydrag_1 = new Draggable(''clipping_1'',{revert:true,ghosting:true}); mydrag_2 = new Draggable(''clipping_2'',{revert:true,ghosting:true}); mydrag_3 = new Draggable(''clipping_3'',{revert:true,ghosting:true}); } function disableDragging() { mydrag_1.destroy(); mydrag_2.destroy(); mydrag_3.destroy(); } HTML <div id="dragDiv"><a href="javascript: switchDragging(this)" onclick="switchDragging(this); return false;">Disable Block Dragging</ a></div> <textarea cols="55" rows="30" id="docText"></textarea> <div id="clipping_1" class="clipping"><b>one</b> Proin molestie quam. Sed non felis eu mi auctor semper.</div> <div id="clipping_2" class="clipping"><b>two</b> Consectetuer adipiscing elit.</div> <div id="clipping_3" class="clipping"><b>three</b> Lorem ipsum dolor sit amet</div> If anyone is able to offer any advice I''d be very grateful. Thanks in advance Mark --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Christophe Porteneuve
2007-Feb-20 13:29 UTC
Re: Drag and Drop - dynamically enable/disable dragging - how?
Hey Mark, Mark a écrit :> I realise this is a ruby group, but I''ve got this link fromIt''s not a Ruby group at all. We only use Ruby code when we explain usage of Rail''s spinoffs-related helpers. This group focuses on Prototype and script.aculo.us.> But as I don''t know how many clippings there will be at design time I > can''t get it to work and I''m not sure how to approach it.Your client-side, JS code parses your XML data to create the DIVs. I assume it can determines which ones need to become draggable. So why not just add the new Draggable call to them after inserting them in the DOM? BTW, I assume your page will also remove previous DIV sets to replace them with new ones when your user selects some other option? If that is the case, you may want to be über-clean and deregister the draggable for the previous DIVs. Failing to do so won''t prevent your page from working, but it unnecessarily holds onto a few resources.> What I would like is a way of looping through and making all the > clipping divs (they each have a unique id) draggable. I will know theDoesn''t your XML-parsing JS code already do this? I mean, it sounds like it is responsible fro creating the DIVs anyway, so it doesn''t even need their IDs: it has their HTMLElement references already.> able to toggle the dragging on and off (as I have done in my test), > this would be useful if a user for example wishes to highlight only a > section of the div and not drag the whole div.AFAIK, toggling the behavior requires destroying the draggable (calling destroy() on the reference you got back when doing new Draggable). You would then recreate it later by using new Draggable again. Of course, this means you keep a list of your Draggable objects somewhere... -- Christophe Porteneuve aka TDD tdd-x+CfDp/qHev2eFz/2MeuCQ@public.gmane.org --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Hi Christophe, Many thanks for your response, it is much appreciated.> Your client-side, JS code parses your XML data to create the DIVs. I > assume it can determines which ones need to become draggable. So why > not just add the new Draggable call to them after inserting them in the DOM?Yes my javscript runs through the XML and creates the divs, so if I knew how to associate them here I would. So far I have only used the calls in the onload i.e. window.onload=function() { mydrag_1 = new Draggable(''clipping_1'', {revert:true,ghosting:true}); mydrag_2 = new Draggable(''clipping_2'', {revert:true,ghosting:true}); mydrag_3 = new Draggable(''clipping_3'', {revert:true,ghosting:true}); } I think this is the biggest reason for me having problems, I''m not quite sure how else to apply the calls, or get a handle on draggable objects that haven''t been specifically associated with a global variable. How would I apply the draggable call to the div when I''m creating it at run time?> BTW, I assume your page will also remove previous DIV sets to replace > them with new ones when your user selects some other option? If that is > the case, you may want to be über-clean and deregister the draggable for > the previous DIVs. Failing to do so won''t prevent your page from > working, but it unnecessarily holds onto a few resources.Yes when the user selects a different category from the drop down list the clipping divs are all removed from the DOM and the new ones added. I would want to deregister the draggable divs when they were removed if possible, again I''m not sure how I would get a handle on them to remove them (I''m sure this will make more sense when I see how to apply the draggable call to the divs during creation in the first place).> Doesn''t your XML-parsing JS code already do this? I mean, it sounds > like it is responsible fro creating the DIVs anyway, so it doesn''t even > need their IDs: it has their HTMLElement references already.Yes my XML does loop through and create the divs, I would love to add the dragable calls here, I''m just really not sure how. I have read the info on the scriptaculous wiki and I''m still none the wiser. If I want to add the calls in the onload then no worries, it works absolutley fine (as in my example above) otherwise I''m really not too sure. Perhaps I''m just being a bit silly, but I would definitley appreciate any examples etc.> AFAIK, toggling the behavior requires destroying the draggable (calling > destroy() on the reference you got back when doing new Draggable). You > would then recreate it later by using new Draggable again.Yes, in my static example above I disable and enabled the dragging by setting global variables with the create draggable calls then calling destroy on them i.e. function disableDragging() { mydrag_1.destroy(); mydrag_2.destroy(); mydrag_3.destroy(); } But again (and this is really my confusion in a nutshell at the moment) I''m not sure how I would destroy the draggable behaviour if I haven''t got a variable to call destroy on. Again a code example or something would be a great deal of help. I really just need to understand how to dynamically apply and remove the draggable behaviour rather than just having static elements setup at design time. Thanks again for taking the time to reply. Mark --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Christophe Porteneuve
2007-Feb-20 15:00 UTC
Re: Drag and Drop - dynamically enable/disable dragging - how?
Hey Mark, Mark a écrit :> window.onload=function()First, don''t do that. Please :-) Use this: Event.observe(window, ''load'', function() {...});> variable. How would I apply the draggable call to the div when I''m > creating it at run time?Right after you create those. OK, let''s say I''m smack in your XML parsing code. It probably goes something like this: // general loop over some XML nodeset -- n is the current node var div = document.createElement(''DIV''); div.id = ''clipping_'' + ....; ... someParentNode.appendChild(div); // end of loop Am I right? Now, what you can do is this, right after appendChild: div._myDraggable = new Draggable(div, { ...options... }); That takes care of the creation time. Now, the code that strips existing DIVs from their container before creating new ones in their stead could go like this: 1) Fetch the DIVs. If these are the only children of your container, go like this: var divs = $(''containerId'').immediateDescendants(); If there are other things, but they have a specific class: var divs = $(''containerId'').getElementsByClassName(''clipping''); If they only have their ID pattern to identify them, go like this: var divs = $(''containerId'').immediateDescendants().select( function(div) { return div.id.startsWith(''clipping_''); }); Now, you can deregister their draggables: divs.each(function(div) { div._myDraggable.destroy(); }); And you can remove them (either on the fly, in the callback function: divs.each(function(div) { div.remove()._myDraggable.destroy(); }); Or by clearing the container: $(''containerId'').update(''''); However, you might want to split deregistration and removal, since the fetch-and-destroy-draggable bit can be used for toggling dragging off, as well. And symetric code can be used for toggling it on (reusing the create-and-assign line described earlier). ''HTH -- Christophe Porteneuve aka TDD tdd-x+CfDp/qHev2eFz/2MeuCQ@public.gmane.org --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Thats fantastic Christophe, thank you very much for your help. It all makes much more sense now, I''m going to go and have a play. I''ll be sure to come back and let you know how I get on. Once again thank you very much for taking the time out to help, you''re a gent!! Many thanks Mark On Feb 20, 3:00 pm, Christophe Porteneuve <t...-x+CfDp/qHev2eFz/2MeuCQ@public.gmane.org> wrote:> Hey Mark, > > Mark a écrit : > > > window.onload=function() > > First, don''t do that. Please :-) Use this: > > Event.observe(window, ''load'', function() {...}); > > > variable. How would I apply the draggable call to the div when I''m > > creating it at run time? > > Right after you create those. OK, let''s say I''m smack in your XML > parsing code. It probably goes something like this: > > // general loop over some XML nodeset -- n is the current node > var div = document.createElement(''DIV''); > div.id = ''clipping_'' + ....; > ... > someParentNode.appendChild(div); > // end of loop > > Am I right? > > Now, what you can do is this, right after appendChild: > > div._myDraggable = new Draggable(div, { ...options... }); > > That takes care of the creation time. > > Now, the code that strips existing DIVs from their container before > creating new ones in their stead could go like this: > > 1) Fetch the DIVs. If these are the only children of your container, > go like this: > > var divs = $(''containerId'').immediateDescendants(); > > If there are other things, but they have a specific class: > > var divs = $(''containerId'').getElementsByClassName(''clipping''); > > If they only have their ID pattern to identify them, go like this: > > var divs = $(''containerId'').immediateDescendants().select( > function(div) { return div.id.startsWith(''clipping_''); }); > > Now, you can deregister their draggables: > > divs.each(function(div) { div._myDraggable.destroy(); }); > > And you can remove them (either on the fly, in the callback function: > > divs.each(function(div) { div.remove()._myDraggable.destroy(); }); > > Or by clearing the container: > > $(''containerId'').update(''''); > > However, you might want to split deregistration and removal, since the > fetch-and-destroy-draggable bit can be used for toggling dragging off, > as well. And symetric code can be used for toggling it on (reusing the > create-and-assign line described earlier). > > ''HTH > > -- > Christophe Porteneuve aka TDD > t...-x+CfDp/qHev2eFz/2MeuCQ@public.gmane.org--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Hi Christophe, Many thanks for your help, with the above information I was able to do exactly what I needed to. I was really just missing the information on the _myDraggable handle. So thank you for all your help, it was VERY useful indeed. I do now have another slight problem, but I''m not sure if this is a query for a new thread or to be continued here, so initially I''ll post it here. Now I have used the above and I have my HTML page, with javascript loading nodes from an xml file and creating divs dynamically, removing and creating draggable divs as required etc. It''s working fine from that perspective. I have a text area on the right side of the screen (TinyMCE but that is irrelevant in this issue) and a scrollable div on the left side of the screen which the clippings divs are loaded into. After a little bit of experimentation I am now able to load my clipping divs into the scrollable div and then drag my clipping divs from the scrollable div to the text area and update it. So that was my initial goal. The only problem I have is that if I scroll down within my scrollable div for a clipping and I then drag it, for a split second when I begin to drag I see the ghost image loaded further down the page (i.e. the location it would have been when the div was registered as a draggable item), then it quickly updates and I''m able to drag it etc. I am using the following settings when creating my draggable divs: obj._myDraggable = new Draggable(obj,{revert:true,ghosting:true}); It is the ghost that is the problem, if I turn the ghosting off then there is no problem. I can drag from where the item is in the scrolling div and there is no unexpected behaviours. However I think the ghost is required if possible as it provides exactly the look/user experience I had in mind. The thing is it just looks as though there is something wrong with it for a split second from a user point of view. I''m wondering if there is anyway I can prevent this from happening, maybe by hiding the ghost while it recalculates the position initially then displaying it? I have read a few posts on the group with people talking about similar issues, this thread specifically deals with a similar issue: http://groups.google.com/group/rubyonrails-spinoffs/browse_thread/thread/4dbfa19d13742485/1c0c4d6082299ccf?lnk=gst&q=drag+scrolling&rnum=2# I hope I''ve explained myself properly. Does anyone have any ideas how I might go about resolving this issue? Any help would be much appreciated. Thanks again Mark --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---