Django admin custom form submission force to select action from dropdown list - django

I want to add a custom form to a django admin-site change list view. As soon as I add a submit button it asking to select the custom action from the drop-down list. I created a separate form with a unique id. Still it look for a action be select. How can I overcome this?
Here is my template code.
{% extends "admin/change_list.html" %}
{% load staticfiles %}
{% block content %}
<div align="right">
<form id="generate-form" method="POST">
{% csrf_token %}
<select>
<option value="">-- section name --</option>
{% for section in sections %}
<option value="{{ section.short_name }}">{{ section.name }}</option>
{% endfor %}
</select>
<input type="text" name="from_date" class="vTextField" placeholder="from">
<input type="text" name="to_date" class="vTextField" placeholder="to">
<input type="submit" value="Generate" class="default" id="gen-schedules"
style="margin:0; height: 30px; padding-top: 5px;">
<form>
</div>
{{ block.super }}
{% endblock %}

Assuming you copy/pasted without changing it, you have this because the form tag isn't properly closed: <form> should be replaced by </form>:
...
</form>
</div>
{{ block.super }}
{% endblock %}
Because it's not closed, the browser thinks it's the same form as the the next form, the actions one.
To avoid this kind of problems, I'd recommend relying on Django's forms to generate the right HTML for you, when possible. To help with complex layouts, django-crispy-forms is a great library that is very helpful.

Related

HTMX does not trigger get on load if it's a radio check

I am working on Django and using htmx I have checkbox input, select tag and radio input both work as expected on page load it sends a request to an endpoint to the server to retrieve certain information which is rendered through a partial template. The problem is only radio deosn't trigger it when the appropriate input value is checked.
Here is the radio input.
<input id="option_{{ option.id }}" class="form-check-input" type="radio"
name="radio_{{ question.id }}" value="{{ option.id }}" {% if question.required %} required
{% endif %} {% if question.disable %} disabled {% endif %} {% if option.id == radio_response %}
checked {% endif %} hx-get="{% url 'survey:dynamic_loader' %}" hx-trigger="load, change"
hx-target="#radio-result-{{question.id}}"/>
Is this a normal behaviour for htmx? Or I am doing something wrong.
You should not put the load trigger on radio inputs. If you have 10 radio inputs, then the load trigger creates 10 requests in total from which 9 will not have the value you expect, because HTMX just extracts the actual state of a radio input when the page loads. Instead of that, you should put HTMX attributes on a parent (grouping) element. For example:
<div hx-get="{% url 'survey:dynamic_loader' %}"
hx-trigger="load, change"
hx-target="#radio-result-{{question.id}}">
hx-include="this"
{% for option in options %}
<input id="option_{{ option.id }}"
class="form-check-input" type="radio"
name="radio_{{ question.id }}"
value="{{ option.id }}"
{% if question.required %} required{% endif %}
{% if question.disable %} disabled {% endif %}
{% if option.id == radio_response %}checked {% endif %} />
{% endfor %}
</div>
This creates only one request on page load (and of course when the user clicks on a radio input) and it will have the correct value of the radio input. The hx-include="this" attribute includes all child inputs' value in the request.

Change button size bootstrap 4 (Django)

I'm working with Django and I'm trying to line up a Bootstrap button with a select field. I've got the form inline where I'd like it to be, but I can't seem to make the button smaller to make it align properly. I'm sure there is a simple solution but I've been struggling with this for hours and can't seem to find anything that works for me. Here is a picture as it is currently to give you a better idea of the problem: button not aligned
And here is my current code in my template:
<form class="form-inline" action="{% url 'displayStats:proindvleaders'%}" method="post">
{% csrf_token %}
<div class="row">
{{ form.as_p }}
<button id="submit" type="submit" class="btn btn-primary btn-sm">Submit</button>
</div>
I've tried just setting height on the button ID with css but it doesn't seem to be working for me. Any ideas?
By default bootstrap btn class has padding. Inspect the code in a browser and remove that padding, either by adding a new padding class, or use custom styling class and remove btn, btn-primary etc, but all the same, its better to edit the form, rather than button. Bootstrap default buttons are perfect for most scenario, and most probably you need form styling. I suggest form styling. Below is an example from code.
Ps: i'm replying from phone, code may not be formatted
{% for field in form %}
<div class="fieldWrapper">{{ field.errors }}
<input type="{{ field.field.widget.input_type }}" name="{{ field.html_name }}" id="{{field.id_for_label}}" class="col-12 input-login" placeholder="{{field.label}}" >
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}

