提升 - 自动填充Ajax提交 [英] Lift - Autocomplete with Ajax Submission

查看:104
本文介绍了提升 - 自动填充Ajax提交的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用ajax的自动完成功能。所以我的目标是:

I would like to use an autocomplete with ajax. So my goal is to have:


  • 当用户在文本字段中输入内容时,服务器提供的一些建议我必须在数据库中查找建议)

  • When the user types something in the text field, some suggestions provided by the server appear (I have to find suggestions in a database)

当用户按下输入时,点击自动填充框以外的地方,一个建议,文本字段中的字符串被发送到服务器。

When the user presses "enter", clicks somewhere else than in the autocomplete box, or when he/she selects a suggestion, the string in the textfield is sent to the server.

我第一次尝试使用电梯提供的自动完成小工具,但我遇到三个问题:

I first tried to use the autocomplete widget provided by lift but I faced three problems:


  • 它是一个扩展的选择,也就是说你最初只能提交建议的值。

  • 这并不意味着与ajax一起使用。

  • 结合 WiringUI 时会出现错误。
  • it is meant to be an extended select, that is to say you can originally only submit suggested values.
  • it is not meant to be used with ajax.
  • it gets buggy when combined with WiringUI.

因此,我的问题是:如何结合 jquery autocomplete ,并与电梯中的服务器进行交互。我想我应该使用一些回调,但我不掌握它们。

So, my question is: How can I combine jquery autocomplete and interact with the server in lift. I think I should use some callbacks but I don't master them.

提前感谢。

UPDATE 这是我尝试的第一个实现,但回调不起作用:

UPDATE Here is a first implementation I tried but the callback doesn't work:

private def update_source(current: String, limit: Int) = {   
  val results = if (current.length == 0) Nil else /* generate list of results */
  new JsCmd{def toJsCmd = if(results.nonEmpty) results.mkString("[\"", "\", \"", "\"]") else "[]" }
}   

def render = {
  val id = "my-autocomplete"
  val cb = SHtml.ajaxCall(JsRaw("request"), update_source(_, 4))
  val script = Script(new JsCmd{
    def toJsCmd = "$(function() {"+
      "$(\"#"+id+"\").autocomplete({ "+
      "autocomplete: on, "+
      "source: function(request, response) {"+
        "response("+cb._2.toJsCmd + ");"  +
      "}"+
      "})});"
  })

  <head><script charset="utf-8"> {script} </script></head> ++
  <span id={id}> {SHtml.ajaxText(init, s=>{ /*set cell to value s*/; Noop}) }   </span>
}

所以我的想法是:


  • 通过 SHtml.ajaxText 字段获取选定的结果,该字段将包含到自动填充字段中

  • 使用javascript功能更新自动填充建议

  • to get the selected result via an SHtml.ajaxText field which would be wraped into an autocomplete field
  • to update the autocomplete suggestions using a javascript function

推荐答案

1)确保您使用Lift 2.5-SNAPSHOT(这在早期版本中是可行的,但更困难)

1) Make sure you are using Lift 2.5-SNAPSHOT (this is doable in earlier versions, but it's more difficult)

2)在用来渲染页面的代码片段中,使用SHtml.ajaxCall(特别是你可能想要这个版本: https://github.com/lift/framework/blob/master/web/ webkit / src / main / scala / net / liftweb / http / SHtml.scala#L170 ),这将允许您注册一个服务器端函数,接受您的搜索项并返回包含完成的JSON响应。你还将注册一些操作发生在JSON响应与JsContext。

2) In the snippet you use to render the page, use SHtml.ajaxCall (in particular, you probably want this version: https://github.com/lift/framework/blob/master/web/webkit/src/main/scala/net/liftweb/http/SHtml.scala#L170) which will allow you to register a server side function that accepts your search term and return a JSON response containing the completions. You will also register some action to occur on the JSON response with the JsContext.

3)上面的ajaxCall将返回一个JsExp对象,将导致ajax请求时调用。

3) The ajaxCall above will return a JsExp object which will result in the ajax request when it's invoked. Embed it within a javascript function on the page using your snippet.

4)使用某些客户端JS将其连接到网页上。

4) Wire them up with some client side JS.

更新 - 一些代码可以帮助你。它可以绝对使用Lift 2.5更简洁,但由于2.4中的一些不一致,我最终滚动我自己的ajaxCall like函数。 S.fmapFunc在服务器端注册该函数,函数体从客户端发出一个Lift ajax调用,然后调用JSON响应上的res函数(来自jQuery autocomplete)。

Update - Some code to help you out. It can definitely be done more succinctly with Lift 2.5, but due to some inconsistencies in 2.4 I ended up rolling my own ajaxCall like function. S.fmapFunc registers the function on the server side and the function body makes a Lift ajax call from the client, then invokes the res function (which comes from jQuery autocomplete) on the JSON response.

我的jQuery插件激活文本输入

My jQuery plugin to "activate" the text input


(function($) {
    $.fn.initAssignment = function() {
     return this.autocomplete({
         autoFocus: true,
         source: function(req, res) {
              search(req.term, res);
         },
         select: function(event, ui) {
             assign(ui.item.value, function(data){
                eval(data);
             });
             event.preventDefault();
             $(this).val("");
         },
         focus: function(event, ui) {
             event.preventDefault();
         }
     });
    }
})(jQuery);

导致javascript搜索功能的我的Scala代码:

My Scala code that results in the javascript search function:


def autoCompleteJs = JsRaw("""
        function search(term, res) {
        """ +
             (S.fmapFunc(S.contextFuncBuilder(SFuncHolder({ terms: String =>
                val _candidates = 
                  if(terms != null && terms.trim() != "")
                    assigneeCandidates(terms)
                  else
                    Nil
                JsonResponse(JArray(_candidates map { c => c.toJson }))
             })))
             ({ name => 
               "liftAjax.lift_ajaxHandler('" + name 
             })) + 
             "=' + encodeURIComponent(term), " +
             "function(data){ res(data); }" +
             ", null, 'json');" +
        """
        }
        """)

Update 2 - 要将上述函数添加到页面,请使用类似于下面的CssSelector变换。 > *表示追加到匹配的脚本元素中已存在的任何内容。我已经在该页面上定义了其他函数,并向它们添加了搜索函数。

Update 2 - To add the function above to your page, use a CssSelector transform similar to the one below. The >* means append to anything that already exists within the matched script element. I've got other functions I've defined on that page, and this adds the search function to them.


"script >*" #> autoCompleteJs

您可以查看源代码以验证其是否存在于页面上并且可以像任何其他JS函数一样被调用。

You can view source to verify that it exists on the page and can be called just like any other JS function.

这篇关于提升 - 自动填充Ajax提交的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