示例#1
0
def _update_positions(*args):
    if _scrolling:
        # not sure why this fires on scroll but it does on chrome
        return
    _S(".popover").addClass("PopNoTransition").popover("show").removeClass(
        "PopNoTransition"
    )
示例#2
0
def _get_jquery_for_component(component):
    if isinstance(component, _anvil.Button):
        return _S(_js.get_dom_node(component).firstElementChild)
    elif isinstance(component, _anvil.FileLoader):
        return _S(_js.get_dom_node(component)).find('form')
    else:
        return _S(_js.get_dom_node(component))
示例#3
0
def _sticky_leave(e):
    popper_element = None
    popover_id = _S(e.currentTarget).attr("popover_id")
    if popover_id in _sticky_popovers and not _S(
        "[popover_id='{}']:hover".format(popover_id)
    ):
        popper_element = _visible_popovers.get(popover_id)
    if popper_element is not None:
        _popper_execute(popper_element, "hide")
示例#4
0
def _get_jquery_for_component(component):
    if isinstance(component, _anvil.Button):
        return _S(_js.get_dom_node(component).firstElementChild)
    elif isinstance(component, _anvil.FileLoader):
        return _S(_js.get_dom_node(component)).find("form")
    elif isinstance(component, (_anvil.CheckBox, _anvil.RadioButton)):
        return _S(_js.get_dom_node(component)).find("input")
    else:
        return _S(_js.get_dom_node(component))
示例#5
0
def _sticky_leave(e):
    popper_element = None
    popover_id = _S(e.currentTarget).attr('popover_id')
    if popover_id in _sticky_popovers and not _S(
            '[popover_id={}]:hover'.format(popover_id)):
        popper_element = _visible_popovers.get(popover_id)
    if popper_element is not None:
        popper_element.data(
            'bs.popover'
        ).inState.click = False  # see bug https://github.com/twbs/bootstrap/issues/16732
        popper_element.popover('hide')
示例#6
0
def _get_jquery_popper_element(popper):
    if isinstance(popper, _anvil.Button):
        # use the button node not the div node so that point is in the right place
        element = _anvil.js.get_dom_node(popper).firstElementChild
    else:
        element = _anvil.js.get_dom_node(popper)
    return _S(element)  # return the jquery element
示例#7
0
    def __init__(self, **properties):
        # Set Form properties and Data Bindings.
        self._init = False

        self._dom_node = _js.get_dom_node(self)
        _S_dom_node = _S(self._dom_node)
        self._el = _S_dom_node.find("select")

        _S_dom_node.html("").append(self._el)
        # remove all the script tags before they load into the dom

        self._values = {}
        self._invalid = []
        # Any code you write here will run when the form opens
        self._props = props = _defaults | properties
        props["items"] = props["items"] or []
        selected = props.pop("selected", ())

        self.init_components(**props)

        self._el.selectpicker()
        self._el.on("changed.bs.select", self.change)
        self._el.on("shown.bs.select", self._opened)
        self._el.on("hidden.bs.select", self._closed)
        self.set_event_handler("x-popover-init", self._mk_popover)
        if selected:
            self.selected = selected
        self._user_selected_all(False)
        menu = self._el.data("selectpicker")["$menu"]
        menu.find(".bs-actionsbox").on("click", self._user_selected_all)
        self._init = True
示例#8
0
    def __init__(self, margin_top=0, border="1px solid grey", **properties):
        dom_node = _S(anvil.js.get_dom_node(self))
        self.margin_node = dom_node.find(".margin-element")
        self.break_container = dom_node.find(".break-container")

        self.margin_top = margin_top
        self.border = border

        self.init_components(**properties)
示例#9
0
def _hide_popovers_on_outside_click(e):
    target = e.target
    if target.classList.contains('anvil-popover'):
        nearest_id = target.getAttribute('popover_id')
    else:
        nearest_id = _S(target).closest('.anvil-popover').attr('popover_id')
    visible_popovers = _visible_popovers.copy()
    for popover_id in visible_popovers:  # use copy since we don't want the dict to change size
        if nearest_id is not popover_id:
            _hide(popover_id, visible_popovers)
示例#10
0
def _hide_popovers_on_outside_click(e):
    target = e.target
    if target.classList.contains("anvil-popover"):
        nearest_id = target.getAttribute("popover_id")
    else:
        nearest_id = _S(target).closest(".anvil-popover").attr("popover_id")
    # use copy since the dict changes size during iteration
    for popover_id, popper_element in _visible_popovers.copy().items():
        if nearest_id == popover_id:
            continue
        if _get_data(popper_element, "autoDismiss", True):
            _popper_execute(popper_element, "hide")
示例#11
0
def _clean_items(items):
    options = []
    value_dict = {}

    for idx, item in enumerate(items):

        if isinstance(item, str):
            option, value = _option_from_str(item, idx)
        elif isinstance(item, (tuple, list)):
            option, value = _option_from_tuple(item, idx)
        elif isinstance(item, dict):
            option, value = _option_from_dict(item, idx)
        else:
            raise TypeError(
                f"Invalid item at index {idx} (got type {type(item)})")

        # use strings since the value from jquery is always a string
        value_dict[str(idx)] = value
        options.append(option)

    return _S("\n".join(options)), value_dict
