Monday, October 8, 2007

Javascript problem of the day.. and a solution YAY :-)

This evening I have been working on the "Add a New Task" section of the project page. I copied across some code from the "Create a New Project" page, because both pages involve selecting person/s, entering a date and time. I got the calendar and time selector to work with no problems, but the autocompleter for the name input exhibited some strange behaviour. It is meant to show suggestions immediately below the input box, but it was showing them in the top corner of the page. See the screenshot below.




There is a lot of functionality on this page, and it has a huge amount of Javascript (including 7 different jQuery utilities). My first thought was that something else was interfering with the autocompleter, probably with its CSS.

But another possibility occured to me. On this page, the form is located in a DIV that is hidden until the user clicks to show it. That is different to the "Create a New Project" page where I have the autocompleter working. Maybe that difference was the reason it wasn't working. To test my theory, I stopped the DIV from being hidden and refreshed the page. Low and behold, the autocomplete suggestions were shown in the correct position:



I had identified what was causing the error. But I didn't have an adequate solution, because we can't leave that ugly form on the page when the user doesn't need to use it. I continued examining the page's behaviour and stepping through my code. I noted that when I clicked "Add a New Task", followed by "Cancel Adding Task", followed by "Add a New Task" again, the autocomplete suggestions were not displayed at all, let alone in the correct position. All the "Cancel Adding Task" link does is hide the DIV that the form is in, so once again, the problem was linked to the DIV being hidden.

That gave me an idea. Maybe I could initialise the autocomplete function whenever the form was shown, rather than when the page was loaded. So I changed this line of code:
$(document).ready(function() {
     $("div#addnewtask input.person").autocomplete(...);
});
to this:
$("button#addtask").click(function() {
     $("div#addnewtask input.person").autocomplete(...);
});
And it worked! Hoorah!

No comments: