在Lift Web框架中是否可以创建通过AJAX做出反应的表单(和链接),但是在没有Javascript支持的情况下也可以工作?如果是这样,怎么样?
当我使用<lift:form.ajax>
构建表单时,表单的action
设置为javascript://
,以便在没有JS的情况下不再提交。如果我在没有显式AJAX支持的情况下构建表单,我不知道如何插入AJAX功能。
我想我可以构建一个RESTful接口(无论如何我们必须构建它)并编写自定义Javascript以通过它提交表单。我想避免代码重复:如果可以使用相同的代码处理所有三个输入(RESTful,传统的HTTP POST,AJAX),那将是最好的。
答案 0 :(得分:4)
查看http://demo.liftweb.net/form_ajax
class FormWithAjax extends StatefulSnippet {
private var firstName = ""
private var lastName = ""
private val from = S.referer openOr "/"
def dispatch = {
case _ => render _
}
def render(xhtml: NodeSeq): NodeSeq =
{
def validate() {
(firstName.length, lastName.length) match {
case (f, n) if f < 2 && n < 2 => S.error("First and last names too short")
case (f, _) if f < 2 => S.error("First name too short")
case (_, n) if n < 2 => S.error("Last name too short")
case _ => S.notice("Thanks!"); S.redirectTo(from)
}
}
bind( "form", xhtml,
"first" -> textAjaxTest(firstName, s => firstName = s, s => {S.notice("First name "+s); Noop}),
"last" -> textAjaxTest(lastName, s => lastName = s, s => {S.notice("Last name "+s); Noop}),
"submit" -> submit("Send", validate _)
)
}
<lift:surround with="default" at="content">
Enter your first and last name:<br>
<form class="lift:FormWithAjax?form=post">
First Name: <form:first></form:first>
Last Name: <form:last></form:last>
<form:submit></form:submit>
</form>
</lift:surround>
这将在没有javascript的情况下运行:
<form action="/form_ajax" method="post">
<input name="F1069091373793VHXH01" type="hidden" value="true">
First Name: <input value="" type="text" name="F1069091373788OVAAWQ" onblur="liftAjax.lift_ajaxHandler('F1069091373789N2AO0C=' + encodeURIComponent(this.value), null, null, null)">
Last Name: <input value="" type="text" name="F1069091373790VANYVT" onblur="liftAjax.lift_ajaxHandler('F1069091373791CJMQDY=' + encodeURIComponent(this.value), null, null, null)">
<input name="F1069091383792JGBYWE" type="submit" value="Send">
</form>
答案 1 :(得分: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>
注意: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;
});
<?php
if (isset($_POST['method']) && $_POST['method'] == 'ajax') {
// AJAX is used this time, only #result div is updating in this case.
} else {
// Traditional POST is used to send data, whole page is reloading. Maybe send <html><head>... etc.
}
?>
这是你应该决定使用或不使用的东西,它不是支持其他方法(ajax,传统)的替代品,而是更多东西集成在其他方法中。
当然,您始终可以启用或禁用REST功能。
您始终可以将表单method="POST/GET/PUT/DELETE"
和ajax调用为RESTful:
...
$.ajax({
type: 'PUT',
url: 'formhandler.php',
...
...
$.ajax({
type: 'DELETE',
url: 'formhandler.php',
...
嗯,浏览器(没有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;
};
你是对的,电脑应该做我们的工作。这就是它们的设计目标。
因此,需要做的另一件事是检查我们的原始html表单想要使用的http方法,并使其适应发送 ajax请求,使用相同的方法,无需javascript 支持。 这是之前使用的 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
...
现在,我们的AJAX处理程序使用在<form method="put" ...>
定义的方法(post | get | put | delete)将数据作为JSON对象发送,如果表单方法发生更改,那么我们的ajax处理程序也将适应更改。
这就是全部,一些代码经过测试并且实际上正在使用中,有些代码根本没有经过测试但应该可以正常工作。