电梯 - 自动完成使用Ajax提交(Lift - Autocomplete with Ajax Su

2019-07-28 20:04发布

我想用自动完成阿贾克斯。 所以我的目标是有:

  • 当用户键入的东西在文本字段中,由服务器提供的一些建议出现(我必须找到一个数据库的建议)

  • 当用户按下“确认”键,点击其他地方比在自动完成框,或当他/她选择的建议,在文本框的字符串被发送到服务器。

我第一次尝试使用通过电梯提供的自动完成构件,但我面临三个问题:

  • 它的目的是要扩展选择,也就是说,你可以原本只提交建议值。
  • 这并不意味着使用Ajax使用。
  • 当结合它得到马车WiringUI

所以,我的问题是:如何结合jQuery的自动完成 ,并在提升服务器交互。 我想我应该用一些回调,但我不掌握它们。

提前致谢。

更新这里是第一个实现我试过,但回调不工作:

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函数来更新自动完成建议

Answer 1:

下面是你需要做的事。

1)确保您使用的电梯2.5快照(这是在早期版本可行的,但它更困难)

2)在摘要中使用渲染页面,使用SHtml.ajaxCall(特别是,你可能想这个版本: https://github.com/lift/framework/blob/master/web/webkit/src/main/斯卡拉/ NET / liftweb / HTTP / SHtml.scala#L170 ),这将允许您注册接受您的搜索字词的服务器端函数返回一个包含落成的JSON响应。 您也将注册在与JsContext JSON响应发生一些动作。

3)把AjaxCall的上面将返回JsExp对象,这将导致在AJAX请求时,它的调用。 使用内容的网页上的JavaScript函数中嵌入它。

4)线材他们与一些客户端JS。

更新 -一些代码来帮助你。 它绝对可以用电梯2.5更简洁地完成,但由于2.4一些不一致的地方,我结束了我自己的滚动AjaxCall的类似功能。 S.fmapFunc在服务器端登记的功能和作用体使来自客户机的电梯AJAX调用,然后调用JSON响应的RE函数(它来自的jQuery自动完成)。

我的jQuery插件“激活”的文本输入


(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);

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


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');" +
        """
        }
        """)

更新2 -要添加上面的函数到您的网页,使用CssSelector变换类似于下面的一个。 该> *手段追加到已经匹配的脚本元素中存在什么。 我已经得到了我在页面上定义等功能,这增加了搜索功能给他们。


"script >*" #> autoCompleteJs

您可以查看源代码,以验证它是否存在在页面上可以称得上就像任何其他JS功能。



Answer 2:

随着戴夫·惠特克的帮助下,这里是我想出了解决方案。

我不得不改变一些行为来获得:

  • 在ajaxText元件所需的文本(从自动完成与否)
  • 可能有同一个页面上的多个自动完成的表格
  • 当自动完成建议选择一些模糊之前ajaxText提交答案。

秤配件

private def getSugggestions(current: String, limit: Int):List[String] = {
  /* returns list of suggestions */
}

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


def xml = {
  val id = "myId" //possibility to have multiple autocomplete fields on same page
  Script(OnLoad(JsRaw("jQuery('#"+id+"').createAutocompleteField("+autoCompleteJs.toJsCmd+")")))     ++
  SHtml.ajaxText(cell.get, s=>{ cell.set(s); SearchMenu.recomputeResults; Noop}, "id" -> id)
}

脚本插入到页面页眉:

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

注:我接受戴夫的回答,我的仅仅是我的目的提供了一个完整的答案



文章来源: Lift - Autocomplete with Ajax Submission