Compare commits
No commits in common. "9283c38eaa5ef0f07e3b5e16d1af8c17c3d90f35" and "dabd456c996f7fc85fa494779115770fb568ad85" have entirely different histories.
9283c38eaa
...
dabd456c99
4 changed files with 28 additions and 51 deletions
|
|
@ -48,31 +48,18 @@ class DynamicArrayWidget(forms.Widget):
|
||||||
|
|
||||||
def value_from_datadict(self, data, files, name):
|
def value_from_datadict(self, data, files, name):
|
||||||
value = data.get(name)
|
value = data.get(name)
|
||||||
if value is None:
|
if value:
|
||||||
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:
|
try:
|
||||||
parsed = json.loads(value)
|
parsed = json.loads(value)
|
||||||
if parsed is None:
|
if parsed:
|
||||||
return []
|
|
||||||
if isinstance(parsed, list):
|
|
||||||
return [
|
return [
|
||||||
item
|
item
|
||||||
for item in parsed
|
for item in parsed
|
||||||
if item is not None and str(item).strip()
|
if item is not None and str(item).strip()
|
||||||
]
|
]
|
||||||
return [parsed] if str(parsed).strip() else []
|
return []
|
||||||
except (json.JSONDecodeError, TypeError):
|
except (json.JSONDecodeError, TypeError):
|
||||||
return [value] if value.strip() else []
|
pass
|
||||||
|
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -117,17 +104,11 @@ class DynamicArrayField(forms.JSONField):
|
||||||
if value is None:
|
if value is None:
|
||||||
return []
|
return []
|
||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
return [item for item in value if item is not None]
|
return value
|
||||||
if isinstance(value, str):
|
if isinstance(value, str):
|
||||||
if value.strip() == "" or value.strip().lower() == "null":
|
|
||||||
return []
|
|
||||||
try:
|
try:
|
||||||
parsed = json.loads(value)
|
parsed = json.loads(value)
|
||||||
if parsed is None:
|
return parsed if isinstance(parsed, list) else [parsed]
|
||||||
return []
|
|
||||||
if isinstance(parsed, list):
|
|
||||||
return [item for item in parsed if item is not None]
|
|
||||||
return [parsed]
|
|
||||||
except (json.JSONDecodeError, TypeError):
|
except (json.JSONDecodeError, TypeError):
|
||||||
return [value] if value else []
|
return [value] if value else []
|
||||||
return [str(value)]
|
return [str(value)]
|
||||||
|
|
@ -136,24 +117,16 @@ class DynamicArrayField(forms.JSONField):
|
||||||
"""Handle bound data properly to avoid JSON parsing issues"""
|
"""Handle bound data properly to avoid JSON parsing issues"""
|
||||||
if data is None:
|
if data is None:
|
||||||
return initial
|
return initial
|
||||||
|
# If data is already a list (from our widget), return it as-is
|
||||||
if isinstance(data, list):
|
if isinstance(data, list):
|
||||||
return [item for item in data if item is not None and str(item).strip()]
|
return data
|
||||||
|
# If data is a string, try to parse it as JSON
|
||||||
if isinstance(data, str):
|
if isinstance(data, str):
|
||||||
if data.strip() == "" or data.strip().lower() == "null":
|
|
||||||
return []
|
|
||||||
try:
|
try:
|
||||||
parsed = json.loads(data)
|
parsed = json.loads(data)
|
||||||
if parsed is None:
|
return parsed if isinstance(parsed, list) else [parsed]
|
||||||
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):
|
except (json.JSONDecodeError, TypeError):
|
||||||
return [data] if data and data.strip() else []
|
return [data] if data else []
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def validate(self, value):
|
def validate(self, value):
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
method="post"
|
method="post"
|
||||||
{% if form_action %}action="{{ form_action }}"{% endif %}>
|
{% if form_action %}action="{{ form_action }}"{% endif %}>
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% include "frontend/forms/errors.html" %}
|
|
||||||
<ul class="nav nav-tabs" id="myTab" role="tablist">
|
<ul class="nav nav-tabs" id="myTab" role="tablist">
|
||||||
{% for fieldset in form.get_fieldsets %}
|
{% for fieldset in form.get_fieldsets %}
|
||||||
{% if not fieldset.hidden %}
|
{% if not fieldset.hidden %}
|
||||||
|
|
|
||||||
|
|
@ -163,12 +163,14 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView
|
||||||
)
|
)
|
||||||
return redirect(service_instance.urls.base)
|
return redirect(service_instance.urls.base)
|
||||||
except ValidationError as e:
|
except ValidationError as e:
|
||||||
form.add_error(None, e.message or str(e))
|
messages.error(self.request, e.message or str(e))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error_message = self.organization.add_support_message(
|
messages.error(
|
||||||
_(f"Error creating instance: {str(e)}.")
|
self.request,
|
||||||
|
self.organization.add_support_message(
|
||||||
|
_(f"Error creating instance: {str(e)}.")
|
||||||
|
),
|
||||||
)
|
)
|
||||||
form.add_error(None, error_message)
|
|
||||||
|
|
||||||
# If the form is not valid or if the service creation failed, we render it again
|
# If the form is not valid or if the service creation failed, we render it again
|
||||||
context["service_form"] = form
|
context["service_form"] = form
|
||||||
|
|
@ -344,6 +346,10 @@ class ServiceInstanceUpdateView(
|
||||||
kwargs["instance"] = self.object.spec_object
|
kwargs["instance"] = self.object.spec_object
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
|
def form_invalid(self, form):
|
||||||
|
messages.error(self.request, form.errors)
|
||||||
|
return super().form_invalid(form)
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
try:
|
try:
|
||||||
spec_data = form.get_nested_data().get("spec")
|
spec_data = form.get_nested_data().get("spec")
|
||||||
|
|
@ -356,13 +362,15 @@ class ServiceInstanceUpdateView(
|
||||||
)
|
)
|
||||||
return redirect(self.object.urls.base)
|
return redirect(self.object.urls.base)
|
||||||
except ValidationError as e:
|
except ValidationError as e:
|
||||||
form.add_error(None, e.message or str(e))
|
messages.error(self.request, e.message or str(e))
|
||||||
return self.form_invalid(form)
|
return self.form_invalid(form)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error_message = self.organization.add_support_message(
|
messages.error(
|
||||||
_(f"Error updating instance: {str(e)}.")
|
self.request,
|
||||||
|
self.organization.add_support_message(
|
||||||
|
_(f"Error updating instance: {str(e)}.")
|
||||||
|
),
|
||||||
)
|
)
|
||||||
form.add_error(None, error_message)
|
|
||||||
return self.form_invalid(form)
|
return self.form_invalid(form)
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,6 @@ const initDynamicArrayWidget = () => {
|
||||||
addRemoveEventListeners(container)
|
addRemoveEventListeners(container)
|
||||||
addInputEventListeners(container)
|
addInputEventListeners(container)
|
||||||
updateRemoveButtonVisibility(container)
|
updateRemoveButtonVisibility(container)
|
||||||
|
|
||||||
// Ensure hidden input is synced with visible inputs on initialization
|
|
||||||
updateHiddenInput(container)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,7 +94,7 @@ const updateHiddenInput = (container) => {
|
||||||
if (!hiddenInput) return
|
if (!hiddenInput) return
|
||||||
|
|
||||||
const values = Array.from(inputs)
|
const values = Array.from(inputs)
|
||||||
.map(input => input.value ? input.value.trim() : '')
|
.map(input => input.value.trim())
|
||||||
.filter(value => value !== '')
|
.filter(value => value !== '')
|
||||||
|
|
||||||
hiddenInput.value = JSON.stringify(values)
|
hiddenInput.value = JSON.stringify(values)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue