Ejemplo n.º 1
0
class ONXFORM(object):

    """
    SQLFORM(
        table,
        record=None,
        deletable=False,
        linkto=None,
        upload=None,
        fields=None,
        labels=None,
        col3={},
        submit_button='Submit',
        delete_label='Check to delete:',
        showid=True,
        readonly=False,
        comments=True,
        keepopts=[],
        ignore_rw=False,
        record_id=None,
        formstyle='table3cols',
        buttons=['submit'],
        separator=': ',
        **attributes)
    """

    ACTIONS = ['new', 'read', 'update', 'delete', 'select']

    customize_default = dict(
        on_manager_extra_links=lambda self, row: [],
        on_grid_orderby=lambda self:None,
        on_before_init=lambda self, action: None,
        on_after_init=lambda self, form, action: None,
        on_navegate=lambda self, nav, action: None,
        on_fields_list=lambda self, action: None,
        on_form_success=lambda form:None,
        on_form_buttons=lambda self, action, buttons: buttons,
        on_grid_query=lambda self: None,
        on_hidden_fields=lambda self, action, record_id, hidden: None,
        )

    def __init__(self, table):
        self.table = table
        self.view_layout = None
        self.customize = Storage(self.customize_default)
        self.is_modal = False
        self.modal_cancel_onclick = None
        self.save_and_add_enabled = True
        self.child_controls = False
        self.nav = None
        return


    @staticmethod
    def get_btn_save():
        T = current.T
        btn_save = INPUT(_type='submit', _value=T('Save'), _class='btn btn-success')
        return btn_save

    def navegate(self, action):
        '''
        workflow
        # new
            cance:
            save and add:
            save and next:
        # read
            back:
            edit:
            new:
        # update
            cancel:
            save and add:
            save and next:
        # delete
            cancel:
            delete:

        '''
        request = current.request

        vredirect = request.get_vars.get('redirect')
        vnext = request.get_vars.get('next')
        vprevious= request.get_vars.get('previous')

        new_vars = clear_vars_navegate(request.get_vars)
        grid_url = URL(args=['select'], vars=new_vars)
        new_record = URL(args=['new'],  vars=new_vars)

        next = vnext or vredirect or grid_url
        previous = vprevious or vredirect or grid_url

        navegate = Storage(
            next=next,
            previous=previous,
            new_record=new_record,
            )

        self.customize.on_navegate(self, navegate, action)
        return navegate

    def get_form_buttons(self, action, record_id):
        T = current.T
        request = current.request
        new_vars = clear_vars_navegate(request.get_vars)

        btn_save = None
        btn_save_and_add = None
        btn_edit = None
        btn_delete = None
        btn_cancel = None
        btn_new = None

        if action in ['new', 'update']:
            btn_save = ONXFORM.get_btn_save()
            if self.save_and_add_enabled and not self.is_modal:
                btn_save_and_add = A(I(_class='fa fa-plus'),
                    _title=T('Save and Add'),
                    _class='btn',
                    _href='javascript:void(0);',
                    _onclick='submit_and_add(this);',
                    **{'_data-toggle':'tooltip'})

        if action in ['read']:
            new_vars['previous'] = URL(args=request.args, vars=request.get_vars)
            new_vars['origin'] = 'read'
            btn_edit = A(T('Edit'),
                _class='btn btn-primary',
                _style='margin-right:8px;',
                _href=URL(args=['update', record_id], vars=new_vars))
            btn_new = A(I(_class='fa fa-plus'),
                    _title=T('New Record'),
                    _class='btn',
                    _href=URL(args=['new'], vars=new_vars),
                    **{'_data-toggle':'tooltip'})

        if action in ['delete']:
            btn_delete = A(T('Delete'),
                _class='btn btn-danger',
                _style='margin-right:8px;',
                _href=URL(args=request.args, vars=request.get_vars))

        if action in ['read', 'delete']:
            btn_cancel = A(T('Back'), _class='btn', _href=self.nav.previous)
        else:
            if self.is_modal:
                if self.modal_cancel_onclick:
                    btn_cancel = A(
                        T('Cancel'),
                        _class='btn',
                        _href='javascript:void(0);',
                        _style='margin-right:8px;',
                        _onclick=self.modal_cancel_onclick)
            else:
                btn_cancel = A(T('Cancel'),
                    _class='btn',
                    _style='margin-right:8px;',
                    _href=self.nav.previous)

        buttons = dict(
            btn1_save=btn_save,
            btn2_save_and_add=btn_save_and_add,
            btn3_edit=btn_edit,
            btn4_delete=btn_delete,
            btn5_cancel=btn_cancel,
            btn6_new=btn_new)

        self.customize.on_form_buttons(self, action, buttons)
        btns = []
        for k in sorted(buttons):
            if buttons[k]:
                btns.append(buttons[k])
        return btns

    def js_submit_and_add(self):
        js = '''
            function submit_and_add(e) {
                var url = "%(url)s";
                var form = $(e).parents("form:first");
                $("input[name='_next']",form).val(url);
                $(form).submit();
            }
            ''' % {'url':self.nav.new_record}
        jq_script=SCRIPT(js, _type="text/javascript")
        return jq_script

    def get_hidden_fields(self, action, record_id):
        request = current.request
        hidden = dict()
        if not self.is_modal:
            save_redirect = self.nav.next
            if self.child_controls:
                new_vars = clear_vars_navegate(request.get_vars)
                save_redirect = URL(args=['read', '[id]'], vars=new_vars, url_encode=False)
            hidden['_next'] = save_redirect

        self.customize.on_hidden_fields(self, action, record_id, hidden)
        return hidden

    def do_form_new(self):
        response = current.response
        request = current.request
        T = current.T
        action = 'new'
        self.nav = self.navegate(action)

        response.title = T(self.table._plural)
        response.subtitle = T('New Record')
        response.breadcrumbs = '+'+response.title

        buttons = self.get_form_buttons(action, 0)

        self.customize.on_before_init(self, action)

        attr = dict(
            onsuccess=self.customize.on_form_success)
        hidden = self.get_hidden_fields(action, 0)
        if request.post_vars.get('_next'):
            hidden['_next'] = request.post_vars['_next']
        if hidden.get('_next'):
            attr['next'] = hidden['_next']

        form = SQLFORM(
            self.table,
            buttons=buttons,
            formstyle=formstyle_onx,
            fields=self.customize.on_fields_list(self, action),
            hidden=hidden,
            )
        if self.save_and_add_enabled:
            form[0].append(self.js_submit_and_add())
        self.customize.on_after_init(self, form, action)

        if form.process(**attr).accepted:
            response.flash = T('Record Created')
        elif form.errors:
            response.flash = form.errors
        return dict(content=form)


    def do_form_read(self, record_id):
        response = current.response
        request = current.request
        T = current.T
        table = self.table
        action = 'read'
        self.nav = self.navegate(action)

        record = None
        if isinstance(record_id, str):
            record_id = int(record_id)

        record = table[ record_id ]
        if not record: raise HTTP(404, 'Record ID invalid!')

        if isinstance(table._format,str):
            record_label = table._format % record
        else:
            record_label = table._format(record)

        response.title = T(table._plural)
        response.subtitle = T('View')+': '+record_label
        response.breadcrumbs = record_label


        buttons = self.get_form_buttons(action, record_id)

        self.customize.on_before_init(self, action)
        form = SQLFORM(
            table,
            record=record,
            readonly=True,
            formstyle=formstyle_onx,
            fields=self.customize.on_fields_list(self, action),
            )
        form[0].append(DIV(buttons))
        self.customize.on_after_init(self, form, action)
        return dict(content=form)


    def do_form_update(self, record_id):
        response = current.response
        T = current.T
        table = self.table
        action = 'update'
        self.nav = self.navegate(action)

        record = None
        if isinstance(record_id, str):
            record_id = int(record_id)

        record = table[ record_id ]
        if not record: raise HTTP(404, 'Record ID invalid!')

        if isinstance(table._format,str):
            record_label = table._format % record
        else:
            record_label = table._format(record)

        response.title = T(table._plural)
        response.subtitle = T('Editing')+': '+record_label
        response.breadcrumbs = record_label

        buttons = self.get_form_buttons(action, record_id)

        attr = dict(
            onsuccess=self.customize.on_form_success)
        hidden = self.get_hidden_fields(action, record.id)
        if hidden.get('_next'):
            attr['next'] = hidden['_next']

        self.customize.on_before_init(self, action)
        form = SQLFORM(
            table,
            record=record,
            buttons=buttons,
            deletable=False,
            formstyle=formstyle_onx,
            fields=self.customize.on_fields_list(self, action),
            hidden=hidden
            )
        if self.save_and_add_enabled:
            form[0].append(self.js_submit_and_add())
        self.customize.on_after_init(self, form, action)

        if form.process(**attr).accepted:
            response.flash = T('Record Updated')
        elif form.errors:
            response.flash = form.errors
        return dict(content=form)


    def do_form_delete(self, record_id):
        response = current.response
        request = current.request
        T = current.T
        db = current.db
        table = self.table
        action = 'delete'
        self.nav = self.navegate(action)

        if isinstance(record_id, str):
            record_id = int(record_id)

        record = table[ record_id ]
        if not record: raise HTTP(404, 'Record ID invalid!')

        if request.args(2) == 'confirmed':
            try:
                db(table.id == record.id).delete()
                response.flash = T('Record Deleted')
                redirect(self.nav.next)
            except Exception, e:
                raise e
        else: