Compound
--------

Preparation::

    >>> import yafowil.common
    >>> import yafowil.compound
    >>> from yafowil.base import factory
    >>> from yafowil.utils import Tag
    >>> tag = Tag(lambda msg: msg)           

Render Compound with values set via compound widget::

    >>> value = {
    ...     'inner': 'Value 1 from parent',
    ...     'inner2': 'Value 2 from parent',
    ... }
    >>> compound = factory('compound', name='COMPOUND', value=value)
    >>> compound['inner']  = factory('text')
    >>> compound['inner2'] = factory('text', props={'required': True})
    >>> pxml(tag('div', compound()))
    <div>
      <input class="text" id="input-COMPOUND-inner" name="COMPOUND.inner" type="text" value="Value 1 from parent"/>
      <input class="required text" id="input-COMPOUND-inner2" name="COMPOUND.inner2" required="required" type="text" value="Value 2 from parent"/>
    </div>
    <BLANKLINE>

ValueError if value for a compound member is defined both::

    >>> value = {'inner': 'Value 1 from parent'}
    >>> compound = factory('compound', name='COMPOUND', value=value)
    >>> compound['inner']  = factory('text', value='value1')
    >>> pxml(tag('div', compound()))
    Traceback (most recent call last):
      ...
    ValueError: Both compound and compound member provide a value for 'inner'

Render Compound with values set via compound members::

    >>> compound = factory('compound', name='COMPOUND')
    >>> compound['inner']  = factory('text', value='value1')
    >>> compound['inner2'] = factory('text', value='value2', 
    ...                              props={'required': True})
    >>> pxml(tag('div', compound()))
    <div>
      <input class="text" id="input-COMPOUND-inner" name="COMPOUND.inner" type="text" value="value1"/>
      <input class="required text" id="input-COMPOUND-inner2" name="COMPOUND.inner2" required="required" type="text" value="value2"/>
    </div>
    <BLANKLINE>

Extract Compound empty::    

    >>> data = compound.extract({})
    >>> data 
    <RuntimeData COMPOUND, value=<UNSET>, 
    extracted=odict([('inner', <UNSET>), ('inner2', <UNSET>)]) at ...> 

    >>> data['inner']
    <RuntimeData COMPOUND.inner, value='value1', extracted=<UNSET> at ...>
    
    >>> data.extracted
    odict([('inner', <UNSET>), ('inner2', <UNSET>)])

Extract with a value in request::

    >>> data = compound.extract({'COMPOUND.inner': 'newvalue'})
    >>> data['inner']
    <RuntimeData COMPOUND.inner, value='value1', extracted='newvalue' at ...> 
    
    >>> data.extracted
    odict([('inner', 'newvalue'), ('inner2', <UNSET>)])

Extract with empty required, error should be there::

    >>> data = compound.extract({'COMPOUND.inner2': ''})
    >>> data['inner2']
    <RuntimeData COMPOUND.inner2, value='value2', extracted='', 
    1 error(s) at ...>

Compound display renderers, same as edit renderers::

    >>> compound = factory('compound', name='COMPOUND', mode='display')
    >>> pxml(tag('div', compound()))
    <div/>
    <BLANKLINE>

Compound with structural compound as child::

    >>> value = {
    ...     'inner': 'Value 1 from parent',
    ...     'inner2': 'Value 2 from parent',
    ... }
    >>> compound = factory('compound', name='COMPOUND', value=value)
    >>> structural = compound['STRUCTURAL'] = factory(
    ...     'compound',
    ...     props={'structural': True})
    >>> structural['inner']  = factory('text')
    >>> structural['inner2'] = factory('text', props={'required': True})
    >>> pxml(tag('div', compound()))
    <div>
      <input class="text" id="input-COMPOUND-inner" name="COMPOUND.inner" type="text" value="Value 1 from parent"/>
      <input class="required text" id="input-COMPOUND-inner2" name="COMPOUND.inner2" required="required" type="text" value="Value 2 from parent"/>
    </div>
    <BLANKLINE>
    
    >>> compound.printtree()
    <class 'yafowil.base.Widget'>: COMPOUND
      <class 'yafowil.base.Widget'>: STRUCTURAL
        <class 'yafowil.base.Widget'>: inner
        <class 'yafowil.base.Widget'>: inner2
    
    >>> data = compound.extract({
    ...     'COMPOUND.inner': 'newvalue',
    ...     'COMPOUND.inner2': '',
    ... })
    >>> data.printtree()
    <RuntimeData COMPOUND, value={'inner2': 'Value 2 from parent', 'inner': 'Value 1 from parent'}, extracted=odict([('inner', 'newvalue'), ('inner2', '')]) at ...>
      <RuntimeData COMPOUND.inner, value='Value 1 from parent', extracted='newvalue' at ...>
      <RuntimeData COMPOUND.inner2, value='Value 2 from parent', extracted='', 1 error(s) at ...>
    
    >>> data.extracted
    odict([('inner', 'newvalue'), ('inner2', '')])

