diff --git a/sleekxmpp/plugins/xep_0004/stanza/field.py b/sleekxmpp/plugins/xep_0004/stanza/field.py
index 9bb9231..43293bf 100644
--- a/sleekxmpp/plugins/xep_0004/stanza/field.py
+++ b/sleekxmpp/plugins/xep_0004/stanza/field.py
@@ -29,8 +29,19 @@ class FormField(ElementBase):
multi_value_types = set(('hidden', 'jid-multi',
'list-multi', 'text-multi'))
+ def setup(self, xml=None):
+ if ElementBase.setup(self, xml):
+ self._type = None
+ else:
+ self._type = self['type']
+
+ def set_type(self, value):
+ self._set_attr('type', value)
+ if value:
+ self._type = value
+
def add_option(self, label='', value=''):
- if self['type'] in self.option_types:
+ if self._type in self.option_types:
opt = FieldOption(parent=self)
opt['label'] = label
opt['value'] = value
@@ -72,15 +83,15 @@ class FormField(ElementBase):
valsXML = self.xml.findall('{%s}value' % self.namespace)
if len(valsXML) == 0:
return None
- elif self['type'] == 'boolean':
+ elif self._type == 'boolean':
return valsXML[0].text in self.true_values
- elif self['type'] in self.multi_value_types:
+ elif self._type in self.multi_value_types:
values = []
for valXML in valsXML:
if valXML.text is None:
valXML.text = ''
values.append(valXML.text)
- if self['type'] == 'text-multi':
+ if self._type == 'text-multi':
values = "\n".join(values)
return values
else:
@@ -113,7 +124,7 @@ class FormField(ElementBase):
del self['value']
valXMLName = '{%s}value' % self.namespace
- if self['type'] == 'boolean':
+ if self._type == 'boolean':
if value in self.true_values:
valXML = ET.Element(valXMLName)
valXML.text = '1'
@@ -122,14 +133,12 @@ class FormField(ElementBase):
valXML = ET.Element(valXMLName)
valXML.text = '0'
self.xml.append(valXML)
- elif self['type'] in self.multi_value_types or not self['type']:
+ elif self._type in self.multi_value_types or self._type in ('', None):
if not isinstance(value, list):
- if self['type'] in self.multi_line_types:
- value = value.split('\n')
- else:
- value = [value]
+ value = value.replace('\r', '')
+ value = value.split('\n')
for val in value:
- if self['type'] in ['', None] and val in self.true_values:
+ if self._type in ('', None) and val in self.true_values:
val = '1'
valXML = ET.Element(valXMLName)
valXML.text = val
@@ -137,7 +146,7 @@ class FormField(ElementBase):
else:
if isinstance(value, list):
raise ValueError("Cannot add multiple values " + \
- "to a %s field." % self['type'])
+ "to a %s field." % self._type)
valXML = ET.Element(valXMLName)
valXML.text = value
self.xml.append(valXML)
diff --git a/tests/test_stanza_xep_0004.py b/tests/test_stanza_xep_0004.py
index 22f8b77..e183e5e 100644
--- a/tests/test_stanza_xep_0004.py
+++ b/tests/test_stanza_xep_0004.py
@@ -117,4 +117,82 @@ class TestDataForms(SleekTest):
""")
+ def testSubmitType(self):
+ """Test that setting type to 'submit' clears extra details"""
+ msg = self.Message()
+ form = msg['form']
+
+ fields = OrderedDict()
+ fields['f1'] = {'type': 'text-single',
+ 'label': 'Username',
+ 'required': True}
+ fields['f2'] = {'type': 'text-private',
+ 'label': 'Password',
+ 'required': True}
+ fields['f3'] = {'type': 'text-multi',
+ 'label': 'Message',
+ 'value': 'Enter message.\nA long one even.'}
+ fields['f4'] = {'type': 'list-single',
+ 'label': 'Message Type',
+ 'options': [{'label': 'Cool!',
+ 'value': 'cool'},
+ {'label': 'Urgh!',
+ 'value': 'urgh'}]}
+ form['fields'] = fields
+
+ form['type'] = 'submit'
+ form['values'] = {'f1': 'username',
+ 'f2': 'hunter2',
+ 'f3': 'A long\nmultiline\nmessage',
+ 'f4': 'cool'}
+
+ self.check(form, """
+
+
+ username
+
+
+ hunter2
+
+
+ A long
+ multiline
+ message
+
+
+ cool
+
+
+ """, use_values=False)
+
+ def testCancelType(self):
+ """Test that setting type to 'cancel' clears all fields"""
+ msg = self.Message()
+ form = msg['form']
+
+ fields = OrderedDict()
+ fields['f1'] = {'type': 'text-single',
+ 'label': 'Username',
+ 'required': True}
+ fields['f2'] = {'type': 'text-private',
+ 'label': 'Password',
+ 'required': True}
+ fields['f3'] = {'type': 'text-multi',
+ 'label': 'Message',
+ 'value': 'Enter message.\nA long one even.'}
+ fields['f4'] = {'type': 'list-single',
+ 'label': 'Message Type',
+ 'options': [{'label': 'Cool!',
+ 'value': 'cool'},
+ {'label': 'Urgh!',
+ 'value': 'urgh'}]}
+ form['fields'] = fields
+
+ form['type'] = 'cancel'
+
+ self.check(form, """
+
+ """)
+
+
suite = unittest.TestLoader().loadTestsFromTestCase(TestDataForms)