How to integrate this form with my existing custom template?

I've installed Userena, and I am trying to figure out how to integrate the existing userena form with my own custom HTML form template, I have pasted part of the code for the userena form template, and I do not see ANY css or html, so I'm very confused about how I would integrate this with my own template consisting of HTML, CSS. I figured with Django I'd be able to take any old HTML form and just plugin Django's variables to get it working.
So my question is how can I integrate the top example (userenas form template) into the bottom example (generic HTML example). An example might be helpful.
{% block content %}
<form action="" method="post">
{% csrf_token %}
<fieldset>
<legend>{% trans "Signup" %}</legend>
{{ form.non_field_errors }}
{% for field in form %}
{{ field.errors }}
{% comment %} Displaying checkboxes differently {% endcomment %}
{% if field.name == 'tos' %}
<form action="/register/" method="post" role="form">
<div class="form-group">
<input type="text" class="form-control input-lg" id="nameinput" placeholder="Name" name="contact-name">
</div>
<div class="form-group">
<input type="email" class="form-control input-lg" id="emailinput" placeholder="Email" name="contact-email">
</div>

Why is this django formset not being submitted?

i have a formset as follows:
EduFormSet = formset_factory(forms.CandidateDegreeForm, can_delete=True)
edu_formset = EduFormSet(prefix='candidate_degree')
in the templates i am doing the following:
{% if edu_formset %}
{% for form in edu_formset %}
<div class="formset-form" style="visibility: visible;">
<form id="{{ form.prefix }}" method="POST" action="/degree/add/">
<h4>Some Heading Here</h4>
{% csrf_token %}
{% for field in form %}
{% include "form_field.html" %}
{% endfor %}
</form>
<script type="text/javascript">
jQuery(document).ready ( function(){
jQuery('{{ form.prefix }}').validationEngine();
});
</script>
<div class="clearfix"></div>
</div>
{% endfor %}
{{ edu_formset.management_form }}
<div class="button-container right">
<input class="button" type="submit" value="submit" />
</div>
{% endif %}
I am not sure why but nothing really happens when i hit the submit button.
Your submit button is not within the form, so the action is not triggered by the click!
Here's how the docs show you to render formsets:
<form method="post" action="">
<!-- Notice how the formset (below) and thus its submit button
is INSIDE the form (above) -->
{{ formset.management_form }}
<table>
{% for form in formset %}
{{ form }}
{% endfor %}
</table>
</form>
You try to create multiple forms with the form.prefix for id. This could work but each form would have to be rendered with its own submit button. Formsets are designed to combine multiple forms into one and guarantee uniqueness of value names by said prefix. They would be enclosed in a singe form and share any submit triggers.

How to sort list_filter labels for foreign key filters in Django admin?

List_filter labels for foreign key filters in django admin are always ordered by id and that can cause a pretty mess when there are many filters in the list.
I have been searching for simple solution how to order those labels alphabetically or by date for some time now. It seemed that besides of using FilterSpec there is no solution for it.
Until I did this.
I have changed the template for filter.html (put it in admin folder in your templates directory) so it looks like this (found it somewhere on django snippets I guess):
{% load i18n %}
<h3>{% blocktrans with title as filter_title %} By {{ filter_title }} {% endblocktrans %}</h3>
<div align="right">
<select onChange="javascript:window.location = this.options[this.selectedIndex].value;" style="width: 80%">
{% for choice in choices %}
<option {% if choice.selected %}selected{% endif %} value="{{ choice.query_string|iriencode }}">
{{ choice.display }}
</option>
{% endfor %}
</select>
</div>
And then I used 'dictsort:"name"' template tag on for loop so the template finally looked like this:
{% load i18n %}
<h3>{% blocktrans with title as filter_title %} By {{ filter_title }} {% endblocktrans %}</h3>
<div align="right">
<select onChange="javascript:window.location = this.options[this.selectedIndex].value;" style="width: 80%">
{% for choice in choices|dictsort:"display" %}
<option {% if choice.selected %}selected{% endif %} value="{{ choice.query_string|iriencode }}">
{{ choice.display }}
</option>
{% endfor %}
</select>
</div>
I have used select drop-down since I had many labels, but it can be used on the standard 'ul' list too. Now I finally have all my foreign key based filters ordered alphabetically (and it works even if using dates).
If you need reversed dosting there is dictsortreversed template tag for that.
Hope that this helps someone.
Errr, the question itself contains the answer. Sorry for not structuring it better.