如何获取表单所有字段的值?

时间:2014-12-27 06:05:35

标签: smalltalk amber-smalltalk

我在客户端Amber解决方案中有这样的HTML表单

<form id="myForm1">
  Creator:  <input type="text" name="creator" />
  <br>
  Title:  <input type="text" name="title" />
  <br>
  Description:  <input type="text" name="description" />
  <br>
  Doctype:  <input type="text" name="doctype" />
  <br>
  Tags:  <input type="text" name="tags" />
</form>

问题

如何迭代表单的所有字段,以便将字段内容放入Amber字典中,字段名称为键,文本内容为值?

Stephen-Eggermont和MKroenert回答之后的新版问题

如何获取表单所有字段的值,以便将它们放入Amber字典中,字段名称为键,文本内容为值?

或者是否有一种惯用的方法来创建表单并检索值?

注意:如果这样可以使内容更具可读性,则可以使用Amber代码构建表单。

参考

回答后编辑:FileIn code

MKroenert提供的答案很好

以下是我测试过的代码。它可以直接在工作区中提交

    Widget subclass: #AmberFormExample
    instanceVariableNames: 'dictionary inputs'
    package: 'TodoList'!

!AmberFormExample methodsFor: 'not yet classified'!

collectValues
    inputs do: [ :each |
        dictionary at: (each asJQuery attr: 'name')
            put: (each asJQuery val).
        ].

Transcript show: dictionary printString
!

initialize
    dictionary := Dictionary new.
    inputs := Array new.
!

renderInput: inputName on: html
    html p: [
        html label with: inputName.
            inputs add: (html input id: inputName;
                name: inputName;
                yourself)]
!

renderOn: html
    inputs removeAll.
    html form id: 'myForm1'; with: [
        #('Creator' 'Title' 'Description' 'Doctype' 'Tags') do: [ :each |
            self renderInput: each on: html]].
    html button
        with: 'Collect Inputfield Values';
        onClick: [
            self collectValues.
            ]
! !

2 个答案:

答案 0 :(得分:4)

我重用了this SO question中的代码并在Amber中重写了它以解决问题的第一部分。 以下是迭代所有输入字段的方法:

(('#myForm1 *' asJQuery)
    filter: ':input')
        each: [ :thisArg :index |
            console log: thisArg ] currySelf
需要

This Amber recipe才能访问JavaScript this

将输入字段的名称和值打印到JavaScript控制台可以这样做:

(('#myForm1 *' asJQuery)
    filter: ':input')
        each: [ :thisArg :index |
            console log: (thisArg asJQuery attr: 'name').
            console log: (thisArg asJQuery val)] currySelf

将值放入字典中:

| dict |
dict := Dictionary new.
(('#myForm1 *' asJQuery)
    filter: ':input')
        each: [ :thisArg :index |
            dict at: (thisArg asJQuery attr: 'name')
                put: (thisArg asJQuery val)] currySelf

至于问题的第二部分,Amber中有Web包,其中包含用于生成HTML页面的类。 您所做的是创建Widget的子类并实现renderOn: html方法。 作为html参数传入的对象的类型为HTMLCanvas,可用于创建这样的HTML表单:

renderOn: html
    html form with: [
        html input id: 'creator'.
        html input id: 'title'.]

这是一个完整的例子。 以此为出发点,并意识到它可能不是最有效的做事方式

Widget subclass: #AmberFormExample
    instanceVariableNames: 'dictionary inputs'
    package: 'Examples'

AmberFormExample>>initialize
    dictionary := Dictionary new.
    inputs := Array new.

AmberFormExample>>renderOn: html
    inputs removeAll.
    html form id: 'myForm1'; with: [
        #('Creator' 'Title' 'Description' 'Doctype' 'Tags') do: [ :each |
            self renderInput: each on: html]].
    html button
        with: 'Collect Inputfield Values';
        onClick: [
            self collectValues.
            ]

AmberFormExample>>renderInput: inputName on: html
    html p: [
        html label with: inputName.
            inputs add: (html input id: inputName;
                name: inputName;
                yourself)]

AmberFormExample>>collectValues
    inputs do: [ :each |
        dictionary at: (each asJQuery attr: 'name')
            put: (each asJQuery val).
        ].

在正在运行的Amber实例中实现此类之后,可以使用以下代码执行它:

AmberFormExample new appendToJQuery: 'body' asJQuery

答案 1 :(得分:1)

您的表单中有很多重复项。您可能想看一下HTMLCanvas及其在IDE中的使用方法。

您可以添加方法renderField: aFieldName on: aCanvas并重复使用该方法5次。你看过Seaside了吗?

最终结果应该是

renderOn: html
    html form with: [
        #('Creator' 'Title' 'Description' 'Doctype' 'Tags') do: [:each |
            self renderField: each on: html]