I'm working on a Django project involving the use of validating forms. I have my validation working, including all the rules I have applied, in one approach (the form is created when the page is rendered), but now I am trying a different approach to gain some efficiency in the number of lines of code I am using of the overall website.
It's come to my attention that I have to use the same HTML code to create a form in multiple scenarios (i.e formABC and formCBA will use the same inputs), so my new approach involves creating the form with JQuery using $(document).ready() and store the form's HTML code in a module JS files. That way, I can just call the function anytime I need that form created for a certain URL.
Let me try and break it down how my setup was vs. how it is now to shed some light where my issue may be.
Original Setup - that does work
My base.html code involves the layout
<body>
<script
src="/static/js/bootstrap/bootstrap.bundle.min.js"
></script>
<script
src="/static/js/jquery/jquery-3.6.0.min.js"
></script>
<script
src="/static/js/jquery/jquery.validate.min.js"
></script>
<script
src="/static/js/jquery/additional-methods.min.js"
></script>
<script
src="/static/js/jquery/jquery-ui.min.js"
></script>
<div
class="d-flex flex-row vh-100"
>
{% include "navbar.html" %}
{% block content %}
{% endblock content %}
</div>
{% csrf_token %}
<script
src="/static/js/authenticate.js"
></script>
<script
src="/static/js/validation.js"
></script>
</body>
Where block content is the area Django will add the specific app's HTML code I want to render. This is where my content lives, including any forms I am validating. As you can see, I have a validation.js file listed at the bottom where I store ALL my form's validators, rules, addMethods, setDefaults, etc. It kicks off when the DOM is ready (I believe) and looks like:
$(function) {
$.validator.setDefaults({
.......
})
$.validator.addMethod(....) {
....
})
$("#formABC").validate({
rules: {
....
},
messages: {
....
},
})
$("#form123").validate({
rules: {
....
},
messages: {
....
},
})
[....A lot more forms captured here.....]
$("#formXYZ").validate({
rules: {
....
},
messages: {
....
},
})
}
And finally, my HTML <main>
content will have the creation of the form that will look like:
{% extends 'base.html' %}
{% load static %}
{% block content %}
<main>
<form
method='POST'
id='formABC'
novalidate
>
{% csrf_token %}
[...inputs...]
</form>
</main>
<script
type="module"
src="/static/js/formABC.js"
></script>
{% endblock content %}
...where formABC.js just captures any JQuery code that is specific to this form.
NEW Setup - Forms are created from functions
Nothing changes with my base.html or validation.js file. My <main>
content gets shorten to:
{% extends 'base.html' %}
{% load static %}
{% block content %}
<main>
<div id="formABC"></div>
</main>
<script
type="module"
src="/static/js/formABC.js"
></script>
{% endblock content %}
...where formABC.js captures any JQuery code that is specific to this form AND ...
import {create_formABC} from "./forms.mjs"
$(document).ready(function () {
var form = $("#formABC")
create_formABC(form)
})
And my new JS module, called forms.mjs, that I plan to store all my forms like so:
export function create_formABC(section) {
var form = `
<form
method='POST'
id="formABC"
novalidate
>
<input
type="hidden"
name="csrfmiddlewaretoken"
value="${csrftoken}"
>
[...same HTML code as before....]
</form>
`
$(section).append(form)
To Summarize my Confusion
Why is $("#formABC").validate()
not working when my form appears in this setup? Is it because my .validate() and .append(form) happen at the same time?
What makes it more confusing to me is that I have the JQuery autocomplete plugin working on this setup for inputs that need it, but it is tied to an event handler $(document).on(focus)