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...@gmail.com> 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...@gmail.com> 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@googlegroups.com To unsubscribe from this group, send email to rubyonrails-talk+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---