How to put link in submit-button, using Clojure - forms

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!

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.

Related

Elm lang redirect to external URL

How can I redirect to external url? I've tried with Navigation module, but it seems to work only for local routes. Is there a way to do it natively, without js ports?
I.e. window.location.href = http://google.com;
Edit: I somehow missed Navigation.load function. As suggested below, it will help with redirects.
Since a tag can be always used with specified href, I'd rather try to find a solution which would avoid using redirection from update function.
a [ href "http://google.com" ] [ text "Google link" ]
But in case it's necessary to implement the logic similar to window.location.href = "http://google.com";, elm-lang/navigation provides load function (and a couple of other useful ones for forcing page loads) which does, what you're expecting.
It takes a url and returns a command load : String -> Cmd msg, so it's going to look like this:
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
RedirectToGoogle ->
( model, load "http://google.com" )

How to crawl data from encrypted url?

I'm trying to use scrapy to collect the university's professors' contact information from its directory. Since I can't post more than 2 links, I put all links in the following picture.
I set last name equals from the drop-down menu as shown in the picture. Then I search all professors by last name.
Usually, the url will have some pattern from other universities' website. However, for this one, the original url is (1). It becomes (2)when I search 'An' as last name. It seems like 'An' is replaced by something like 529385FD5FF90A198625819E002B8B41? I'm not sure. Is there any way I can get the url that I need to send as a request? I mean, this time I search 'An'. If I search another last name like Lee. It will be another request. They are irregular. I can't find a pattern.
The scraper is not as complex as you think it is. It just makes a POST call from the form and that returns a GET request. Below would work
import scrapy
from scrapy.utils.response import open_in_browser
class univSpider(scrapy.Spider):
name = "univ"
start_urls = ["http://appl103.lsu.edu/dir003.nsf/(NoteID)/5903C096337C2AA28625819E0038E3E4?OpenDocument"]
def parse(self, response):
yield FormRequest.from_response(response, formname="_DIRVNAM", formdata={"LastName": "Lalwani"},callback = self.search_result)
def search_result(self, response):
open_in_browser(response)
print(response.body)

Is GET /entry/new considered best practice for displaying the input form for creating a new resource?

Consider a Resource named Entry, with endpoints:
GET /entries (show all entries)
GET /entries/<x> (show entry x)
POST /entries (create new entry)
PUT /entries/<x> (change an existing entry x)
DELETE /entries/<x> (delete an existing entry x)
These I'm sure of. But how about:
GET /entries/new (show input form for creation of new entry)
GET /entries/<x>/edit (show input form for update of existing entry)
Are these patterns considered best practice as well? If not, which are?
GET /entries (show all entries)
GET /entries/<x> (show entry x)
POST /entries (create new entry)
PUT /entries/<x> (change an existing entry x)
DELETE /entries/<x> (delete an existing entry x)
Are all OK, as you expected.
GET /entries/new (show input form for creation of new entry)
GET /entries/<x>/edit (show input form for update of existing entry)
If you want to keep it simple, these two are OK as well (they are common, used by big players and frameworks, respect RESTful principles and are somewhat of a standard).
Sources/samples:
Microformats wiki - some good info here, with suggestions on how to work around browser method limitations
Stack Exchange: /questions/ask (instead of /new) to display the create form; /questions/id/slugified-title to view; /post/<x>/edit to display the edit form.
GitHub's issues: /project/issues; /project/issues/new; /project/issues/<x>; they don't have an /edit URL, as all editing is done in-place via JS.
The standard followed by Rails: http://guides.rubyonrails.org/routing.html#crud-verbs-and-actions
Long story
To achieve the scalability and loose coupling of a go RESTful architecture, it helps to think of your application in terms of resources. So every URL should be pointing to a different resource. So:
GET /entries/<x> is OK because it would return the resource "entry of identity <x>".
Now, the GET /entries/new is a resource as well, but more of a "utility" one. It is just that the resource presented by this address is a form (a document explaining how to create entries - could be a WADL instead of a form as well).
The /edit possibilities
The GET /entries/<x>/edit, if you want, is the one we could get by without. As we know, the GET returns a representation of the current state of a resource, not (necessarily) the resource. This way, if a resource is (currently) editable, the GET URL would return it in an editable fashion, if not, then it would be read-only (thus no need for an /edit resource).
Another way of achieving this is having GET entries/<x> return JSON of HTML content based on the Accept header. This way, if the Accept had text/html, the page returned would be a form containing the all the info (again, if the resource was in an editable state, the form would be editable. If not, then it would be read-only).
Now I see this may not be optimal, as you may not want to display the form everytime (on GET /entries/<x>). If this is the case, you have almost two resources:
GET /entries/<x> - the entry
GET /entries/<x>/edit - This "resource" would be a file describing what sort of HTTP request the client must make if it wants to edit an entry state. In your case it is a form (telling the client how to send or simulate a PUT request), but could be a short WADL file as well.