Compound with compound as child::

    >>> value = {
    ...     'CHILD_COMPOUND': {
    ...         'inner': 'Value 1 from parent',
    ...         'inner2': 'Value 2 from parent',
    ...     }
    ... }
    >>> compound = factory('compound', name='COMPOUND', value=value)
    >>> child_compound = compound['CHILD_COMPOUND'] = factory('compound')
    >>> child_compound['inner']  = factory('text')
    >>> child_compound['inner2'] = factory('text', props={'required': True})
    >>> pxml(tag('div', compound()))
    <div>
      <input class="text" id="input-COMPOUND-CHILD_COMPOUND-inner" name="COMPOUND.CHILD_COMPOUND.inner" type="text" value="Value 1 from parent"/>
      <input class="required text" id="input-COMPOUND-CHILD_COMPOUND-inner2" name="COMPOUND.CHILD_COMPOUND.inner2" required="required" type="text" value="Value 2 from parent"/>
    </div>
    <BLANKLINE>
    
    >>> compound.printtree()
    <class 'yafowil.base.Widget'>: COMPOUND
      <class 'yafowil.base.Widget'>: CHILD_COMPOUND
        <class 'yafowil.base.Widget'>: inner
        <class 'yafowil.base.Widget'>: inner2
    
    >>> data = compound.extract({
    ...     'COMPOUND.CHILD_COMPOUND.inner': 'newvalue',
    ...     'COMPOUND.CHILD_COMPOUND.inner2': 'newvalue2',
    ... })
    >>> data.printtree()
    <RuntimeData COMPOUND, value={'CHILD_COMPOUND': {'inner2': 'Value 2 from parent', 'inner': 'Value 1 from parent'}}, extracted=odict([('CHILD_COMPOUND', odict([('inner', 'newvalue'), ('inner2', 'newvalue2')]))]) at ...>
      <RuntimeData COMPOUND.CHILD_COMPOUND, value={'inner2': 'Value 2 from parent', 'inner': 'Value 1 from parent'}, extracted=odict([('inner', 'newvalue'), ('inner2', 'newvalue2')]) at ...>
        <RuntimeData COMPOUND.CHILD_COMPOUND.inner, value='Value 1 from parent', extracted='newvalue' at ...>
        <RuntimeData COMPOUND.CHILD_COMPOUND.inner2, value='Value 2 from parent', extracted='newvalue2' at ...>

    >>> data.extracted
    odict([('CHILD_COMPOUND', 
    odict([('inner', 'newvalue'), 
    ('inner2', 'newvalue2')]))])

