如何处理 scala.js bootstrap 模态对话框中的数据输入?

How do I handle data entry in a scala.js bootstrap modal dialog?

我正在使用 scala.js,加上 bootstrap facade,从我的用户那里收集一些数据:

def showModal(kopiUser: KopiUser): Unit = {
  def modal = Modal().withTitle("modal title").
    withBody(
      p(s"${kopiUser.displayName}, please enter your data"),
      Form(
        FormInput.text("fieldlabel")
      )
    ).
    withButtons(
      Modal.closeButton(),
      Modal.button("Submit", Modal.dismiss)
    )
  modal.show()
}

当用户点击 "Submit" 时,我想获取输入的数据并对其进行处理。

对话框是动画的,根据 bootstrap 默认设置滑动和淡入淡出,所以我不能只在按钮上注册一个 onClick,对吗?

我如何以一种好的方式做到这一点 - 即最好是某种 bootstrap/scala.js 的方式,以便我保持我的类型安全?

我查看了 bootstrap/scala.js 项目示例,但它只显示了一个示例对话框,对数据没有任何作用。

我故意从这个问题中删除了 bootstrap 标签,我正在寻找如何用 scala.js 解决这个问题(是否通过 bootstrap 外观),而不是仅仅使用 bootstrap 本身。

这是 bootstrap/scala.js v1.1.1 中对象 TestModal 的修改示例。当然还有其他方法可以做到这一点,但一种解决方案是将字段定义移出 apply() 和表单。 这样您就可以在 TestModal2 对象之外查看和使用它们。

object TestModal2 {
  val modalInputValue = Var("10000000") // Better use string
  val radioGroup = FormInput.radioGroup(FormInput.radio("Test1", "modal-title", "First radio"), FormInput.radio("Test2", "modal-title", "Second radio"))
  val select = FormInput.simpleSelect("Plain select", "Option 1", "Option 2", "Option 3")
  val multipleSelect = FormInput.simpleMultipleSelect("Multiple select", "Option 1", "Option 2", "Option 3")
  val inputTextArea = FormInput.textArea("Money text area", rows := 1, modalInputValue.reactiveInput)
  val selectedFile = Var("")
  val inputFile = FormInput.file("Test file", onchange := Bootstrap.jsInput { input ⇒
    val file = input.files.head
    selectedFile.update(file.name)
    window.alert(s"File selected: ${file.name}")
  })
  val form = Form(
    FormInputGroup(FormInputGroup.label("Money"), FormInputGroup.addon("usd".fontAwesome(FontAwesome.fixedWidth)), FormInputGroup.number(modalInputValue.reactiveInput)),
    radioGroup,
    select,
    multipleSelect,
    inputTextArea,
    inputFile
  )

  def apply()(implicit ctx: Ctx.Owner): Modal = {
    Modal()
      .withTitle(radioGroup.value, " / ", select.selected.map(_.head), " / ", multipleSelect.selected.map(_.mkString(" + ")))
      .withBody(p("You won ", modalInputValue, "$"), p(form))
      .withButtons(Modal.closeButton(), Modal.button("Take", Modal.dismiss))
  }
}

如果您在调用代码中的某处放置,例如这个

    TestModal2.modalInputValue.trigger(
      println("modalInputValue = " + TestModal2.modalInputValue.now)
    )
    TestModal2.select.selected.trigger(
      println("select = " + TestModal2.select.selected.now)
    )
    TestModal2.selectedFile.trigger(
      println("selectedFile = " + TestModal2.selectedFile.now)
    )

当输入值在打开的对话框中发生时,您会立即在控制台上看到输入值发生变化。

这是 scalajs-bootstrap 项目的维护者给我的答案。

def showModal(kopiUser: KopiUser): Unit = {
  val data = Var("")
  def modal = Modal().withTitle("modal title").
    withBody(
      p(s"${kopiUser.displayName}, please enter your data"),
      Form(
        FormInput.text("fieldlabel", data.reactiveInput)
      )
    ).
    withButtons(
      Modal.closeButton(),
      Modal.button("Submit", Modal.dismiss, onclick := Bootstrap.jsClick { _ ⇒
        // Do something with input
        window.alert(data.now)
      })
    )
  modal.show()
}

为了做我想做的事(包括在没有输入数据时不关闭对话框),我不得不另外破解 Modal facade class 这样我就可以注册 onHide、onHidden 事件来不关闭对话框等