Hi, Ive got a form for a blog post and there are 3 buttons - Publish, Preview and Save as Draft. Clicking on Preview should open a new window with the preview of the post without saving it while the current window stays on the "New Post" form. I dont want the post to be saved because, once the user views the preview and closes it, when he clicks on, say, Save as Draft on the form, a second post with the same details gets created. How can I achieve this functionality? On a side note, I also want to perform model validations only if the post is Published. Thought it might be relevant. Im quite stumped so any and all ideas are welcome :) Thanks.
Use a state machine. posts are initially in ''draft'' state, and thus can be previewed, but are not published. When publish is pressed, change the state to ''published''. You probably don''t even need to manage state transition formally. Just make sure when you display posts to get only published ones (use named_scope to make this more automatic). On Sep 9, 2009, at 10:49 PM, Ram wrote:> > Hi, > > Ive got a form for a blog post and there are 3 buttons - Publish, > Preview and Save as Draft. > > Clicking on Preview should open a new window with the preview of the > post without saving it while the current window stays on the "New > Post" form. I dont want the post to be saved because, once the user > views the preview and closes it, when he clicks on, say, Save as Draft > on the form, a second post with the same details gets created. How can > I achieve this functionality? > > On a side note, I also want to perform model validations only if the > post is Published. Thought it might be relevant. > > Im quite stumped so any and all ideas are welcome :) > > Thanks.
Hi ross, Thats what im doing right now. Im saving it as a Draft and rendering the show action for the instance @post as a preview. But that breaks 2 requirements, namely 1. The preview does not open in a new window.. its the same window. 2. There are no call to action buttons on the Preview page (there should not be any) and so when the user hits the back button, he''s taken back to the new post form where hitting Save as Draft saves a whole new post with the same data. Even if I manage to show the preview in a new window, i will still have the duplicating posts problem if i save it before previewing it. On Sep 10, 10:58 am, "s.ross" <cwdi...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Use a state machine. posts are initially in ''draft'' state, and thus > can be previewed, but are not published. When publish is pressed, > change the state to ''published''. You probably don''t even need to > manage state transition formally. Just make sure when you display > posts to get only published ones (use named_scope to make this more > automatic). > > On Sep 9, 2009, at 10:49 PM, Ram wrote: > > > > > > > Hi, > > > Ive got a form for a blog post and there are 3 buttons - Publish, > > Preview and Save as Draft. > > > Clicking on Preview should open a new window with the preview of the > > post without saving it while the current window stays on the "New > > Post" form. I dont want the post to be saved because, once the user > > views the preview and closes it, when he clicks on, say, Save as Draft > > on the form, a second post with the same details gets created. How can > > I achieve this functionality? > > > On a side note, I also want to perform model validations only if the > > post is Published. Thought it might be relevant. > > > Im quite stumped so any and all ideas are welcome :) > > > Thanks.
A simple solution for that, open the preview in new window <%= link_to "Preview", "url_path", :popup => true %> For avoiding duplication, check in DB: if any post was saved with the same attributes within a time range, if yes, most likely its a duplicate (you can see more in rails space book''s RESTful blog chapter) Thanks, Abhinav -- अभिनव http://twitter.com/abhinav On Thu, Sep 10, 2009 at 11:45 AM, Ram <yourstruly.vinay-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > Hi ross, > > Thats what im doing right now. Im saving it as a Draft and rendering > the show action for the instance @post as a preview. But that breaks 2 > requirements, namely > > 1. The preview does not open in a new window.. its the same window. > 2. There are no call to action buttons on the Preview page (there > should not be any) and so when the user hits the back button, he''s > taken back to the new post form where hitting Save as Draft saves a > whole new post with the same data. > > Even if I manage to show the preview in a new window, i will still > have the duplicating posts problem if i save it before previewing it. > > > On Sep 10, 10:58 am, "s.ross" <cwdi...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: >> Use a state machine. posts are initially in ''draft'' state, and thus >> can be previewed, but are not published. When publish is pressed, >> change the state to ''published''. You probably don''t even need to >> manage state transition formally. Just make sure when you display >> posts to get only published ones (use named_scope to make this more >> automatic). >> >> On Sep 9, 2009, at 10:49 PM, Ram wrote: >> >> >> >> >> >> > Hi, >> >> > Ive got a form for a blog post and there are 3 buttons - Publish, >> > Preview and Save as Draft. >> >> > Clicking on Preview should open a new window with the preview of the >> > post without saving it while the current window stays on the "New >> > Post" form. I dont want the post to be saved because, once the user >> > views the preview and closes it, when he clicks on, say, Save as Draft >> > on the form, a second post with the same details gets created. How can >> > I achieve this functionality? >> >> > On a side note, I also want to perform model validations only if the >> > post is Published. Thought it might be relevant. >> >> > Im quite stumped so any and all ideas are welcome :) >> >> > Thanks. > > >
Hi Abhinav, I was looking at this angle in the beginning but what would the "url_path" be? I basically need the resource''s show method but that is a member method and the path is incomplete without a model id in the parameters. However, the post is not saved and does not have an id yet. Is there a way to create a member method/route for a resource that does not require a model id? Checking in the DB to avid duplication isnt really elegant. I''d like to implement that as a last resort solution. It throws up other workflow problems too (if the user closes preview window and changes something in the form, how would u update the relevant model when the form is a POST form?). On Sep 10, 11:50 am, Abhinav Saxena <abhinav...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> A simple solution for that, open the preview in new window > > <%= link_to "Preview", "url_path", :popup => true %> > > For avoiding duplication, check in DB: if any post was saved with the > same attributes within a time range, if yes, most likely its a > duplicate (you can see more in rails space book''s RESTful blog > chapter) > > Thanks, > Abhinav > > -- > अभिनवhttp://twitter.com/abhinav > > > > On Thu, Sep 10, 2009 at 11:45 AM, Ram <yourstruly.vi...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > Hi ross, > > > Thats what im doing right now. Im saving it as a Draft and rendering > > the show action for the instance @post as a preview. But that breaks 2 > > requirements, namely > > > 1. The preview does not open in a new window.. its the same window. > > 2. There are no call to action buttons on the Preview page (there > > should not be any) and so when the user hits the back button, he''s > > taken back to the new post form where hitting Save as Draft saves a > > whole new post with the same data. > > > Even if I manage to show the preview in a new window, i will still > > have the duplicating posts problem if i save it before previewing it. > > > On Sep 10, 10:58 am, "s.ross" <cwdi...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > >> Use a state machine. posts are initially in ''draft'' state, and thus > >> can be previewed, but are not published. When publish is pressed, > >> change the state to ''published''. You probably don''t even need to > >> manage state transition formally. Just make sure when you display > >> posts to get only published ones (use named_scope to make this more > >> automatic). > > >> On Sep 9, 2009, at 10:49 PM, Ram wrote: > > >> > Hi, > > >> > Ive got a form for a blog post and there are 3 buttons - Publish, > >> > Preview and Save as Draft. > > >> > Clicking on Preview should open a new window with the preview of the > >> > post without saving it while the current window stays on the "New > >> > Post" form. I dont want the post to be saved because, once the user > >> > views the preview and closes it, when he clicks on, say, Save as Draft > >> > on the form, a second post with the same details gets created. How can > >> > I achieve this functionality? > > >> > On a side note, I also want to perform model validations only if the > >> > post is Published. Thought it might be relevant. > > >> > Im quite stumped so any and all ideas are welcome :) > > >> > Thanks.
As I see it, there are two ways of doing it: 1. As previously suggested, save it , but let the state be "preview", after a user saves it state can change to "draft". Essentially means as soon as user clicks on preview, you create in db and then you have an id 2. Othe way (I am not very sure about this): pass the content in params and in your preview action read from params and display. Not a very RESTful design I believe. Thanks, Abhinav -- अभिनव http://twitter.com/abhinav On Thu, Sep 10, 2009 at 12:41 PM, Ram <yourstruly.vinay-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > Hi Abhinav, > > I was looking at this angle in the beginning but what would the > "url_path" be? I basically need the resource''s show method but that is > a member method and the path is incomplete without a model id in the > parameters. However, the post is not saved and does not have an id > yet. Is there a way to create a member method/route for a resource > that does not require a model id? > > Checking in the DB to avid duplication isnt really elegant. I''d like > to implement that as a last resort solution. It throws up other > workflow problems too (if the user closes preview window and changes > something in the form, how would u update the relevant model when the > form is a POST form?). > > > On Sep 10, 11:50 am, Abhinav Saxena <abhinav...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: >> A simple solution for that, open the preview in new window >> >> <%= link_to "Preview", "url_path", :popup => true %> >> >> For avoiding duplication, check in DB: if any post was saved with the >> same attributes within a time range, if yes, most likely its a >> duplicate (you can see more in rails space book''s RESTful blog >> chapter) >> >> Thanks, >> Abhinav >> >> -- >> अभिनवhttp://twitter.com/abhinav >> >> >> >> On Thu, Sep 10, 2009 at 11:45 AM, Ram <yourstruly.vi...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: >> >> > Hi ross, >> >> > Thats what im doing right now. Im saving it as a Draft and rendering >> > the show action for the instance @post as a preview. But that breaks 2 >> > requirements, namely >> >> > 1. The preview does not open in a new window.. its the same window. >> > 2. There are no call to action buttons on the Preview page (there >> > should not be any) and so when the user hits the back button, he''s >> > taken back to the new post form where hitting Save as Draft saves a >> > whole new post with the same data. >> >> > Even if I manage to show the preview in a new window, i will still >> > have the duplicating posts problem if i save it before previewing it. >> >> > On Sep 10, 10:58 am, "s.ross" <cwdi...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: >> >> Use a state machine. posts are initially in ''draft'' state, and thus >> >> can be previewed, but are not published. When publish is pressed, >> >> change the state to ''published''. You probably don''t even need to >> >> manage state transition formally. Just make sure when you display >> >> posts to get only published ones (use named_scope to make this more >> >> automatic). >> >> >> On Sep 9, 2009, at 10:49 PM, Ram wrote: >> >> >> > Hi, >> >> >> > Ive got a form for a blog post and there are 3 buttons - Publish, >> >> > Preview and Save as Draft. >> >> >> > Clicking on Preview should open a new window with the preview of the >> >> > post without saving it while the current window stays on the "New >> >> > Post" form. I dont want the post to be saved because, once the user >> >> > views the preview and closes it, when he clicks on, say, Save as Draft >> >> > on the form, a second post with the same details gets created. How can >> >> > I achieve this functionality? >> >> >> > On a side note, I also want to perform model validations only if the >> >> > post is Published. Thought it might be relevant. >> >> >> > Im quite stumped so any and all ideas are welcome :) >> >> >> > Thanks. > > >
Hmm... haven''t tried this but: 1. add a div, usually hidden, to your ''new'' form, 2. on a ''preview'' request, pass the content back in the params to the new method 3. if params[:preview_data] (or whatever), have that content rendered in the div on the ''new'' form -- no preview content means the div stays hidden, with preview content shows the div? -- Posted via http://www.ruby-forum.com/.
On Sep 9, 2009, at 11:15 PM, Ram wrote:> > Hi ross, > > Thats what im doing right now. Im saving it as a Draft and rendering > the show action for the instance @post as a preview. But that breaks 2 > requirements, namely > > 1. The preview does not open in a new window.. its the same window. > 2. There are no call to action buttons on the Preview page (there > should not be any) and so when the user hits the back button, he''s > taken back to the new post form where hitting Save as Draft saves a > whole new post with the same data. > > Even if I manage to show the preview in a new window, i will still > have the duplicating posts problem if i save it before previewing it.It seems like you are trying to make your show action work too hard. If you are dead set against saving the data, you''ll probably have to come up with a Javascript preview. On the other hand, creating a one- off action like ''preview'' makes a ton of sense here because its job would be simply to preview some disposable data. Again, I don''t know your requirements, but my philosophy is to write really stupid controllers. If something like the show action tries to get too clever, it''s a code smell to me.> On Sep 10, 10:58 am, "s.ross" <cwdi...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: >> Use a state machine. posts are initially in ''draft'' state, and thus >> can be previewed, but are not published. When publish is pressed, >> change the state to ''published''. You probably don''t even need to >> manage state transition formally. Just make sure when you display >> posts to get only published ones (use named_scope to make this more >> automatic). >> >> On Sep 9, 2009, at 10:49 PM, Ram wrote: >> >> >> >> >> >>> Hi, >> >>> Ive got a form for a blog post and there are 3 buttons - Publish, >>> Preview and Save as Draft. >> >>> Clicking on Preview should open a new window with the preview of the >>> post without saving it while the current window stays on the "New >>> Post" form. I dont want the post to be saved because, once the user >>> views the preview and closes it, when he clicks on, say, Save as >>> Draft >>> on the form, a second post with the same details gets created. How >>> can >>> I achieve this functionality? >> >>> On a side note, I also want to perform model validations only if the >>> post is Published. Thought it might be relevant. >> >>> Im quite stumped so any and all ideas are welcome :) >> >>> Thanks. > >
Ok I solved this by using a combination of suggestions above and to cover my specific requirements. Save as Draft and Publish are input buttons. Preview is a link_to_function with the following javascript function. function preview_post(element){ element.up(''#post_form'').writeAttribute(''target'', ''_blank''); element.up(''#post_form'').down(''#preview_value'').value += 1; element.up(''#post_form'').submit(); element.up(''#post_form'').writeAttribute(''target'', false); } The above function is called only if Preview is clicked and adds a target = "_blank" attribute to the form in the page. This ensures that the form submit opens a new window with the response(which is in this case a preview). I then set the same attribute to ''false'' so that subsequent form submissions dont open in a new window except if its preview again. During the course of solving this, I decided i HAD to save before previewing for requirement reasons. Im updating a hidden ''preview'' attribute (with a default value of 0) in the form to 1 so that back in the controller, i check for this value and if its 1, I save and render ''show'' (which opens in a new window). Controller is quite complicated so im just gonna paste the code below and let you understand for yourself. def create @post = current_account.posts.build(params[:post]) if ((params[:preview].to_i == 1) && !((params[:save] == "Save") || params["save.x"]) && !((params[:publish] == "Publish") || params ["publish.x"])) @post.status = "Draft" @post.save(false) render :action => ''show'', :layout => ''application'' elsif ((params[:preview].to_i > 1) && !((params[:save] == "Save") || params["save.x"]) && !((params[:publish] == "Publish") || params ["publish.x"])) render :action => ''show'', :layout => ''application'' elsif ((params[:save] == "Save") || params["save.x"]) unless (params[:preview].to_i > 0) if @post.save(false) @post.update_attribute(:status, "Draft") redirect_to posts_path else flash[:error] = "There was a problem creating your blog post. Please try again later." render :action => ''new'' end else flash[:success] = "Post successfully created" redirect_to posts_path end elsif ((params[:publish] == "Publish") || params["publish.x"]) unless (params[:preview].to_i > 0) @post.status = "Active" @post.published = 1 if @post.save flash[:success] = "Post successfully published" redirect_to post_path(@post) else render :action => ''new'' end else if @post.valid? flash[:success] = "Post successfully published" redirect_to post_path(@post) else render :action => ''new'' end end end end Thats quite a lot and quite ugly. Am refactoring it. But this is perfectly functional. Hope it helps someone. Thank you all for your suggestions. On Sep 11, 10:40 am, "s.ross" <cwdi...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On Sep 9, 2009, at 11:15 PM, Ram wrote: > > > > > Hi ross, > > > Thats what im doing right now. Im saving it as a Draft and rendering > > the show action for the instance @post as a preview. But that breaks 2 > > requirements, namely > > > 1. The preview does not open in a new window.. its the same window. > > 2. There are no call to action buttons on the Preview page (there > > should not be any) and so when the user hits the back button, he''s > > taken back to the new post form where hitting Save as Draft saves a > > whole new post with the same data. > > > Even if I manage to show the preview in a new window, i will still > > have the duplicating posts problem if i save it before previewing it. > > It seems like you are trying to make your show action work too hard. > If you are dead set against saving the data, you''ll probably have to > come up with a Javascript preview. On the other hand, creating a one- > off action like ''preview'' makes a ton of sense here because its job > would be simply to preview some disposable data. > > Again, I don''t know your requirements, but my philosophy is to write > really stupid controllers. If something like the show action tries to > get too clever, it''s a code smell to me. > > > > > On Sep 10, 10:58 am, "s.ross" <cwdi...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > >> Use a state machine. posts are initially in ''draft'' state, and thus > >> can be previewed, but are not published. When publish is pressed, > >> change the state to ''published''. You probably don''t even need to > >> manage state transition formally. Just make sure when you display > >> posts to get only published ones (use named_scope to make this more > >> automatic). > > >> On Sep 9, 2009, at 10:49 PM, Ram wrote: > > >>> Hi, > > >>> Ive got a form for a blog post and there are 3 buttons - Publish, > >>> Preview and Save as Draft. > > >>> Clicking on Preview should open a new window with the preview of the > >>> post without saving it while the current window stays on the "New > >>> Post" form. I dont want the post to be saved because, once the user > >>> views the preview and closes it, when he clicks on, say, Save as > >>> Draft > >>> on the form, a second post with the same details gets created. How > >>> can > >>> I achieve this functionality? > > >>> On a side note, I also want to perform model validations only if the > >>> post is Published. Thought it might be relevant. > > >>> Im quite stumped so any and all ideas are welcome :) > > >>> Thanks.
You should separate out publish & save to 2 different actions, also using state machine will help. Thanks, Abhinav -- अभिनव http://twitter.com/abhinav On Fri, Sep 11, 2009 at 2:37 PM, Ram <yourstruly.vinay-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > Ok I solved this by using a combination of suggestions above and to > cover my specific requirements. > > Save as Draft and Publish are input buttons. > Preview is a link_to_function with the following javascript function. > > function preview_post(element){ > element.up(''#post_form'').writeAttribute(''target'', ''_blank''); > element.up(''#post_form'').down(''#preview_value'').value += 1; > element.up(''#post_form'').submit(); > element.up(''#post_form'').writeAttribute(''target'', false); > } > > The above function is called only if Preview is clicked and adds a > target = "_blank" attribute to the form in the page. This ensures that > the form submit opens a new window with the response(which is in this > case a preview). I then set the same attribute to ''false'' so that > subsequent form submissions dont open in a new window except if its > preview again. > > During the course of solving this, I decided i HAD to save before > previewing for requirement reasons. Im updating a hidden ''preview'' > attribute (with a default value of 0) in the form to 1 so that back in > the controller, i check for this value and if its 1, I save and render > ''show'' (which opens in a new window). Controller is quite complicated > so im just gonna paste the code below and let you understand for > yourself. > > def create > @post = current_account.posts.build(params[:post]) > if ((params[:preview].to_i == 1) && !((params[:save] == "Save") || > params["save.x"]) && !((params[:publish] == "Publish") || params > ["publish.x"])) > @post.status = "Draft" > @post.save(false) > render :action => ''show'', :layout => ''application'' > elsif ((params[:preview].to_i > 1) && !((params[:save] == "Save") > || params["save.x"]) && !((params[:publish] == "Publish") || params > ["publish.x"])) > render :action => ''show'', :layout => ''application'' > elsif ((params[:save] == "Save") || params["save.x"]) > unless (params[:preview].to_i > 0) > if @post.save(false) > @post.update_attribute(:status, "Draft") > redirect_to posts_path > else > flash[:error] = "There was a problem creating your blog > post. Please try again later." > render :action => ''new'' > end > else > flash[:success] = "Post successfully created" > redirect_to posts_path > end > elsif ((params[:publish] == "Publish") || params["publish.x"]) > unless (params[:preview].to_i > 0) > @post.status = "Active" > @post.published = 1 > if @post.save > flash[:success] = "Post successfully published" > redirect_to post_path(@post) > else > render :action => ''new'' > end > else > if @post.valid? > flash[:success] = "Post successfully published" > redirect_to post_path(@post) > else > render :action => ''new'' > end > end > end > end > > Thats quite a lot and quite ugly. Am refactoring it. But this is > perfectly functional. Hope it helps someone. > > Thank you all for your suggestions. > > > On Sep 11, 10:40 am, "s.ross" <cwdi...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > On Sep 9, 2009, at 11:15 PM, Ram wrote: > > > > > > > > > Hi ross, > > > > > Thats what im doing right now. Im saving it as a Draft and rendering > > > the show action for the instance @post as a preview. But that breaks 2 > > > requirements, namely > > > > > 1. The preview does not open in a new window.. its the same window. > > > 2. There are no call to action buttons on the Preview page (there > > > should not be any) and so when the user hits the back button, he''s > > > taken back to the new post form where hitting Save as Draft saves a > > > whole new post with the same data. > > > > > Even if I manage to show the preview in a new window, i will still > > > have the duplicating posts problem if i save it before previewing it. > > > > It seems like you are trying to make your show action work too hard. > > If you are dead set against saving the data, you''ll probably have to > > come up with a Javascript preview. On the other hand, creating a one- > > off action like ''preview'' makes a ton of sense here because its job > > would be simply to preview some disposable data. > > > > Again, I don''t know your requirements, but my philosophy is to write > > really stupid controllers. If something like the show action tries to > > get too clever, it''s a code smell to me. > > > > > > > > > On Sep 10, 10:58 am, "s.ross" <cwdi...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > >> Use a state machine. posts are initially in ''draft'' state, and thus > > >> can be previewed, but are not published. When publish is pressed, > > >> change the state to ''published''. You probably don''t even need to > > >> manage state transition formally. Just make sure when you display > > >> posts to get only published ones (use named_scope to make this more > > >> automatic). > > > > >> On Sep 9, 2009, at 10:49 PM, Ram wrote: > > > > >>> Hi, > > > > >>> Ive got a form for a blog post and there are 3 buttons - Publish, > > >>> Preview and Save as Draft. > > > > >>> Clicking on Preview should open a new window with the preview of the > > >>> post without saving it while the current window stays on the "New > > >>> Post" form. I dont want the post to be saved because, once the user > > >>> views the preview and closes it, when he clicks on, say, Save as > > >>> Draft > > >>> on the form, a second post with the same details gets created. How > > >>> can > > >>> I achieve this functionality? > > > > >>> On a side note, I also want to perform model validations only if the > > >>> post is Published. Thought it might be relevant. > > > > >>> Im quite stumped so any and all ideas are welcome :) > > > > >>> Thanks. > > >--~--~---------~--~----~------------~-------~--~----~ 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@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---