Enhance form handling and response structure in BaseView and user login flow

1 parent c69c7bef
......@@ -20,6 +20,7 @@ from opensipkd.tools.buttons import btn_save, btn_cancel, btn_close, btn_delete,
btn_pdf, btn_unpost, btn_post
from opensipkd.tools.captcha import get_captcha
from opensipkd.tools.report import csv_response, file_response
from pyramid.request import Response
from .common import DataTables
from .. import DBSession, get_params, get_urls
from ..scripts.initializedb import append_csv
......@@ -199,7 +200,19 @@ class BaseView(object):
'jenis'] or self.jenis
self.ses['jenis'] = self.jenis
def form2dict(self, field):
children = []
for c in field.children:
children.append(self.form2dict(c))
d = {
"id": field.oid,
"name": field.name,
"error" : {"msg": field.error and field.error.msg or ""},
"children":children
}
return d
def query_register(self, **kwargs):
pass
......@@ -546,6 +559,10 @@ class BaseView(object):
return self.route_list(**kwargs)
def returned_form(self, form, table=None, **kwargs):
if self.req.is_xhr:
d = self.form2dict(form.field)
return Response(json=d)
resources = form.get_widget_resources()
readonly = "readonly" in kwargs and kwargs["readonly"] or False
kwargs["readonly"] = readonly
......@@ -556,18 +573,21 @@ class BaseView(object):
table = table["form"]
# resources["js"] = list(resources["js"])
# resources["css"] = list(resources["css"])
if is_object:
return dict(form=form,
table=table and table.render() or None,
scripts=self.form_scripts,
css=resources["css"],
js=resources["js"],
**kwargs
)
return dict(form=form.render(readonly=readonly),
if not is_object:
form = form.render(readonly=readonly)
# return dict(form=form,
# table=table and table.render() or None,
# scripts=self.form_scripts,
# css=resources["css"],
# js=resources["js"],
# **kwargs
# )
return dict(form=form,
table=table and table.render() or None,
scripts=self.form_scripts, css=resources["css"],
scripts=self.form_scripts,
css=resources["css"],
js=resources["js"],
**kwargs
)
......
......@@ -312,7 +312,7 @@ class Registrasi(BaseView):
forget(self.req)
self.ses.delete()
@view_config(route_name='register', renderer='templates/form.pt')
# @view_config(route_name='register', renderer='templates/form.pt')
def view_register(self):
self.bindings = dict(user=None)
request = self.req
......
<html metal:use-macro="load: ./base3.1.pt" tal:define="
scripts scripts|scripts;
readonly readonly|readonly;">
<div metal:fill-slot="content">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-fw fa-plus"></i>&nbsp;${request.title}</h3>
</div>
<div class="panel-body">
<div tal:content="structure form.render(readonly=readonly)"></div>
</div>
</div>
</div>
<div metal:fill-slot="scripts">
<script>
$(document).ready(function () {
// $(".read-only").attr("readonly", true);
$(".readonly").attr("readonly", true);
$(".date").attr("readonly", true);
// $(".date").datepicker({
// format: 'dd-mm-yyyy'
// });
${ structure: scripts }
});
</script>
<div metal:define-slot="scripts"></div>
</div>
</html>
\ No newline at end of file
......@@ -23,7 +23,7 @@ import os
import re
from datetime import timedelta, datetime
from importlib import import_module
from pyramid.request import Response
import colander
from deform import widget, Form, ValidationFailure, Button
from pyramid.csrf import new_csrf_token
......@@ -196,7 +196,12 @@ class ViewLogin(BaseView):
except ValidationFailure as e:
msg = 'Login gagal'
set_user_log(msg, request, log, identity)
if self.req.is_xhr:
d = self.form2dict(form.field)
return Response(json=d)
request.session.flash(msg, 'error')
return HTTPFound(location=get_urls(request.route_url('login')))
values = dict(c)
......
<form
tal:define="style style|field.widget.style;
<form tal:define="style style|field.widget.style;
css_class css_class|string:${field.widget.css_class or field.css_class or ''};
item_template item_template|field.widget.item_template;
autocomplete autocomplete|field.autocomplete;
......@@ -11,62 +10,45 @@
ajax_options ajax_options|field.ajax_options;
formid formid|field.formid;
action action|field.action or None;
method method|field.method;"
tal:attributes="autocomplete autocomplete;
method method|field.method;" tal:attributes="autocomplete autocomplete;
style style;
class css_class;
action action;
attributes|field.widget.attributes|{};"
id="${formid}"
method="${method}"
enctype="multipart/form-data"
accept-charset="utf-8"
class="deform ${field.bootstrap_form_style | 'form-horizontal'}"
i18n:domain="deform"
>
attributes|field.widget.attributes|{};" id="${formid}" method="${method}" enctype="multipart/form-data"
accept-charset="utf-8" class="deform ${field.bootstrap_form_style | 'form-horizontal'}" i18n:domain="deform">
<fieldset class="deform-form-fieldset">
<div class="row">
<legend tal:condition="title">${title}</legend>
<input type="hidden" name="_charset_"/>
<input type="hidden" name="__formid__" value="${formid}"/>
<input type="hidden" name="_charset_" />
<input type="hidden" name="__formid__" value="${formid}" />
<div class="alert alert-danger" tal:condition="field.error">
<div class="error-msg-lbl" i18n:translate="">There was a problem with your submission</div>
<div class="error-msg-detail" i18n:translate="">Errors have been highlighted below</div>
<p class="error-msg">${field.errormsg}</p>
</div>
<p class="section first" tal:condition="description">
${description}
${description}
</p>
<div tal:repeat="child field"
tal:replace="structure child.render_template(item_template)"/>
<div tal:repeat="child field" tal:replace="structure child.render_template(item_template)" />
</div>
<div class="row">
<div class="form-group deform-form-buttons">
<tal:loop tal:repeat="button buttons">
<button
tal:define="btn_disposition repeat.button.start and 'btn-primary' or 'btn-default';"
tal:attributes="disabled button.disabled if button.disabled else None;
attributes|button.attributes|{};"
id="${formid+button.name}"
name="${button.name}"
type="${button.type}"
class="btn ${button.css_class or btn_disposition}"
value="${button.value}"
tal:condition="button.type != 'link'">
<button tal:define="btn_disposition repeat.button.start and 'btn-primary' or 'btn-default';"
tal:attributes="disabled button.disabled if button.disabled else None;
attributes|button.attributes|{};" id="${formid+button.name}" name="${button.name}"
type="${button.type}" class="btn ${button.css_class or btn_disposition}" value="${button.value}"
tal:condition="button.type != 'link'">
<span tal:condition="button.icon" class="glyphicon glyphicon-${button.icon}"></span>
${button.title}
${button.title}
</button>
<a
tal:define="btn_disposition repeat.button.start and 'btn-primary' or 'btn-default';
btn_href button.value|''"
class="btn ${button.css_class or btn_disposition}"
id="${field.formid + button.name}"
href="${btn_href}"
tal:condition="button.type == 'link'">
<a tal:define="btn_disposition repeat.button.start and 'btn-primary' or 'btn-default';
btn_href button.value|''" class="btn ${button.css_class or btn_disposition}"
id="${field.formid + button.name}" href="${btn_href}" tal:condition="button.type == 'link'">
<span tal:condition="button.icon" class="glyphicon glyphicon-${button.icon}"></span>
${button.title}
${button.title}
</a>
</tal:loop>
</div>
......@@ -75,34 +57,38 @@
<script type="text/javascript" tal:condition="use_ajax">
deform.addCallback(
'${formid}',
function (oid) {
var target = '#' + oid;
var options = {
target: target,
replaceTarget: true,
success: function () {
deform.processCallbacks();
deform.focusFirstInput(target);
},
beforeSerialize: function () {
// See http://bit.ly/1agBs9Z (hack to fix tinymce-related ajax bug)
if ('tinymce' in window) {
$(tinymce.get()).each(
function (i, el) {
var content = el.getContent();
var editor_input = document.getElementById(el.id);
editor_input.value = content;
});
}
'${formid}',
function (oid) {
var target = '#' + oid;
var options = {
// target: target,
// replaceTarget: true,
replaceTarget: false,
success: function () {
deform.processCallbacks();
deform.focusFirstInput(target);
},
beforeSerialize: function () {
// See http://bit.ly/1agBs9Z (hack to fix tinymce-related ajax bug)
if ('tinymce' in window) {
$(tinymce.get()).each(
function (i, el) {
var content = el.getContent();
var editor_input = document.getElementById(el.id);
editor_input.value = content;
});
}
};
var extra_options = ${ajax_options} ||
{
}
;
$('#' + oid).ajaxForm($.extend(options, extra_options));
}
};
var extra_options = ${ ajax_options }|| {};
$('#' + oid).ajaxForm($.extend(options, extra_options));
// $('#' + oid).ajaxForm(
// function () {
// alert("test");
// }
// );
}
);
</script>
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!