示例#12
0
 def _on_hide(self, **e_args):
     """This method is called when the TextBox is removed from the screen"""
     _document.body.removeChild(self._lp_node)
     _S(_window).off("resize", self._reset_position)
示例#13
0
 def _on_show(self, **e_args):
     """This method is called when the TextBox is shown on the screen"""
     _document.body.appendChild(self._lp_node)
     _S(_window).on("resize", self._reset_position)
示例#14
0
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2021 The Anvil Extras project team members listed at
# https://github.com/anvilistas/anvil-extras/graphs/contributors
#
# This software is published at https://github.com/anvilistas/anvil-extras

__version__ = "2.0.1"

from anvil.js.window import jQuery as _S

alert_modal = _S("#alert-modal")


def handle_alert_unload() -> bool:
    """
    if there is an active alert which is not dismissible then navigation is prevented
    return value indicates whether this function took control of the on_navigation
    """
    data = alert_modal.data("bs.modal")
    if data is None:
        return False
    elif not data.isShown:
        return False
    elif data.options and data.options.backdrop != "static":
        # bootstrap alerts have a backdrom of static when not dismissible
        alert_modal.modal("hide")
        return False
    from . import _navigation

    _navigation.stopUnload()
示例#15
0
 def sticky_leave(e):
     sleep(0.1)  # small delay to allow the mouse to move to the element
     if not _S("[popover_id='{}']:hover".format(popper_id)):
         pop(self, "hide")
示例#16
0
def popover(self,
            content,
            title='',
            placement='right',
            trigger='click',
            animation=True,
            delay={
                "show": 100,
                "hide": 100
            },
            max_width=None,
            auto_dismiss=True):
    """should be called by a button or link
    content - either text or an anvil component or Form
    placement -  right, left, top, bottom (for left/right best to have links and buttons inside flow panels)
    trigger - manual, focus, hover, click (can be a combination of two e.g. 'hover focus')
    animation - True or False
    delay - {'show': 100, 'hide': 100}
    max_width - bootstrap default is 276px you might want this wider

    if the content is a form then the form will have an attribute self.popper added
    """
    html = not isinstance(content, str)
    if html:
        content.popper = self  # add the popper to the content form
        content = _anvil.js.get_dom_node(content)  # get the dom node

    max_width = _default_max_width if max_width is None else max_width

    # can effect the title of the popover so temporarily set it to ''
    tooltip, self.tooltip = self.tooltip, ''

    popper_id = _get_random_string(5)
    popper_element = _get_jquery_popper_element(self)

    if trigger is 'stickyhover':
        trigger = 'manual'
        popper_element.on('mouseenter', lambda e: None if pop(self, 'is_visible') else pop(self, 'show'))\
                      .on('mouseleave', lambda e: None if _S('[popover_id={}]:hover'.format(popper_id)) else pop(self, 'hide'))
        _set_sticky_hover()
        _sticky_popovers.add(popper_id)

    popper_element.popover({
        'content': content,
        'title': title,
        'placement': placement,
        'trigger': trigger,
        'animation': animation,
        'delay': delay,
        'html': html,
        'template': _template.format(popper_id, max_width),
        'container': 'body'
    })

    if tooltip:
        self.tooltip = tooltip
        # otherwise the tooltip doesn't work for Buttons
        popper_element.attr('title', tooltip)

    popper_element.on("show.bs.popover", lambda e: _visible_popovers.update({popper_id: popper_element}) if auto_dismiss else None)\
                  .on("hide.bs.popover", lambda e: _visible_popovers.pop(popper_id, None))\
                  .addClass('anvil-popover')\
                  .attr('popover_id', popper_id)
示例#17
0
def _set_sticky_hover():
    if not _sticky_popovers:
        _S("body").on("mouseleave", ".popover", _sticky_leave)
示例#18
0
def _update_positions(*args):
    _S('.popover').addClass("PopNoTransition")\
                  .popover('show')\
                  .removeClass("PopNoTransition")
示例#19
0
def _set_sticky_hover():
    if not _sticky_popovers:
        _S('body').on('mouseleave', '.popover', _sticky_leave)
示例#20
0

def _get_random_string(_len):
    return ''.join(_random_choice(_letters) for _ in range(_len))


_visible_popovers = {}

_template = '<div class="popover anvil-popover" role="tooltip" popover_id={} style="max-width:{}; "><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'

# temp style for updating popovers without transition animations
_S("""<style>
.PopNoTransition {
    -moz-transition: none !important;
    -webkit-transition: none !important;
    -o-transition: none !important;
    transition: none !important;
}
</style>
""").appendTo(_S('head'))

if __name__ == "__main__":
    _ = _anvil.ColumnPanel()
    _.set_event_handler(
        'show',
        lambda **e: _anvil.Notification('oops, popover is a dependency',
                                        style='danger',
                                        timeout=None).show())
    _anvil.open_form(_)

_ = None
示例#21
0
 def _make_popover_element(dom_node):
     _S(dom_node).addClass("anvil-popover").attr("popover_id", id)
示例#22
0
 def selected(self):
     return [
         self._values[e.value] for e in _S("option:selected", self._el)
         if e.value != ""
     ]
示例#23
0
def off_dd_click(e):
    # see bug #271
    if not e.target.closest(".bootstrap-select"):
        _S(_document).trigger("click.bs.dropdown.data-api")