Import requirements
::

    >>> import yafowil.loader
    >>> import yafowil.widget.dict
    >>> from yafowil.base import factory

Create empty Dict widget
::
    
    >>> form = factory('form',
    ...                name='myform',
    ...                props={'action': 'myaction'})
    >>> form['mydict'] = factory('dict',
    ...                          props={
    ...                              'head': {
    ...                                  'key': 'Key',
    ...                                  'value': 'Value',
    ...                              }
    ...                          })
    >>> form()
    u'<form action="myaction" enctype="multipart/form-data" id="form-myform" 
    method="post"><table class="dictwidget" 
    id="dictwidget_myform.mydict.entry"><thead><tr><th>Key</th><th>Value</th><th><div 
    class="dict_actions"><a class="dict_row_add" 
    href="#">&#160;</a></div></th></tr></thead><tbody></tbody></table></form>'

Create dict widget with preset values
::

    >>> from odict import odict
    >>> value = odict()
    >>> value['key1'] = u'Value1'
    >>> value['key2'] = u'Value2'
    >>> form = factory('form',
    ...                name='myform',
    ...                props={'action': 'myaction'})
    >>> form['mydict'] = factory('dict',
    ...                          value=value,
    ...                          props={
    ...                              'head': {
    ...                                  'key': 'Key',
    ...                                  'value': 'Value',
    ...                              }
    ...                          })
    >>> form()
    u'<form action="myaction" enctype="multipart/form-data" 
    ... 
    value="Value1" 
    ...
    value="Value2" 
    ...

Base Extraction
::

    >>> request = {
    ...     'myform.mydict.entry0.key': 'key1',
    ...     'myform.mydict.entry0.value': 'New Value 1',
    ...     'myform.mydict.entry1.key': 'key2',
    ...     'myform.mydict.entry1.value': 'New Value 2',
    ... }
    >>> data = form.extract(request=request)
    >>> data.fetch('myform.mydict.entry0.value').extracted
    'New Value 1'
    
    >>> data.fetch('myform.mydict.entry1.value').extracted
    'New Value 2'
    
    >>> data.fetch('myform.mydict').extracted
    odict([('key1', 'New Value 1'), ('key2', 'New Value 2')])

Dict entries increased in UI
::

    >>> request = {
    ...     'myform.mydict.entry0.key': 'key1',
    ...     'myform.mydict.entry0.value': 'New Value 1',
    ...     'myform.mydict.entry1.key': 'key2',
    ...     'myform.mydict.entry1.value': 'New Value 2',
    ...     'myform.mydict.entry2.key': 'key3',
    ...     'myform.mydict.entry2.value': 'New Value 3',
    ... }
    >>> data = form.extract(request=request)
    >>> data.fetch('myform.mydict').extracted
    odict([('key1', 'New Value 1'), 
    ('key2', 'New Value 2'), 
    ('key3', 'New Value 3')])
    
    >>> form(data=data)
    u'<form action="myaction" enctype="multipart/form-data" 
    ... 
    value="New Value 1" 
    ...
    value="New Value 2" 
    ...
    value="New Value 3" 
    ...

Dict entries decreased in UI
::

    >>> request = {
    ...     'myform.mydict.entry0.key': 'key1',
    ...     'myform.mydict.entry0.value': 'Very New Value 1',
    ... }
    >>> data = form.extract(request=request)
    >>> data.fetch('myform.mydict').extracted
    odict([('key1', 'Very New Value 1')])
    
    >>> form(data=data)
    u'<form action="myaction" enctype="multipart/form-data" 
    ... 
    value="Very New Value 1" 
    ...
    
    >>> form(data=data).find('New Value 2')
    -1

Empty keys are ignored
::

    >>> request = {
    ...     'myform.mydict.entry0.key': 'key1',
    ...     'myform.mydict.entry0.value': 'Very New Value 1',
    ...     'myform.mydict.entry1.key': '',
    ...     'myform.mydict.entry1.value': '',
    ... }
    >>> data = form.extract(request=request)
    >>> data.fetch('myform.mydict').extracted
    odict([('key1', 'Very New Value 1')])

Check required
::

    >>> form['mydict'] = factory('error:dict',
    ...                          props={
    ...                              'required': 'I am required',
    ...                              'head': {
    ...                                  'key': 'Key',
    ...                                  'value': 'Value',
    ...                              }
    ...                          })
    >>> request = {}
    >>> data = form.extract(request=request)
    >>> data.fetch('myform.mydict').errors
    [ExtractionError('I am required',)]
    
    >>> form(data=data)
    u'<form action="myaction" enctype="multipart/form-data" id="form-myform" 
    method="post"><div 
    class="error"><div 
    class="errormessage">I am required</div><table 
    class="dictwidget" 
    id="dictwidget_myform.mydict.entry"><thead><tr><th>Key</th><th>Value</th><th><div 
    class="dict_actions"><a class="dict_row_add" 
    href="#">&#160;</a></div></th></tr></thead><tbody></tbody></table></div></form>'
    
    >>> request = {
    ...     'myform.mydict.entry0.key': 'key1',
    ...     'myform.mydict.entry0.value': 'Very New Value 1',
    ... }
    >>> data = form.extract(request=request)
    >>> data.fetch('myform.mydict').errors
    []
    
    >>> form(data=data)
    u'<form action="myaction" enctype="multipart/form-data" 
    ... 
    value="Very New Value 1" 
    ...
    
    >>> form(data=data).find('error')
    -1

Use dict widget as static widget
::

    >>> form['mydict'] = factory('error:dict',
    ...                          value=odict([('k1', 'v1')]),
    ...                          props={
    ...                              'required': 'I am required',
    ...                              'static': True,
    ...                              'head': {
    ...                                  'key': 'Key',
    ...                                  'value': 'Value',
    ...                              }
    ...                          })
    >>> pxml(form())
    <form action="myaction" enctype="multipart/form-data" id="form-myform" method="post">
      <table class="dictwidget" id="dictwidget_myform.mydict.entry">
        <thead>
          <tr>
            <th>Key</th>
            <th>Value</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td class="key">
              <input class="key" disabled="disabled" id="input-myform-mydict-entry0-key" name="myform.mydict.entry0.key" type="text" value="k1"/>
            </td>
            <td class="value">
              <input class="value" id="input-myform-mydict-entry0-value" name="myform.mydict.entry0.value" type="text" value="v1"/>
            </td>
          </tr>
        </tbody>
      </table>
    </form>
    <BLANKLINE>

Static dict extraction. Disabled form fields are not transmitted, but since
order is fixed dict could be reconstructed from original value
::

    >>> request = {
    ...     'myform.mydict.entry0.value': 'New Value 1',
    ... }
    >>> data = form.extract(request=request)
    >>> data.fetch('myform.mydict').extracted
    odict([('k1', 'New Value 1')])

Static dicts required. By default checks if there's a value in every entry
::

    >>> request = {}
    >>> data = form.extract(request=request)
    >>> data.fetch('myform.mydict').errors
    [ExtractionError('I am required',)]

    >>> request = {
    ...     'myform.mydict.entry0.value': '',
    ... }
    >>> data = form.extract(request=request)
    >>> data.fetch('myform.mydict').errors
    [ExtractionError('I am required',)]
