Skip to content

Commit

Permalink
HTMLFormElement.addClass: Improve removal of duplicates.
Browse files Browse the repository at this point in the history
It's now possible to add multiple classes as whitespace seperated string and
still detect class duplicates.
  • Loading branch information
thet committed Jul 14, 2023
1 parent e41e44b commit 60b2071
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 11 deletions.
4 changes: 4 additions & 0 deletions CHANGES.rst
Expand Up @@ -11,6 +11,10 @@ Changelog

- Drop deprecated support for ``python setup.py test``.

- HTMLFormElement.addClass: Improve removal of duplicates. It's now possible to
add multiple classes as whitespace seperated string and still detect class
duplicates.


4.3 (2022-03-24)
----------------
Expand Down
21 changes: 10 additions & 11 deletions src/z3c/form/browser/widget.py
Expand Up @@ -142,21 +142,20 @@ class HTMLFormElement(WidgetLayoutSupport):
# layout support
css = FieldProperty(interfaces.IHTMLFormElement['css'])

def addClass(self, klass):
"""See interfaces.IHTMLFormElement"""
def addClass(self, klass: str):
"""Add a class to the HTML element.
See interfaces.IHTMLFormElement.
"""
if not self.klass:
self.klass = str(klass)
else:
# make sure items are not repeated
parts = self.klass.split() + [str(klass)]
seen = {}
unique = []
for item in parts:
if item in seen:
continue
seen[item] = 1
unique.append(item)
self.klass = ' '.join(unique)
parts = self.klass.split() + klass.split()
# Remove duplicates and keep order.
# Dictionaries are ordered in Python 3.7+
parts = list(dict.fromkeys(parts))
self.klass = " ".join(parts)

def update(self):
"""See z3c.form.interfaces.IWidget"""
Expand Down
42 changes: 42 additions & 0 deletions src/z3c/form/browser/widget.rst
@@ -0,0 +1,42 @@
Widget base classes
===================

HTMLFormElement
---------------

addClass
........

Widgets based on :code:`HTMLFormElement` also have the :code:`addClass` method which can be used to add CSS classes to the widget.
::

>>> from z3c.form.browser.widget import HTMLFormElement
>>> form = HTMLFormElement()

The :code:`klass` attribute is used because :code:`class` is a reserved keyword in Python.
It's empty per default::

>>> form.klass


After adding a class it shows up in :code:`klass`::

>>> form.addClass("my-css-class")
>>> form.klass
'my-css-class'


:code:`addClass` prevents adding the same class twice::

>>> form.addClass("my-css-class")
>>> form.klass
'my-css-class'

>>> form.addClass("another-class")
>>> form.klass
'my-css-class another-class'

>>> form.addClass("another-class third-class")
>>> form.klass
'my-css-class another-class third-class'

5 changes: 5 additions & 0 deletions src/z3c/form/tests/test_doc.py
Expand Up @@ -144,6 +144,11 @@ def test_suite():
'../hint.rst',
setUp=setUp, tearDown=testing.tearDown,
optionflags=flags, checker=testing.outputChecker,
),
doctest.DocFileSuite(
'../browser/widget.rst',
setUp=setUp, tearDown=testing.tearDown,
optionflags=flags, checker=testing.outputChecker,
))
for setUp in setups)

Expand Down

0 comments on commit 60b2071

Please sign in to comment.