def style_container(self, attrs, important=True, page=None): """ Description: ------------ Set the CSS style for the container page in a Jupyter Notebook. Usage:: page = pk.Page() pk.jupyter.Notebook.display.full_width(page) Attributes: ---------- :param attrs: Dictionary. Optional. The key, value pairs with the CSS attributes, :param important: Boolean. Optional. Set all the CSS attributes are important. :param page: Report. Optional. The web page or cell in the Jupyter notebook. """ self.page = page or self.page if self.page is not None: self.page.properties.css.add_text( ".container {%s}" % Defaults_css.inline(attrs, important)) return self else: return self.css(".container {%s}" % Defaults_css.inline(attrs, important))
def left(self, components, title="", color=None, align="center", width=(100, "%"), height=(None, "px"), html_code=None, helper=None, options=None, profile=False): """ Description: ------------ Sliding panels with the arrow on the left. :tags: :categories: Usage:: Attributes: ---------- :param components: List. The different HTML objects to be added to the component. :param title: String. Optional. A panel title. This will be attached to the title property. :param color: String. Optional. The font color in the component. Default inherit. :param align: String. The text-align property within this component. :param width: Tuple. Optional. A tuple with the integer for the component width and its unit. :param height: Tuple. Optional. A tuple with the integer for the component height and its unit. :param html_code: String. Optional. An identifier for this component (on both Python and Javascript side). :param helper: String. Optional. A tooltip helper. :param options: Dictionary. Optional. Specific Python options available for this component. :param profile: Boolean | Dictionary. Optional. A flag to set the component performance storage. """ sliding = self.page.ui.panels.sliding(components, color=color, title=title, align=align, width=width, height=height, html_code=html_code, helper=helper, options=options, profile=profile) sliding.options.icon_closed = Defaults_css.get_icon("chevron_up")["icon"] sliding.options.icon_expanded = Defaults_css.get_icon("chevron_down")["icon"] sliding.style.css.width = "80%" sliding.style.css.border_bottom = "1px solid black" html.Html.set_component_skin(sliding) return sliding
def plus(self, components, title="", color=None, align="center", width=(100, "%"), height=(None, "px"), html_code=None, helper=None, options=None, profile=False): """ Description: ------------ Same component than sliding with a different style. :tags: :categories: Usage:: Attributes: ---------- :param components: List. The different HTML objects to be added to the component. :param title: String. Optional. A panel title. This will be attached to the title property. :param color: String. Optional. The font color in the component. Default inherit. :param align: String. The text-align property within this component. :param width: Tuple. Optional. A tuple with the integer for the component width and its unit. :param height: Tuple. Optional. A tuple with the integer for the component height and its unit. :param html_code: String. Optional. An identifier for this component (on both Python and Javascript side). :param helper: String. Optional. A tooltip helper. :param options: Dictionary. Optional. Specific Python options available for this component. :param profile: Boolean | Dictionary. Optional. A flag to set the component performance storage. """ html_slide = self.page.ui.panels.sliding( components, title, color, align, width, height, html_code, helper, options, profile) html_slide.title.style.css.padding = 0 html_slide.title[1].style.css.margin_left = 15 html_slide.options.icon_closed = Defaults_css.get_icon("plus")["icon"] html_slide.options.icon_expanded = Defaults_css.get_icon("minus")["icon"] html_slide.val[1].style.padding_left = 40 html.Html.set_component_skin(html_slide) return html_slide
def __str__(self): header = [ "<th style='width:%s%%;%s'>%s</th>" % (100 / len(self.labels), Defaults.inline(self.options.header), d) for d in self.labels ] body, row = [], [] for i, day in enumerate(self.val): if 'number' in day: total_capacity, tooltip = 0, ["<b>%s</b>" % day['date']] for t in day.get("tasks", []): c = t.get("capacity", 0) total_capacity += c tooltip.append("<div>%s: %s%%</div>" % (t['name'], c)) if total_capacity > 100: day["total_capacity"] = total_capacity day["style"] = Defaults.inline(self.options.overload) numer_day = "<div style='%(style)s' data-html='true' data-toggle='tooltip' title='overload: %(total_capacity)s%%'>%(number)s</div>" % day else: day["style"] = Defaults.inline(self.options.number) numer_day = "<div style='%(style)s'>%(number)s</div>" % day tasks = "<div>%s</div>" % "".join([ "<div style='width:100%%;height:20px;display:block;vertical-align:middle'><div style='background:%(color)s;width:100%%;height:%(capacity)s%%;display:inline-block' title='%(name)s: %(capacity)s%%'></div></div>" % t for t in day.get("tasks", []) ]) cell_style = Defaults.inline(self.options.today) if day.get("today", False): row.append( "<td data-placement='right' data-toggle='tooltip' data-html='true' title='<div>%s</div>' style='%s;background:%s'>%s%s</td>" % ("".join(tooltip), cell_style, self._report.theme.success[0], numer_day, tasks)) else: row.append( "<td data-placement='right' data-toggle='tooltip' data-html='true' title='<div>%s</div>' style='%s'>%s%s</td>" % ("".join(tooltip), cell_style, numer_day, tasks)) else: row.append("<td style='padding:0'></td>") if i % len(self.labels) == 0: body.append("<tr>%s</tr>" % "".join(row)) row = [] if row: for i in range(7 - len(row)): row.append("<td style='padding:0'></td>") body.append("<tr>%s</tr>" % "".join(row)) self._report._props['js']['onReady'].add( "%s.tooltip()" % JsQuery.decorate_var("'[data-toggle=tooltip]'", convert_var=False)) return '<table %(strAttr)s><caption style="text-align:right">%(caption)s</caption><tr>%(header)s</tr>%(content)s</table>' % { 'strAttr': self.get_attrs(pyClassNames=self.style.get_classes()), 'caption': self.caption, 'header': "".join(header), 'content': "".join(body) }
def loading(self, status=True, color=None): """ Description: ------------ Display / hide the loading status for this component. Attributes: ---------- :param status: Boolean. Optional. The loading status. :param color: String. Optional. The loading text color. """ self.require.add(cssDefaults.get_icon(None)["icon_family"]) if status: return ''' if (typeof window['popup_loading_%(htmlId)s'] === 'undefined'){ var divLoading = document.createElement("div"); window['popup_loading_%(htmlId)s'] = divLoading; divLoading.style.width = '100%%'; divLoading.style.height = '100%%'; divLoading.style.background = '%(background)s'; divLoading.style.position = 'absolute'; divLoading.style.top = 0; divLoading.style.left = 0; divLoading.style.display = 'flex'; divLoading.style.flexDirectio = 'column'; divLoading.style.justifyContent = 'center'; divLoading.style.zIndex = 200; divLoading.style.alignItems = 'center'; divLoading.style.color = '%(color)s'; divLoading.style.border = '1px solid %(color)s'; divLoading.innerHTML = "<div style='font-size:%(size)spx'><i class='fas fa-spinner fa-spin' style='margin-right:10px'></i>Loading...</div>"; document.getElementById('%(htmlId)s').appendChild(divLoading) } ''' % {"htmlId": self.htmlCode, 'color': color or self.page.theme.success[1], 'background': self.page.theme.greys[0], "size": self.page.body.style.globals.font.size + 5} return ''' if (typeof window['popup_loading_%(htmlId)s'] !== 'undefined'){ document.getElementById('%(htmlId)s').removeChild(window['popup_loading_%(htmlId)s']); window['popup_loading_%(htmlId)s'] = undefined}''' % {"htmlId": self.htmlCode}
def __init__(self, page: primitives.PageModel, records: list, width: tuple, height: tuple, html_code: Optional[str], helper: Optional[str], options: Optional[dict], profile: Optional[Union[bool, dict]]): options['is_root'] = True icon_details = cssDefaults.get_icon("folder_open") options['icon_open'] = icon_details["icon"] if icon_details['icon_family'] != 'bootstrap-icons': self.requirements = (icon_details['icon_family'], ) options['style'] = { "list-style": 'none', 'margin-left': '8px', 'padding-left': 0 } super(Tree, self).__init__(page, records, profile=profile, options=options, css_attrs={ "width": width, 'height': height }) self.add_helper(helper) self.css(options['style']) self._jsStyles['click_node'] = None
def __str__(self): divs = [] css_inline = Defaults.inline(self.options.style) for val in self.val: val["css_inline"] = css_inline divs.append("<div><div style='background:%(color)s;%(css_inline)s'></div>%(name)s</div>" % val) return '<div %s>%s</div>' % (self.get_attrs(css_class_names=self.style.get_classes()), "".join(divs))
def __init__(self, page: primitives.PageModel, val, width: tuple, profile: Optional[Union[bool, dict]], options: Optional[dict]): icon_details = Defaults.get_icon("info") if icon_details['icon_family'] != 'bootstrap-icons': self.requirements = (icon_details['icon_family'],) super(Help, self).__init__(page, val, css_attrs={"width": width}, profile=profile) self.attr['class'].add(icon_details["icon"]) self.attr['title'] = val self._jsStyles = options
def style_prompt(self, attrs, important=True, page=None): """ Description: ------------ :param attrs: :param important: :param page: :return: """ self.page = page or self.page if self.page is not None: self.page.properties.css.add_text( ".prompt {%s}" % Defaults_css.inline(attrs, important)) return self else: return self.css(".prompt {%s}" % Defaults_css.inline(attrs, important))
def adv_text(self, section, title, content, background=""): """ Description: ------------ Attributes: ---------- :param section: :param title: :param content: :return: """ container = self.context.rptObj.ui.div() if section is not None: text = self.context.rptObj.ui.text(section, width=(100, '%')) text.style.css.text_align = "center" text.style.css.font_size = Defaults_css.font(-1) text.style.css.line_height = Defaults_css.font(5) text.style.css.font_weight = 500 text.style.css.letter_spacing = "0.15em" text.style.css.text_transform = "uppercase" container.add(text) if title is not None: title = self.context.rptObj.ui.text(title, width=(100, '%')) title.style.css.text_align = "center" title.style.css.font_size = Defaults_css.font(12) title.style.css.font_weight = 300 title.css({'margin-block-end': '0.67em', 'margin-block-start': '0'}) container.add(title) if content is not None: content = self.context.rptObj.ui.text(content, width=(80, "%")) content.style.css.text_align = "center" content.style.css.font_size = Defaults_css.font(2) content.style.css.margin = "auto" container.add(content) # container0.style.css.border = "10px solid white" container.style.css.text_align = "center" container.style.css.background = background container.style.css.padding = 10 return container
def search(self, text='', placeholder='Search..', align="left", color=None, width=(100, "%"), height=(None, "px"), html_code=None, tooltip='', extensible=False, options=None, profile=None): """ Description: ------------ Add an input search component. Usage:: page.ui.inputs.search() Underlying HTML Objects: - :class:`epyk.core.html.HtmlTextEditor.Cell` Related Pages: https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_anim_search Templates: https://github.com/epykure/epyk-templates/blob/master/locals/components/list_filter.py Attributes: ---------- :param text: :param placeholder: :param align: :param color: :param width: Optional. A tuple with the integer for the component width and its unit :param height: Optional. A tuple with the integer for the component height and its unit :param html_code: :param tooltip: :param extensible: :param options: Dictionary. Optional. Specific Python options available for this component :param profile: Boolean | Dictionary. Optional. A flag to set the component performance storage """ width = Arguments.size(width, unit="px") height = Arguments.size(height, unit="px") icon_details = Defaults_css.get_icon("search") dflt_options = {"icon": icon_details["icon"], 'position': 'left', 'select': True, "border": 1} if options is not None: dflt_options.update(options) html_s = html.HtmlInput.Search(self.page, text, placeholder, color, width, height, html_code, tooltip, extensible, dflt_options, profile) html_s.style.css.height = Defaults.LINE_HEIGHT + 5 html_s.style.css.margin_bottom = 10 if align == "center": html_s.style.css.margin = "auto" html_s.style.css.display = "block" html.Html.set_component_skin(html_s) return html_s
def __init__(self, report, text, level, name, contents, color, picture, icon, marginTop, htmlCode, width, height, align, options, profile): cssStyles = re.search(" css\{(.*)\}", text) if cssStyles is not None: text = text.replace(cssStyles.group(0), '') for cssAttr in cssStyles.group(1).split(","): cssKey, cssVal = cssAttr.split(":") options[cssKey.strip()] = cssVal.strip() super(Title, self).__init__(report, text, htmlCode=htmlCode, css_attrs={"width": width, "height": height}, profile=profile) self.__options = OptText.OptionsTitle(self, options) self._name, self.level, self.picture = name, level, picture self.add_icon(icon, htmlCode=self.htmlCode, family=options.get("icon_family")) if contents is not None: self._name = contents.add(text, level or 1, name) if level is not None and level < 5: getattr(self.style.add_classes.text, "title_%s" % level)() self.css({'color': color, 'margin': '%spx 0 5px 0' % marginTop, 'font-size': Default_css.font({1: 15, 2: 10, 3: 6, 4: 3}[level])}) else: self.style.add_classes.text.title() self.css({'margin': '%spx 0 5px 0' % marginTop, 'font-size': Default_css.font(10)}) if align == 'center': self.css({'margin': '5px auto 10px auto', 'display': 'block', 'text-align': 'center'}) elif align is not None: self.css({'margin': '5px auto 10px auto', 'display': 'block', 'text-align': align}) else: self.css({'display': 'block', "margin-right": "10px"}) if hasattr(report, '_content_table') and self.__options.content_table: # Special attribute set in the base component interface div = self._report.ui.div(htmlCode="%s_anchor" % self.htmlCode) if self._report.body.css('padding-top') is None: div.style.css.margin_top = - 10 else: div.style.css.margin_top = - int(self._report.body.css('padding-top')[:-2]) - 10 div.style.css.position = "absolute" div.style.css.z_index = -1 report._content_table.anchor(text, level or 4, "#%s_anchor" % self.htmlCode) report._content_table[-1].click([ self.dom.transition(["color", "font-size"], ['red', '102%'], duration=[0.5, 0.5], reverse=True)])
def popup(self, components=None, width=(100, '%'), height=(None, 'px'), options=None, profile=None): """ Description: ------------ Display a generic popup. Usage:: popup = page.ui.modals.popup(page.ui.title('Test'), color="red") popup.add(page.ui.texts.paragraph('Test')) Underlying HTML Objects: - :class:`epyk.core.html.HtmlPopup.Popup` Related Pages: https://www.w3schools.com/tags/tag_div.asp Templates: https://github.com/epykure/epyk-templates/blob/master/locals/components/modals.py Attributes: ---------- :param components: List. The different HTML objects to be added to the component. :param width: Tuple. Optional. A tuple with the integer for the component width and its unit. :param height: Tuple. Optional. A tuple with the integer for the component height and its unit. :param options: Dictionary. Optional. Specific Python options available for this component. :param profile: Boolean or Dictionary. Optional. A flag to set the component performance storage. """ width = Arguments.size(width, unit="%") height = Arguments.size(height, unit="px") icon_details = Defaults_css.get_icon("close") dfl_options = { 'margin': 10, 'closure': icon_details["icon"], 'top': 100 } if options is not None: dfl_options.update(options) popup = html.HtmlPopup.Popup(self.page, components, width, height, dfl_options, profile) html.Html.set_component_skin(popup) return popup
def __str__(self): if not hasattr(self.page, 'user') or self.page.user == 'local': icon_details = cssDefaults.get_icon(self.icon or "user") self.attr["class"].add(icon_details["icon"]) self.style.css.font_family = "Font Awesome 5 Free" self.style.css.padding = "2px" self.style.css.font_size = self.size return '<i title="Guest Mode" %(attrs)s></i>' % { 'size': self.size, 'attrs': self.get_attrs(css_class_names=self.style.get_classes())} return ''' <div title="%(user)s" %(attrs)s> <p style="font-size:%(size)s;line-height:%(height)s;margin:0;padding:0">%(letter)s</p> </div> ''' % {'size': self.size, 'height': self.style.css.height, 'letter': self.page.user[0].upper(), 'user': self.page.user, 'attrs': self.get_attrs(css_class_names=self.style.get_classes())}
def __init__(self, page: primitives.PageModel, text: str, color: str, size: tuple, options: Optional[dict], profile: Optional[Union[bool, dict]]): icon_details = Defaults.get_icon("spin") if icon_details['icon_family'] != 'bootstrap-icons': self.requirements = (icon_details['icon_family'],) super(Loading, self).__init__(page, text, profile=profile) self.color = self.page.theme.greys[-1] if color is None else color self.size = size[0] self.css({'color': self.color, 'font-size': "%s%s" % (size[0], size[1]), 'z-index': 5, 'margin': 0}) self.add_icon("%s fa-spin" % icon_details["icon"], html_code=self.htmlCode, css={"font-size": "%spx" % (self.size+8)}, family=icon_details["icon_family"]) if options.get('fixed', False): self.icon.css({"margin-right": '5px', "font-size": 'inherit'}) self.css({"position": 'fixed', 'bottom': '0px', 'right': '5px'}) self.add_span("%s..." % text, position="after", css={"width": 'auto'}) else: self.add_span("%s..." % text, position="after", css={"width": '100%', "margin": "5px"})
def jsAdd(self, data): """ Description: ----------- Attributes: ---------- :param data: """ data = JsUtils.jsConvertData(data, None) icon_details = cssDefaults.get_icon("close") self.page.properties.js.add_builders('RemoveSelection(srcObj, htmlCode)', 'srcObj.parent().remove()', func_dsc="Remove the item from the Tags Html component but also from the underlying javascript variable") return ''' $('#%(htmlCode)s_tags').append("<span style='margin:2px;background:%(baseColor)s;color:%(whiteColor)s;border-radius:8px;1em;vertical-align:middle;display:inline-block;padding:0 2px 1px 10px;cursor:pointer'>"+ %(jsData)s +"<i onclick='RemoveSelection($(this), \\\"%(htmlCode)s\\\")' style='margin-left:10px' class='%(close)s'></i></span>") ''' % {"htmlCode": self.htmlCode, "jsData": data, 'whiteColor': self.page.theme.greys[0], "baseColor": self.page.theme.colors[9], "close": icon_details["icon"]}
def badge(self, report): """ Description: ------------ Add text object with badges to the list Attributes: ---------- :param report: Page object. The internal page object """ item_def = ''' var item = document.createElement("DIV"); var span = document.createElement("span"); span.setAttribute('name', 'value'); span.innerHTML = data.text; var badge = document.createElement("span"); badge.innerHTML = data.value; badge.style.backgroundColor = 'red'; badge.style.color = 'white'; badge.style.borderRadius = '50%%'; badge.style.padding = '0 3px'; badge.style.marginLeft = '5px'; badge.style.fontSize = '%s'; for(const attr in options.badge){badge.style[attr] = options.badge[attr]}; item.appendChild(span); item.appendChild(badge)''' % Defaults.font(-2) return self._item(item_def)
def icons(self, data=None, width=('auto', ""), height=(None, 'px'), html_code: str = None, helper: str = None, options=None, profile=None): """ Description: ------------ Usage:: page.ui.lists.badges([{'label': 'Python', 'value': 12}, {'label': 'R', 'value': 3}]) Underlying HTML Objects: - :class:`epyk.core.html.HtmlList.Badges` Related Pages: https://www.w3schools.com/bootstrap/bootstrap_list_groups.asp https://v4-alpha.getbootstrap.com/components/list-group/ Attributes: ---------- :param data: :param width: Tuple. Optional. A tuple with the integer for the component width and its unit :param height: Tuple. Optional. A tuple with the integer for the component height and its unit :param html_code: String. Optional. An identifier for this component (on both Python and Javascript side) :param helper: String. Optional. A tooltip helper :param options: Dictionary. Optional. Specific Python options available for this component :param profile: Boolean or Dictionary. Optional. A flag to set the component performance storage """ width = Arguments.size(width, unit="%") height = Arguments.size(height, unit="px") icon_details = Defaults_css.get_icon("check") dft_options = {"icon": icon_details["icon"], 'markdown': True, "items_type": 'icon'} if options is not None: dft_options.update(options) html_list = html.HtmlList.Items(self.page, data or [], width, height, dft_options, html_code, profile, helper) html_list.css({"list-style": 'none'}) html.Html.set_component_skin(html_list) return html_list
def __init__(self, page: primitives.PageModel, val, label, color, align, best, html_code, helper, options, profile): icon_details = Defaults.get_icon("star") if icon_details['icon_family'] != 'bootstrap-icons': self.requirements = (icon_details['icon_family'],) super(Stars, self).__init__(page, val, html_code=html_code, profile=profile, options=options) # Add the HTML components self._spans = [] self._jsStyles = {'color': self.page.theme.success[1] if color is None else color} for i in range(best): self.add_span("", position="after", css=False) self._sub_htmls[-1].attr['class'].add(icon_details["icon"]) self._sub_htmls[-1].css({"margin": 0, "padding": 0}) self._sub_htmls[-1].set_attrs(name="data-level", value=i) if i < val: self._sub_htmls[-1].css({"color": self._jsStyles['color']}) self._spans.append(self._sub_htmls[-1]) self.set_attrs(name='data-level', value=val) self.add_label(label, {"margin": "0 0 0 5px", 'height': 'none', "text-align": "left", "display": "inline-block", 'float': 'None'}, html_code=self.htmlCode, position="after") self.add_helper(helper) if self.helper: self.helper.css({"margin": '1px 4px'}) self.css({'text-align': align, "display": 'block'})
def days(self, month=None, content=None, year=None, width=(None, "%"), height=(None, "px"), align=None, options=None, htmlCode=None, profile=None): """ Description: ------------ Usage:: Related Pages: https://github.com/epykure/epyk-templates/blob/master/locals/components/calendar.py Attributes: ---------- :param month: :param content: :param width: :param height: :param align: :param options: :param htmlCode: :param profile: """ width = Arguments.size(width, unit="%") height = Arguments.size(height, unit="px") today = datetime.date.today() month = month or today.month content = content or {} dfl_options = { 'overload': { 'font-size': Defaults.font(5), 'text-align': 'center', 'color': self.context.rptObj.theme.danger[1], 'font-weight': 'bold', 'cursor': 'pointer' }, 'number': { "font-size": Defaults.font(5), "text-align": "center" }, 'today': { "padding": "0 0 5px 0", "border-bottom": "1px solid grey" }, 'header': { 'font-size': Defaults.font(3), "background": self.context.rptObj.theme.colors[-1], "color": self.context.rptObj.theme.colors[0], "padding": "5px 2px", "text-align": "center" } } factor = 100 / options.get("unit", 100) if options is not None else 1 if options is not None: dfl_options.update(options) year = year or today.year start = datetime.date(year, month, 1) days_data, tasks = [], {} for values in content.values(): for t in values.keys(): tasks[t] = None sorted_tasks = sorted(list(tasks)) for i, t in enumerate(sorted_tasks): tasks[t] = dfl_options.get('colors', {}).get( t, self.context.rptObj.theme.charts[i]) for _ in range(start.weekday() + 1): days_data.append({}) while start.month == month: day_tasks = content.get(start.isoformat(), {}) tasks_view = [] for i, t in enumerate(sorted_tasks): tasks_view.append({ "name": t, 'capacity': factor * day_tasks.get(t, 0), 'color': tasks[t] }) days_data.append({ 'today': today == start, "number": start.day, 'tasks': tasks_view, 'date': start.isoformat(), 'weekend': start.weekday() >= 5 }) start += datetime.timedelta(days=1) html_table = html.HtmlDates.Calendar(self.context.rptObj, days_data, width, height, align, dfl_options, htmlCode, profile) html_table.tasks = tasks html_table.caption = "%s %s" % (datetime.date(year, month, 1).strftime("%B"), year) return html_table
def __init__(self, page: primitives.PageModel, start, width: tuple, height: tuple, options: Optional[dict], profile: Optional[Union[dict, bool]]): icon_details_right = Defaults.get_icon("arrow_right") if icon_details_right['icon_family'] != 'bootstrap-icons': self.requirements = (icon_details_right['icon_family'],) icon_details_left = Defaults.get_icon("arrow_left") super(Slides, self).__init__(page, [], options=options, css_attrs={"width": width, 'height': height}, profile=profile) self.attr['data-current_slide'] = start self.title = self.page.ui.title("") self.title.style.css.border_bottom = "1px solid %s" % page.theme.colors[7] self.title.style.css.color = page.theme.colors[7] self.title.style.css.margin = 0 self.title.options.managed = False if 'contents' in options: del page._content_table self._content_table = options['contents'] self._content_table.style.css.z_index = 100 if 'timer' in options: self.page.ui.calendars.timer(options['timer']).css( {"position": 'fixed', "font-size": '15px', 'top': '8px', "padding": '8px', "right": '15px', 'width': 'none', 'color': page.theme.greys[5]}) self.next = self.page.ui.icon(icon_details_right["icon"]).css( {"position": 'fixed', "font-size": '35px', 'bottom': '0', "padding": '8px', "right": '10px', 'width': 'none'}) self.previous = self.page.ui.icon(icon_details_left["icon"]).css( {"position": 'fixed', "font-size": '35px', 'bottom': '0', "padding": '8px', "left": '10px', 'width': 'none'}) self.page_number = self.page.ui.text("").css( {"position": 'fixed', 'z-index': 101, "font-size": '25px', 'bottom': '0', "padding": '8px', "left": '50%', 'width': 'none'}) self.next.click([ self.page.js.getElementsByName(self.htmlCode).all([data.loops.dom_list.hide()]), data.primitives.float(self.dom.attr("data-current_slide").toString().parseFloat().add(1), 'slide_index'), self.js.if_(page.js.object('slide_index') <= self.dom.attr('data-last_slide'), [ self.title.build(self.page.js.getElementsByName( self.htmlCode)[page.js.object('slide_index')].attr('data-slide_title')), self.dom.attr("data-current_slide", page.js.object('slide_index')), self.page.js.getElementsByName(self.htmlCode)[page.js.object('slide_index')].show(display_value='flex'), self.page.js.getElementById( "%s_count" % self.htmlCode).innerHTML(page.js.object('slide_index').toString().parseFloat().add(1)), ]).else_([ self.title.build(self.page.js.getElementsByName( self.htmlCode)[page.js.object('slide_index').add(-1)].attr('data-slide_title')), self.page.js.getElementsByName( self.htmlCode)[page.js.object('slide_index').add(-1)].show(display_value='flex')]), self.js.if_(page.js.object('slide_index') > 0, [self.previous.dom.show()]), self.js.if_(page.js.object('slide_index') == self.dom.attr('data-last_slide'), [self.next.dom.hide()]) ]) self.previous.click([ self.page.js.getElementsByName(self.htmlCode).all([data.loops.dom_list.hide()]), data.primitives.float(self.dom.attr("data-current_slide").toString().parseFloat().add(-1), 'slide_index'), self.js.if_(page.js.object('slide_index') >= 0, [ self.title.build(self.page.js.getElementsByName( self.htmlCode)[page.js.object('slide_index')].attr('data-slide_title')), self.dom.attr("data-current_slide", page.js.object('slide_index')), self.page.js.getElementsByName(self.htmlCode)[page.js.object('slide_index')].show(display_value='flex'), self.page.js.getElementById( "%s_count" % self.htmlCode).innerHTML(page.js.object('slide_index').toString().parseFloat().add(1)), ]).else_([ self.title.build(self.page.js.getElementsByName(self.htmlCode)[0].attr('data-slide_title')), self.page.js.getElementsByName(self.htmlCode)[0].show(display_value='flex')]), self.js.if_(page.js.object('slide_index') == 0, [self.previous.dom.hide()]), self.js.if_(page.js.object('slide_index') < self.dom.attr('data-last_slide'), [self.next.dom.show()]) ]) # Add the keyboard shortcut page.body.keydown.right([self.next.dom.events.trigger("click")]) page.body.keydown.left([self.previous.dom.events.trigger("click")]) self.style.css.padding = "0 20px 20px 20px"
def agenda(self, task, start, end, details=None, location=None, icon="far fa-calendar-alt", text="Add to Calendar", options=None, profile=None): """ Description: ------------ Usage:: Related Pages: https://stackoverflow.com/questions/5179760/add-events-to-google-calendar-yahoo-calendar-outlook-and-ical https://codepen.io/vlemoine/pen/MLwygX TODO: improve the time management in this component Attributes: ---------- :param task: :param start: :param end: :param details: :param location: :param icon: :param text: :param options: :param profile: """ # Default options calendar_options = {'CALSCALE': 'GREGORIAN', 'VERSION': '2.0'} events_options = { 'DTSTART;VALUE=DATE': start, 'DTEND;VALUE=DATE': end, 'SUMMARY': task or '', 'LOCATION': location or '', 'DESCRIPTION': details or '', 'STATUS': 'CONFIRMED', 'SEQUENCE': 3 } str_calendar = "BEGIN:VCALENDAR\n%s\n%%s\nEND:VCALENDAR" % "\n".join( ["%s:%s" % (k, v) for k, v in calendar_options.items()]) str_event = "BEGIN:VEVENT\n%s\nEND:VEVENT" % "\n".join( ["%s:%s" % (k, v) for k, v in events_options.items()]) link = self.context.rptObj.ui.links.data( "<i style='font-size:%s;color:%s' class='%s'></i> %s" % (Defaults.font(5), self.context.rptObj.theme.greys[-1], icon, text), str_calendar % str_event) link.attr['download'] = 'event.ics' link.style.css.background = self.context.rptObj.theme.greys[0] link.style.css.color = self.context.rptObj.theme.greys[-1] link.style.css.padding = '2px 5px' link.style.css.margin = 2 link.style.css.display = 'inline-block' link.style.css.border = "1px solid %s" % self.context.rptObj.theme.greys[ 3] link.style.css.border_radius = 20 return link
def validation(self, components=None, width=(100, '%'), height=(None, 'px'), options=None, profile=None): """ Description: ------------ Usage:: popup = page.popup(page.ui.title('Test'), color="red") popup + page.paragraph('Test') Underlying HTML Objects: - :class:`epyk.core.html.HtmlPopup.Popup` Related Pages: https://www.w3schools.com/tags/tag_div.asp Templates: https://github.com/epykure/epyk-templates/blob/master/locals/components/modals.py Attributes: ---------- :param components: List. The different HTML objects to be added to the component. :param width: Tuple. Optional. A tuple with the integer for the component width and its unit. :param height: Tuple. Optional. A tuple with the integer for the component height and its unit. :param options: Dictionary. Optional. Specific Python options available for this component. :param profile: Boolean | Dictionary. Optional. A flag to set the component performance storage. """ width = Arguments.size(width, unit="%") height = Arguments.size(height, unit="px") icon_details = Defaults_css.get_icon("close") dfl_options = { 'margin': 10, 'closure': icon_details["icon"], 'top': 100 } if options is not None: dfl_options.update(options) if not isinstance(components, list): components = [components] validate = self.page.ui.buttons.validate("Validate") cancel = self.page.ui.buttons.cancel() row = self.page.ui.row([validate, cancel], position="top", align="center") row.options.autoSize = False components.append(row) popup = html.HtmlPopup.Popup(self.page, components, width, height, dfl_options, profile) popup.validate = validate popup.cancel = cancel cancel.click([popup.dom.hide()]) html.Html.set_component_skin(popup) return popup
def select(self, records=None, html_code: str = None, selected: str = None, width=(100, "%"), height=(None, "%"), profile: Union[bool, dict] = None, multiple: bool = False, options: dict = None): """ Description: ------------ HTML Select component. Usage:: record = [ {"text": 'Text 1', "value": "text 1"}, {"text": 'Text 2', "value": "text 2"}, {"text": 'Text 3', "value": "text 3"}, ] select = page.ui.select(record) Underlying HTML Objects: - :class:`epyk.core.html.HtmlSelect.Select` Related Pages: https://silviomoreto.github.io/bootstrap-select/examples/ https://www.npmjs.com/package/bootstrap-select-v4 https://www.jqueryscript.net/form/Bootstrap-4-Dropdown-Select-Plugin-jQuery.html Attributes: ---------- :param records: List. Optional. The list of dictionaries with the input data. :param html_code: String. Optional. An identifier for this component (on both Python and Javascript side). :param selected: String. Optional. The selected value or values. :param width: Tuple. Optional. Integer for the component width. :param height: Tuple. Optional. Integer for the component height. :param profile: Boolean | Dictionary. Optional. A flag to set the component performance storage. :param multiple: Boolean. Optional. To set if the component can handle multiple selections. :param options: Dictionary. The select options as defined https://developer.snapappointments.com/bootstrap-select/options/ """ width = Arguments.size(width, unit="%") height = Arguments.size(height, unit="%") records = records or [] if not isinstance(records, list): records = [{'text': v, 'value': v, "selected": True} for v in records.split(",")] options = options or {} options['selected'] = selected if multiple: if not isinstance(multiple, dict): multiple = {"max": 2} if selected is not None: for rec in records: if rec["value"] in selected: rec["selected"] = True icon_details = Defaults_css.get_icon("check") options["iconBase"] = "iconBase" options["tickIcon"] = icon_details["icon"] html_select = html.HtmlSelect.Select(self.page, records, html_code, width, height, profile, multiple, options) html.Html.set_component_skin(html_select) return html_select if selected is not None: for rec in records: if rec["value"] == selected: rec["selected"] = True html_select = html.HtmlSelect.Select(self.page, records, html_code, width, height, profile, multiple, options) html.Html.set_component_skin(html_select) return html_select
def price(self, value, title, items, url=None, align="center", width=(250, 'px'), currency="£", options=None, profile=None): """ Description: ------------ Usage:: page.ui.vignets.price(10, "This is the price", []) Attributes: ---------- :param value: :param title: :param items: :param url: :param align: :param width: :param currency: :param options: :param profile: """ container = self.context.rptObj.ui.div(align=align, width=width, options=options, profile=profile) container.style.css.border = "1px solid %s" % self.context.rptObj.theme.greys[ 3] container.style.css.margin = "auto" if not hasattr(title, 'options'): title = self.context.rptObj.ui.titles.title(title) title.style.css.display = "block" title.style.css.text_align = align container.add(title) if not hasattr(value, 'options'): value = self.context.rptObj.ui.texts.number(value, options={ "type_number": 'money', 'symbol': currency }, profile=profile) value.style.css.font_size = Defaults_css.font(30) container.add(value) if url is not None: button = self.context.rptObj.ui.button("Subscribe", align="center", profile=profile) button.style.css.background_color = self.context.rptObj.theme.success[ 1] button.style.css.color = 'white' button.style.css.margin_top = 10 button.style.css.margin_bottom = 10 container.add(button) if not hasattr(items, 'options'): items = self.context.rptObj.ui.lists.icons(items, profile=profile) items.style.css.margin = "auto 20%" items.style.css.text_align = "left" container.add(items) return container
def search_input(self, text='', placeholder='Search..', color=None, width=(100, '%'), height=(None, "px"), html_code=None, tooltip=None, extensible=False, options=None, profile=None): """ Description: ------------ Search bar. :tags: :categories: Usage:: page.ui.inputs.search() Underlying HTML Objects: - :class:`epyk.core.html.HtmlInput.Search` Related Pages: https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_anim_search Attributes: ---------- :param text: String. Optional. The value to be displayed to the component. :param placeholder: String. Optional. The text display when empty. :param color: String. Optional. The font color in the component. Default inherit. :param width: Tuple. Optional. A tuple with the integer for the component width and its unit. :param height: Tuple. Optional. A tuple with the integer for the component height and its unit. :param html_code: String. Optional. An identifier for this component (on both Python and Javascript side). :param tooltip: String. Optional. A string with the value of the tooltip. :param extensible: Boolean. Optional. Flag to specify the input style. :param options: Dictionary. Optional. Specific Python options available for this component. :param profile: Boolean | Dictionary. Optional. A flag to set the component performance storage. """ width = Arguments.size(width, unit="px") height = Arguments.size(height, unit="px") icon_details = Defaults_css.get_icon("search") dflt_options = { "icon": icon_details["icon"], "icon_family": icon_details["icon_family"], 'position': 'left', 'select': True, "border": 1 } if options is not None: dflt_options.update(options) html_s = html.HtmlInput.Search(self.page, text, placeholder, color, width, height, html_code, tooltip, extensible, dflt_options, profile) html.Html.set_component_skin(html_s) return html_s
def customize(self): self.css({'font-size': '%s%s' % (Defaults_css.font(4), Defaults_css.Font.unit), 'font-family': Defaults_css.Font.family})
def download(self, name: str, icon: str = None, path: str = None, width: Union[tuple, int] = (25, 'px'), height: Union[tuple, int] = (25, 'px'), html_code: str = None, options: dict = None, profile: Union[dict, bool] = None): """ Description: ------------ Usage:: Attributes: ---------- :param name: String. Optional. :param icon: String. Optional. The component icon content from font-awesome references. :param path: String. Optional. String. The image file path. :param width: Tuple. Optional. A tuple with the integer for the component width and its unit. :param height: Tuple. Optional. A tuple with the integer for the component height and its unit. :param html_code: String. Optional. The id for this component. :param options: Dictionary. Optional. Specific Python options available for this component. :param profile: Boolean | Dictionary. Optional. A flag to set the component performance storage. """ options = options or {} mapped_file = { "excel": Defaults_css.get_icon("excel"), 'pdf': Defaults_css.get_icon("pdf"), 'code': Defaults_css.get_icon("code"), 'csv': Defaults_css.get_icon("csv"), 'word': Defaults_css.get_icon("word") } extension = name.split(".")[-1] if extension in mapped_file: icon = mapped_file[extension]["icon"] options["icon_family"] = mapped_file[extension]["icon_family"] if icon is None: icon = Defaults_css.get_icon("upload")["icon"] options["icon_family"] = Defaults_css.get_icon( "upload")["icon_family"] file = self.page.ui.icons.awesome(icon, width=width, height=height, html_code=html_code, options=options, profile=profile) file.tooltip(r"Download file: %(path)s\%(name)s" % { "path": path, "name": name }) if path is not None: file.click([ ''' var link = document.createElement("a"); link.href = 'file://localhost/%(path)s'; link.target="_blank"; link.setAttribute('download', '%(name)s'); document.body.appendChild(link); link.click(); document.body.removeChild(link); ''' % { "path": os.path.join(path, name), "name": name } ]) html.Html.set_component_skin(file) return file
def chips(self, items=None, category='group', placeholder="", width=(100, "%"), height=(60, "px"), htmlCode=None, helper=None, options=None, profile=None): """ Description: ------------ Add a chip (filter) html component Usage:: chips = rptObj.ui.chips([]) Underlying HTML Objects: - :class:`epyk.core.html.HtmlEvent.Filters` Related Pages: https://www.w3schools.com/howto/howto_css_contact_chips.asp Templates: https://github.com/epykure/epyk-templates/blob/master/locals/components/chips.py https://github.com/epykure/epyk-templates/blob/master/locals/components/list.py Attributes: ---------- :param items: List. Selected items :param category: String. The group of the items. :param placeholder: String. The input field placeholder :param width: Tuple. Optional. A tuple with the integer for the component width and its unit :param height: Tuple. Optional. A tuple with the integer for the component height and its unit :param htmlCode: String. Optional. An identifier for this component (on both Python and Javascript side) :param helper: String. Optional. A tooltip helper :param options: Dictionary. Optional. Specific Python options available for this component :param profile: Boolean or Dictionary. Optional. A flag to set the component performance storage """ width = Arguments.size(width, unit="%") height = Arguments.size(height, unit="px") dflt_options = { "item_css": { "padding": '5px', 'border': '1px solid %s' % self.context.rptObj.theme.success[0], 'border-radius': '5px', 'margin': '2px', "width": 'auto', 'display': 'inline', 'background': 'inherit' }, 'category': category, 'visible': True, 'value_css': { 'font-size': Defaults.font(3), 'font-weight': 'bold', 'vertical-align': 'bottom' }, 'category_css': { 'display': 'inline', 'margin-right': '2px', 'vertical-align': 'top', 'font-size': Defaults.font(-3) }, 'icon_css': { 'color': self.context.rptObj.theme.success[1], 'margin-left': '5px', 'cursor': 'pointer' } } if not hasattr(category, 'toStr') and category == 'group': dflt_options['visible'] = False if options is not None: dflt_options.update(options) html_f = html.HtmlEvent.Filters(self.context.rptObj, items or [], width, height, htmlCode, helper, dflt_options, profile) html_f.input.attr['placeholder'] = placeholder return html_f
def digits(self, text=None, color=None, align='center', width=None, height=None, htmlCode=None, tooltip=None, options=None, profile=None): """ Description: ------------ The <span> tag is used to group inline-elements in a document. The <span> tag provides no visual change by itself. The <span> tag provides a way to add a hook to a part of a text or a part of a document. Usage:: rptObj.ui.texts.span("Test") Underlying HTML Objects: - :class:`epyk.core.html.HtmlText.Position` Related Pages: https://www.w3schools.com/tags/tag_span.asp Templates: https://github.com/epykure/epyk-templates/blob/master/locals/components/numbers.py Attributes: ---------- :param text: Optional. The string value to be displayed in the component :param color: Optional. The color of the text :param align: Optional. The position of the icon in the line (left, right, center) :param width: Optional. A tuple with the integer for the component width and its unit :param height: Optional. A tuple with the integer for the component height and its unit :param htmlCode: Optional. An identifier for this component (on both Python and Javascript side) :param tooltip: Optional. A string with the value of the tooltip :param profile: Optional. A flag to set the component performance storage """ if width is None: width = (defaults_html.TEXTS_SPAN_WIDTH, 'px') if height is None: height = (defaults_html.LINE_HEIGHT, 'px') html_label = html.HtmlText.Position(self.context.rptObj, text, color, align, width, height, htmlCode, tooltip, options, profile) html_label.position(3, { "font-size": defaults_css.font(5), "font-weight": "bold" }) html_label.position(4, { "font-size": defaults_css.font(5), "font-weight": "bold" }) html_label.digits(True) return html_label