Lift - Autocomplete with Ajax Submission

后端 未结 2 994
难免孤独
难免孤独 2021-02-09 02:32

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

2条回答
  •  闹比i
    闹比i (楼主)
    2021-02-09 03:39

    With the help of Dave Whittaker, here is the solution I came with.

    I had to change some behaviors to get:

    • the desired text (from autocomplete or not) in an ajaxText element
    • the possibility to have multiple autocomplete forms on same page
    • submit answer on ajaxText before blurring when something is selected in autocomplete suggestions.

    Scala part

    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)
    }
    

    Script to insert into page header:

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

    Note: I accepted Dave's answer, mine is just to provide a complete answer for my purpose

提交回复
热议问题