Skip to content
Snippets Groups Projects
Verified Commit e1f97c63 authored by Nik | Klampfradler's avatar Nik | Klampfradler
Browse files

Simplify interface by passing full options as JSON

parent f1e9c3d6
No related branches found
No related tags found
No related merge requests found
// Get all elements that have the data attribute from the widget set
document.querySelectorAll("[data-dj-cleavejs]").forEach(function(element) {
// Parse JSON generated from widget data class into object
let cleave_options = JSON.parse(element.getAttribute("data-dj-cleavejs"]);
// Pass options verbatim to Cleave constructor
new Cleave(element, cleave_options);
});
import json import json
from dataclasses import InitVar, dataclass from dataclasses import InitVar, asdict, dataclass
from typing import Any, Dict, List, Optional, Sequence, Union from typing import Any, Dict, List, Optional, Sequence, Union
from django.conf import settings from django.conf import settings
...@@ -11,10 +11,10 @@ __all__ = ("CleaveWidget",) ...@@ -11,10 +11,10 @@ __all__ = ("CleaveWidget",)
@dataclass @dataclass
class CleaveWidget(TextInput): class CleaveWidget(TextInput):
attr_prefix: str = "data-dj-cleavejs" # Options as defined by the original Cleave.js options object
blocks: Optional[Sequence[int]] = None blocks: Optional[Sequence[int]] = None
delimiter: Optional[Union[str, Sequence[str]]] = None delimiter: Optional[str] = None
delimiters: Optional[Sequence[str]] = None
delimiter_lazy_show: bool = True delimiter_lazy_show: bool = True
attrs: InitVar[Optional[Dict[str, str]]] = None attrs: InitVar[Optional[Dict[str, str]]] = None
...@@ -23,26 +23,19 @@ class CleaveWidget(TextInput): ...@@ -23,26 +23,19 @@ class CleaveWidget(TextInput):
def media(self) -> Dict[str, List[str]]: def media(self) -> Dict[str, List[str]]:
js = [] js = []
if settings.get("CLEAVE_JS", None): if settings.get("CLEAVE_JS", None):
# Add Cleave.js to form media if requested by setting
js.append(settings.get("CLEAVE_JS")) js.append(settings.get("CLEAVE_JS"))
js.append("dj_cleave.js") js.append("dj_cleave.js")
return {"js": js} return {"js": js}
@classmethod
def _add_cleaved_attr(cls, attrs, name: str, value: Any):
attrs[f"{cls.attr_prefix}-{name}"] = json.dumps(value)
def __post_init__(self, attrs: Optional[Dict[str, str]] = None): def __post_init__(self, attrs: Optional[Dict[str, str]] = None):
cleaved_attrs = {} if attrs is None else attrs.copy() # Allow passing own HTML attributes, like TextInput itself
attrs = {} if attrs is None else attrs.copy()
if self.blocks is not None:
self._add_cleaved_attr(cleaved_attrs, "blocks", self.blocks) # Build dictionary from all Cleave.js options that were set
if self.delimiter is not None: cleave_options = {name: value for name, value in asdict(self).items() if value is not None}
if isinstance(self.delimiter, Sequence): # Pass as JSON string in a data attribute
if self.blocks is None or len(self.delimiter) != len(self.blocks) - 1: attrs["data-dj-cleavejs"] = json.dumps(cleave_options)
raise TypeError("If delimiters are given, they must be one less than blocks and blocks must be provided.")
self._add_cleaved_attr(cleaved_attrs, "delimiters", self.delimiter) # Allow TextInput to do whatever it is supposed to do
else: super().__init__(attrs)
self._add_cleaved_attr(cleaved_attrs, "delimiter", self.delimiter)
self._add_cleaved_attr(cleaved_attrs, "delimiter-lazy-show", self.delimiter_lazy_show)
super().__init__(cleaved_attrs)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment