Dynamic Select Based Date Entry Forms

The code I’m going to talk about can be found in my Dynamic Date Selects repository

Been a while since I’ve posted anything! One of the reasons is that I’ve spent a bit of time over the last few months building and developing my curated Funko Pop! Vault. I developed the backend (simple web-scraping) using Python, and had to re-learn some php to get the front side working again (it’s currently using a hacked version of this blog). For the last couple of months, I’ve split my time between learning Django and auditing some Coursera courses on Data Science.

This post is to share with you a small piece of code I worked on yesterday, which aims to help with the search form for the vault. Here I give users the option to search for when a Pop! might have been vaulted. One of the advantages of Django is that it comes with built in form validation. However, one of the recommended ways to build a field such as a multi-select date entry field is to build it as a “widget”, that extends a class.[1] Unfortunately, due to building a custom widget, I needed to also build my own date validation.

I decided that it would be easier for users if I did my best to prevent them from entering an invalid date, rather than checking on the validity of the date and then returning them to the search form if they made a mistake. Having recently taken the codecademy course on jQuery, I figured this would be the easiest way to implement what I had in mind: dynamically alter the number of days a user could select when they chose a specific month.

The code was, initially, fairly straightforward, until I hit a stumbling block. I had set up a Javascript object to hold the days of the month, with the days the keys and the months in an array as the values, like so:

days = {
    31 : [1, 3, 5, 7, 8, 10, 12],
    30 : [4, 6, 9, 11],
    28 : [2]
};

I set up the rest of the function to grab the month selected and input it into a function that would cycle through this days object and for each number of days (each key of the object), it would cycle through the months in the array. Upon finding the month in the array, the function was supposed to return the number of days, the key. Unfortunately, every time I ran this function, the variable I had set to it was returning undeclared. I’d stumbled upon a problem due to function closure. In order to cycle through the object and the arrays as values properly, I was having to use the jQuery $.each() built in function, which requires a function as its second value to separate out the keys and values:

$.each(obj, function(keys, values) {
   ...
}

This meant that when I attempted to return the key once I had found the correct number of days in the selected month, I was only returning it to the parent function, not to the variable that was calling the function. However, as this child function was within the scope of the $.each() function, and it was unnamed, I had no way of assigning the returned value to a variable in the parent function.

Fortunately I’m not the first person to come across this issue. This great answer on Stack Overflow explains what I found to be the easiest solution: create a variable within the scope of the parent function, which can be accessed by the child $.each() function. Assign the value you want to return in the parent function to this variable, and crucially, return the child function as false to break out of the loop set up by the $.each() function.

[1] I started by copying & adjusting the example for this, given in the documentation.

This entry was posted in Programming. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *