2012-04-06 19 views
8

के साथ स्वत: पूर्ण मैं AJAX के साथ एक स्वत: पूर्ण का उपयोग करना चाहता हूं।लिफ्ट - अजाक्स सबमिशन

  • जब पाठ क्षेत्र में उपयोगकर्ता प्रकार कुछ, कुछ सर्वर द्वारा प्रदान की सुझाव दिखाई देते हैं

  • जब उपयोगकर्ता प्रेस (मैं एक डेटाबेस में सुझाव प्राप्त करने के लिए है): तो मेरा लक्ष्य है "दर्ज करें", स्वत: पूर्ण बॉक्स की तुलना में कहीं और क्लिक करता है, या जब वह कोई सुझाव चुनता है, तो टेक्स्टफील्ड में स्ट्रिंग सर्वर पर भेजी जाती है।

मैं पहली बार लिफ्ट द्वारा प्रदान की स्वत: पूर्ण विजेट का उपयोग करने की कोशिश की, लेकिन मैं तीन समस्याओं का सामना करना पड़ा:

  • यह है, कि तुम मूल रूप से केवल सुझाव दिया मूल्यों प्रस्तुत कर सकते हैं कहने के लिए है एक विस्तारित चयन करने के लिए है ।
  • इसका उपयोग AJAX के साथ नहीं किया जाना है।
  • WiringUI के साथ संयुक्त होने पर यह छोटी हो जाती है।

तो, मेरा सवाल है: मैं jquery autocomplete को कैसे जोड़ सकता हूं और लिफ्ट में सर्वर से कैसे बातचीत कर सकता हूं। मुझे लगता है कि मुझे कुछ कॉलबैक का उपयोग करना चाहिए लेकिन मैं उन्हें मास्टर नहीं करता हूं।

अग्रिम धन्यवाद।

अद्यतन यहाँ एक पहले कार्यान्वयन मैंने कोशिश की है, लेकिन कॉलबैक काम नहीं करता:

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 क्षेत्र के माध्यम से चयनित परिणाम प्राप्त करने के जो एक जावास्क्रिप्ट फ़ंक्शन
  • का उपयोग कर स्वत: पूर्ण सुझावों को अद्यतन करने के लिए एक स्वत: पूर्ण फ़ील्ड
  • में लपेटा जाएगा

उत्तर

8

यहां आपको क्या करना है।

1) आप लिफ्ट का उपयोग कर रहे यकीन है कि 2.5 स्नैपशॉट (यह पहले के संस्करणों में संभव है, लेकिन यह अधिक कठिन है)

2) टुकड़ा में आप SHtml.ajaxCall का उपयोग करें, पेज रेंडर करने के लिए उपयोग करें (मेक इन विशेष रूप से, आप शायद यह संस्करण चाहते हैं: https://github.com/lift/framework/blob/master/web/webkit/src/main/scala/net/liftweb/http/SHtml.scala#L170) जो आपको एक सर्वर साइड फ़ंक्शन पंजीकृत करने की अनुमति देगा जो आपके खोज शब्द को स्वीकार करता है और पूर्णांक युक्त JSON प्रतिक्रिया लौटाता है। आप JSContext के साथ JSON प्रतिक्रिया पर होने वाली कुछ कार्रवाइयां भी पंजीकृत करेंगे।

3) ऊपर AJAXCall एक जेएसईएक्सपी ऑब्जेक्ट वापस करेगा जो परिणामस्वरूप AJAX अनुरोध के परिणामस्वरूप होगा। इसे अपने स्निपेट का उपयोग करके पृष्ठ पर जावास्क्रिप्ट फ़ंक्शन के भीतर एम्बेड करें।

4) कुछ ग्राहक पक्ष जेएस के साथ उन्हें तार दें।

अद्यतन - कुछ कोड आपकी मदद करने के लिए। यह निश्चित रूप से लिफ्ट 2.5 के साथ अधिक संक्षेप में किया जा सकता है, लेकिन 2.4 में कुछ विसंगतियों के कारण मैंने अपना खुद का AJAX रोल चालू कर दिया। एसfmapFunc सर्वर साइड पर समारोह पंजीकृत करता है और समारोह शरीर ग्राहक से एक लिफ्ट ajax कॉल करता है, तो JSON उत्तर पर रेस समारोह (जो jQuery स्वत: पूर्ण से आता है) invokes।

मेरे 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); 

मेरे स्काला कोड है कि जावास्क्रिप्ट खोज समारोह में परिणाम है "को सक्रिय करने के लिए" पाठ इनपुट:


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 

आप यह देखने के लिए स्रोत देख सकते हैं कि यह पृष्ठ पर मौजूद है और इसे किसी अन्य जेएस फ़ंक्शन की तरह ही कहा जा सकता है।

+0

हाय, दुर्भाग्य से मैं लिफ्ट 2.5 का उपयोग नहीं कर सकता। मैं 2.4 एम 4 लिफ्ट पर हूं। हालांकि, जो मैंने पहले ही उपयोग किया है, ऐसा लगता है कि 2.4 में पहले से ही कॉलबैक लागू किए गए हैं। आपके उत्तर के लिए धन्यवाद। –

+0

मैंने उस समय के साथ अपना प्रश्न अपडेट किया जहां मैं अब अवरुद्ध हूं, किसी भी सुझाव का स्वागत है। –

+0

मुझे यकीन नहीं है कि जब आप कहते हैं कि कॉलबैक काम नहीं करता है तो आपका क्या मतलब है। अद्यतन_सोर्स निष्पादित है? यदि हां, तो आपकी समस्या आपकी वापसी के साथ होने की संभावना है। आप एक एसिंक्रोनस कॉल कर रहे हैं, इसलिए बस JSON को वापस करना पर्याप्त नहीं है, ब्राउज़र नहीं जानता कि इसके साथ क्या किया जाए। आपको एक जेएससीएमडी वापस करने की आवश्यकता होगी जो एक क्रिया करता है, और उस क्रिया का परिणाम JQuery UI स्वत: पूर्ण होना चाहिए। –

2
डेव Whittaker की मदद से

, यहाँ समाधान मैं के साथ आया है।

मैं कुछ व्यवहार को बदलने के लिए पाने के लिए था: एक 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); 
    

    नोट: मैं डेव के जवाब को स्वीकार कर लिया, मेरा बस के लिए एक पूरा जवाब प्रदान करना है मेरा उद्देश्य