Поднимите Ajax Multi Select Box - PullRequest
       5

Поднимите Ajax Multi Select Box

10 голосов
/ 26 января 2012

Я новичок в скале и лифте, и я хочу сделать форму с небольшим количеством Аякса.Поэтому основная форма происходит из обычного фрагмента с сохранением состояния, а среднее содержимое заключено в некоторую форму Ajax (содержимое в другом фрагменте, но не с сохранением состояния, поскольку я не могу использовать ValueCell в состоянии с сохранением состояния).

В него я хочу динамически добавлять любые нет,из нескольких полей выбора, как пользователь хочет, нажав кнопку «ДОБАВИТЬ».

Я сделал это для обычного выпадающего списка, выбрав SHtml.ajaxSelect () и сохранить в ValueCell, а также сохранить в контексте сеанса.

Здесь я могу использовать ValueCell для хранения данных, потому что ajaxSelect поддерживает ajax.Но в multi-select нет "ajaxMultiSelect" ??Поэтому мне нужно извлекать данные из этих динамически добавляемых полей множественного выбора в переменные моей формы при нажатии кнопки «Отправить» в общей форме.

http://seventhings.liftweb.net/wiring - этот пример является моим руководством для выполнения моей задачи,Здесь они используют динамически добавлять текстовые поля.Но я хочу добавить множественный выбор и сохранить данные при нажатии кнопки подтверждения.

Пожалуйста, помогите мне кому-нибудь.Если вам нужны дальнейшие разъяснения, я могу дать.

Спасибо ВСЕМ ...

Ответы [ 2 ]

2 голосов
/ 28 июня 2012

Если все, что вам нужно, это множественный выбор, чьи значения могут быть отправлены на сервер, когда пользователь нажимает кнопку «Сохранить», тогда достаточно набора SHtml.multiselect объектов в форме AJAX.

С другой стороны, если вам нужен AJAX-вызов каждый раз, когда пользователь изменяет значение множественного выбора, вам, вероятно, придется использовать тот же SHtml.multiselect, но добавить обработчик события onchange, который вызывает функцию JavaScript, содержащую ajaxCall.

Вот фрагмент, который создает функцию JavaScript doCallback() и добавляет ее на страницу в #placeholder.Это вызывает commandCallback(commandString) на сервере.

val log = SHtml.ajaxCall(JsRaw("commandString"), commandCallback _)._2.cmd
val f = JsCmds.Function("doCallback", List[String](), log)
("#placeholder" #> JsCmds.Script(f)).apply(ns)
0 голосов
/ 20 сентября 2012

Я знаю, что это немного более старый вопрос, но вот мой снимок (поскольку в последних снимках по-прежнему отсутствует ajax multiSelect), и я мог видеть, что он пригодится

Вы можете основывать его на обычном ajaxSelect. Основные изменения:

  1. Вы должны извлечь все значения и отправить их (отправка формы - это просто обычные urlEncoded postParams), но это наиболее непонятно, если вы просто посмотрите, как это сделать.
  2. Вы должны изменить значение по умолчанию на Seq [String] (это также требует изменения теста, чтобы увидеть, должен ли быть выбран выбранный параметр)
  3. Вы должны решить, хотите ли вы, чтобы колбэк был изменен или размыт. В моем примере я сделаю это onblur, но вы можете сделать это настраиваемым.

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

Это должно работать, но я не проверял это. Если у меня будет время, я протестирую его и посмотрю, смогу ли я добавить его (и его перегрузки) в основную ветку.

Удачи!

-Austen

...