I'd like to know how to change pages in Form Post

I'd like to know how to change pages by putting some in Forms by Post way.
http://www.aldoshoes.com/us/women/shoes/flats
in this page
How do I move to page 2 by putting some variabels in URL?
Please help me out.
This is not possible because it seems to me that the server does not handle GET parameters in the http request.
However it is possible to achieve this using POST parameters, either programmatically or using a plug-in for Chrome/Firefox (see Super User question).
The server accepts the following parameters:
formAction:
startRow:1
rowsperPage:12
flagID:
seasonID:
dimensionID:
sizeID:
colorID:
colorGroupID:
itemCategoryLevel1:1100
itemCategoryLevel2:1101
itemCategoryLevel3:1120
itemCategoryLevel4:
styleID:
styleDescription:
keywords:
alternateDescription:
descriptionDetail1:
descriptionDetail2:
descriptionDetail3:
onsale:N
sortBy:
itemFamilyID:
heelHeight:
To get to the second page of the shop you can set the parameter startRow to 13:
startRow:13
rowsperPage:12

Why does CasperJS form submit not redirect to the next page?

This is my first casper test, so I'm still struggling with the basics. I would like to fill in the username and password on my login form, then submit it. And then confirm if a 'log off' link is rendered on the next page (confirming that the user has been logged in).
But as far as I can tell, when then is called, the url is still the same. Looks like no post or redirect to the next page is happening. What am I doing wrong?
casper.start "http://test.local.mycompany.local/", ->
#echo 'at ' + #getCurrentUrl()
#fill 'form', { UserAlias : 'joe', Password : 'password' }, true
casper.then ->
#echo 'at ' + #getCurrentUrl()
#test.assertExists '#log-off-link', 'log-off link exists'
casper.run ->
#test.done()
So the echo of #getCurrentUrl both returns the same URL, which is wrong.
You can try to use chrome extension ressurectio to generate automated tests, for casperjs, in browser. It's very simple to use and useful. May be in a few lines(- part of generated code) you should to make some fixes but anyway it's very useful and convenient.
I had the same problem. One day my casper tests stopped working. More exactly casperjs stopped following redirects. The problem really was that my server was returning an invalid HTTP set-cookie header (with an invalid date). This was due to a configuration problem with the expiration date. Anyway, it seems that if there is an incorrect value in some header value something makes casperjs to ignore other header values such as the "location" http header for redirects.
Once I fixed the problem with the expiration date in the cookies the HTTP set-cookie header was ok and casperjs started to follow again the redirects.
Hope this helps!
It is possible that casper doesn't find the fields by name. You could try
casper.start "http://test.local.mycompany.local/", ->
#echo 'at ' + #getCurrentUrl()
#fillSelectors 'form', { 'input[name=UserAlias]' : 'joe', 'input[name=Password]' : 'password' }, true
It should mean the same as your code, but sometimes it doesn't.