Improve instance form errors #173
2 changed files with 42 additions and 12 deletions
|
|
@ -48,18 +48,31 @@ class DynamicArrayWidget(forms.Widget):
|
|||
|
||||
def value_from_datadict(self, data, files, name):
|
||||
value = data.get(name)
|
||||
if value:
|
||||
if value is None:
|
||||
return []
|
||||
if value == "":
|
||||
return []
|
||||
|
||||
if isinstance(value, list):
|
||||
return [item for item in value if item is not None and str(item).strip()]
|
||||
|
||||
if isinstance(value, str):
|
||||
if value.strip() == "" or value.strip().lower() == "null":
|
||||
return []
|
||||
try:
|
||||
parsed = json.loads(value)
|
||||
if parsed:
|
||||
if parsed is None:
|
||||
return []
|
||||
if isinstance(parsed, list):
|
||||
return [
|
||||
item
|
||||
for item in parsed
|
||||
if item is not None and str(item).strip()
|
||||
]
|
||||
return []
|
||||
return [parsed] if str(parsed).strip() else []
|
||||
except (json.JSONDecodeError, TypeError):
|
||||
pass
|
||||
return [value] if value.strip() else []
|
||||
|
||||
return []
|
||||
|
||||
|
||||
|
|
@ -104,11 +117,17 @@ class DynamicArrayField(forms.JSONField):
|
|||
if value is None:
|
||||
return []
|
||||
if isinstance(value, list):
|
||||
return value
|
||||
return [item for item in value if item is not None]
|
||||
if isinstance(value, str):
|
||||
if value.strip() == "" or value.strip().lower() == "null":
|
||||
return []
|
||||
try:
|
||||
parsed = json.loads(value)
|
||||
return parsed if isinstance(parsed, list) else [parsed]
|
||||
if parsed is None:
|
||||
return []
|
||||
if isinstance(parsed, list):
|
||||
return [item for item in parsed if item is not None]
|
||||
return [parsed]
|
||||
except (json.JSONDecodeError, TypeError):
|
||||
return [value] if value else []
|
||||
return [str(value)]
|
||||
|
|
@ -117,16 +136,24 @@ class DynamicArrayField(forms.JSONField):
|
|||
"""Handle bound data properly to avoid JSON parsing issues"""
|
||||
if data is None:
|
||||
return initial
|
||||
# If data is already a list (from our widget), return it as-is
|
||||
if isinstance(data, list):
|
||||
return data
|
||||
# If data is a string, try to parse it as JSON
|
||||
return [item for item in data if item is not None and str(item).strip()]
|
||||
if isinstance(data, str):
|
||||
if data.strip() == "" or data.strip().lower() == "null":
|
||||
return []
|
||||
try:
|
||||
parsed = json.loads(data)
|
||||
return parsed if isinstance(parsed, list) else [parsed]
|
||||
if parsed is None:
|
||||
return []
|
||||
if isinstance(parsed, list):
|
||||
return [
|
||||
item
|
||||
for item in parsed
|
||||
if item is not None and str(item).strip()
|
||||
]
|
||||
return [parsed] if str(parsed).strip() else []
|
||||
except (json.JSONDecodeError, TypeError):
|
||||
return [data] if data else []
|
||||
return [data] if data and data.strip() else []
|
||||
return data
|
||||
|
||||
def validate(self, value):
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@ const initDynamicArrayWidget = () => {
|
|||
addRemoveEventListeners(container)
|
||||
addInputEventListeners(container)
|
||||
updateRemoveButtonVisibility(container)
|
||||
|
||||
// Ensure hidden input is synced with visible inputs on initialization
|
||||
updateHiddenInput(container)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -94,7 +97,7 @@ const updateHiddenInput = (container) => {
|
|||
if (!hiddenInput) return
|
||||
|
||||
const values = Array.from(inputs)
|
||||
.map(input => input.value.trim())
|
||||
.map(input => input.value ? input.value.trim() : '')
|
||||
.filter(value => value !== '')
|
||||
|
||||
hiddenInput.value = JSON.stringify(values)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue