class HtmlFormTable(HtmlColumnTable): def __init__(self, app=None, ignore_uncap=False, ignore_wrappers=False, cloth=None, attr_name='spyne_id', root_attr_name='spyne', cloth_parser=None, can_add=True, can_remove=True): super(HtmlFormTable, self).__init__(app=app, ignore_uncap=ignore_uncap, ignore_wrappers=ignore_wrappers, cloth=cloth, attr_name=attr_name, root_attr_name=root_attr_name, cloth_parser=cloth_parser) self.serialization_handlers = cdict({ ModelBase: self.model_base_to_parent, }) self.prot_form = HtmlForm() self.can_add = can_add self.can_remove = can_remove def _init_cloth(self, *args, **kwargs): super(HtmlFormTable, self)._init_cloth(*args, **kwargs) form = E.form(method='POST', enctype="multipart/form-data") if self._root_cloth is None: self._cloth = self._root_cloth = form else: self._root_cloth.append(form) self._root_cloth = form def model_base_to_parent(self, ctx, cls, inst, parent, name, array_index=None, from_arr=False, **kwargs): if from_arr: with parent.element('tr'): with parent.element('td'): self.prot_form.to_parent(ctx, cls, inst, parent, name, **kwargs) else: self.prot_form.to_parent(ctx, cls, inst, parent, name, **kwargs) def extend_header_row(self, ctx, cls, parent, name, **kwargs): if self.can_add or self.can_remove: parent.write(E.td())
class HtmlFormTable(HtmlColumnTable, HtmlFormRoot): def __init__(self, app=None, ignore_uncap=False, ignore_wrappers=True, cloth=None, polymorphic=True, doctype=None, hier_delim='.', cloth_parser=None, header=True, table_name_attr='class', table_name=None, input_class=None, input_div_class=None, input_wrapper_class=None, label_class=None, action=None, table_class=None, field_name_attr='class', border=0, row_class=None, cell_class=None, header_cell_class=None, can_add=True, can_remove=True, label=True, before_table=None): super(HtmlFormTable, self).__init__(app=app, ignore_uncap=ignore_uncap, ignore_wrappers=ignore_wrappers, polymorphic=polymorphic, hier_delim=hier_delim, doctype=doctype, cloth=cloth, cloth_parser=cloth_parser, header=header, table_name_attr=table_name_attr, table_name=table_name, table_class=table_class, field_name_attr=field_name_attr, border=border, row_class=row_class, cell_class=cell_class, header_cell_class=header_cell_class, before_table=before_table) self.prot_form = HtmlForm(label=label, label_class=label_class, action=action, input_class=input_class, input_div_class=input_div_class, input_wrapper_class=input_wrapper_class) self.can_add = can_add self.can_remove = can_remove self.use_global_null_handler = False self.label = label self._init_input_vars(input_class, input_div_class, input_wrapper_class, label_class) @coroutine def model_base_to_parent(self, ctx, cls, inst, parent, name, from_arr=False, remove=None, **kwargs): if from_arr: td_attrs = {} if self.field_name_attr: td_attrs[self.field_name_attr] = name with parent.element('tr'): with parent.element('td', attrib=td_attrs): ret = self.prot_form.to_parent(ctx, cls, inst, parent, name, from_arr=from_arr, no_label=True, **kwargs) if isgenerator(ret): try: while True: y = (yield) ret.send(y) except Break as b: try: ret.throw(b) except StopIteration: pass if remove is None: remove = True self.extend_data_row(ctx, cls, inst, parent, name, remove=remove, **kwargs) else: ret = self.prot_form.to_parent(ctx, cls, inst, parent, name, from_arr=from_arr, no_label=True, **kwargs) if isgenerator(ret): try: while True: y = (yield) ret.send(y) except Break as b: try: ret.throw(b) except StopIteration: pass # sole reason to override is to generate labels @coroutine def wrap_table(self, ctx, cls, inst, parent, name, gen_rows, **kwargs): if name == "": name = cls.get_type_name() if self.label: parent.write(E.label(self.trc(cls, ctx.locale, name))) ret = self._gen_table(ctx, cls, inst, parent, name, gen_rows, **kwargs) if isgenerator(ret): try: while True: sv2 = (yield) ret.send(sv2) except Break as b: try: ret.throw(b) except StopIteration: pass def extend_header_row(self, ctx, cls, parent, name, **kwargs): if self.can_add or self.can_remove: parent.write(E.th(**{'class': 'array-button'})) def extend_data_row(self, ctx, cls, inst, parent, name, array_index=None, add=False, remove=True, **kwargs): if array_index is None: return if not (self.can_remove or self.can_add): return td = E.td(style='white-space: nowrap;') td.attrib['class'] = 'array-button' self._gen_buttons(td, name, add, remove) parent.write(td) def _gen_buttons(self, elt, name, add, remove): name = "%s-%d" % (self.selsafe(name), SOME_COUNTER[0]) if add: elt.append( E.button('+', **{ "class": "%s_btn_add" % name, "type": "button", }), ) if remove: elt.append( E.button('-', **{ "class": "%s_btn_remove" % name, "type": "button", }), ) def extend_table(self, ctx, cls, parent, name, **kwargs): if not self.can_add: return # FIXME: just fix me. if issubclass(cls, Array): cls = next(iter(cls._type_info.values())) self._gen_row(ctx, cls, [(cls.__orig__ or cls)()], parent, name) # even though there are calls to coroutines here, as the passed objects # are empty, so it's not possible to have push data. so there's no need # to check the returned generators. from_arr = True if issubclass(cls, ComplexModelBase): inst = (cls.__orig__ or cls)() ctx.protocol.inst_stack.append((cls, inst, from_arr)) if cls.Attributes.max_occurs > 1: self._gen_row(ctx, cls, [inst], parent, name, add=True, remove=False, array_index=-1) else: self._gen_row(ctx, cls, inst, parent, name, add=True, remove=False, array_index=-1) else: inst = None ctx.protocol.inst_stack.append((cls, inst, from_arr)) if cls.Attributes.max_occurs > 1: self.model_base_to_parent(ctx, cls, inst, parent, name, from_arr=True, add=True, remove=False, array_index=-1) else: self.model_base_to_parent(ctx, cls, inst, parent, name, add=True, remove=False, array_index=-1) ctx.protocol.inst_stack.pop() name = '%s-%d' % (self.selsafe(name), SOME_COUNTER[0]) SOME_COUNTER[0] += 1 parent.write(self._format_js(ADD_JS, name=name))
class HtmlFormTable(HtmlColumnTable, HtmlWidget): def __init__(self, app=None, ignore_uncap=False, ignore_wrappers=True, cloth=None, attr_name='spyne_id', root_attr_name='spyne', polymorphic=True, doctype=None, hier_delim='.', cloth_parser=None, produce_header=True, table_name_attr='class', field_name_attr='class', border=0, row_class=None, cell_class=None, header_cell_class=None, can_add=True, can_remove=True): super(HtmlFormTable, self).__init__(app=app, ignore_uncap=ignore_uncap, ignore_wrappers=ignore_wrappers, polymorphic=polymorphic, hier_delim=hier_delim, doctype=doctype, cloth=cloth, attr_name=attr_name, root_attr_name=root_attr_name, cloth_parser=cloth_parser, produce_header=produce_header, table_name_attr=table_name_attr, field_name_attr=field_name_attr, border=border, row_class=row_class, cell_class=cell_class, header_cell_class=header_cell_class) self.prot_form = HtmlForm() self.can_add = can_add self.can_remove = can_remove self.use_global_null_handler = False def _init_cloth(self, *args, **kwargs): super(HtmlFormTable, self)._init_cloth(*args, **kwargs) form = E.form(method='POST', enctype="multipart/form-data") if self._root_cloth is None: self._cloth = self._root_cloth = form else: self._root_cloth.append(form) self._root_cloth = form @coroutine def model_base_to_parent(self, ctx, cls, inst, parent, name, from_arr=False, remove=None, **kwargs): if from_arr: td_attrs = {} if self.field_name_attr: td_attrs[self.field_name_attr] = name with parent.element('tr'): with parent.element('td', attrib=td_attrs): ret = self.prot_form.to_parent(ctx, cls, inst, parent, name, from_arr=from_arr, no_label=True, **kwargs) if isgenerator(ret): try: while True: y = (yield) ret.send(y) except Break as b: try: ret.throw(b) except StopIteration: pass if remove is None: remove = True self.extend_data_row(ctx, cls, inst, parent, name, remove=remove, **kwargs) else: ret = self.prot_form.to_parent(ctx, cls, inst, parent, name, from_arr=from_arr, no_label=True, **kwargs) if isgenerator(ret): try: while True: y = (yield) ret.send(y) except Break as b: try: ret.throw(b) except StopIteration: pass def extend_header_row(self, ctx, cls, parent, name, **kwargs): if self.can_add or self.can_remove: parent.write(E.th()) def extend_data_row(self, ctx, cls, inst, parent, name, array_index=None, add=False, remove=True, **kwargs): if array_index is None: return if not (self.can_remove or self.can_add): return td = E.td(style='white-space: nowrap;') self._gen_buttons(td, name, add, remove) parent.write(td) def _gen_buttons(self, elt, name, add, remove): name = "%s-%d" % (self.selsafe(name), SOME_COUNTER[0]) if add: elt.append( E.button('+', **{ "class": "%s_btn_add" % name, "type": "button", }), ) if remove: elt.append( E.button( '-', **{ "class": "%s_btn_remove" % name, "type": "button", }), ) def extend_table(self, ctx, cls, parent, name, **kwargs): if not self.can_add: return # FIXME: just fix me. if issubclass(cls, Array): cls = next(iter(cls._type_info.values())) self._gen_row(ctx, cls, [cls()], parent, name) # even though there are calls to coroutines here, as the passed objects # are empty, it's not possible to have push data. so there's no need to # check the returned generators. if issubclass(cls, ComplexModelBase): if cls.Attributes.max_occurs > 1: self._gen_row(ctx, cls, [cls()], parent, name, add=True, remove=False, array_index=-1) else: self._gen_row(ctx, cls, cls(), parent, name, add=True, remove=False, array_index=-1) else: if cls.Attributes.max_occurs > 1: self.model_base_to_parent(ctx, cls, None, parent, name, from_arr=True, add=True, remove=False, array_index=-1) else: self.model_base_to_parent(ctx, cls, None, parent, name, add=True, remove=False, array_index=-1) name = '%s-%d' % (self.selsafe(name), SOME_COUNTER[0]) SOME_COUNTER[0] += 1 parent.write(self._format_js(ADD_JS, name=name))