Liftweb:创建一个可以传统和AJAX提交的表单

mat*_*cik 13 ajax scala lift

是否可以在Lift Web框架中创建通过AJAX做出反应的表单(和链接),但是也可以在没有Javascript支持的情况下工作?如果是这样,怎么样?

当我使用构建表单时<lift:form.ajax>,表单action被设置为javascript://不再没有JS提交.如果我在没有显式AJAX支持的情况下构建表单,我不知道如何插入AJAX功能.

我想我可以构建一个RESTful接口(无论如何我们必须构建它)并编写自定义Javascript以通过它提交表单.我想避免代码重复:如果可以使用相同的代码处理所有三个输入(RESTful,传统HTTP POST,AJAX),那将是最好的.

Sam*_*ala 1

我对 Lift 不太了解,所以我的回答重点是替代方法。这是基于 jQuery 的,当 Javascript 可用时将使用 AJAX,如果没有启用 Javascript 支持则使用传统的 POST。

形式:

<form id="ajaxform" action="formhandler.php" method="post" enctype="multipart/form-data" >

<input name="firstname" type="text" />
<input name="email" type="email" />
<input name="accept" type="submit" value="Send" />

</form>

<div id="result"></div>
Run Code Online (Sandbox Code Playgroud)

JS:

注意:jQuery默认$.ajax()发送application/x-www-form-urlencoded,也可以设置表单enctype="application/x-www-form-urlencoded"

$("#ajaxform").submit(function(e){

  // Alternative way to prevent default action:
  e.preventDefault();

  $.ajax({
    type: 'POST',
    url: 'formhandler.php',
    // Add method=ajax so in server side we can check if ajax is used instead of traditional post:
    data: $("#ajaxform").serialize()+"&method=ajax",
    success: function(data){ // formhandler.php returned some data:
      // Place returned data <div id="result">here</div>
      $("#result").html(data);
    }
  });

  // Prevent default action (reposting form without ajax):
  return false;
});
Run Code Online (Sandbox Code Playgroud)

服务器端(PHP)

$("#ajaxform").submit(function(e){

  // Alternative way to prevent default action:
  e.preventDefault();

  $.ajax({
    type: 'POST',
    url: 'formhandler.php',
    // Add method=ajax so in server side we can check if ajax is used instead of traditional post:
    data: $("#ajaxform").serialize()+"&method=ajax",
    success: function(data){ // formhandler.php returned some data:
      // Place returned data <div id="result">here</div>
      $("#result").html(data);
    }
  });

  // Prevent default action (reposting form without ajax):
  return false;
});
Run Code Online (Sandbox Code Playgroud)

那么休息呢?

这是您应该决定使用或不使用的东西,它不是作为其他方法(ajax、传统)的替代方法来支持的,而是更多地集成在其他方法中。当然,您始终可以启用或禁用 REST 功能。您始终可以使表单method="POST/GET/PUT/DELETE"和ajax调用RESTful:

...
  $.ajax({
    type: 'PUT',
    url: 'formhandler.php',
...

...
  $.ajax({
    type: 'DELETE',
    url: 'formhandler.php',
...
Run Code Online (Sandbox Code Playgroud)

但 REST 也要求我们对请求使用 XML、JSON...

好吧,浏览器(没有 JavaScript)不能很好地支持它,但$.ajax()可以用作application/x-www-form-urlencoded默认编码。

当然,使用 Javascript,我们总是可以将数据容器转换为 XML 或 JSON ...以下是如何使用 jQuery、JSON 对象来完成此操作:

/* This is function that converts elements to JSON object,
 * $.fn. is used to add new jQuery plugin serializeObject() */
$.fn.serializeObject = function()
{
   var o = {};
   var a = this.serializeArray();
   $.each(a, function() {
       if (o[this.name]) {
           if (!o[this.name].push) {
               o[this.name] = [o[this.name]];
           }
           o[this.name].push(this.value || '');
       } else {
           o[this.name] = this.value || '';
       }
   });
   return o;
};
Run Code Online (Sandbox Code Playgroud)

但我想要一个 AJAX 调用来完成所有事情:

你是对的,计算机应该完成我们的工作。这就是它们的设计目的。

因此,需要做的另一件事是检查我们的原始 html 表单想要使用什么 http 方法,并对其进行调整,以使用与没有 javascript支持时使用的相同方法发送 ajax 请求。这是JS:之前使用的标题下的修改版本:

...
  // Alternative way to prevent default action:
  e.preventDefault();

  // Find out what is method that form wants to use and clone it:
  var restmethod = $('#ajaxform').attr('method');

  // Put form data inside JSON object:
  var data = $('#orderform').serializeObject();
  // Add method=ajax so in server side we can check if ajax is used instead of traditional post:
  data.method = 'ajax';

  $.ajax({
    type: restmethod, // Use method="delete" for ajax if so defined in <form ...>
    url: 'formhandler.php',
    data: data, // data is already serialized as JSON object
...
Run Code Online (Sandbox Code Playgroud)

现在,我们的 AJAX 处理程序使用在 定义的方法 (post|get|put|delete) 将数据作为 JSON 对象发送<form method="put" ...>,如果表单方法发生更改,那么我们的 ajax 处理程序也将适应更改。

就是这样,一些代码已经过测试并且正在实际使用,有些代码根本没有经过测试但应该可以工作。

  • 抱歉,op 提出的正是我正在寻找的问题。我很快就产生了敌意,因为我找到的唯一答案是在 php 中。下次点击“添加评论”按钮时我会三思而后行;)。 (3认同)
  • @Guillaume是的,你是对的,op是关于提升的具体内容,这就是为什么我明确表示我正在讲述替代方法来做到这一点。[SO](http://stackoverflow.com) 毕竟是 wiki,而不是 op 是唯一的论坛。也就是说,我认为我应该将这些信息保留在这里。如果我错了请纠正我。 (2认同)