Enhance XHR handling in BaseView and AddSchema, improve captcha management in CaptchaWidget

1 parent 74ba6c88
...@@ -671,7 +671,8 @@ class BaseView(object): ...@@ -671,7 +671,8 @@ class BaseView(object):
form.set_appstruct(values) form.set_appstruct(values)
table = self.get_item_table(parent=row) table = self.get_item_table(parent=row)
kwargs["readonly"] = True kwargs["readonly"] = True
return self.returned_form(form, table, **kwargs) kwargs["table"] = table
return self.returned_form(form, **kwargs)
def after_view(self, **kwargs): def after_view(self, **kwargs):
"""Digunakan untuk customize Proses """Digunakan untuk customize Proses
...@@ -776,6 +777,8 @@ class BaseView(object): ...@@ -776,6 +777,8 @@ class BaseView(object):
def after_add(self, row=None, **kwargs): def after_add(self, row=None, **kwargs):
"""Digunakan untuk memproses setelah data tersimpan ke database""" """Digunakan untuk memproses setelah data tersimpan ke database"""
if self.req.is_xhr:
return self.resp_xhr({"data": {"status": "success"}})
return self.route_list(**kwargs) return self.route_list(**kwargs)
def after_edit(self, row=None, **kwargs): def after_edit(self, row=None, **kwargs):
...@@ -814,10 +817,28 @@ class BaseView(object): ...@@ -814,10 +817,28 @@ class BaseView(object):
if self.req.POST: if self.req.POST:
if 'save' in self.req.POST: if 'save' in self.req.POST:
controls = self.req.POST.items() controls = self.req.POST.items()
if self.req.is_xhr:
cloned = self.req.POST.items()
controls = []
for ctrl in cloned:
if isinstance(ctrl[1], FieldStorage):
controls.append(
("__start__", f"{ctrl[0]}:mapping"))
controls.append(("upload", ctrl[1]))
controls.append(("uid", ""))
controls.append(("__end__", f"{ctrl[0]}:mapping"))
log.debug(f"Control: {ctrl}")
else:
controls.append(ctrl)
try: try:
c = form.validate(controls) c = form.validate(controls)
except ValidationFailure as e: except ValidationFailure as e:
value = self.before_add() value = self.before_add()
if self.req.is_xhr:
error = e.error.asdict()
error.update(value)
return self.resp_xhr({"error": error})
for f in e.field.children: for f in e.field.children:
if isinstance(f.typ, colander.Date): if isinstance(f.typ, colander.Date):
e.cstruct[f.name] = date_from_str( e.cstruct[f.name] = date_from_str(
...@@ -826,7 +847,8 @@ class BaseView(object): ...@@ -826,7 +847,8 @@ class BaseView(object):
e.cstruct[f.name] = self.get_captcha_url() e.cstruct[f.name] = self.get_captcha_url()
value = self.update_value(value, e.cstruct) value = self.update_value(value, e.cstruct)
form.set_appstruct(value) form.set_appstruct(value)
return self.returned_form(form, table, **kwargs) kwargs["table"]=table
return self.returned_form(form, **kwargs)
values = dict(c) values = dict(c)
row = self.save_request(values) row = self.save_request(values)
...@@ -942,6 +964,8 @@ class BaseView(object): ...@@ -942,6 +964,8 @@ class BaseView(object):
def resp_xhr(self, values): def resp_xhr(self, values):
if values.get("data"): if values.get("data"):
data = [] data = []
if values and type(values["data"]) is not list:
values["data"] = [values["data"]]
for val in values["data"]: for val in values["data"]:
data.append(obj2json(val)) data.append(obj2json(val))
values["data"] = data values["data"] = data
......
...@@ -26,8 +26,10 @@ ...@@ -26,8 +26,10 @@
# 4. Form edit registrasi http://server/register/{uid}/edit # 4. Form edit registrasi http://server/register/{uid}/edit
# 5. Form Upload template # 5. Form Upload template
# """ # """
from calendar import c
import logging import logging
from datetime import datetime from datetime import datetime
import re
import colander import colander
from deform import (widget, FileData, ValidationFailure, Button) from deform import (widget, FileData, ValidationFailure, Button)
...@@ -156,6 +158,12 @@ class AddSchema(colander.Schema): ...@@ -156,6 +158,12 @@ class AddSchema(colander.Schema):
request=request, request=request,
url=request.static_url(BASE_CLASS.captcha_files)), url=request.static_url(BASE_CLASS.captcha_files)),
oid="captcha", title=_("Captcha")) oid="captcha", title=_("Captcha"))
if request.is_xhr:
self["captcha_text"] = colander.SchemaNode(
colander.String(),
widget = widget.TextInputWidget(),
missing=colander.drop,
)
if request.user and request.user.id and not external_user: if request.user and request.user.id and not external_user:
self["password"] = colander.SchemaNode( self["password"] = colander.SchemaNode(
...@@ -355,6 +363,12 @@ class Views(BaseView): ...@@ -355,6 +363,12 @@ class Views(BaseView):
nama=" ".join([result["given_name"], result["family_name"]]))) nama=" ".join([result["given_name"], result["family_name"]])))
# if BASE_CLASS.reg_captcha: # if BASE_CLASS.reg_captcha:
# result.update(dict(captcha=self.req.static_url(BASE_CLASS.captcha_files))) # result.update(dict(captcha=self.req.static_url(BASE_CLASS.captcha_files)))
if self.req.is_xhr:
url = self.req.static_url(BASE_CLASS.captcha_files)
kode_captcha, file_name = widget_os.img_captcha(self.req)
self.ses["captcha"] = kode_captcha
result.update(dict(captcha=url+file_name,
captcha_text=kode_captcha))
return result return result
# # def after_save(self, row, values): # # def after_save(self, row, values):
......
...@@ -375,9 +375,10 @@ class CaptchaWidget(Widget): ...@@ -375,9 +375,10 @@ class CaptchaWidget(Widget):
super(CaptchaWidget, self).__init__(**kw) super(CaptchaWidget, self).__init__(**kw)
def serialize(self, field, cstruct, **kw): def serialize(self, field, cstruct, **kw):
kode_captcha, file_name = img_captcha(self.request) if not cstruct:
self.request.session["captcha"] = kode_captcha kode_captcha, file_name = img_captcha(self.request)
cstruct = self.url+file_name self.request.session["captcha"] = kode_captcha
cstruct = cstruct or self.url+file_name
readonly = kw.get("readonly", self.readonly) readonly = kw.get("readonly", self.readonly)
template = readonly and self.readonly_template or self.template template = readonly and self.readonly_template or self.template
values = self.get_template_values(field, cstruct, kw) values = self.get_template_values(field, cstruct, kw)
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!