3

I've been working on a Clojure project for some time and was wondering how to navigate user from one page to another after clicking the submit-button. Code goes like this:

(defn view-film-input [] 
 (view-layout 
   [:body {:style "background-color: #F2FB78"}
   [:h2 "Add new film"] 
   (form-to [:post "/addfilm" ]

  (label "movname" "Film title: ")
  (text-field  :txtname) [:br] 

  (label "prname" "Producer name: ")
  (text-field  :txtprname) [:br] 
  (label "location" "File location: ")
  (text-field :txtlocation)[:br]

  (label "duration" "Duration(minutes): ")
  (text-field  :txtduration)[:br]
  (submit-button "Save"))]))

Now, this works but I would like to navigate user to same "Add new film" page, or refresh the form after clicking "Save" button, instead it shows just a blank page.

This is the GET\POST part:

 (GET "/addfilm" [] (view-film-input))
 (POST "/addfilm" [txtname txtprname txtlocation txtduration]
    (insert-flick txtname txtprname txtlocation txtduration 90) )

Thanks in advance!

Wombat
  • 31
  • 3
  • I assume this is compojure. Your views need to return a response. What does `insert-flick` return? – Diego Basch Aug 29 '14 at 19:26
  • It's defined in another class, which manages database. Adds new film to the table, using txtname, txtprname, txtlocation and txtduration as attributes – Wombat Aug 29 '14 at 20:27

1 Answers1

2

You have two possibilities here.

Redirect the User

Using the Location header of a HTTP 302 (or 303) response you can specify a path the user's browser should display instead of the current one:

(POST "/addfilm" [...]
  ...
  {:status 302
   :headers {"Location" "/addfilm"}})

There are also two functions in ring.util.response that would generate the responses for you: redirect and redirect-after-post - with the latter being more applicable to your use case.

EDIT: This answer elaborates on why 303 would be the status code to send after POST, specifically:

If you use 302, you're risking that UA will re-send POST to the new URL instead of switching to GET.

Render the same Page again

Simpler and prompting less I/O, but imposing some duplication would be to render the same view again, i.e.:

(POST "/addfilm" [...]
  ...
  (view-film-input))

This seems less maintainable to me but it is probably the shortest path to solving your problem.

Community
  • 1
  • 1
xsc
  • 5,983
  • 23
  • 30