【问题标题】:How to change a form's action in Lift如何在 Lift 中更改表单的操作
【发布时间】:2012-06-08 16:15:58
【问题描述】:

我正在构建一个 Lift 应用程序,其中一个页面基于 Lift 演示中的“文件上传”示例:http://demo.liftweb.net/file_upload

如果您查看source code for that page...,您会看到有一个 Lift“sn-p”标签,围绕着两个“选择”标签:

<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 生成的表单包装,在这两种情况下,它的“操作”设置为相同的 sn-p。如何更改此设置,以便在 POST 版本中,表单的操作更改为不同的 sn-p?

在典型的 Web 框架中,我会使用“onclick”事件和两行基本的 JavaScript 来处理这样的事情。然而,我什至还没有开始思考 Lift 的……呃,关于在 Scala 中编写 JavaScript 的有趣概念。也许我需要走那条路,或者可能有更好的方法。

【问题讨论】:

    标签: scala lift


    【解决方案1】:

    首先,我建议您使用 Lift 的新设计友好 CSS 绑定,而不是自定义 XHTML 标记。

    当您使用 Lift 的 sn-p 时,您应该记住一件事,它是递归的,您可以将 lift sn-p 放在另一个 sn-p 的 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>
    

    然后在 sn -p class EMailForm 处理邮件表单动作。

    最后,您可以使用隐藏的表单元素或 SessionVar 传递文件名/类型等信息。

    【讨论】:

      【解决方案2】:

      我同意 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
      

      文件上传sn-p:

      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 _ )
          }
      }
      

      获取电子邮件 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

      如果您需要更多详细信息,请告诉我。

      希望有用

      干杯

      达米安

      【讨论】:

        【解决方案3】:

        如果有人在接下来的几天内提出更优雅(或“Lift-y”)的方法,那么我会接受他们的回答。但是,我自己想出了一个解决方法。

        我保留了当前布局,其中视图有一个 GET 块和一个 POST 块,它们都提交给同一个 sn-p 函数。 sn-p 函数仍然有一个 if-else 块,根据它是 GET 还是 POST 来处理每个请求。

        但是,现在我在 POST 块的 inside 中还有一个二级 if-else 块。这个内部if-else 查看被点击的提交按钮的名称。如果提交按钮是用于上传文件的按钮,则 sn-p 处理文件的上传和处理。否则,如果是第一次 POST 之后显示的发送电子邮件提交按钮,则 sn-p 处理电子邮件的发送。

        不是特别迷人,但效果很好。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-07-15
          • 2013-08-30
          • 2012-12-20
          • 1970-01-01
          • 1970-01-01
          • 2018-01-31
          • 1970-01-01
          相关资源
          最近更新 更多