2012-06-08 23 views
2

我正在構建電梯應用程序,其中一個頁面基於Lift演示中的「文件上載」示例:http://demo.liftweb.net/file_upload如何在電梯中更改表單的動作

如果你看一下source code for that page ...你看,有一個電梯「片段」標籤,圍繞兩個「選擇」標籤:

<lift:snippet type="misc:upload" form="post" multipart="true"> 

<choose:post> 
<p> 
File name: <ul:file_name></ul:file_name><br > 
MIME Type: <ul:mime_type></ul:mime_type><br > 
File length: <ul:length></ul:length><br > 
MD5 Hash: <ul:md5></ul:md5><br > 
</p> 
</choose:post> 

<choose:get> 
Select a file to upload: <ul:file_upload></ul:file_upload><br > 
<input type="submit" value="Upload File"> 
</choose:get> 

</lift:snippet> 

的想法是,當用戶點擊該頁面第一次(即GET請求),然後Lift會顯示上傳文件的表單。當用戶提交表單時(例如POST請求到同一頁面),Lift將顯示正在處理的文件的結果。

與我的應用程序,新的皺紋是我的「結果」POST視圖需要包含一個窗體。我想爲用戶提供輸入一個電子郵件地址的文本輸入,以及一個提交按鈕按下時會通過電子郵件有關處理文件的信息:

... 
<choose:post> 
<p> 
File name: <ul:file_name></ul:file_name><br > 
MIME Type: <ul:mime_type></ul:mime_type><br > 
File length: <ul:length></ul:length><br > 
MD5 Hash: <ul:md5></ul:md5><br > 
</p> 

<!-- BEGIN NEW STUFF --> 
Output: <br/> 
<textarea rows="30" cols="100"><ul:output></ul:output></textarea> 
<br/><br/> 
Email the above output to this email address:<br/> 
<ul:email/><br/> 
<input type="submit" value="Email"/> 
<!-- END NEW STUFF --> 

</choose:post> 
... 

然而,無論是GET和這個頁面的POST版本由相同的Lift生成的表單包裝,在兩種情況下都將其「操作」設置爲相同的片段。我怎樣才能改變這種情況,在POST版本中,表單的動作變成了不同的片段?

在一個典型的web框架中,我會用「onclick」事件和兩個基本的JavaScript腳本來處理這種事情。然而,我甚至沒有開始想起Lift的...... err,關於在Scala中編寫JavaScript的有趣概念。也許我需要沿着這條路走下去,或者也許有更好的方法。

回答

1

我同意Brian的看法,使用Lift的新設計器友好的CSS綁定。

使用兩個單獨的表單,一個用於文件上傳,另一個用於提交電子郵件。當第一個處理完成時,使用S.seeOther將用戶重定向到第二個表單。

我更喜歡新的'data-lift'HTML屬性。

文件上傳HTML:

<div data-lift="uploadSnippet?form=post"> 
    <input type="file" id="filename" /> 
    <input type="submit" id="submit" /> 
</div 

文件上傳片段:

class uploadSnippet { 
    def processUpload = { 
     // do your processing 
     .... 
     if (success) 
      S.seeOther("/getemail") 

     // if processing fails, just allow this method to exit to re-render your 
     // file upload form 
    } 

    def render = { 
     "#filename" #> SHtml.fileUpload(...) & 
     "#submit" #> SHtml.submit("Upload", processUpload _) 
    } 
} 

GetEmail HTML:

<div data-lift="getEmailSnippet?form=post"> 
    <input type="text" id="email" /> 
    <input type="submit" id="submit" /> 
</div 

獲取電子郵件摘錄:

class getEmailSnippet { 
    def processSubmit = { 
     .... 
    } 

    def render = { 
     "#email" #> SHtml.text(...) & 
     "#submit" #> SHtml.submit("Upload", processSubmit _) 
    } 

還有更多的形式處理在我的博客文章有點使用RequestVar的位置: http://tech.damianhelme.com/understanding-lifts-requestvars

讓我知道,如果你想要更多的細節。

希望這是有用的

乾杯

達米安

0

如果在接下來的幾天內有人提出更優雅的(或「Lift-y」)方法,那麼我會接受他們的答案。不過,我自己想出了一種解決方法。

我保留了當前的佈局,其中視圖有一個GET塊和一個POST塊都提交到相同的片段功能。代碼段函數仍然有一個if-else塊,根據它是GET還是POST來處理每個請求。

但是,現在我也有一個if-else裏面的 POST的塊。這個內核if-else查看被點擊的提交按鈕的名稱。如果提交按鈕是用於上傳文件的提交按鈕,則該片段處理文件的上傳和處理。否則,如果是第一次POST後顯示的發送電子郵件提交按鈕,則片段會處理髮送電子郵件。

不是特別迷人,但它工作得很好。

2

首先,我會建議您使用Lift的新設計器友好的CSS綁定,而不是自定義的XHTML標記。

當您使用Lift的片段時,您應該記住的一件事是它是遞歸的,您可以在另一個片段的HTML塊中放置一個提升片段。

例如,如果你希望在POST之後有另一個表單,那麼就把它放到塊中。

<choose:post> 
<p> 
File name: <ul:file_name></ul:file_name><br > 
MIME Type: <ul:mime_type></ul:mime_type><br > 
File length: <ul:length></ul:length><br > 
MD5 Hash: <ul:md5></ul:md5><br > 
</p> 
<!-- 
    The following is same as <lift:snippet type="EMailForm" form="post" multipart="true"> 
--> 
<form action="" method="post" data-lift="EMailForm"> 
    <input type="text" name="email"/> 
    <input type="submit" /> 
</form> 
</choose:post> 

然後處理片段類EMailForm上的電子郵件表單操作。

最後,您可以通過使用隱藏的表單元素或SessionVar來傳遞文件名/ minetype和其他信息。