I do a custom UI/UX for an inlineformset.
By default the inlineformset widget has a delete button.
I wan to add and remove forms from inlineformset dynamic using javascript.
In some cases the delete is just a button instead of the checkbox, in other cases is in a modal window.
When a user click delete the form is removed from the page with javascript.
So, I try to do this without using the default widget, render fields in the template, but I don't know how to tell Django witch fields to remove and if is necessary to readjust the ids and names of the fields.
My solution for this problem was to just overwrite the template_name of CheckboxInput widget class:
widgets.CheckboxInput.template_name = 'widgets/delete.html'
I added that in my {app}/widgets.py that hosts my custom widgets. As I am using the same format accross my app, I think it's the only way to go.
{app}/templates/widgets/delete.html:
<div class="checkbox checkbox-styled">
<label>
<input name={{ widget.name }} type="checkbox" value="true" {% if widget.attrs.checked == True %}checked{% endif %}>
<span>Delete</span>
</label>
</div>
If it would not have been the inlineformset_factory then the best way was to create a new class extending BaseFormSet and to overwrite the widget in add_fields method like suggested in this answer.
Related
This is the html django form generated for an ImageField
<div id="div_id_image" class="form-group">
<label for="id_image" class=""> Image </label>
<div class=""> <input type="file" name="image" accept="image/*" class="clearablefileinput form-control-file" id="id_image">
</div>
Now, I can write custom html code to customize this field. But, my use-case is just to add 3 classes, one for the outer div, one for the label and one for the input field itself.
Is it possible to add these 3 classes in django form without writing any custom html code
It is possible. use "django-widget-tweaks" tools. It will give you full flexibility in your form.
check out the official documentation:
https://pypi.org/project/django-widget-tweaks/
If you want to add only class name from form.py
(you can try this but code is not tested)
from django import forms
class xyzform(forms.ModelForm):
x= forms.CharField(widget= forms.TextInput
(attrs={'class':'some_class',
'id':'some_id'}))
y= forms.CharField(widget= forms.TextInput
(attrs={'class':'some_class',
'id':'some_id'}))
class Meta:
model = xyzModal
fields = [
'x',
'y'
]
I have a big form, some fields, depends on other fields value to compute.
Since so, i used jquery blur to submit the form each time user done editing a field and redirect it to updateview again with new values.
I have this day_absent and amount absent to test this.
If i just put form.day_absent in the form and put object.amt_absent, it doesnt save the form. But if i put form.amt_absent, it saves the form.
Why is that? I do not wish to put amt_absent as editable, it should just be the day_absent.
class PayrollTransactionUpdate(LoginRequiredMixin,UpdateView):
model = t_pay
template_name = 'payroll/transaction/update.html'
fields = [
'day_absent',
'amt_absent',
]
<div id='input-item' class="col-1">
{{ form.day_absent }}
{{ form.day_absent.errors}}
</div>
<div id='item' class="col-2">
{{ object.amt_absent }}
</div>
Couple of points:
When you use {{object.amt_absent}}, you are not rendering the form for the field amt_absent, rather just the value saved in the DB.
You added amt_absent as a field to be included in the UpdateView, so, until and unless this field is not required, the form will keep throwing error for this field. That is why your form works when you include both the fields. You can check all errors by using {{form.errors}} or field specified errors by using {{form.amt_absent.errors}} in your template.
I have a form which allows you to upload an image, but I want to know if it is possible to customise the markup that Django generates.
In the model it is created as an ImageField:
logo = models.ImageField(blank=True, null=True)
In the template I am creating an 'upload' form field using
{{ form.logo }}
This is the markup that gets generated:
Currently: dog.jpg
<input id="logo-clear_id" name="logo-clear" type="checkbox">
<label for="logo-clear_id">Clear</label>
<br>Change: <input id="id_logo" name="logo" type="file">
I want to know if I can change that markup by drilling down further, so that I can for example nest the checkbox to clear the image within its label. I also would like to use my own markup to separate the option to clear the form field from the option to upload a new one. However, I can't find any documentation on how to do this. I've tried outputting
{{ logo.logo-clear }}
directly but this throws an error.
The solution was to create a custom version of the widget being used in my forms.py: https://docs.djangoproject.com/en/1.10/_modules/django/forms/widgets/#ClearableFileInput
from django.forms.widgets import ClearableFileInput
class CustomImageFieldWidget(ClearableFileInput):
template_with_clear = '<label for="%(clear_checkbox_id)s">%(clear)s %(clear_checkbox_label)s</label>'
class OrganisationProfileForm(OrganisationCreateForm):
class Meta(OrganisationCreateForm.Meta):
widgets = {
'logo': CustomImageFieldWidget,
}
I am not quite sure about if i am taking the right approach to accomplish this. What i want is to (change the css for) / (use some jQuery methods on) the form elements rendered by the modelformset that have pre-filled data. For example i have the following modelformset.
EduFormSet = modelformset_factory(models.CandidateDegree,
form=forms.CandidateDegreeForm)
edu_formset = EduFormSet(prefix='candidate_degree',
queryset=models.CandidateDegree.objects\
.filter(candidate=can))
when i pass this formset to the template it renders forms for all the existing CandidateDegree objects with the pre-filled data and a blank form as well.
What i am trying to achieve is not to show the pre-filled forms but just the data for the objects that are already created and append an edit button to the element (using jQuery) which would then show the form. And at the end of the object list show the blank form generated by formset.
i am aware that i could pass all the CandidateDegree objects related to a Candidate as a seperate dictionary to show the information. but in that case how do i append the form to the formset so that the dynamically generated forms become the part of the formset and all the information is saved when a user clicks on a submit button.
what would be the best approach to achieve something like this ?
You don't have to show the complete form, you can loop over the formset like this:
{% for form in edu_formset %}
form.FIELDNAME#1.value
form.FIELDNAME#2.value
etc.
{% endfor %}
<!-- Manually render empty form for new entry -->
<div class='input'>
<label>Locality: </label> <input id="FIELDNAME#1" disabled=disabled value="">
<label>Country: </label> <input id="FIELDNAME#2" disabled=disabled value="">
etc.
</div>
So you're only showing the database values of all objects send to the template, not the form inputs.
Then indeed with minimal jquery (or plain javascript) you can show/hide the div.input
I want to display a ManyToMany field into a widget/Html-form which the user can delete by X-ing items using jquery.
class user_profile:
links = ManyToManyField(...)
Then when I render the formset it would be something like:
<form>
<input type="checkbox" name="id" value="link_to_delete_item_using_ajax_call" />
....
....
</form>
Is there any existing? If not, how should I code it? ModelForm? Custom Form?
Thanks!
The best place for this is usually a custom Widget class. For example you could subclass CheckboxSelectMultiple and then use your custom widget in your form classes for relevant form fields.
The widget can automatically include the required JS/CSS by specifying it in the internal Media class