def get_display(my): search_type_obj = SearchType.get(my.search_type) sobj_title = search_type_obj.get_title() my.color_mode = my.kwargs.get("color_mode") if not my.color_mode: my.color_mode = "default" top_div = my.top top_div.add_class("spt_edit_top") if not my.is_refresh: my.set_as_panel(top_div) content_div = DivWdg() content_div.add_class("spt_edit_top") content_div.add_class("spt_edit_form_top") content_div.set_attr("spt_search_key", my.search_key) if not Container.get_dict("JSLibraries", "spt_edit"): content_div.add_behavior( { 'type': 'load', 'cbjs_action': my.get_onload_js() } ) layout_view = my.kwargs.get("layout_view") if layout_view: layout_wdg = my.get_custom_layout_wdg(layout_view) content_div.add(layout_wdg) return content_div # add close listener # NOTE: this is an absolute search, but is here for backwards # compatibility content_div.add_named_listener('close_EditWdg', ''' var popup = bvr.src_el.getParent( ".spt_popup" ); if (popup) spt.popup.close(popup); ''') attrs = my.config.get_view_attributes() default_access = attrs.get("access") if not default_access: default_access = "edit" project_code = Project.get_project_code() security = Environment.get_security() base_key = search_type_obj.get_base_key() key = { 'search_type': base_key, 'project': project_code } access = security.check_access("sobject", key, "edit", default=default_access) if not access: my.is_disabled = True else: my.is_disabled = False disable_wdg = None if my.is_disabled: # TODO: This overlay doesn't work in IE, size, position, # and transparency all fail. disable_wdg = DivWdg(id='edit_wdg') disable_wdg.add_style("position: absolute") disable_wdg.add_style("height: 90%") disable_wdg.add_style("width: 100%") disable_wdg.add_style("left: 0px") #disable_wdg.add_style("bottom: 0px") #disable_wdg.add_style("top: 0px") disable_wdg.add_style("opacity: 0.2") disable_wdg.add_style("background: #fff") #disable_wdg.add_style("-moz-opacity: 0.2") disable_wdg.add_style("filter: Alpha(opacity=20)") disable_wdg.add("<center>EDIT DISABLED</center>") content_div.add(disable_wdg) attrs = my.config.get_view_attributes() inner = DivWdg() content_div.add(inner) menu = my.get_header_context_menu() menus = [menu.get_data()] menus_in = { 'HEADER_CTX': menus, } SmartMenu.attach_smart_context_menu( inner, menus_in, False ) table = Table() inner.add(table) if my.color_mode == "default": table.add_color("background", "background") table.add_color("color", "color") width = attrs.get('width') if not width: width = my.kwargs.get("width") if not width: width = 500 table.add_style("width: %s" % width) height = attrs.get('height') if height: table.add_style("height: %s" % height) tr = table.add_row() show_header = my.kwargs.get("show_header") if show_header not in ['false', False]: my.add_header(table, sobj_title) single = my.kwargs.get("single") if single in ['false', False] and my.mode == 'insert': multi_div = DivWdg() multi_div.add_style("text-align: left") multi_div.add("Specify the number of items that will be added with this form:<br/><br/>") multi_div.add("<b># of new items to add: </b>") multi_div.add(" "*4) multi_text = TextWdg("multiplier") multi_text.add_style("width: 30px") multi_div.add(multi_text) tr, td = table.add_row_cell( multi_div ) if my.color_mode == "default": td.add_color("border-color", "table_border", default="border") td.add_style("border-width: 1px") td.add_style("border-style: solid") td.add_style("padding: 8 3 8 3") td.add_color("background", "background3") td.add_color("color", "color3") security = Environment.get_security() # break the widgets up in columns num_columns = attrs.get('num_columns') if not num_columns: num_columns = my.kwargs.get('num_columns') if not num_columns: num_columns = 1 else: num_columns = int(num_columns) # go through each widget and draw it for i, widget in enumerate(my.widgets): # since a widget name called code doesn't necessariy write to code column, it is commented out for now """ key = { 'search_type' : search_type_obj.get_base_key(), 'column' : widget.get_name(), 'project': project_code} # check security on widget if not security.check_access( "sobject_column",\ key, "edit"): my.skipped_element_names.append(widget.get_name()) continue """ if not hasattr(widget, 'set_input_prefix'): msg = DivWdg("Warning: The widget definition for [%s] uses [%s] and is not meant for use in Edit Layout. Please revise the edit_definition in widget config."% (widget.get_name(), widget.__class__.__name__ )) msg.add_style('color: orange') content_div.add(msg) content_div.add(HtmlElement.br()) continue if my.input_prefix: widget.set_input_prefix(my.input_prefix) if isinstance(widget, HiddenWdg): content_div.add(widget) continue # Set up any validations configured on the widget ... from tactic.ui.app import ValidationUtil v_util = ValidationUtil( widget=widget ) v_bvr = v_util.get_validation_bvr() if v_bvr: if (isinstance(widget, CalendarInputWdg)): widget.set_validation( v_bvr.get('cbjs_validation'), v_bvr.get('validation_warning') ); else: widget.add_behavior( v_bvr ) widget.add_behavior( v_util.get_input_onchange_bvr() ) new_row = i % num_columns == 0 if new_row: tr = table.add_row() if my.color_mode == "default": if i % 2 == 0: tr.add_color("background", "background") else: tr.add_color("background", "background", -5) show_title = (widget.get_option("show_title") != "false") if show_title: title = widget.get_title() td = table.add_cell(title) td.add_style("padding: 10px 15px 10px 5px") td.add_style("vertical-align: top") title_width = my.kwargs.get("title_width") if title_width: td.add_style("width: %s" % title_width) else: td.add_style("width: 100px") security = Environment.get_security() if security.check_access("builtin", "view_site_admin", "allow"): SmartMenu.assign_as_local_activator( td, 'HEADER_CTX' ) if my.color_mode == "default": td.add_color("border-color", "table_border", default="border") td.add_style("border-width: 1" ) td.add_style("border-style: solid" ) td.add_style("text-align: right" ) if not show_title: th, td = table.add_row_cell( widget ) #td.add_border() continue else: td = table.add_cell( widget ) #td = table.add_cell( widget.get_value() ) td.add_style("min-width: 300px") td.add_style("padding: 10px 15px 10px 5px") td.add_style("vertical-align: top") if my.color_mode == "default": td.add_color("border-color", "table_border", default="border") td.add_style("border-width: 1" ) td.add_style("border-style: solid" ) hint = widget.get_option("hint") if hint: table.add_data( HintWdg(hint) ) if not my.is_disabled and not my.mode == 'view': tr, td = table.add_row_cell( my.get_action_html() ) if my.input_prefix: prefix = HiddenWdg("input_prefix", my.input_prefix) tr, td = table.add_row_cell() td.add(prefix) top_div.add(content_div) return top_div
def get_action_html(my): search_key = SearchKey.get_by_sobject(my.sobjects[0], use_id=True) search_type = my.sobjects[0].get_base_search_type() div = DivWdg(css='centered') # construct the bvr element_names = my.element_names[:] for element_name in my.skipped_element_names: element_names.remove(element_name) bvr = { 'type': 'click_up', 'mode': my.mode, 'element_names': element_names, 'search_key': search_key, 'input_prefix': my.input_prefix, 'view': my.view } if my.mode == 'insert': bvr['refresh'] = 'true' # for adding parent relationship in EditCmd if my.parent_key: bvr['parent_key'] = my.parent_key hidden_div = DivWdg() hidden_div.add_style("display: none") div.add(hidden_div) hidden = TextAreaWdg("__data__") hidden_div.add(hidden) hidden.set_value( jsondumps(bvr) ) show_action = my.kwargs.get("show_action") if show_action in [False, 'false']: return div div.add_styles('height: 35px; margin-top: 5px;') div.add_named_listener('close_EditWdg', ''' var popup = spt.popup.get_popup( $('edit_popup') ); if (popup != null) { spt.popup.destroy(popup); } ''') # custom callbacks cbjs_cancel = my.kwargs.get('cbjs_cancel') if not cbjs_cancel: cbjs_cancel = ''' spt.named_events.fire_event('preclose_edit_popup', {}); spt.named_events.fire_event('close_EditWdg', {}) ''' # custom callbacks cbjs_insert_path = my.kwargs.get('cbjs_%s_path' % my.mode) cbjs_insert = None if cbjs_insert_path: script_obj = CustomScript.get_by_path(cbjs_insert_path) if script_obj: cbjs_insert = script_obj.get_value("script") # get it inline if not cbjs_insert: cbjs_insert = my.kwargs.get('cbjs_%s' % my.mode) # use a default if not cbjs_insert: mode_label = my.mode.capitalize() cbjs_insert = ''' spt.app_busy.show("%sing items", ""); spt.edit.edit_form_cbk(evt, bvr); spt.app_busy.hide(); '''%mode_label save_event = my.kwargs.get('save_event') if not save_event: save_event = div.get_unique_event("save") bvr['save_event'] = save_event bvr['named_event'] = 'edit_pressed' bvr['cbjs_action'] = cbjs_insert ok_btn_label = my.mode.capitalize() if ok_btn_label == 'Edit': ok_btn_label = 'Save' if ok_btn_label == 'Insert': ok_btn_label = 'Add' if my.kwargs.get('ok_btn_label'): ok_btn_label = my.kwargs.get('ok_btn_label') ok_btn_tip = ok_btn_label if my.kwargs.get('ok_btn_tip'): ok_btn_tip = my.kwargs.get('ok_btn_tip') cancel_btn_label = 'Cancel' if my.kwargs.get('cancel_btn_label'): cancel_btn_label = my.kwargs.get('cancel_btn_label') cancel_btn_tip = cancel_btn_label if my.kwargs.get('cancel_btn_tip'): cancel_btn_tip = my.kwargs.get('cancel_btn_tip') # create the buttons insert_button = ActionButtonWdg(title=ok_btn_label, tip=ok_btn_tip) insert_button.add_behavior(bvr) cancel_button = ActionButtonWdg(title=cancel_btn_label, tip=cancel_btn_tip) cancel_button.add_behavior({ 'type': 'click_up', 'cbjs_action': cbjs_cancel }) table = Table() table.add_style("margin-left: auto") table.add_style("margin-right: auto") table.add_style("margin-top: 15px") table.add_style("margin-bottom: 15px") table.add_row() table.add_cell(insert_button) table.add_cell(cancel_button) div.add(table) #div.add(SpanWdg(edit, css='med')) #div.add(SpanWdg(edit_close, css='med')) #div.add(SpanWdg(cancel, css='med')) return div
def get_example_display(self): div = DivWdg() # --------------------------------------------------------------------------------------------------------- self.setup_next_example(div,"Demonstrates the adding of a 'listen' type behavior Named Event in Javascript " \ "dynamically") dummy_listener_div = DivWdg() dummy_listener_div.set_id("dummy_listener_div") dummy_listener_div.set_style("border: 1px solid #000000; background: #AAAAAA; color: #000000; " \ "width: 1000px; padding: 10px;") dummy_listener_div.add("This DIV has no listener on it, add one dynamically by running:<br/><br/>" \ "<pre>\n spt.named_events.add_listener( $('dummy_listener_div'), 'mike_test_event', " \ "{ 'cbjs_action': 'bvr.src_el.setStyle(\"background-color\",\"red\");' } );\n" \ " spt.named_events.fire_event('mike_test_event',{});\n" \ "</pre><br/>" \ "in the TACTIC Script Editor.") div.add( dummy_listener_div ) # --------------------------------------------------------------------------------------------------------- self.setup_next_example(div,"Demonstrates the firing of an SPT Named Event for 'listen' type behavior. This " \ "example also shows the adding of stacked 'listen' type behaviors on a single " \ "element listening for a single event name (allowing 2 actions to occur on the " \ "firing of one event name)" ) named_event_name = 'SingleNamedEvent' named_fire_div = DivWdg() named_fire_div.set_id( "%s_Firer" % named_event_name ) named_fire_div.set_style("border: 1px solid #000000; background: #AAAAAA; color: #000000; width: 200px; " \ "cursor: pointer; padding: 4px;") named_fire_div.add("Click me to Fire an SPT Named Event!") named_fire_div.add_behavior( {'type': 'click', 'cbjs_action': 'spt.named_events.fire_event("%s",bvr);' % named_event_name, 'cbfn_preprocess': 'spt.ui_play.named_event_fire_preprocess', 'cbfn_postprocess': 'spt.ui_play.named_event_fire_postprocess'} ) div.add( named_fire_div ) div.add( '<br/>' ) named_listener_div = DivWdg() named_listener_div.set_style("border: 1px solid #000000; background: #0000AA; width: 200px; padding: 4px;") named_listener_div.add("Listening for an SPT Named Event!") named_listener_div.add_behavior( {'type': 'listen', 'event_name': named_event_name, 'cbjs_action': 'alert("Named event [%s] has fired!");' % named_event_name} ) # show ability to stack more call-backs on the same event for the same element ... named_listener_div.add_behavior( {'type': 'listen', 'event_name': named_event_name, 'cbjs_action': 'bvr.src_el.setStyle("background-color","red");'} ) div.add( named_listener_div ) # --------------------------------------------------------------------------------------------------------- self.setup_next_example( div, "Demonstrates the ability for a single Named Event 'listen' behavior to listen to " \ "multiple event names, but execute a single call-back" ) event_name_list = [ 'MultipleNamedEvents_Event_One', 'MultipleNamedEvents_Event_Two', 'MultipleNamedEvents_Event_Three', 'MultipleNamedEvents_Event_Four' ] named_listener_div = DivWdg() named_listener_div.set_id( "MultiNamedEventListenerDiv" ) named_listener_div.set_style("border: 1px solid #000000; background: #005500; width: 300px; padding: 4px;") named_listener_div.add("Listening on MULTIPLE SPT Named Events!") named_listener_div.add_behavior( {'type': 'listen', 'event_name': event_name_list, 'cbfn_action': 'spt.ui_play.named_event_listen_cbk'} ) div.add( named_listener_div ) div.add( '<br/>' ) for event_name in event_name_list: named_fire_div = DivWdg() named_fire_div.set_id( "%s_Firer" % event_name ) named_fire_div.set_style("border: 1px solid #000000; background: #AAAAAA; color: #000000; width: 200px; " \ "cursor: pointer; padding: 4px;") named_fire_div.add("Click me to Fire '%s'!" % event_name) behavior = {'type': 'click', 'cb_fire_named_event': event_name} if event_name.endswith( "_One" ): behavior['cbjs_preprocess'] = 'log.debug(">>> Ran cbjs_preprocess!");' behavior['cbjs_postprocess'] = 'log.debug(">>> Ran cbjs_postprocess!");' named_fire_div.add_behavior( behavior ) div.add( named_fire_div ) div.add( '<br/>' ) # ------------------------------------------------------------------------------------------------------------ self.setup_next_example( div, "Demonstrates the use of the convenience short cut for adding a 'listen' " \ "type behavior by using HtmlElement.add_named_listener() method" ) # Add a div to click on to fire the desired named event ... event_name = "whatever_refresh" named_fire_div = DivWdg() named_fire_div.set_id( "%s_Firer" % event_name ) named_fire_div.set_style("border: 1px solid #000000; background: #CC0000; color: #000000; width: 200px; " \ "cursor: pointer; padding: 4px;") named_fire_div.add("Click me to Fire '%s'!" % event_name) named_fire_div.add_behavior( {'type': 'click', 'cbjs_action' : 'alert("About to fire event on postaction ...");', 'cbjs_postaction' : 'spt.named_events.fire_event("%s",bvr);' % event_name, 'cbjs_preprocess': 'log.debug("Running preprocess on postaction fire event!");', 'cbjs_postprocess': 'log.debug("Running postprocess on postaction fire event!");' } ) div.add( named_fire_div ) div.add( '<br/>' ) # Now call convenience function to more easily set up a named listener behavior ... still needs to be # parked on an HTML element, so call it from the top level div in this get_display() method ... # # NOTE: the last parameter is for any extra bvr specification, like preaction or postaction call-backs # ... if no specs to add then use {} as last param # div.add_named_listener( event_name, 'alert("Named event [%s] has fired!");' % event_name, {'cbjs_postaction': 'spt.panel.refresh("main_body");'} ) # ------------------------------------------------------------------------------------------------------------ self.setup_next_example( div, "" ) return div
def get_action_html(my): search_key = SearchKey.get_by_sobject(my.sobjects[0]) search_type = my.sobjects[0].get_base_search_type() div = DivWdg(css='centered') div.add_behavior( { 'type': 'load', 'cbjs_action': my.get_onload_js() } ) div.add_styles('height: 35px; margin-top: 10px;') div.add_named_listener('close_EditWdg', ''' var popup = bvr.src_el.getParent( ".spt_popup" ); if (popup) spt.popup.close(popup); ''') # custom callbacks cbjs_cancel = my.kwargs.get('cbjs_cancel') if not cbjs_cancel: cbjs_cancel = ''' spt.named_events.fire_event('preclose_edit_popup', {}); spt.named_events.fire_event('close_EditWdg', {}) ''' # custom callbacks cbjs_insert_path = my.kwargs.get('cbjs_%s_path' % my.mode) cbjs_insert = None if cbjs_insert_path: script_obj = CustomScript.get_by_path(cbjs_insert_path) cbjs_insert = script_obj.get_value("script") cbjs_insert = cbjs_insert.replace("'", '"') # get it inline if not cbjs_insert: cbjs_insert = my.kwargs.get('cbjs_%s' % my.mode) # use a default if not cbjs_insert: cbjs_insert = ''' spt.edit.edit_form_cbk(evt, bvr); ''' element_names = my.element_names[:] for element_name in my.skipped_element_names: element_names.remove(element_name) # Must not have postaction which closes the EditWdg before upload finishes from tactic.ui.widget import TextBtnWdg, TextBtnSetWdg bvr = { 'cbjs_action': cbjs_insert, 'named_event': 'close_EditWdg', 'element_names': element_names, 'search_key': search_key, 'input_prefix': my.input_prefix, 'view': my.view } keys = WebContainer.get_web().get_form_keys() for key in keys: bvr[key] = WebContainer.get_web().get_form_value(key) label = my.mode if label == 'edit': label = 'save' buttons_list = [ { 'label': label.capitalize(), 'tip': label.capitalize(), 'bvr': bvr }, { 'label': 'Cancel', 'tip': 'Cancel', 'bvr': { 'cbjs_action': cbjs_cancel } } ] buttons = TextBtnSetWdg( align="center", buttons=buttons_list, spacing=10, size='large', side_padding=4 ) div.add(buttons) return div
def get_display(my): search_type_obj = SearchType.get(my.search_type) sobj_title = search_type_obj.get_title() my.color_mode = my.kwargs.get("color_mode") if not my.color_mode: my.color_mode = "default" top_div = my.top top_div.add_class("spt_edit_top") if not my.is_refresh: my.set_as_panel(top_div) content_div = DivWdg() content_div.add_class("spt_edit_top") content_div.add_class("spt_edit_form_top") content_div.set_attr("spt_search_key", my.search_key) if not Container.get_dict("JSLibraries", "spt_edit"): content_div.add_behavior( { 'type': 'load', 'cbjs_action': my.get_onload_js() } ) layout_view = my.kwargs.get("layout_view") if layout_view: layout_wdg = my.get_custom_layout_wdg(layout_view) content_div.add(layout_wdg) return content_div # add close listener # NOTE: this is an absolute search, but is here for backwards # compatibility content_div.add_named_listener('close_EditWdg', ''' var popup = bvr.src_el.getParent( ".spt_popup" ); if (popup) spt.popup.close(popup); ''') attrs = my.config.get_view_attributes() default_access = attrs.get("access") if not default_access: default_access = "edit" project_code = Project.get_project_code() security = Environment.get_security() base_key = search_type_obj.get_base_key() key = { 'search_type': base_key, 'project': project_code } access = security.check_access("sobject", key, "edit", default=default_access) if not access: my.is_disabled = True else: my.is_disabled = False disable_wdg = None if my.is_disabled: # TODO: This overlay doesn't work in IE, size, position, # and transparency all fail. disable_wdg = DivWdg(id='edit_wdg') disable_wdg.add_style("position: absolute") disable_wdg.add_style("height: 90%") disable_wdg.add_style("width: 100%") disable_wdg.add_style("left: 0px") #disable_wdg.add_style("bottom: 0px") #disable_wdg.add_style("top: 0px") disable_wdg.add_style("opacity: 0.2") disable_wdg.add_style("background: #fff") #disable_wdg.add_style("-moz-opacity: 0.2") disable_wdg.add_style("filter: Alpha(opacity=20)") disable_wdg.add("<center>EDIT DISABLED</center>") content_div.add(disable_wdg) attrs = my.config.get_view_attributes() #inner doesn't get styled. inner = DivWdg() content_div.add(inner) menu = my.get_header_context_menu() menus = [menu.get_data()] menus_in = { 'HEADER_CTX': menus, } SmartMenu.attach_smart_context_menu( inner, menus_in, False ) #insert the header before body into inner show_header = my.kwargs.get("show_header") if show_header not in ['false', False]: my.add_header(inner, sobj_title) #insert table into a body container so styling gets applied table = Table() body_container = DivWdg() body_container.add_class("spt_popup_body") body_container.add(table) inner.add(body_container) if my.color_mode == "default": table.add_color("background", "background") elif my.color_mode == "transparent": table.add_style("background", "transparent") table.add_color("color", "color") width = attrs.get('width') if not width: width = my.kwargs.get("width") if not width: width = 600 height = attrs.get('height') if height: table.add_style("height: %s" % height) tr = table.add_row() stype_type = search_type_obj.get_value("type", no_exception=True) if my.mode != 'insert' and stype_type in ['media'] and my.sobjects: td = table.add_cell() width += 300 from tactic.ui.panel import ThumbWdg2 thumb = ThumbWdg2() thumb.set_sobject(my.sobjects[0]) td.add(thumb) thumb.add_style("margin: 0px 10px") path = thumb.get_lib_path() td.add_style("padding: 10px") td.add_attr("rowspan", len(my.widgets)+2) td.add_style("min-width: 250px") td.add_style("vertical-align: top") td.add_border(direction="right") if path: td.add("<h3>File Information</h3>") td.add("<br/>") from pyasm.checkin import BaseMetadataParser parser = BaseMetadataParser.get_parser_by_path(path) data = parser.get_tactic_metadata() data_table = Table() data_table.add_style("margin: 15px") td.add(data_table) for name, value in data.items(): data_table.add_row() display_name = Common.get_display_title(name) dtd = data_table.add_cell("%s: " % display_name) dtd.add_style("width: 150px") dtd.add_style("padding: 3px") dtd = data_table.add_cell(value) dtd.add_style("padding: 3px") else: td.add("<h3>No Image</h3>") td.add("<br/>") # set the width table.add_style("width: %s" % width) single = my.kwargs.get("single") if single in ['false', False] and my.mode == 'insert': multi_div = DivWdg() multi_div.add_style("text-align: left") multi_div.add_style("padding: 5px 10px") multi_div.add("<b>Specify number of new items to add: </b>") multi_div.add(" "*4) multi_text = TextWdg("multiplier") multi_text.add_class("form-control") multi_div.add(multi_text) multi_text.add_style("display: inline-block") multi_text.add_style("width: 60px") tr, td = table.add_row_cell( multi_div ) if my.color_mode == "defaultX": td.add_color("border-color", "table_border", default="border") td.add_style("border-width: 1px") td.add_style("border-style: solid") td.add_style("padding: 8 3 8 3") td.add_color("background", "background3") td.add_color("color", "color3") security = Environment.get_security() # break the widgets up in columns num_columns = attrs.get('num_columns') if not num_columns: num_columns = my.kwargs.get('num_columns') if not num_columns: num_columns = 1 else: num_columns = int(num_columns) # go through each widget and draw it index = 0 for i, widget in enumerate(my.widgets): # since a widget name called code doesn't necessariy write to code column, it is commented out for now """ key = { 'search_type' : search_type_obj.get_base_key(), 'column' : widget.get_name(), 'project': project_code} # check security on widget if not security.check_access( "sobject_column",\ key, "edit"): my.skipped_element_names.append(widget.get_name()) continue """ if not hasattr(widget, 'set_input_prefix'): msg = DivWdg("Warning: The widget definition for [%s] uses [%s] and is not meant for use in Edit Layout. Please revise the edit_definition in widget config."% (widget.get_name(), widget.__class__.__name__ )) msg.add_style('color: orange') content_div.add(msg) content_div.add(HtmlElement.br()) continue if my.input_prefix: widget.set_input_prefix(my.input_prefix) # Bootstrap widget.add_class("form-control") if not isinstance(widget, CheckboxWdg): widget.add_style("width: 100%") if isinstance(widget, EditTitleWdg): tr, td = table.add_row_cell() tr.add_color("background", "background", -5) td.add_style("height", "30px") td.add_style("padding", "0px 10px") td.add(widget) index = 0 continue if isinstance(widget, HiddenWdg): content_div.add(widget) continue # Set up any validations configured on the widget ... from tactic.ui.app import ValidationUtil v_util = ValidationUtil( widget=widget ) v_bvr = v_util.get_validation_bvr() if v_bvr: if (isinstance(widget, CalendarInputWdg)): widget.set_validation( v_bvr.get('cbjs_validation'), v_bvr.get('validation_warning') ); else: widget.add_behavior( v_bvr ) widget.add_behavior( v_util.get_input_onchange_bvr() ) new_row = index % num_columns == 0 if new_row: tr = table.add_row() if my.color_mode == "default": if index % 2 == 0: tr.add_color("background", "background") else: tr.add_color("background", "background", -1 ) index += 1 show_title = widget.get_option("show_title") if not show_title: show_title = my.kwargs.get("show_title") if show_title in ['false', False]: show_title = False else: show_title = True if show_title: title = widget.get_title() td = table.add_cell(title) td.add_style("padding: 15px 15px 10px 5px") td.add_style("vertical-align: top") title_width = my.kwargs.get("title_width") if title_width: td.add_style("width: %s" % title_width) else: td.add_style("width: 150px") security = Environment.get_security() if security.check_access("builtin", "view_site_admin", "allow"): SmartMenu.assign_as_local_activator( td, 'HEADER_CTX' ) if my.color_mode == "defaultX": td.add_color("border-color", "table_border", default="border") td.add_style("border-width: 1" ) td.add_style("border-style: solid" ) td.add_style("text-align: right" ) hint = widget.get_option("hint") if hint: #hint_wdg = HintWdg(hint) #hint_wdg.add_style("float: right") #td.add( hint_wdg ) td.add_attr("title", hint) if not show_title: th, td = table.add_row_cell( widget ) continue else: td = table.add_cell( widget ) #td = table.add_cell( widget.get_value() ) td.add_style("min-width: 300px") td.add_style("padding: 10px 25px 10px 5px") td.add_style("vertical-align: top") if my.color_mode == "defaultX": td.add_color("border-color", "table_border", default="border") td.add_style("border-width: 1" ) td.add_style("border-style: solid" ) if not my.is_disabled and not my.mode == 'view': inner.add( my.get_action_html() ) if my.input_prefix: prefix = HiddenWdg("input_prefix", my.input_prefix) tr, td = table.add_row_cell() td.add(prefix) top_div.add(content_div) return top_div
def get_action_html(my): search_key = SearchKey.get_by_sobject(my.sobjects[0], use_id=True) search_type = my.sobjects[0].get_base_search_type() div = DivWdg(css='centered') # construct the bvr element_names = my.element_names[:] for element_name in my.skipped_element_names: element_names.remove(element_name) bvr = { 'type': 'click_up', 'mode': my.mode, 'element_names': element_names, 'search_key': search_key, 'input_prefix': my.input_prefix, 'view': my.view } if my.mode == 'insert': bvr['refresh'] = 'true' # for adding parent relationship in EditCmd if my.parent_key: bvr['parent_key'] = my.parent_key hidden_div = DivWdg() hidden_div.add_style("display: none") div.add(hidden_div) hidden = TextAreaWdg("__data__") hidden_div.add(hidden) hidden.set_value( jsondumps(bvr) ) show_action = my.kwargs.get("show_action") if show_action in [False, 'false']: return div div.add_styles('height: 35px; margin-top: 5px;') div.add_named_listener('close_EditWdg', ''' var popup = spt.popup.get_popup( $('edit_popup') ); if (popup != null) { spt.popup.destroy(popup); } ''') # custom callbacks cbjs_cancel = my.kwargs.get('cbjs_cancel') if not cbjs_cancel: cbjs_cancel = ''' spt.named_events.fire_event('preclose_edit_popup', {}); spt.named_events.fire_event('close_EditWdg', {}) ''' # custom callbacks cbjs_insert_path = my.kwargs.get('cbjs_%s_path' % my.mode) cbjs_insert = None if cbjs_insert_path: script_obj = CustomScript.get_by_path(cbjs_insert_path) if script_obj: cbjs_insert = script_obj.get_value("script") # get it inline if not cbjs_insert: cbjs_insert = my.kwargs.get('cbjs_%s' % my.mode) # use a default if not cbjs_insert: mode_label = my.mode.capitalize() cbjs_insert = ''' spt.app_busy.show("%sing items", ""); spt.edit.edit_form_cbk(evt, bvr); spt.app_busy.hide(); '''%mode_label save_event = my.kwargs.get('save_event') if not save_event: save_event = div.get_unique_event("save") bvr['save_event'] = save_event bvr['named_event'] = 'edit_pressed' bvr['cbjs_action'] = cbjs_insert ok_btn_label = my.mode.capitalize() if ok_btn_label == 'Edit': ok_btn_label = 'Save' if ok_btn_label == 'Insert': ok_btn_label = 'Add' if my.kwargs.get('ok_btn_label'): ok_btn_label = my.kwargs.get('ok_btn_label') ok_btn_tip = ok_btn_label if my.kwargs.get('ok_btn_tip'): ok_btn_tip = my.kwargs.get('ok_btn_tip') cancel_btn_label = 'Cancel' if my.kwargs.get('cancel_btn_label'): cancel_btn_label = my.kwargs.get('cancel_btn_label') cancel_btn_tip = cancel_btn_label if my.kwargs.get('cancel_btn_tip'): cancel_btn_tip = my.kwargs.get('cancel_btn_tip') # create the buttons insert_button = ActionButtonWdg(title=ok_btn_label, tip=ok_btn_tip) insert_button.add_behavior(bvr) cancel_button = ActionButtonWdg(title=cancel_btn_label, tip=cancel_btn_tip) cancel_button.add_behavior({ 'type': 'click_up', 'cbjs_action': cbjs_cancel }) table = Table() table.add_style("margin-left: auto") table.add_style("margin-right: auto") table.add_style("margin-top: 15px") table.add_style("margin-bottom: 15px") table.add_row() table.add_cell(insert_button) table.add_cell(cancel_button) div.add(table) #div.add(SpanWdg(edit, css='med')) #div.add(SpanWdg(edit_close, css='med')) #div.add(SpanWdg(cancel, css='med')) return div
def get_display(my): search_type_obj = SearchType.get(my.search_type) sobj_title = search_type_obj.get_title() my.color_mode = my.kwargs.get("color_mode") if not my.color_mode: my.color_mode = "default" top_div = my.top top_div.add_class("spt_edit_top") if not my.is_refresh: my.set_as_panel(top_div) content_div = DivWdg() content_div.add_class("spt_edit_top") content_div.add_class("spt_edit_form_top") content_div.set_attr("spt_search_key", my.search_key) if not Container.get_dict("JSLibraries", "spt_edit"): content_div.add_behavior( { 'type': 'load', 'cbjs_action': my.get_onload_js() } ) layout_view = my.kwargs.get("layout_view") if layout_view: layout_wdg = my.get_custom_layout_wdg(layout_view) content_div.add(layout_wdg) return content_div # add close listener # NOTE: this is an absolute search, but is here for backwards # compatibility content_div.add_named_listener('close_EditWdg', ''' var popup = bvr.src_el.getParent( ".spt_popup" ); if (popup) spt.popup.close(popup); ''') attrs = my.config.get_view_attributes() default_access = attrs.get("access") if not default_access: default_access = "edit" project_code = Project.get_project_code() security = Environment.get_security() base_key = search_type_obj.get_base_key() key = { 'search_type': base_key, 'project': project_code } access = security.check_access("sobject", key, "edit", default=default_access) if not access: my.is_disabled = True else: my.is_disabled = False disable_wdg = None if my.is_disabled: # TODO: This overlay doesn't work in IE, size, position, # and transparency all fail. disable_wdg = DivWdg(id='edit_wdg') disable_wdg.add_style("position: absolute") disable_wdg.add_style("height: 90%") disable_wdg.add_style("width: 100%") disable_wdg.add_style("left: 0px") #disable_wdg.add_style("bottom: 0px") #disable_wdg.add_style("top: 0px") disable_wdg.add_style("opacity: 0.2") disable_wdg.add_style("background: #fff") #disable_wdg.add_style("-moz-opacity: 0.2") disable_wdg.add_style("filter: Alpha(opacity=20)") disable_wdg.add("<center>EDIT DISABLED</center>") content_div.add(disable_wdg) attrs = my.config.get_view_attributes() inner = DivWdg() content_div.add(inner) menu = my.get_header_context_menu() menus = [menu.get_data()] menus_in = { 'HEADER_CTX': menus, } SmartMenu.attach_smart_context_menu( inner, menus_in, False ) table = Table() inner.add(table) if my.color_mode == "default": table.add_color("background", "background") elif my.color_mode == "transparent": table.add_style("background", "transparent") table.add_color("color", "color") width = attrs.get('width') if not width: width = my.kwargs.get("width") if not width: width = 600 table.add_style("width: %s" % width) height = attrs.get('height') if height: table.add_style("height: %s" % height) tr = table.add_row() show_header = my.kwargs.get("show_header") if show_header not in ['false', False]: my.add_header(table, sobj_title) single = my.kwargs.get("single") if single in ['false', False] and my.mode == 'insert': multi_div = DivWdg() multi_div.add_style("text-align: left") multi_div.add("Specify the number of items that will be added with this form:<br/><br/>") multi_div.add("<b># of new items to add: </b>") multi_div.add(" "*4) multi_text = TextWdg("multiplier") multi_text.add_style("width: 30px") multi_div.add(multi_text) tr, td = table.add_row_cell( multi_div ) if my.color_mode == "default": td.add_color("border-color", "table_border", default="border") td.add_style("border-width: 1px") td.add_style("border-style: solid") td.add_style("padding: 8 3 8 3") td.add_color("background", "background3") td.add_color("color", "color3") security = Environment.get_security() # break the widgets up in columns num_columns = attrs.get('num_columns') if not num_columns: num_columns = my.kwargs.get('num_columns') if not num_columns: num_columns = 1 else: num_columns = int(num_columns) # go through each widget and draw it for i, widget in enumerate(my.widgets): # since a widget name called code doesn't necessariy write to code column, it is commented out for now """ key = { 'search_type' : search_type_obj.get_base_key(), 'column' : widget.get_name(), 'project': project_code} # check security on widget if not security.check_access( "sobject_column",\ key, "edit"): my.skipped_element_names.append(widget.get_name()) continue """ if not hasattr(widget, 'set_input_prefix'): msg = DivWdg("Warning: The widget definition for [%s] uses [%s] and is not meant for use in Edit Layout. Please revise the edit_definition in widget config."% (widget.get_name(), widget.__class__.__name__ )) msg.add_style('color: orange') content_div.add(msg) content_div.add(HtmlElement.br()) continue if my.input_prefix: widget.set_input_prefix(my.input_prefix) # Bootstrap widget.add_class("form-control") widget.add_style("width: 100%") class EditTitleWdg(BaseRefreshWdg): pass #if isinstance(widget, EditTitleWdg): """ has_title = True if has_title and i % 3 == 0: tr, td = table.add_row_cell() tr.add_color("background", "background", -5) td.add("TITLE") td.add_style("height", "30px") td.add_style("padding", "0px 10px") """ if isinstance(widget, HiddenWdg): content_div.add(widget) continue # Set up any validations configured on the widget ... from tactic.ui.app import ValidationUtil v_util = ValidationUtil( widget=widget ) v_bvr = v_util.get_validation_bvr() if v_bvr: if (isinstance(widget, CalendarInputWdg)): widget.set_validation( v_bvr.get('cbjs_validation'), v_bvr.get('validation_warning') ); else: widget.add_behavior( v_bvr ) widget.add_behavior( v_util.get_input_onchange_bvr() ) new_row = i % num_columns == 0 if new_row: tr = table.add_row() if my.color_mode == "default": if i % 2 == 0: tr.add_color("background", "background") else: tr.add_color("background", "background", -2 ) show_title = widget.get_option("show_title") if not show_title: show_title = my.kwargs.get("show_title") if show_title in ['false', False]: show_title = False else: show_title = True if show_title: title = widget.get_title() td = table.add_cell(title) td.add_style("padding: 10px 15px 10px 5px") td.add_style("vertical-align: top") title_width = my.kwargs.get("title_width") if title_width: td.add_style("width: %s" % title_width) else: td.add_style("width: 150px") security = Environment.get_security() if security.check_access("builtin", "view_site_admin", "allow"): SmartMenu.assign_as_local_activator( td, 'HEADER_CTX' ) if my.color_mode == "default": td.add_color("border-color", "table_border", default="border") td.add_style("border-width: 1" ) td.add_style("border-style: solid" ) td.add_style("text-align: right" ) hint = widget.get_option("hint") if hint: #hint_wdg = HintWdg(hint) #hint_wdg.add_style("float: right") #td.add( hint_wdg ) td.add_attr("title", hint) if not show_title: th, td = table.add_row_cell( widget ) continue else: td = table.add_cell( widget ) #td = table.add_cell( widget.get_value() ) td.add_style("min-width: 300px") td.add_style("padding: 10px 15px 10px 5px") td.add_style("vertical-align: top") if my.color_mode == "default": td.add_color("border-color", "table_border", default="border") td.add_style("border-width: 1" ) td.add_style("border-style: solid" ) if not my.is_disabled and not my.mode == 'view': tr, td = table.add_row_cell( my.get_action_html() ) if my.input_prefix: prefix = HiddenWdg("input_prefix", my.input_prefix) tr, td = table.add_row_cell() td.add(prefix) top_div.add(content_div) return top_div
def get_action_html(my): search_key = SearchKey.get_by_sobject(my.sobjects[0]) search_type = my.sobjects[0].get_base_search_type() div = DivWdg(css='centered') div.add_behavior( { 'type': 'load', 'cbjs_action': my.get_onload_js() } ) div.add_styles('height: 35px; margin-top: 10px;') div.add_named_listener('close_EditWdg', ''' var popup = bvr.src_el.getParent( ".spt_popup" ); if (popup) spt.popup.close(popup); ''') # custom callbacks cbjs_cancel = my.kwargs.get('cbjs_cancel') if not cbjs_cancel: cbjs_cancel = ''' spt.named_events.fire_event('preclose_edit_popup', {}); spt.named_events.fire_event('close_EditWdg', {}) ''' # custom callbacks cbjs_insert_path = my.kwargs.get('cbjs_%s_path' % my.mode) cbjs_insert = None if cbjs_insert_path: script_obj = CustomScript.get_by_path(cbjs_insert_path) cbjs_insert = script_obj.get_value("script") cbjs_insert = cbjs_insert.replace("'", '"') # get it inline if not cbjs_insert: cbjs_insert = my.kwargs.get('cbjs_%s' % my.mode) # use a default if not cbjs_insert: cbjs_insert = ''' spt.edit.edit_form_cbk(evt, bvr); ''' element_names = my.element_names[:] for element_name in my.skipped_element_names: element_names.remove(element_name) # Must not have postaction which closes the EditWdg before upload finishes from tactic.ui.widget import TextBtnWdg, TextBtnSetWdg bvr = { 'cbjs_action': cbjs_insert, 'named_event': 'close_EditWdg', 'element_names': element_names, 'search_key': search_key, 'input_prefix': my.input_prefix, 'view': my.view } keys = WebContainer.get_web().get_form_keys() for key in keys: bvr[key] = WebContainer.get_web().get_form_value(key) label = my.mode if label == 'edit': label = 'save' buttons_list = [ { 'label': label.capitalize(), 'tip': label.capitalize(), 'bvr': bvr }, { 'label': 'Cancel', 'tip': 'Cancel', 'bvr': { 'cbjs_action': cbjs_cancel } } ] buttons = TextBtnSetWdg( align="center", buttons=buttons_list, spacing=10, size='large', side_padding=4 ) div.add(buttons) return div
def get_example_display(self): div = DivWdg() # --------------------------------------------------------------------------------------------------------- self.setup_next_example(div,"Demonstrates the adding of a 'listen' type behavior Named Event in Javascript " \ "dynamically") dummy_listener_div = DivWdg() dummy_listener_div.set_id("dummy_listener_div") dummy_listener_div.set_style("border: 1px solid #000000; background: #AAAAAA; color: #000000; " \ "width: 1000px; padding: 10px;") dummy_listener_div.add("This DIV has no listener on it, add one dynamically by running:<br/><br/>" \ "<pre>\n spt.named_events.add_listener( $('dummy_listener_div'), 'mike_test_event', " \ "{ 'cbjs_action': 'bvr.src_el.setStyle(\"background-color\",\"red\");' } );\n" \ " spt.named_events.fire_event('mike_test_event',{});\n" \ "</pre><br/>" \ "in the TACTIC Script Editor.") div.add(dummy_listener_div) # --------------------------------------------------------------------------------------------------------- self.setup_next_example(div,"Demonstrates the firing of an SPT Named Event for 'listen' type behavior. This " \ "example also shows the adding of stacked 'listen' type behaviors on a single " \ "element listening for a single event name (allowing 2 actions to occur on the " \ "firing of one event name)" ) named_event_name = 'SingleNamedEvent' named_fire_div = DivWdg() named_fire_div.set_id("%s_Firer" % named_event_name) named_fire_div.set_style("border: 1px solid #000000; background: #AAAAAA; color: #000000; width: 200px; " \ "cursor: pointer; padding: 4px;") named_fire_div.add("Click me to Fire an SPT Named Event!") named_fire_div.add_behavior({ 'type': 'click', 'cbjs_action': 'spt.named_events.fire_event("%s",bvr);' % named_event_name, 'cbfn_preprocess': 'spt.ui_play.named_event_fire_preprocess', 'cbfn_postprocess': 'spt.ui_play.named_event_fire_postprocess' }) div.add(named_fire_div) div.add('<br/>') named_listener_div = DivWdg() named_listener_div.set_style( "border: 1px solid #000000; background: #0000AA; width: 200px; padding: 4px;" ) named_listener_div.add("Listening for an SPT Named Event!") named_listener_div.add_behavior({ 'type': 'listen', 'event_name': named_event_name, 'cbjs_action': 'alert("Named event [%s] has fired!");' % named_event_name }) # show ability to stack more call-backs on the same event for the same element ... named_listener_div.add_behavior({ 'type': 'listen', 'event_name': named_event_name, 'cbjs_action': 'bvr.src_el.setStyle("background-color","red");' }) div.add(named_listener_div) # --------------------------------------------------------------------------------------------------------- self.setup_next_example( div, "Demonstrates the ability for a single Named Event 'listen' behavior to listen to " \ "multiple event names, but execute a single call-back" ) event_name_list = [ 'MultipleNamedEvents_Event_One', 'MultipleNamedEvents_Event_Two', 'MultipleNamedEvents_Event_Three', 'MultipleNamedEvents_Event_Four' ] named_listener_div = DivWdg() named_listener_div.set_id("MultiNamedEventListenerDiv") named_listener_div.set_style( "border: 1px solid #000000; background: #005500; width: 300px; padding: 4px;" ) named_listener_div.add("Listening on MULTIPLE SPT Named Events!") named_listener_div.add_behavior({ 'type': 'listen', 'event_name': event_name_list, 'cbfn_action': 'spt.ui_play.named_event_listen_cbk' }) div.add(named_listener_div) div.add('<br/>') for event_name in event_name_list: named_fire_div = DivWdg() named_fire_div.set_id("%s_Firer" % event_name) named_fire_div.set_style("border: 1px solid #000000; background: #AAAAAA; color: #000000; width: 200px; " \ "cursor: pointer; padding: 4px;") named_fire_div.add("Click me to Fire '%s'!" % event_name) behavior = {'type': 'click', 'cb_fire_named_event': event_name} if event_name.endswith("_One"): behavior[ 'cbjs_preprocess'] = 'log.debug(">>> Ran cbjs_preprocess!");' behavior[ 'cbjs_postprocess'] = 'log.debug(">>> Ran cbjs_postprocess!");' named_fire_div.add_behavior(behavior) div.add(named_fire_div) div.add('<br/>') # ------------------------------------------------------------------------------------------------------------ self.setup_next_example( div, "Demonstrates the use of the convenience short cut for adding a 'listen' " \ "type behavior by using HtmlElement.add_named_listener() method" ) # Add a div to click on to fire the desired named event ... event_name = "whatever_refresh" named_fire_div = DivWdg() named_fire_div.set_id("%s_Firer" % event_name) named_fire_div.set_style("border: 1px solid #000000; background: #CC0000; color: #000000; width: 200px; " \ "cursor: pointer; padding: 4px;") named_fire_div.add("Click me to Fire '%s'!" % event_name) named_fire_div.add_behavior({ 'type': 'click', 'cbjs_action': 'alert("About to fire event on postaction ...");', 'cbjs_postaction': 'spt.named_events.fire_event("%s",bvr);' % event_name, 'cbjs_preprocess': 'log.debug("Running preprocess on postaction fire event!");', 'cbjs_postprocess': 'log.debug("Running postprocess on postaction fire event!");' }) div.add(named_fire_div) div.add('<br/>') # Now call convenience function to more easily set up a named listener behavior ... still needs to be # parked on an HTML element, so call it from the top level div in this get_display() method ... # # NOTE: the last parameter is for any extra bvr specification, like preaction or postaction call-backs # ... if no specs to add then use {} as last param # div.add_named_listener( event_name, 'alert("Named event [%s] has fired!");' % event_name, {'cbjs_postaction': 'spt.panel.refresh("main_body");'}) # ------------------------------------------------------------------------------------------------------------ self.setup_next_example(div, "") return div