emmett-framework / emmett

The web framework for inventors
Other
1.03k stars 70 forks source link

Feature request widget_multiple_string_fields #468

Open SvenKeimpema opened 1 year ago

SvenKeimpema commented 1 year ago

The idea behind this widget is that i can click on a button and add a input row that i can fill in manually. This is the easiest done by 2 buttons(+ and -) that add and remove input fields.

For example

def add_tag_js(field, UUID) -> str:
    return f"""
        var x = document.createElement('input')
        x.setAttribute('name', '{field.name}')
        x.setAttribute('id', '{field.name}')
        x.setAttribute('type', 'text')
        x.setAttribute('value', '')
        var y = document.createElement('br')
        document.getElementById('{UUID}').appendChild(x)
        document.getElementById('{UUID}').appendChild(y)
    """

def remove_tag_js(UUID) -> str:
    return f"""
        var select = document.getElementById('{UUID}');
    """ + """
        if(select.childNodes.length > 4) {
            select.removeChild(select.lastChild);
            select.removeChild(select.lastChild);
        }
    """

def input_field(field, value=""):
    return tag.input(
            _type="text",
            _name=field.name,
            _id=field.name,
            _value=value,
            _class="string multiple",
        )

def widget_multiple_field(field, value):
    fields_uuid = uuid.uuid4()
    if not value:
        value = [""]

    first_value = value.pop(0)
    field_elements = [
        input_field(field, first_value),
        tag.a(
            tag.button("+", _type="button"),
            _onclick=add_tag_js(field, fields_uuid),
        ),
        tag.a(
            tag.button("-", _type="button"),
            _onclick=remove_tag_js(fields_uuid),
        ),
        tag.br(),
    ]
    field_elements.extend(
        tag.input(
            _type="text",
            _name=field.name,
            _id=field.name,
            _value=v,
            _class="string multiple",
        ) + tag.br()
        for v in value
    )
    return tag.div(*field_elements, _id=f"{fields_uuid}")
SvenKeimpema commented 1 year ago

The code isn't perfect and for sure needs some tweaking but this is nice to have as an widget and i personally was missing