2012-01-26 19 views
10

Jestem nowy w scala i windy i chcę, aby formularz z niektórych ajax. Z tego powodu główny formularz pochodzi z normalnego fragmentu kodu stanowego, a treść środkowa jest dołączona do formularza ajaxowego (zawartość w innym fragmencie, ale nie jest stanowa, ponieważ nie można używać wartości ValueCell w pliku Stateful).Wyciąg Ajax multi wybierz box

Tam chcę dodać dynamicznie dowolne nie. pól wyboru wielokrotnego jako użytkownik chcesz, naciskając przycisk "DODAJ".

Zrobiłem to dla zwykłego wyboru rozwijanego wybierając SHtml.ajaxSelect() i zapisać w ValueCell, a także zapisać w kontekście sesji.

Tutaj mogę użyć ValueCell do przechowywania danych, ponieważ ajaxSelect obsługuje dla ajax . Ale w multi-select nie ma "ajaxMultiSelect" ?? Potrzebuję więc , aby pobrać dane z dynamicznie dodawanych pól wyboru wielokrotnego do moich zmiennych formularza po naciśnięciu przycisku "Wyślij" w ogólnym formularzu.

http://seventhings.liftweb.net/wiring - ten przykład jest moim przewodnikiem do wykonania mojego zadania polegającego na wykonaniu . Tutaj używają dynamicznie dodawać pola tekstowe. Ale chcę dodać multiselect i zapisać dane po naciśnięciu przycisku Wyślij.

Proszę, pomóżcie mi. Jeśli chcesz dalszych wyjaśnień, mogę dać.

Dziękuję wszystkim ...

+0

Czy możesz podać kod i powiedzieć nam, co już robi i co powinien zrobić? –

+0

Przykład byłby przydatny, jak już wcześniej powiedziałem. –

Odpowiedz

2

Jeśli chcesz to multi-zaznaczanie, których wartości mogą być wysyłane do serwera, gdy użytkownik naciska przycisk „Zapisz”, potem banda SHtml.multiselect obiektów na formularzu powinny AJAX bądź wystarczający. Z drugiej strony, jeśli potrzebujesz wywołania AJAX za każdym razem, gdy użytkownik zmienia wartość wielokrotnego wyboru, prawdopodobnie będziesz musiał użyć tego samego SHtml.multiselect, ale dodaj obsługę zdarzenia onchange, która wywołuje funkcję JavaScript zawierającą wywołanie ajaxCall .

Oto fragment, który tworzy funkcję JavaScript doCallback() i dodaje ją do strony pod adresem #placeholder. To wywołuje commandCallback(commandString) na serwerze.

val log = SHtml.ajaxCall(JsRaw("commandString"), commandCallback _)._2.cmd 
val f = JsCmds.Function("doCallback", List[String](), log) 
("#placeholder" #> JsCmds.Script(f)).apply(ns) 
+0

Cześć Donald, wiem, że to stary post, który komentuję. Jednak moja sytuacja wygląda następująco. Próbuję rozwiązać dokładnie ten sam problem, co powyższy plakat. Chciałbym uchwycić wartość zaznaczenia (w multiselect) w module onChange, aby móc wykonać pewne przetwarzanie, takie jak edycja wartości tego wyboru, a następnie aktualizowanie zawartości multliselect. Jednak nie mogę użyć twojej funkcji w zwykłym multiselektrze LiftWeb. Proszę zasugerować, co mogę zrobić. – user3825558

0

Wiem, że to nieco starszej pytanie, ale tutaj jest mój strzał (ponieważ wciąż nie wydaje się być ajax wielokrotny w najnowsze migawek), i widziałem jak to nadchodzi w poręcznej

Można to oprzeć na zwykłym ajaxSelect. Główne zmiany to:

  1. Trzeba wyodrębnić wszystkie wartości i przedkłada je (złożenie forma jest po prostu regularne urlencoded postParams), ale jest to najbardziej jasne, czy jesteś po prostu patrząc na to, jak to zrobić.
  2. Trzeba zmienić domyślną wartość seq [String] (Ten requres również zmianę test, aby sprawdzić, czy wybrany powinien być ustawiony)
  3. Musisz zdecydować, czy chcesz, oddzwanianie na zmiany lub na rozmycie. W moim przykładzie zrobię to onblur, ale możesz go skonfigurować.

    private def ajaxMultiSelect_*(opts: Seq[(String, String)], deflt: Seq[String], jsFunc: Box[Call], func: AFuncHolder, attrs: ElemAttr*): Elem = { 
        val optionSelect = 
        """function(funcName, element) { 
         | var postData = "" 
         | var i = 0; 
         | var k = 0; 
         | for (k = 0; k < element.length; k++) { 
         | if (element[k].selected) { 
         |  if (i == 0) 
         |  postData = funcName + '=' + encodeURIComponent(element[k].value); 
         |  else { 
         |  postData = postData + '&' + funcName + '=' + encodeURIComponent(element[k].value); 
         |  } 
         |  i++; 
         | } 
         | } 
         | return postData; 
         |}""".stripMargin 
    
        val raw = (funcName: String, value: String) => JsRaw(optionSelect + "('" + funcName + "'," + value + ")") 
        val key = formFuncName 
    
        val vals = opts.map(_._1) 
        val testFunc = LFuncHolder(in => in.filter(v => vals.contains(v)) match {case Nil => false case xs => func(xs)}, func.owner) 
        fmapFunc((testFunc)) { 
         funcName => 
          (attrs.foldLeft(<select multiple="multiple">{opts.flatMap {case (value, text) => (<option value={value}>{text}</option>) % selected(default.contains(value)))}}</select>)(_ % _)) % 
           ("onblur" -> (jsFunc match { 
            case Full(f) => JsCrVar(key, JsRaw("this")) & deferCall(raw(funcName, key), f) 
            case _ => makeAjaxCall(raw(funcName, "this")) 
           })) 
        } 
    } 
    

To powinno działać, ale nie testowałem go.Jeśli będę miał czas, przetestuję go i zobaczę, czy mogę go uzyskać (i jego przeciążenia) dodałem do gałęzi głównej.

Powodzenia!

-Austen