def app_info_callback(data): if 'error' in data: window.hide_spinner_modal() window.error_toast(data['error']) else: if 'user' in data and data['user'] == '': user_info[0] = '' refresh_UI(data)
def callback(d): d = d[0].strip() if d == '': window.error_toast('没有输入') return if self.event_listener is not None: self.event_listener('add', d)
def upload_file(files): if files.length == 0: return if files.length >= 20: window.error_toast('一次不能上传超过20个文件') return form_data = window.FormData.new() form_data.append('user_info', window.user_info) for i, file in enumerate(files): # if file.size >= 100000000: # window.error_toast('文件大小限制: 100MB') # return form_data.append('file' + str(i + 1), file) xhr = window.XMLHttpRequest.new() xhr.open('POST', '/upload', True) def onload_callback(ev): if xhr.status == 200: reply = JSON.parse(xhr.responseText) if 'url' in reply: if self.event_listener is not None: self.event_listener('add', reply['url']) window.info_toast('已上传' + str(files.length) + '个文件') return if 'error' in reply: window.error_toast('上传失败: ' + reply['error']) else: window.error_toast('上传失败') xhr.onload = onload_callback xhr.send(form_data)
def set_data(self, data_name, data): # print('set_data', data_name) if data_name == 'selected': return self._set_selelcted(data) elif data_name == 'data': return self._set_data(data) else: window.error_toast('No such data: ' + data_name)
def get_data(self, data_name): if data_name == 'selected': return self._get_selelcted() elif data_name == 'data': return self._get_data() elif data_name == 'text_data': return self._get_text_data() else: window.error_toast('No such data: ' + data_name)
def set_data(self, data_name, data): if data_name == 'selected': return self._set_selected(data) elif data_name == 'data': self.text_data = None return self._set_data(data) elif data_name == 'text_data': return self._set_text_data(data) else: window.error_toast('No such data: ' + data_name)
def on_login(data): if 'error' in data: window.error_toast(data['error']) else: user_info = [ data['user'], data['session_code'], app, app_secret + data['app_secret'] ] window.location.href = '/%s?user_info=%s' % ( app, '*'.join(user_info))
def onevent(self, action, ev, ev_arg): print('EVENT %s %s %s' % (action, str(ev), str(ev_arg))) if len(self.event_queue) == 0: self.event_queue.append((action, ev, ev_arg)) self._onevent() else: if len(self.event_queue) >= 5: window.error_toast('网页产生过多事件,将丢弃这些事件') return window.warning_toast('网页连续产生事件,将把这些事件添加到序列') self.event_queue.append((action, ev, ev_arg))
def on_delete_item(name): for i, row in enumerate(rows): if name == row[key_column_index]: rows[i:i + 1] = [] self._set_data(self.data) if self.event_listener is not None: self.event_listener('change', 'data') window.info_toast('已删除' + self.item_name + ': ' + name) break else: window.error_toast('不能删除不存在的' + self.item_name + ': ' + name)
def set_data(self, data_name, data): if self.obj is None: if not hasattr(self.elt, data_name): setattr(self.elt, data_name, data) else: window.error_toast('Component "%s" has no attribute "%s"' % (self.config['tag'], data_name)) else: if not hasattr(self.obj, 'set_data'): window.error_toast('Component "%s" has no function "set_data"' % self.config['init']) else: self.obj.set_data(data_name, data)
def fix_ui_json(ui_json): config = ui_json.get('config', {}) if 'vars' in config and 'data' in config: for var_name, var in config['vars'].items(): if var_name in config['data']: window.error_toast('%s exists as both data and var: data:%s vars:%s' % (var_name, str(config['data']), str(config['vars']))) config['data'][var_name] = var del config['vars'] if 'children' in ui_json: for child_ui_json in ui_json['children']: fix_ui_json(child_ui_json)
def ev_callback(data): if 'error' in data: if self.main_hub: window.error_toast(data['error']) else: for table_name, tb_data in data.items(): if len(tb_data) == 1: self.data[table_name]['__update_time__'] = tb_data['__update_time__'] else: self.data[table_name] = tb_data self.update_data(None, table_name) next_ev()
def callback(d): d = d[0].strip() if d == '': window.error_toast('没有输入') elif d[0] == '-': d = d[1:].strip() on_delete_item(d) elif d[0] == '^': d = d[1:].strip() on_moveup_item(d) else: on_add_item(d)
def onload_callback(ev): if xhr.status == 200: reply = JSON.parse(xhr.responseText) if 'url' in reply: if self.event_listener is not None: self.event_listener('add', reply['url']) window.info_toast('已上传' + str(files.length) + '个文件') return if 'error' in reply: window.error_toast('上传失败: ' + reply['error']) else: window.error_toast('上传失败')
def add_component(self, obj, remove=False): if obj.config is None: return obj_id = id(obj) updates = [] if 'data' in obj.config: data = obj.config['data'] for data_name, table_name in data.items(): if remove: self.data2obj[table_name].remove((data_name, obj_id)) if len(self.data2obj[table_name]) == 0: del self.data2obj[table_name] else: if table_name not in self.data2obj: self.data2obj[table_name] = set() if (data_name, obj_id) in self.data2obj[table_name]: window.error_toast(id(self), '重复添加数据 %s (%s,%s)' % (table_name, data_name, obj_name(obj))) self.data2obj[table_name].add((data_name, obj_id)) # when data[table_name] is changed, will call obj.set_data(data_name, data[table_name]) if table_name[0] == '$': if table_name in self.data and self.data[table_name] is not None: updates.append((obj, data_name, self.data[table_name])) else: if table_name not in self.data: self.data[table_name] = {'__update_time__':-1} if len(self.data[table_name]) > 1: updates.append((obj, data_name, self.data[table_name])) if 'ref' in obj.config: ref = obj.config['ref'] for data_name, var_name in ref.items(): if remove: self.ref2obj[var_name].remove((data_name, obj_id)) if len(self.ref2obj) == 0: del self.ref2obj[var_name] else: if var_name not in self.ref2obj: self.ref2obj[var_name] = set() assert (data_name, obj_id) not in self.ref2obj[var_name] self.ref2obj[var_name].add((data_name, obj_id)) # when var[var_name] or 5data[var[var_name]] is changed, will call obj.set_data(data_name, data[var[var_name]]) if var_name in self.data and self.data[var_name] is not None: var_value = self.data[var_name] table_name = var_value['rows'][0][0] if table_name not in self.data: self.data[table_name] = {'__update_time__':-1} if len(self.data[table_name]) > 1: updates.append((obj, data_name, self.data[table_name])) if remove: del self.components[obj_id] obj.event_listener = None self._remove_headless_table_data() else: self.components[obj_id] = obj if hasattr(obj, 'set_event_listener'): obj.set_event_listener(lambda ev, ev_arg: self.handle_ui_event(obj, ev, ev_arg))
def _set_data(self, is_editing, use_data): data_column, editable, margin, width = _summernote_obj_get_config( self.config) config = self.config self.elt.clear() if use_data: if self.data is None: return if 'rows' not in self.data: window.error_toast('%s 不是数据' % data_name) return rows = self.data['rows'] innerHTML = rows[0][data_column] else: if 'innerHTML' not in config['attr']: config['attr']['innerHTML'] = '' innerHTML = config['attr']['innerHTML'] editor = html.DIV(**{'id': self.summernote_obj_id}) self.elt <= editor if margin is not None: self.elt.style['margin'] = margin if width is not None: self.elt.style['width'] = width self.elt.children[0].innerHTML = innerHTML if is_editing: def onBlur(ev): if 'innerHTML' not in config['attr'] or config['attr'][ 'innerHTML'] != ev.target.innerHTML: config['attr']['innerHTML'] = ev.target.innerHTML if self.edit_listener is not None: self.edit_listener('edited', None) jq('#' + self.summernote_obj_id).summernote( {'callbacks': { 'onBlur': onBlur }}) else: if editable: def onBlur(ev): if rows[0][data_column] != ev.target.innerHTML: rows[0][data_column] = ev.target.innerHTML if self.event_listener is not None: self.event_listener('change', 'data') jq('#' + self.summernote_obj_id).summernote( {'callbacks': { 'onBlur': onBlur }})
def on_submit(ev): user_name = input1.value.strip() current_password = input2.value.strip() new_password = input3.value.strip() new_password2 = input4.value.strip() if user_name == '': window.error_toast('缺少用户名') return if current_password == '': window.error_toast('缺少用旧密码') return if new_password == '': window.error_toast('缺少用新密码') return if new_password != new_password2: window.error_toast('两个新密码不相同') return input2.value = '' input3.value = '' input4.value = '' data = { 'user_name': user_name, 'current_password': current_password, 'new_password': new_password } send_ajax_request('login', 'change_pwd', data, on_pwd_updated)
def on_moveup_item(name): for i, row in enumerate(rows): if name == row[key_column_index]: if i == 0: window.error_toast('不能上移第一个' + self.item_name + ': ' + name) return rows[i], rows[i - 1] = rows[i - 1], rows[i] self._set_data(self.data) if self.event_listener is not None: self.event_listener('change', 'data') window.info_toast('已上移' + self.item_name + ': ' + name) break else: window.error_toast('不能上移不存在的' + self.item_name + ': ' + name)
def get_data(self, data_name): if self.obj is None: if not hasattr(self.elt, data_name): return getattr(self.elt, data_name) else: window.error_toast('Component "%s" has no attribute "%s"' % (self.config['tag'], data_name)) else: if hasattr(self.obj, 'get_data'): return self.obj.get_data(data_name) if hasattr(self.obj, 'get_data_json_text'): data_json = self.obj.get_data_json_text(data_name) if data_json is None: return None return JSON.parse(data_json) window.error_toast('Component "%s" has no function "get_data" or "get_data_json_text"' % self.config['init']) return None
def callback(d): d = d[0].strip() dc = [d1.strip() for d1 in d.split('->') if d1.strip() != ''] if d == '': window.error_toast('没有输入') elif d[0] == '-': d = d[1:].strip() on_delete_item(d) elif d[0] == '^': d = d[1:].strip() on_moveup_item(d) elif len(dc) == 2: on_rename_item(dc[0], dc[1]) else: on_add_item(d)
def on_add_item(name): for row in rows: if row[key_column_index] == name: item_name = '项' if self.item_name is None else self.item_name window.error_toast('已存在的'+item_name+': '+name) return row = ['' for i in range(len(field_names))] row[key_column_index] = name rows.append(row) self._set_data(self.data) if self.event_listener is not None: self.event_listener('change', 'data') self.event_listener('change_data', None) if self.item_name is not None: window.info_toast('已添加'+self.item_name+': ' + name) if len(list_group.children) > 2 and select_item(list_group.children[-2]): self._set_selected_row(row)
def on_rename_item(name, new_name): for row in rows: if row[key_column_index] == new_name: item_name = '项' if self.item_name is None else self.item_name window.error_toast('不能重命名为已存在的'+item_name+': '+new_name) return for i,row in enumerate(rows): if name == row[key_column_index]: row[key_column_index] = new_name self._set_data(self.data) if self.event_listener is not None: self.event_listener('change', 'data') self.event_listener('change_data', None) if self.item_name is not None: window.info_toast('已重命名'+self.item_name+': ' + name + ' -> ' + new_name) break else: item_name = '项' if self.item_name is None else self.item_name window.error_toast('不能重命名不存在的'+item_name+': '+name)
def _set_text_data(self, text): from javascript import JSON if text is None: self.data = None self.text_data = None else: text_data_col = int(self.config['attr']['text_data_col']) self.text_data = text text = text['rows'][0][text_data_col].strip() if text == '': if 'text_data_init' not in self.config['attr']: window.error_toast('控件配置中缺少 text_data_init') else: text_data_init = self.config['attr']['text_data_init'] self.data = JSON.parse(text_data_init) self._set_data(self.data) else: self.data = JSON.parse(text) self._set_data(self.data)
def _check_type(text, field_type): # field_types[c_num] if field_type == 'number': try: float(text) except: window.error_toast('"%s"不是数字' % text) return False if field_type == 'time': try: convert_datetime_to_timestamp(text) except AssertionError as ex: window.error_toast(str(ex)) return False if field_type == 'boolean': if text.lower() not in ('true', 'false'): window.error_toast('"%s"不是True/False' % text) return False return True
def on_submit(ev): user_name = input1.value.strip() password = input2.value.strip() if app == '': window.error_toast('缺少应用名') return if user_name == '': window.error_toast('缺少用户名') return if password == '': window.error_toast('缺少密码') return input1.value = '' input2.value = '' data = { 'user': user_name, 'pwd': password, 'app': app, 'app_secret': app_secret } send_ajax_request('login', 'login_with_pwd', data, on_login)
def on_pwd_updated(data): if 'error' in data: window.error_toast(data['error']) else: window.info_toast('密码已修改.')
def logout_callback(data): if 'error' in data: window.error_toast(data['error']) else: window.location.href = '/%s' % app