I have an app with some positions with possibilities to add each to "my library". By cklicking on "+" add menu is opened using js. The problem is that it does not always works, the variable with list lenght sometimes is not loaded so not every add menu is opening.
It gives error:
main.js:2 Uncaught TypeError: Cannot read properties of null (reading 'value')
at main.js:2:55
My js code:
if (window.location.pathname === '/dashboard/') {
let booksLen = document.getElementById("booksLen").value; // takes number of positions
for (let comp = 1; comp < booksLen; comp++) {
let bookAddButton = document.getElementById(`add-btn-${comp}`)
let bookAddComp = document.getElementById(`add-comp-${comp}`)
bookAddButton.addEventListener('click', () => {
if (bookAddComp.classList.contains('d-none') === false) {
bookAddComp.classList.toggle('d-none')
} else {
// disable all previously opened submit forms and error msg
for (let compDisable = 1; compDisable < 5; compDisable++) {
let bookAddCompDisable = document.getElementById(`add-comp-${compDisable}`)
let errMsgDisable = document.getElementById(`err-msg-${comp}`)
if (bookAddCompDisable.classList.contains('d-none') === false) {
bookAddCompDisable.classList.toggle('d-none')
}
if (errMsgDisable.classList.contains('d-none') === false) {
errMsgDisable.classList.toggle(('d-none'))
}
}
// open only one submit form at a time
bookAddComp.classList.toggle('d-none')
}
})
let submitButton = document.getElementById(`submit-button-${comp}`)
// show error msg
submitButton.addEventListener('click', e => {
let bookInput = document.getElementById(`input-${comp}`).value
let errMsg = document.getElementById(`err-msg-${comp}`)
if (bookInput === "") {
errMsg.classList.remove('d-none')
e.preventDefault()
}
})
}
}
I pass the variable like this:
<input type="hidden" id="booksLen" name="booksLen" value="{{ books_len }}">
also in my base.html i use:
<script src="{% static './js/main.js' %}" async defer></script>
class BooksAvailability(View):
# displays books related to libraries filtered for proper user. Only records desired by user
def get(self, request):
user = request.user
libraries = models.Libraries.objects.all()
books = models.Books.objects.filter(user=user.id)
status = models.BooksLibraries.objects.all()
books_len = len(books) + 1 # passes variable for js purpose. Book add to my library feature
return render(request, 'library/dashboard.html',
context={'libraries': libraries, 'status': status, 'books': books, 'books_len':books_len})
Why does it not always work as it should? When the variable loads corectly it all works as I desire.
I tried to not pass the lenght variable but count positions in js but it didn't work also.