def message_widget(field, value, **attr): """ Widget to edit and preview a notification message body @param field: the Field @param value: the current field value @param attr: DOM attributes for the widget """ widget_id = attr.get("_id") if not widget_id: widget_id = "%s_%s" % (field._tablename, field.name) edit = TEXTAREA( _name=attr.get("_name", field.name), _id=widget_id, _class="message %s" % (field.type), _placeholder=attr.get("_placeholder"), _rows=6, _style="display:none", value=value, requires=field.requires, ) preview = P("", _class="preview") return DIV(preview, edit, _class="preview-widget")
def materialize_form(form, fields): """ Change layout of SQLFORM forms """ form.add_class("form-horizontal center") main_div = DIV(_class="center") for field_id, label, controls, field_help in fields: curr_div = DIV(_class="row") input_field = None _controls = controls try: _name = controls.attributes["_name"] except: _name = "" try: _type = controls.attributes["_type"] except: _type = "string" try: _id = controls.attributes["_id"] except: _id = "" if isinstance(controls, INPUT): if _type == "file": # Layout for file type inputs input_field = DIV( DIV(SPAN("Upload"), INPUT(_type=_type, _id=_id), _class="btn"), DIV(INPUT(_type="text", _class="file-path", _placeholder=label.components[0]), _class="file-path-wrapper"), _class="col input-field file-field offset-s3 s6") if isinstance(controls, SPAN): # Mostly for ids which cannot be edited by user _controls = INPUT(_value=controls.components[0], _id=_id, _name=_name, _disabled="disabled") elif isinstance(controls, TEXTAREA): # Textarea inputs try: _controls = TEXTAREA(controls.components[0], _name=_name, _id=_id, _class="materialize-textarea text") except IndexError: _controls = TEXTAREA(_name=_name, _id=_id, _class="materialize-textarea text") elif isinstance(controls, SELECT): # Select inputs _controls = SELECT(OPTION(label, _value=""), _name=_name, _class="browser-default", *controls.components[1:]) # Note now label will be the first element # of Select input whose value would be "" label = "" elif isinstance(controls, A): # For the links in the bottom while updating tables like auth_user label = "" elif isinstance(controls, INPUT) is False: # If the values are readonly _controls = INPUT(_value=controls, _name=_name, _disabled="") if input_field is None: input_field = DIV(_controls, label, _class="input-field col offset-s3 s6") curr_div.append(input_field) main_div.append(curr_div) return main_div
def cms_post_list_layout(list_id, item_id, resource, rfields, record): """ dataList item renderer for Posts on the Bulletin Board. @param list_id: the HTML ID of the list @param item_id: the HTML ID of the item @param resource: the S3Resource to render @param rfields: the S3ResourceFields to render @param record: the record as dict """ record_id = record["cms_post.id"] #item_class = "thumbnail" T = current.T db = current.db s3db = current.s3db settings = current.deployment_settings permit = current.auth.s3_has_permission raw = record._row date = record["cms_post.date"] title = record["cms_post.title"] body = record["cms_post.body"] #series_id = raw["cms_post.series_id"] # Allow records to be truncated # (not yet working for HTML) body = DIV( body, _class="s3-truncate", ) #if series_id: # series = record["cms_post.series_id"] # translate = settings.get_L10n_translate_cms_series() # if translate: # series_title = T(series) # else: # series_title = series #else: # series_title = series = "" #status = record["cms_post.status_id"] author_id = raw["cms_post.created_by"] person = record["cms_post.created_by"] # @ToDo: Bulk lookup ltable = s3db.pr_person_user ptable = db.pr_person query = (ltable.user_id == author_id) & \ (ltable.pe_id == ptable.pe_id) row = db(query).select(ptable.id, limitby=(0, 1)).first() if row: person_id = row.id else: person_id = None if person: if person_id: # @ToDo: deployment_setting for controller to use? person_url = URL(c="hrm", f="person", args=[person_id]) else: person_url = "#" person = A( person, _href=person_url, ) table = db.cms_post # Toolbar if permit("update", table, record_id=record_id): edit_btn = A( ICON("edit"), SPAN( "edit", _class="show-for-sr", ), _href=URL(c="cms", f="post", args=[record_id, "update.popup"], vars={ "refresh": list_id, "record": record_id }), _class="s3_modal", #_title=T("Edit %(type)s") % dict(type=series_title), _title=T("Edit"), ) else: edit_btn = "" if permit("delete", table, record_id=record_id): delete_btn = A( ICON("delete"), SPAN( "delete", _class="show-for-sr", ), _class="dl-item-delete", _title=T("Delete"), ) else: delete_btn = "" # Bookmarks auth = current.auth user = auth.user if user: #and settings.get_cms_bookmarks(): # @ToDo: Bulk lookup (via list_fields?) ltable = s3db.cms_post_user query = (ltable.post_id == record_id) & \ (ltable.user_id == user.id) exists = db(query).select(ltable.id, limitby=(0, 1)).first() if exists: bookmark = A( ICON("bookmark"), SPAN( "remove bookmark", _class="show-for-sr", ), _class="bookmark", _title=T("Remove Bookmark"), ) else: bookmark = A( ICON("bookmark-empty"), SPAN( "bookmark", _class="show-for-sr", ), _class="bookmark", _title=T("Add Bookmark"), ) bookmark["_data-c"] = "cms" bookmark["_data-f"] = "post" bookmark["_data-i"] = record_id else: bookmark = "" # Dropdown of available documents documents = raw["doc_document.file"] if documents: if not isinstance(documents, list): documents = (documents, ) doc_list = UL( _class="dropdown-menu", _role="menu", ) retrieve = db.doc_document.file.retrieve for doc in documents: try: doc_name = retrieve(doc)[0] except (IOError, TypeError): doc_name = current.messages["NONE"] doc_url = URL(c="default", f="download", args=[doc]) doc_item = LI( A( ICON("file"), " ", doc_name, _href=doc_url, ), _role="menuitem", ) doc_list.append(doc_item) docs = DIV( A(ICON("paper-clip"), SPAN(_class="caret"), _class="btn dropdown-toggle", _href="#", **{"_data-toggle": "dropdown"}), doc_list, _class="btn-group attachments dropdown pull-right", ) else: docs = "" #divider = LI("|") #divider["_aria-hidden"] = "true" toolbar = UL( #LI(share_btn, # _class="item", # ), #LI(A(ICON("flag"), # @ToDo: Use flag-alt if not flagged & flag if already flagged (like for bookmarks) # SPAN("flag this", # _class = "show-for-sr", # ), # _href="#", # _title=T("Flag"), # ), # _class="item", # ), LI( bookmark, _class="item", ), #LI(A(I(_class="fa fa-users", # ), # SPAN("make public", # _class = "show-for-sr", # ), # _href="#", # _title=T("Make Public"), # ), # _class="item", # ), LI( edit_btn, _class="item", ), LI( delete_btn, _class="item", ), _class="controls", ) # Tags #if settings.get_cms_show_tags(): tag_list = UL(_class="left inline-list s3-tags", ) tag_list["_data-post_id"] = record_id tags = raw["cms_tag.name"] if tags: if not isinstance(tags, list): tags = [tags] for tag in tags: tag_list.append(LI(A( tag, _href="#", ), )) # Comments comment_list = UL(_class="card-post-comments") cappend = comment_list.append #if settings.get_cms_comments(): # Add existing comments (oldest 1st) # - should sort by default by ID which is equivalent to oldest first, # however they seem to come in in a random order (even if orderby set on the component) so need to be sorted manually here comments = raw["cms_comment.json_dump"] ncomments = 0 if comments: if not isinstance(comments, list): comments = [comments] comments = [json.loads(comment) for comment in comments] comments.sort(key=lambda c: c["created_on"]) for comment in comments: author = s3_auth_user_represent(comment["created_by"]) cdate = dateutil.parser.parse(comment["created_on"]) ctime = cdate.time().strftime("%H:%M") cdate = cdate.date().strftime("%b %d, %Y") comment = LI(TAG["ASIDE"](P(T("Updated %(date)s @ %(time)s by %(author)s") % \ dict(date = cdate, time = ctime, author = author, ), _class="meta", ), DIV(comment["body"], _class="desc", ), # @ToDo: Show this if more than x chars? #TAG["FOOTER"](P(A(T("More Info"), # _class="more", # ) # ), # _class="footer", # ), _class="card-post-comment", )) cappend(comment) ncomments += 1 if ncomments == 1: num_comments = "1 Comment" else: num_comments = T("%(num)s Comments") % dict(num=ncomments) if user: add_comment = A( T("Add Comment"), _class="add-comment", ) add_comment["_data-l"] = list_id add_comment["_data-i"] = record_id add_comment = P(add_comment) comment_input = LI( TAG["ASIDE"]( TEXTAREA( _class="desc", _placeholder=T("comment here"), ), TAG["FOOTER"](P(A( "Submit Comment", _class="submit", ), ), ), _class="card-post-comment", ), _class="comment-form hide", ) cappend(comment_input) else: add_comment = "" item = TAG["ASIDE"]( TAG["HEADER"]( UL( # post priority icon LI(_class="item icon", ), # post type title #LI(series_title, # _class="item primary", # ), # post status #LI(status, # _class="item secondary border status", # ), # post visibility # @ToDo: Read the visibility #LI(T("Public"), # _class="item secondary border visibility", # ), _class="status-bar-left"), toolbar, _class="status-bar", ), DIV( DIV( SPAN( "Updated ", # @ToDo: i18n TAG["TIME"](date), " by ", person, _class="meta-update", ), SPAN( num_comments, _class="meta-comments", ), _class="meta", ), H4( title, _class="title", ), DIV( body, _class="desc", ), _class="body", ), docs, TAG["FOOTER"]( DIV( tag_list, _class= "tags clearfix", # @ToDo: remove clearfix and style via CSS ), comment_list, add_comment, _class="footer", ), _class="card-post", _id=item_id, ) return item
def materialize_form(form, fields): """ Change layout of SQLFORM forms @params form (FORM): FORM object representing the form DOM @params fields (List): List of fields in the form @return (DIV): Materialized form wrapped with a DIV """ form.add_class("form-horizontal center") main_div = DIV(_class="center") for _, label, controls, field_tooltip in fields: curr_div = DIV(_class="row center valign-wrapper") input_field = None _controls = controls try: _name = controls.attributes["_name"] except: _name = "" try: _type = controls.attributes["_type"] except: _type = "string" try: _id = controls.attributes["_id"] except: _id = "" if isinstance(controls, INPUT): if _type == "file": # Layout for file type inputs input_field = DIV( DIV(SPAN("Upload"), INPUT(_type=_type, _id=_id), _class="btn"), DIV(INPUT(_type="text", _class="file-path", _placeholder=label.components[0]), _class="file-path-wrapper"), _class="col input-field file-field offset-s3 s6") elif _type == "checkbox": # Checkbox input field does not require input-field class input_field = DIV(_controls, label, _class="col offset-s3 s6") if isinstance(controls, SPAN): # Mostly for ids which cannot be edited by user _controls = INPUT(_value=controls.components[0], _id=_id, _name=_name, _disabled="disabled") elif isinstance(controls, TEXTAREA): # Textarea inputs try: _controls = TEXTAREA(controls.components[0], _name=_name, _id=_id, _class="materialize-textarea text") except IndexError: _controls = TEXTAREA(_name=_name, _id=_id, _class="materialize-textarea text") elif isinstance(controls, SELECT): # Select inputs _controls = SELECT(OPTION(label, _value=""), _name=_name, _class="browser-default", *controls.components[1:]) # Note now label will be the first element # of Select input whose value would be "" input_field = DIV(_controls, _class="col offset-s3 s6") elif isinstance(controls, A): # For the links in the bottom while updating tables like auth_user label = "" elif isinstance(controls, INPUT) is False: # If the values are readonly _controls = INPUT(_value=controls, _name=_name, _disabled="") if input_field is None: input_field = DIV(_controls, label, _class="input-field col offset-s3 s6") curr_div.append(input_field) if field_tooltip: curr_div.append( DIV(I(_class="fa fa-info-circle tooltipped", data={ "position": "top", "delay": "30", "tooltip": field_tooltip }, _style="cursor: pointer;"), _class="col s1 valign")) main_div.append(curr_div) return main_div