Compound with structural compound with compound as children::

    >>> value = {
    ...     'CHILD_COMPOUND': {
    ...         'inner': 'Value 1 from parent',
    ...         'inner2': 'Value 2 from parent',
    ...     }
    ... }
    >>> compound = factory('compound', name='COMPOUND', value=value)
    >>> structural = compound['STRUCTURAL'] = factory(
    ...     'compound',
    ...     props={'structural': True})
    >>> child_compound = structural['CHILD_COMPOUND'] = factory('compound')
    >>> child_compound['inner']  = factory('text')
    >>> child_compound['inner2'] = factory('text', props={'required': True})
    >>> pxml(tag('div', compound()))
    <div>
      <input class="text" id="input-COMPOUND-CHILD_COMPOUND-inner" name="COMPOUND.CHILD_COMPOUND.inner" type="text" value="Value 1 from parent"/>
      <input class="required text" id="input-COMPOUND-CHILD_COMPOUND-inner2" name="COMPOUND.CHILD_COMPOUND.inner2" required="required" type="text" value="Value 2 from parent"/>
    </div>
    <BLANKLINE>
    
    >>> compound.printtree()
    <class 'yafowil.base.Widget'>: COMPOUND
      <class 'yafowil.base.Widget'>: STRUCTURAL
        <class 'yafowil.base.Widget'>: CHILD_COMPOUND
          <class 'yafowil.base.Widget'>: inner
          <class 'yafowil.base.Widget'>: inner2
    
    >>> compound['STRUCTURAL'].attrs
    {'structural': True}
    
    >>> compound['STRUCTURAL']['CHILD_COMPOUND'].attrs
    {}
    
    >>> data = compound.extract({
    ...     'COMPOUND.CHILD_COMPOUND.inner': 'newvalue',
    ...     'COMPOUND.CHILD_COMPOUND.inner2': 'newvalue2',
    ... })
    
    >>> data.printtree()
    <RuntimeData COMPOUND, value={'CHILD_COMPOUND': {'inner2': 'Value 2 from parent', 'inner': 'Value 1 from parent'}}, extracted=odict([('CHILD_COMPOUND', odict([('inner', 'newvalue'), ('inner2', 'newvalue2')]))]) at ...>
      <RuntimeData COMPOUND.CHILD_COMPOUND, value={'inner2': 'Value 2 from parent', 'inner': 'Value 1 from parent'}, extracted=odict([('inner', 'newvalue'), ('inner2', 'newvalue2')]) at ...>
        <RuntimeData COMPOUND.CHILD_COMPOUND.inner, value='Value 1 from parent', extracted='newvalue' at ...>
        <RuntimeData COMPOUND.CHILD_COMPOUND.inner2, value='Value 2 from parent', extracted='newvalue2' at ...>
    
    >>> data.extracted
    odict([('CHILD_COMPOUND', 
    odict([('inner', 'newvalue'), 
    ('inner2', 'newvalue2')]))])

Address different compounds with value on parent::

    >>> value = {
    ...     'c1': {
    ...         'f1': 'Foo',
    ...     },
    ...     'c2': {
    ...         'f2': 'Bar',
    ...         'f3': 'Baz',
    ...     },
    ... }
    >>> compound = factory('compound', 'comp', value=value)
    >>> compound['c1'] = factory('compound')
    >>> compound['c1']['f1'] = factory('text')
    >>> compound['c2'] = factory('compound')
    >>> compound['c2']['f2'] = factory('text')
    >>> compound['c2']['f3'] = factory('text')
    >>> compound['c3'] = factory('compound')
    >>> compound['c3']['f4'] = factory('text')
    
    >>> pxml(tag('div', compound()))
    <div>
      <input class="text" id="input-comp-c1-f1" name="comp.c1.f1" type="text" value="Foo"/>
      <input class="text" id="input-comp-c2-f2" name="comp.c2.f2" type="text" value="Bar"/>
      <input class="text" id="input-comp-c2-f3" name="comp.c2.f3" type="text" value="Baz"/>
      <input class="text" id="input-comp-c3-f4" name="comp.c3.f4" type="text" value=""/>
    </div>
    <BLANKLINE>
    
    >>> compound.printtree()
    <class 'yafowil.base.Widget'>: comp
      <class 'yafowil.base.Widget'>: c1
        <class 'yafowil.base.Widget'>: f1
      <class 'yafowil.base.Widget'>: c2
        <class 'yafowil.base.Widget'>: f2
        <class 'yafowil.base.Widget'>: f3
      <class 'yafowil.base.Widget'>: c3
        <class 'yafowil.base.Widget'>: f4
    
    >>> data = compound.extract({
    ...     'comp.c1.f1': 'Foo 1',
    ...     'comp.c2.f2': 'Bar 2',
    ...     'comp.c2.f3': 'Baz 1',
    ... })
    
    >>> data.printtree()
    <RuntimeData comp, value={'c2': {'f2': 'Bar', 'f3': 'Baz'}, 'c1': {'f1': 'Foo'}}, extracted=odict([('c1', odict([('f1', 'Foo 1')])), ('c2', odict([('f2', 'Bar 2'), ('f3', 'Baz 1')])), ('c3', odict([('f4', <UNSET>)]))]) at ...>
      <RuntimeData comp.c1, value={'f1': 'Foo'}, extracted=odict([('f1', 'Foo 1')]) at ...>
        <RuntimeData comp.c1.f1, value='Foo', extracted='Foo 1' at ...>
      <RuntimeData comp.c2, value={'f2': 'Bar', 'f3': 'Baz'}, extracted=odict([('f2', 'Bar 2'), ('f3', 'Baz 1')]) at ...>
        <RuntimeData comp.c2.f2, value='Bar', extracted='Bar 2' at ...>
        <RuntimeData comp.c2.f3, value='Baz', extracted='Baz 1' at ...>
      <RuntimeData comp.c3, value=<UNSET>, extracted=odict([('f4', <UNSET>)]) at ...>
        <RuntimeData comp.c3.f4, value=<UNSET>, extracted=<UNSET> at ...>

