我想上传带有Lift的图像,并立即在页面的某个元素中显示它,而不重新加载。我想在this解决方案(使用PHP)中执行此操作。
这个过程比较简单。我用虚拟HTML片段替换了PHP文件:
<form id="imageform" method="post" enctype="multipart/form-data" action="ajaximage.html">
<input id="imageFile" name="imageFile" type="file" size="50" maxlength="100000"/>
</form><br/>
<script src="jquery-1.8.3.min.js"></script>
<script src="jquery.form.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#imageFile').live('change', function() {
$("#preview").html('');
$("#preview").html('<img src="images/processing.jpg" alt="Uploading...."/>');
$("#imageform").ajaxForm({
target : '#preview'
}).submit();
});
});
</script>
HTML代码段:
<img src="images/someimage.jpg"/>
嗯,这很有效。但我显然需要动态行为。示例页面使用PHP文件代替我的HTML代码段,该文件从请求中提取数据,将其保存在服务器中,并相应地输出预览图像的HTML - echo "<img src='uploads/".$actual_image_name."' class='preview'>";
现在,我不知道如何使用Lift来实现这一目标。
我发现了这个讨论:https://groups.google.com/forum/?fromgroups=#!topic/liftweb/6bxNlbBPJvE但除了对我不想使用的框架和HTML5事物的模糊建议外,没有好的解决方案。
第2部分。我已经在Lift中实现了一些基础知识:
HTML:
<div class="lift:AddImage.addEntry" form="POST" multipart="true">
<p><prefix:imageUpload/></p>
<p><prefix:test/></p>
</div>
片段:
package code
package snippet
import net.liftweb.http.S
import net.liftweb.common.Full
import net.liftweb.common.Empty
import net.liftweb.common.Box
import net.liftweb.http.FileParamHolder
import net.liftweb.util._
import Helpers._
import scala.xml.Group
import scala.xml.NodeSeq
import net.liftweb.http.SHtml
import javax.annotation.Resource
import java.io.OutputStream
import java.io.FileOutputStream
class AddImage {
// Add a variable to hold the FileParamHolder on submission
var fileHolder : Box[FileParamHolder] = Empty
def submitTest () {
println("submitTest called!")
val receiptOk = fileHolder match {
// An empty upload gets reported with a null mime type,
// so we need to handle this special case
case Full(FileParamHolder(_, null, _, _)) => true
case Full(FileParamHolder(_, mime, _, data)) =>
println("MIME: " + mime)
if (mime.startsWith("image/")) {
println("uploading the image: ")
//scala.io.Source.fromBytes(data)
try {
val out: OutputStream = new FileOutputStream("test.jpg");
out.write(data);
out.flush();
out.close();
} catch {
case e: Exception => println("Exception!: " + e)
}
true
}
case Full(_) => {
S.error("Invalid attachment")
false
}
case _ => true
}
// (e.validate, receiptOk) match {
// }
}
def addEntry(content: NodeSeq): NodeSeq = {
bind("prefix", content,
"imageUpload" -> SHtml.fileUpload(f => fileHolder = Box !! f),
"test" -> SHtml.submit("submitz", submitTest))
}
}
但我被困在这里是因为:
我不知道如何引用Lift从jquery创建的表单。
当上传输入字段发生更改时,javascript会使用ajaxForm()
提交表单,并在#preview
元素中插入PHP脚本的结果。我不知道如何在scala中提交表单并进一步输出图像HTML,以便可以将其插入#preview
希望这不是很多问题:)提前感谢。
答案 0 :(得分:1)
这不是一个完整的答案,而是一堆可以帮助你解决问题的指针。
为了将JS附加到您的表单,我认为您应该能够向表单添加id属性并以这种方式附加到它。如果由于某种原因这不适合你,一个简单的解决方法是用div包装表单,如:
<div id="wrapper"><form> ... </form></div>
然后你可以使用jquery抓住它:$('#wrapper form')
。有一篇关于ajax文件上传的wiki文章,并在此处提升:https://www.assembla.com/spaces/liftweb/wiki/AJAX_File_Upload。它还使用jQuery方法重定向表单提交,因此您可能会在那里获得一些洞察力。
关于实际显示图像数据,有一些功能可能派上用场。第一个是JsCmds.SetHtml
,另一个是S.fmapFunc
。
JsCmds.SetHtml(id:String, replacement:NodeSeq)
将允许您使用提供的NodeSeq
替换与特定ID匹配的html元素的内容。
S.fmapFunc
将允许您创建可以返回图像的功能。在下面的示例中,您将创建一个函数,将图像读取为字节数组,然后将其输出到浏览器,并获得唯一ID。第二部分返回一个引用唯一id的对象并对其执行某些操作(在本例中为XML Element)。因此,下面的示例将返回一个调用图像的图像标记。
S.fmapFunc(() => {
val mimeType:String = //set mimeType
val data:Array[Byte] = //get byte array of image
throw ResponseShortcutException.shortcutResponse(
InMemoryResponse(data,
("Content-Type" -> mimeType) :: Nil, Nil, 200))
}) {
name => <img src={"?" + name + "=_"} />
}
这是使用InMemoryResponse
,根据图片的大小,这可能并不理想。您也可以使用StreamingResponse
。
将两者结合使用,您应该生成包含图像链接的Html,您可以在页面上显示该图像。可能有很多方法可以完成这项工作,所以毫无疑问,你将能够获得你需要的工作。 Ajax文件上传可能有点棘手,因此让所有内容协同工作可能需要一些工作,但希望这可以指向正确的方向。
此外,作为附注,电梯问题最活跃的地方是他们的邮件列表:liftweb@googlegroups.com。有很多人监视它,包括项目的提交者,他们反响灵敏。