def get_display(my): if not my.preprocessed: my.preprocess() if my.is_refresh: top = Widget() else: top = DivWdg() top.add_class("spt_work_hours_top") hidden = HiddenWdg('workhour_data') hidden.add_class('spt_workhour_data') header_data = {'start_date': str(my.start_date)} header_data = jsondumps(header_data).replace('"', """) hidden.set_value(header_data, set_form_value=False ) top.add(hidden) days = [] for date in my.dates: days.append( date.strftime("%Y_%m_%d") ) today = my.today.strftime("%Y_%m_%d") task = my.get_current_sobject() if not my.is_refresh: my.set_as_panel(top) entries = my.entries.get(task.get_code()) if isinstance(task, Task): parent = task.get_parent() if not parent: disabled = True else: disabled = False else: disabled = False if not entries: entries = {} table = Table() top.add(table) if my.use_straight_time: row_list = [my.ST_ROW] if my.show_overtime: row_list.append(my.OT_ROW) prefix_list = ['','ot'] else: row_list = [my.STT_ROW, my.ENT_ROW] prefix_list = ['stt','ent'] text = HiddenWdg(my.get_name() ) text.add_class("spt_data") table.add_color("color", "color") table.add_styles("width: %spx; float: left"%my.table_width) for row_to_draw in row_list: tr = table.add_row() tr.add_style('line-height','8px') td = table.add_blank_cell() offset_width = my.MONTH_WIDTH + my.LEFT_WIDTH+8 td.add_style("min-width: %spx" % offset_width) td.add(text) # go through each day and draw an input for overtime total_hours_st = 0 total_hours_ot = 0 search_key = task.get_search_key() # Add a label to indicate if the row is straight time or overtime time_prefix = '' if row_to_draw == my.OT_ROW: time_prefix = 'ot' div = DivWdg() div.add("OT") div.add_styles('text-align: right; margin-right: 4px') td.add(div) elif row_to_draw == my.STT_ROW: time_prefix = 'stt' div = DivWdg() div.add("ST") div.add_styles('text-align: right; margin: 0 4px 4px 0') td.add(div) elif row_to_draw == my.ENT_ROW: time_prefix = 'ent' div = DivWdg() div.add("ET") div.add_styles('text-align: right; margin: 0 4px 4px 0') td.add(div) for idx, day in enumerate(days): day_wdg = DivWdg() day_wdg.add(day) td = table.add_cell() td.add_style("width: %spx" % my.day_width) text = TextWdg('%sday_%s' % (time_prefix, day)) if disabled: text.set_option('read_only','true') text.set_attr('disabled','disabled') td.add(text) text.add_class('spt_day%s' % (time_prefix)) text.add_styles("width: %spx;text-align: right;padding-left: 2px" %(my.day_width-2)) #text.add_styles("width: 100%;text-align: right;padding-left: 2px") if day == today: text.add_style("border: solid 1px black") else: text.add_border() week_day = my.weekday_dict[idx] if week_day in ['Sat','Sun']: # MAIN: Overtime, weekend if row_to_draw == my.OT_ROW: text.add_color("background", "background2", modifier=[-15,0,5]) else: text.add_color("background", "background2", modifier= [0,15,20]) text.add_style("margin: 0px 1px") if row_to_draw == my.OT_ROW: text.add_attr('input_field_type', 'ot') else: text.add_attr('input_field_type', 'st') if my.kwargs.get('show_all_users')=='true': text.set_option('read_only','true') #TODO: while we may have multiple entries per task, we will only use the latest one here # for now, making the UI cleaner # if a corresponding entry exists, display its value entry_list_dict = entries.get(day) daily_sum = 0 value = 0 entry_list = [] if entry_list_dict: row_key = my.ROW_DICT.get(row_to_draw) entry_list = entry_list_dict.get(row_key) if entry_list: for entry in entry_list: # Check if there is something in the category column. category = entry.get_value("category") if row_to_draw == my.OT_ROW: # Skip if the category field does not have a 'ot' indicated. if not category: print "Warning this work_hour entry has no category [%s]" % entry.get_code() continue # Check if there exist a value in the straight_time column value, delta = my.get_time_value(entry, row_to_draw) if value: text.set_value(value) text.add_attr('orig_input_value', value) if row_to_draw == my.OT_ROW: total_hours_ot += float(delta) else: total_hours_st += float(delta) daily_sum += delta # we only use value instead of the sum "daily_sum" for now if row_to_draw == my.OT_ROW: my.summary_ot[idx].update({search_key: daily_sum}) else: my.summary_st[idx].update({search_key: daily_sum}) script = ''' var orig_value = bvr.src_el.getAttribute("orig_input_value"); var input_field_type = bvr.src_el.getAttribute("input_field_type"); bvr.src_el.value = bvr.src_el.value.strip(); if (bvr.src_el.value == '') { if (orig_value) { bvr.src_el.value = 0; } else { return; } } else if (bvr.src_el.value == orig_value) { return; } bvr.prefix_list.splice( bvr.prefix_list.indexOf(bvr.time_prefix),1) var other_time_prefix = bvr.prefix_list[0]; spt.work_hour.update_total(bvr, '.spt_day' + bvr.time_prefix); // register this as changed item var all_top_el = bvr.src_el.getParent(".spt_work_hours_top"); var values1 = spt.api.Utility.get_input_values(all_top_el, '.spt_day'+ bvr.time_prefix, false); var values2 = spt.api.Utility.get_input_values(all_top_el, '.spt_day'+ other_time_prefix, false); // Merge values from straight time and overtime fields in values variable. for (var attr in values2) { values1[attr] = values2[attr]; } for (val in values1) { if (values1[val] && isNaN(values1[val])) { spt.error('You have non-numeric values in your work hours. Please correct it: ' + values[val]); return; } } delete values1.data; var value_wdg = all_top_el.getElement(".spt_data"); var value = JSON.stringify(values1); value_wdg.value = value; var layout = bvr.src_el.getParent(".spt_layout"); var version = layout.getAttribute("spt_version"); if (version == "2") { spt.table.set_layout(layout); spt.table.accept_edit(all_top_el, value, false); } else { var cached_data = {}; spt.dg_table.edit.widget = all_top_el; spt.dg_table.inline_edit_cell_cbk( value_wdg, cached_data ); } ''' # accept on pressing Enter behavior = { 'type': 'keydown', 'time_prefix': time_prefix, 'prefix_list': prefix_list, 'cbjs_action': ''' if (evt.key=='enter') { %s } '''%script} text.add_behavior(behavior) behavior = { 'type': 'blur', 'time_prefix': time_prefix, 'prefix_list': prefix_list, 'cbjs_action': ''' %s '''%script} text.add_behavior(behavior) text = TextWdg("total") td = table.add_cell(text) td.add_style("width: 35px") text.add_border() text.add_attr('spt_total', '.spt_total%s' % (time_prefix)) text.add_class('spt_total%s' % (time_prefix)) text.add_styles("width: %spx; text-align: right; padding-right: 3px"%my.day_width) text.set_attr("readonly", "readonly") # MAIN: Overtime, total. if row_to_draw == my.OT_ROW: text.add_color("background", "background2", modifier=[5,-15,0]) if total_hours_ot: text.set_value("%0.1f" % total_hours_ot) my.summary_ot[7].update({search_key: total_hours_ot}) else: text.add_color("background", "background2", modifier=[20,0,15]) if total_hours_st: text.set_value("%0.1f" % total_hours_st) my.summary_st[7].update({search_key: total_hours_st}) td = table.add_blank_cell() td.add_style('width: 100%') return top
def get_display(my): if not my.preprocessed: my.preprocess() if my.is_refresh: top = Widget() else: top = DivWdg() top.add_class("spt_work_hours_top") hidden = HiddenWdg('workhour_data') hidden.add_class('spt_workhour_data') header_data = {'start_date': str(my.start_date)} header_data = jsondumps(header_data).replace('"', """) hidden.set_value(header_data, set_form_value=False) top.add(hidden) days = [] for date in my.dates: days.append(date.strftime("%Y_%m_%d")) today = my.today.strftime("%Y_%m_%d") task = my.get_current_sobject() if not my.is_refresh: my.set_as_panel(top) entries = my.entries.get(task.get_code()) if isinstance(task, Task): parent = task.get_parent() if not parent: disabled = True else: disabled = False else: disabled = False if not entries: entries = {} table = Table() top.add(table) if my.use_straight_time: row_list = [my.ST_ROW] if my.show_overtime: row_list.append(my.OT_ROW) prefix_list = ['', 'ot'] else: row_list = [my.STT_ROW, my.ENT_ROW] prefix_list = ['stt', 'ent'] text = HiddenWdg(my.get_name()) text.add_class("spt_data") table.add_color("color", "color") table.add_styles("width: %spx; float: left" % my.table_width) for row_to_draw in row_list: tr = table.add_row() tr.add_style('line-height', '8px') td = table.add_blank_cell() offset_width = my.MONTH_WIDTH + my.LEFT_WIDTH + 8 td.add_style("min-width: %spx" % offset_width) td.add(text) # go through each day and draw an input for overtime total_hours_st = 0 total_hours_ot = 0 search_key = task.get_search_key() # Add a label to indicate if the row is straight time or overtime time_prefix = '' if row_to_draw == my.OT_ROW: time_prefix = 'ot' div = DivWdg() div.add("OT") div.add_styles('text-align: right; margin-right: 4px') td.add(div) elif row_to_draw == my.STT_ROW: time_prefix = 'stt' div = DivWdg() div.add("ST") div.add_styles('text-align: right; margin: 0 4px 4px 0') td.add(div) elif row_to_draw == my.ENT_ROW: time_prefix = 'ent' div = DivWdg() div.add("ET") div.add_styles('text-align: right; margin: 0 4px 4px 0') td.add(div) for idx, day in enumerate(days): day_wdg = DivWdg() day_wdg.add(day) td = table.add_cell() td.add_style("width: %spx" % my.day_width) text = TextWdg('%sday_%s' % (time_prefix, day)) if disabled: text.set_option('read_only', 'true') text.set_attr('disabled', 'disabled') td.add(text) text.add_class('spt_day%s' % (time_prefix)) text.add_styles( "width: %spx;text-align: right;padding-left: 2px" % (my.day_width - 2)) #text.add_styles("width: 100%;text-align: right;padding-left: 2px") if day == today: text.add_style("border: solid 1px black") week_day = my.weekday_dict[idx] if week_day in ['Sat', 'Sun']: # MAIN: Overtime, weekend if row_to_draw == my.OT_ROW: text.add_color("background", "background2", modifier=[-15, 0, 5]) else: text.add_color("background", "background2", modifier=[0, 15, 20]) if row_to_draw == my.OT_ROW: text.add_attr('input_field_type', 'ot') else: text.add_attr('input_field_type', 'st') if my.kwargs.get('show_all_users') == 'false': pass else: text.set_option('read_only', 'true') #TODO: while we may have multiple entries per task, we will only use the latest one here # for now, making the UI cleaner # if a corresponding entry exists, display its value entry_list_dict = entries.get(day) daily_sum = 0 value = 0 entry_list = [] if entry_list_dict: row_key = my.ROW_DICT.get(row_to_draw) entry_list = entry_list_dict.get(row_key) if entry_list: for entry in entry_list: # Check if there is something in the category column. category = entry.get_value("category") if row_to_draw == my.OT_ROW: # Skip if the category field does not have a 'ot' indicated. if not category: print "Warning this work_hour entry has no category [%s]" % entry.get_code( ) continue # Check if there exist a value in the straight_time column value, delta = my.get_time_value(entry, row_to_draw) if value: text.set_value(value) text.add_attr('orig_input_value', value) if row_to_draw == my.OT_ROW: total_hours_ot += float(delta) else: total_hours_st += float(delta) daily_sum += delta # we only use value instead of the sum "daily_sum" for now if row_to_draw == my.OT_ROW: my.summary_ot[idx].update({search_key: daily_sum}) else: my.summary_st[idx].update({search_key: daily_sum}) script = ''' var orig_value = bvr.src_el.getAttribute("orig_input_value"); var input_field_type = bvr.src_el.getAttribute("input_field_type"); bvr.src_el.value = bvr.src_el.value.strip(); if (bvr.src_el.value == '') { if (orig_value) { bvr.src_el.value = 0; } else { return; } } else if (bvr.src_el.value == orig_value) { return; } bvr.prefix_list.splice( bvr.prefix_list.indexOf(bvr.time_prefix),1) var other_time_prefix = bvr.prefix_list[0]; spt.work_hour.update_total(bvr, '.spt_day' + bvr.time_prefix); // register this as changed item var all_top_el = bvr.src_el.getParent(".spt_work_hours_top"); var values1 = spt.api.Utility.get_input_values(all_top_el, '.spt_day'+ bvr.time_prefix, false); var values2 = spt.api.Utility.get_input_values(all_top_el, '.spt_day'+ other_time_prefix, false); // Merge values from straight time and overtime fields in values variable. for (var attr in values2) { values1[attr] = values2[attr]; } for (val in values1) { if (values1[val] && isNaN(values1[val])) { spt.error('You have non-numeric values in your work hours. Please correct it: ' + values[val]); return; } } delete values1.data; var value_wdg = all_top_el.getElement(".spt_data"); var value = JSON.stringify(values1); value_wdg.value = value; var layout = bvr.src_el.getParent(".spt_layout"); var version = layout.getAttribute("spt_version"); if (version == "2") { spt.table.set_layout(layout); spt.table.accept_edit(all_top_el, value, false); } else { var cached_data = {}; spt.dg_table.edit.widget = all_top_el; spt.dg_table.inline_edit_cell_cbk( value_wdg, cached_data ); } ''' # accept on pressing Enter behavior = { 'type': 'keydown', 'time_prefix': time_prefix, 'prefix_list': prefix_list, 'cbjs_action': ''' if (evt.key=='enter') { %s } ''' % script } text.add_behavior(behavior) behavior = { 'type': 'blur', 'time_prefix': time_prefix, 'prefix_list': prefix_list, 'cbjs_action': ''' %s ''' % script } text.add_behavior(behavior) text = TextWdg("total") td = table.add_cell(text) td.add_style("width: 35px") text.add_attr('spt_total', '.spt_total%s' % (time_prefix)) text.add_class('spt_total%s' % (time_prefix)) text.add_styles( "width: %spx; text-align: right; padding-right: 3px" % my.day_width) text.set_attr("readonly", "readonly") # MAIN: Overtime, total. if row_to_draw == my.OT_ROW: text.add_color("background", "background2", modifier=[5, -15, 0]) if total_hours_ot: text.set_value("%0.1f" % total_hours_ot) my.summary_ot[7].update({search_key: total_hours_ot}) else: text.add_color("background", "background2", modifier=[20, 0, 15]) if total_hours_st: text.set_value("%0.1f" % total_hours_st) my.summary_st[7].update({search_key: total_hours_st}) td = table.add_blank_cell() td.add_style('width: 100%') return top
class SearchLimitWdg(Widget): DETAIL = "detail_style" LESS_DETAIL = "less_detail_style" SIMPLE = "simple_style" def __init__(self, name='search_limit', label="Showing", limit=None, refresh=True): self.search_limit_name = name self.label = label if limit: self.search_limit = int(limit) else: self.search_limit = None self.fixed_offset = False self.style = self.DETAIL self.prefix = "search_limit" self.refresh = refresh self.refresh_script = 'spt.dg_table.search_cbk(evt, bvr)' if self.refresh: self.prev_hidden_name = 'Prev' self.next_hidden_name = 'Next' else: self.prev_hidden_name = '%s_Prev' %self.label self.next_hidden_name = '%s_Next' %self.label self.chunk_size = 0 self.chunk_num = 0 super(SearchLimitWdg, self).__init__() def init(self): self.current_offset = 0 self.count = None #self.text = TextWdg(self.search_limit_name) self.text = HiddenWdg(self.search_limit_name) self.text.add_style("width: 23px") self.text.add_style("margin-bottom: -1px") self.text.add_class("spt_search_limit_text") self.text.set_persist_on_submit(prefix=self.prefix) behavior = { 'type': 'keydown', 'cbjs_action': ''' if (evt.key=='enter') { // register this as changed item var value = bvr.src_el.value; if (isNaN(value) || value.test(/[\.-]/)) { spt.error('You have to use an integer.'); } } '''} self.text.add_behavior(behavior) # get the search limit that is passed in filter_data = FilterData.get() values = filter_data.get_values_by_prefix(self.prefix) if not values: # check web for embedded table web = WebContainer.get_web() values = {} limit_value = web.get_form_value("search_limit") label_value = web.get_form_value(self.label) if limit_value: values['search_limit'] = limit_value if label_value: values[self.label] = label_value else: values = values[0] self.values2 = filter_data.get_values_by_prefix("search_limit_simple") if not len(self.values2): self.values2 = {} elif len(self.values2) == 2: if self.values2[0]['page']: self.values2 = self.values2[0] else: self.values2 = self.values2[1] else: self.values2 = self.values2[0] self.stated_search_limit = values.get("search_limit") """ if not self.stated_search_limit: self.stated_search_limit = values.get("limit_select") if not self.stated_search_limit: self.stated_search_limit = values.get("custom_limit") """ if self.stated_search_limit: self.stated_search_limit = int(self.stated_search_limit) else: self.stated_search_limit = 0 # reused for alter_search() later self.values = values def set_refresh_script(self, script): self.refresh_script = script def set_label(self, label): self.label = label def get_limit(self): return self.search_limit def get_stated_limit(self): return self.stated_search_limit def get_count(self): return self.count def set_limit(self, limit): self.search_limit = limit # this is user defined, should be set in init() instead #self.stated_search_limit = limit def set_offset(self, offset): self.fixed_offset = True self.current_offset = offset def set_style(self, style): self.style = style def set_chunk(self, chunk_size, chunk_num, limit=None): self.chunk_size = chunk_size self.chunk_num = chunk_num if limit: self.search_limit = limit else: # avoid undefined chunk_size if chunk_size: self.search_limit = chunk_size # to avoid 0 limit on undefined search limit in fast table if self.search_limit == 0: self.search_limit = 50 def alter_search(self, search): if not search: return self.set_search(search) security = Environment.get_security() # allow security to alter the search security.alter_search(search) search.set_security_filter() self.count = search.get_count() web = WebContainer.get_web() values = self.values # look at the stated search limit only if there is no chunk_size if not self.chunk_size: search_limit = self.stated_search_limit if search_limit and self.search_limit != -1: try: self.search_limit = int(search_limit) except ValueError: self.search_limit = 20 if self.search_limit <= 0: self.search_limit = 1 elif self.search_limit: # this usually happens with search_limit set in side bar or kwarg for TableLayoutWdg pass else: # for backward compatibility with the default chunk size of 100 self.search_limit = 100 # find out what the last offset was #last_search_offset = web.get_form_value("last_search_offset") last_search_offset = values.get("%s_last_search_offset"%self.label) if last_search_offset: last_search_offset = int(last_search_offset) else: last_search_offset = 0 # based on the action, set the new offset #if web.get_form_value("Next"): # FIXME: Next Prev not working for embedded tables yet # look at various values to change the search criteria page = self.values2.get("page") if page: current_offset = self.search_limit * (int(page)-1) elif values.get("Next"): current_offset = last_search_offset + self.search_limit if current_offset >= self.count: current_offset = 0 #elif web.get_form_value("Prev"): elif values.get("Prev"): current_offset = last_search_offset - self.search_limit if current_offset < 0: current_offset = int(self.count/self.search_limit) * self.search_limit # this happens when the user jumps from Page 3 of a tab to a tab that # doesn't really need this widget elif last_search_offset > self.count: current_offset = 0 elif values.get(self.label): value = values.get(self.label) if not value.startswith("+"): current_offset, tmp = value.split(" - ") current_offset = int(current_offset) - 1 else: current_offset = 0 else: current_offset = 0 if self.fixed_offset == False: self.current_offset = current_offset # add ability to break search limit search into chunks self.current_offset = self.current_offset if self.chunk_num: self.current_offset = last_search_offset + (self.chunk_num*self.chunk_size) if self.search_limit >= 0: self.search.set_limit(self.search_limit) self.search.set_offset(self.current_offset) def get_info(self): return { "count": self.count, "current_offset": self.current_offset, "search_limit": self.search_limit, } def get_display(self): web = WebContainer.get_web() widget = DivWdg() widget.add_class("spt_search_limit_top") #widget.add_style("border", "solid 1px blue") widget.add_color("background", "background") widget.add_color("color", "color") widget.add_style("padding: 10px") hidden = HiddenWdg("prefix", self.prefix) widget.add(hidden) if not self.search and not self.sobjects: widget.add("No search or sobjects found") return widget # self.count should have been set in alter_search() # which can be called explicitly thru this instance, self. if not self.count: self.count = self.search.get_count(no_exception=True) # if self.sobjects exist thru inheriting from parent widgets # or explicitly set, (this is not mandatory though) if self.sobjects and len(self.sobjects) < self.search_limit: limit = len(self.sobjects) elif self.search and self.count < self.search_limit: # this is only true if the total result of the search is # less than the limit and so this wdg will not display limit = self.count else: limit = self.search_limit if not limit: limit = 50 self.search_limit = limit if self.refresh: prev = SpanWdg( IconButtonWdg(title="Prev", icon="BS_CHEVRON_LEFT") ) prev.add_style("margin-left: 8px") prev.add_style("margin-right: 6px") prev.add_style("margin-top: 5px") hidden_name = self.prev_hidden_name hidden = HiddenWdg(hidden_name, "") prev.add(hidden) prev.add_behavior( { 'type': 'click_up', 'cbjs_action': " bvr.src_el.getElement('input[name=%s]').value ='Prev';%s"\ % (hidden_name, self.refresh_script) } ) next = SpanWdg( IconButtonWdg(title="Next", icon="BS_CHEVRON_RIGHT" ) ) next.add_style("margin-left: 6px") next.add_style("margin-top: 5px") hidden_name = self.next_hidden_name hidden = HiddenWdg(hidden_name, "") next.add(hidden) next.add_behavior( { 'type': 'click_up', 'cbjs_action': " bvr.src_el.getElement('input[name=%s]').value ='Next';%s"\ % (hidden_name, self.refresh_script) } ) prev.add_style("float: left") next.add_style("float: left") else: # the old code pre 2.5 prev = IconButtonWdg(title="Prev", icon="BS_CHEVRON_LEFT" ) hidden_name = self.prev_hidden_name hidden = HiddenWdg(hidden_name,"") prev.add(hidden) prev.add_event('onclick'," spt.api.Utility.get_input(document,'%s').value ='Prev';%s"\ %(hidden_name, self.refresh_script)) next = IconButtonWdg(title="Next", icon="BS_CHEVRON_RIGHT" ) hidden_name = self.next_hidden_name hidden = HiddenWdg(hidden_name,"") next.add(hidden) next.add_event('onclick',"spt.api.Utility.get_input(document,'%s').value ='Next';%s" \ %(hidden_name, self.refresh_script)) showing_wdg = DivWdg() widget.add(showing_wdg) showing_wdg.add_style("padding: 20px") showing_wdg.add_style("margin: 10px") showing_wdg.add_color("background", "background", -5) #showing_wdg.add_color("text-align", "center") showing_wdg.add_border() label_span = SpanWdg("Showing: ") showing_wdg.add(label_span) showing_wdg.add("<br clear='all'/>") showing_wdg.add("<br/>") showing_wdg.add( prev ) # this min calculation is used so that if self.sobjects is not set # above for the calculation of the limit, which will make the last # set of range numbers too big left_bound = self.current_offset+1 if not limit: # prevent error in ItemsNavigatorWdg if a search encounters query error limit = 50 self.search_limit = limit right_bound = min(self.current_offset+limit, self.count) if left_bound > right_bound: left_bound = 1 current_value = "%d - %d" % (left_bound, right_bound) if self.style == self.SIMPLE: showing_wdg.add( current_value ) else: # add a range selector using ItemsNavigatorWdg from pyasm.widget import ItemsNavigatorWdg selector = ItemsNavigatorWdg(self.label, self.count, self.search_limit) selector.select.add_behavior( { 'type': 'change', 'cbjs_action': self.refresh_script } ) selector.set_style(self.style) selector.select.add_style("width: 100px") #selector.add_style("display: inline") selector.add_style("float: left") selector.set_value(current_value) selector.set_display_label(False) showing_wdg.add( selector) showing_wdg.add( next ) showing_wdg.add("<br clear='all'/>") showing_wdg.add("<br clear='all'/>") #showing_wdg.add( " x ") showing_wdg.add(self.text) self.text.add_style("margin-top: -3px") self.text.set_attr("size", "1") self.text.add_attr("title", "Set number of items per page") # set the limit set_limit_wdg = self.get_set_limit_wdg() widget.add(set_limit_wdg) from tactic.ui.widget.button_new_wdg import ActionButtonWdg button = ActionButtonWdg(title='Search') widget.add(button) button.add_style("float: right") button.add_style("margin-top: 8px") button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_search_limit_top"); var select = top.getElement(".spt_search_limit_select"); var value = select.value; if (value == 'Custom') { custom = top.getElement(".spt_search_limit_custom_text"); value = custom.value; } if (value == '') { value = 20; } var text = top.getElement(".spt_search_limit_text"); text.value = value; spt.dg_table.search_cbk({}, bvr) ''' } ) offset_wdg = HiddenWdg("%s_last_search_offset" %self.label) offset_wdg.set_value(self.current_offset) widget.add(offset_wdg) widget.add("<br clear='all'/>") return widget def get_set_limit_wdg(self): limit_content = DivWdg() limit_content.add_style("font-size: 10px") limit_content.add_style("padding", "15px") #limit_content.add_border() limit_content.add("Show ") limit_select = SelectWdg("limit_select") limit_select.add_class("spt_search_limit_select") limit_select.set_option("values", "10|20|50|100|200|Custom") limit_select.add_style("font-size: 10px") limit_content.add(limit_select) limit_content.add(" items per page<br/>") if self.search_limit in [10,20,50,100,200]: limit_select.set_value(self.search_limit) is_custom = False else: limit_select.set_value("Custom") is_custom = True limit_select.add_behavior( { 'type': 'change', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_search_limit_top"); var value = bvr.src_el.value; var custom = top.getElement(".spt_search_limit_custom"); if (value == 'Custom') { custom.setStyle("display", ""); } else { custom.setStyle("display", "none"); } ''' } ) custom_limit = DivWdg() limit_content.add(custom_limit) custom_limit.add_class("spt_search_limit_custom") custom_limit.add("<br/>Custom: ") text = TextWdg("custom_limit") text.add_class("spt_search_limit_custom_text") text.add_style("width: 50px") if not is_custom: custom_limit.add_style("display: none") else: text.set_value(self.search_limit) custom_limit.add(text) text.add(" items") behavior = { 'type': 'keydown', 'cbjs_action': ''' if (evt.key=='enter') { // register this as changed item var value = bvr.src_el.value; if (isNaN(value) || value.test(/[\.-]/)) { spt.error('You have to use an integer.'); } } '''} text.add_behavior(behavior) return limit_content