Check compound with value callbacks::

    >>> def val(widget, data):
    ...     return 'val F1'
    >>> value = {
    ...     'f1': val,
    ... }
    >>> compound = factory('compound', 'comp', value=value)
    >>> compound['f1'] = factory('text')
    >>> compound()
    u'<input class="text" id="input-comp-f1" name="comp.f1" type="text" value="val F1" />'
    
    >>> data = compound.extract({'comp.f1': 'New val 1'})
    >>> data.printtree()
    <RuntimeData comp, value={'f1': <function val at ...>}, extracted=odict([('f1', 'New val 1')]) at ...>
      <RuntimeData comp.f1, value='val F1', extracted='New val 1' at ...>

    >>> def value(widget, data):
    ...     return {
    ...         'f1': 'F1 Val'
    ...     }
    >>> compound = factory('compound', 'comp', value=value)
    >>> compound['f1'] = factory('text')
    >>> compound()
    u'<input class="text" id="input-comp-f1" name="comp.f1" type="text" value="F1 Val" />'
    
    >>> data = compound.extract({'comp.f1': 'New val 1'})
    >>> data.printtree()
    <RuntimeData comp, value={'f1': 'F1 Val'}, extracted=odict([('f1', 'New val 1')]) at ...>
      <RuntimeData comp.f1, value='F1 Val', extracted='New val 1' at ...>


Div
---

Div blueprint can act as compound or leaf widget::

    >>> div = factory('div', name='WRAPPED_COMPOUND')
    >>> div['inner']  = factory('text', value='value1')
    >>> div['inner2'] = factory('text', value='value2', 
    ...                                      props={'required': True})
    >>> pxml(div())
    <div>
      <input class="text" id="input-WRAPPED_COMPOUND-inner" name="WRAPPED_COMPOUND.inner" type="text" value="value1"/>
      <input class="required text" id="input-WRAPPED_COMPOUND-inner2" name="WRAPPED_COMPOUND.inner2" required="required" type="text" value="value2"/>
    </div>
    <BLANKLINE>
    
    >>> data = div.extract({
    ...     'WRAPPED_COMPOUND.inner': '1',
    ...     'WRAPPED_COMPOUND.inner2': '2',
    ... })
    >>> data.printtree()
    <RuntimeData WRAPPED_COMPOUND, value=<UNSET>, extracted=odict([('inner', '1'), ('inner2', '2')]) at ...>
      <RuntimeData WRAPPED_COMPOUND.inner, value='value1', extracted='1' at ...>
      <RuntimeData WRAPPED_COMPOUND.inner2, value='value2', extracted='2' at ...>
    
    >>> div = factory(
    ...     'div',
    ...     name='WRAPPED_COMPOUND',
    ...     props={'class': 'foo'},
    ...     mode='display')
    >>> pxml(div())
    <div class="foo"/>
    <BLANKLINE>
    
    >>> input = factory('div:text', 'field', value='1')
    >>> pxml(input())
    <div>
      <input class="text" id="input-field" name="field" type="text" value="1"/>
    </div>
    <BLANKLINE>
    
    >>> data = input.extract({
    ...     'field': '2',
    ... })
    >>> data.printtree()
    <RuntimeData field, value='1', extracted='2' at ...>
    
    >>> input = factory('div:text', 'field', value='1', mode='display')
    >>> pxml(input())
    <div>
      <div class="display-text" id="display-field">1</div>
    </div>
    <BLANKLINE>


Fieldset
--------

::

    >>> compound = factory('fieldset', 
    ...                    'COMPOUND',
    ...                    props={'legend': 'Some Test'})
    >>> compound['inner'] = factory('text', 'inner', 'value')
    >>> compound['inner2'] = factory('text', 'inner2', 'value2')
    >>> pxml(compound())
    <fieldset id="fieldset-COMPOUND">
      <legend>Some Test</legend>
      <input class="text" id="input-COMPOUND-inner" name="COMPOUND.inner" type="text" value="value"/>
      <input class="text" id="input-COMPOUND-inner2" name="COMPOUND.inner2" type="text" value="value2"/>
    </fieldset>
    <BLANKLINE>

Fieldset display renderers are the same as fieldset edit renderers::

    >>> compound = factory('fieldset', 
    ...                    'COMPOUND',
    ...                    props={'legend': 'Some Test'},
    ...                    mode='display')
    >>> pxml(compound())
    <fieldset id="fieldset-COMPOUND">
      <legend>Some Test</legend>
    </fieldset>
    <BLANKLINE>

Test Form::

    >>> form = factory('form',
    ...                name = 'FORM',
    ...                props={'action': 'http://fubar.com'})
    >>> form()
    u'<form action="http://fubar.com" enctype="multipart/form-data" id="form-FORM" method="post" novalidate="novalidate"></form>'

Form display renderer::

    >>> form = factory('form',
    ...                name = 'FORM',
    ...                props={'action': 'http://fubar.com'},
    ...                mode='display')
    >>> form()
    u'<div></div>'

  
Form
----

::

    >>> from yafowil.base import factory
    >>> from yafowil.controller import Controller
    
Create a form::
    
    >>> form = factory('form', name='myform', 
    ...     props={'action': 'http://www.domain.tld/someform'})
    >>> form['someinput'] = factory('label:text', 
    ...     props={'label': 'Your Text'})
    
    >>> def formaction(widget, data):
    ...     data.printtree()

    >>> def formnext(request):
    ...     return 'http://www.domain.tld/result'
    
    >>> form['submit'] = factory('submit', 
    ...     props={'handler': formaction, 'next': formnext, 'action': True})
    
Render an empty form::

    >>> pxml(form())
    <form action="http://www.domain.tld/someform" enctype="multipart/form-data" id="form-myform" method="post" novalidate="novalidate">
      <label for="input-myform-someinput">Your Text</label>
      <input class="text" id="input-myform-someinput" name="myform.someinput" type="text" value=""/>
      <input id="input-myform-submit" name="action.myform.submit" type="submit" value="submit"/>
    </form>
    <BLANKLINE>

Get form data out of request (request is expected dict-like)::

    >>> request = {'myform.someinput': 'Hello World', 
    ...            'action.myform.submit': 'submit'}
    >>> controller = Controller(form, request)
    <RuntimeData myform, value=<UNSET>, extracted=odict([('someinput', 'Hello World'), ('submit', <UNSET>)]) at ...>
      <RuntimeData myform.someinput, value=<UNSET>, extracted='Hello World' at ...>
      <RuntimeData myform.submit, value=<UNSET>, extracted=<UNSET> at ...>

Form action property can be callable::

    >>> def action(widget, data):
    ...     return 'actionfromcall'
    
    >>> form = factory(
    ...     'form',
    ...     name='form',
    ...     props={
    ...         'action':action,
    ...     })
    >>> form()
    u'<form action="actionfromcall" enctype="multipart/form-data" 
    id="form-form" method="post" novalidate="novalidate"></form>'
    
Create label for field in other compound::

    >>> form = factory(
    ...     'form',
    ...     name = 'form',
    ...     props = {
    ...         'action': 'action'})
    >>> form['label'] = factory(
    ...     'label',
    ...     props={
    ...         'label': 'Foo',
    ...         'for': 'field'})
    >>> form['field'] = factory('text')
    >>> form()
    u'<form action="action" enctype="multipart/form-data" id="form-form" 
    method="post" novalidate="novalidate"><label 
    for="input-form-field">Foo</label><input 
    class="text" id="input-form-field" name="form.field" type="text" 
    value="" /></form>'
