Form Autofill Follies

Been a bit lazy lately, but trying to get back in the groove of writing this thing.  Had a lot of failures lately, so let’s talk about one of those!

I was working to redesign our login screen.  It works fine, but is very basic.  Time to add some jQuery flash!

The idea was to absoultely position the form labels (username and password) over the input fields (which were styled to appear just as underlines).  When a user clicks on a field (or focuses there via tab), the label animates to the right of the input field and shrinks down.  If the input blurs, there are two options: 1) if the user entered something, the label stays small and out of the way.  2) if the user didn’t enter anything, the label grows and moves back into place.

And it worked great!  Took some tweaking to work properly, but I thought it was a cool little trick.  But in my testing, I finally used a browser that had stored credentials for the login screen and everything fell apart.

Different browsers have different events when they autofill fields, and it seems none really broadcast those events to hook into.  As a result, if a user stored their credentials, they were greeted with text on text (their credentials, overlaid with the input labels).  The focus events didn’t fire.

So I scrapped all that and just went with a simple setup of labels over basic input fields with some useful placeholder text.  It’s really fun to create cool looking interfaces, and when it finally works, I always get a rush from the accomplishment.  But it’s important to remember that users don’t care about your rush.  They just want to log in to the damn site, so make it as easy as possible!

If you’re curious about what might have been, I cooked up a quick codepen to show a general idea.  Check it out at http://codepen.io/joedriscoll79/pen/NNoGrv

Feel free to tell me how ugly it is- I though it was kind of cool.  Have an idea for how it might work better (or at all with autofill)?  Let’s discuss!

 

Don’t Repeat Yourself

DRY- of course.  One of the core principles (so I’ve read) of software development.  Repeating yourself in your code or design almost always leads to trouble- repeated bugs, fixing/editing things in multiple locations, general confusion, dogs and cats living together- pretty much all the bad parts of the Bible.

But sometimes I forget that those little machines running behind the scenes don’t really play by the rules.  Like the PHP parser.  That thing (or whoever wrote it) is way smarter than I am.  But one of its main functions is often to repeat itself (the project we’re working on makes liberal use of while loops to output content stored in the database).  So, while this program is happily doing its job, looping over rows and printing titles and text fields, repeating itself, I’m banging my head on the keyboard trying to figure out why my little jQuery ui widget is grabbing 3 elements each call instead of the one it should.

And therein lies the moral of this short Friday night story.  Throwing your css and js code into your php file while you’re developing seems like a great idea- that way, you can just work in one file, and break it out into the proper modules when everything looks right.  But be careful where, within that php file, you put your js.  Because if you accidentally put it inside one of those awesome php while loops, you’re going to end up with multiple identical functions.  And you’re gonna have a bad time.

Seriously- pretty soon I’m going to have to rename this thing to “I’m not as dumb as my code looks.”

Placeholder Workaround

We’ve still been working with Django on a redesign of a site’s blog module.  Still liking the tool- it’s a bit tricky to figure out initially (the url routing in urls.py took me way too long to wrap my head around- and I wouldn’t say I’m fully clear on most of it), but overall it’s so useful.

But in any bargain, there are downsides.  We were customizing the log in screen to get away from the default Django scheme (to try not to scream “We used a template for this!”).  Got the template overriding process down, but ran into an issue on something that should have been real simple.

We wanted to add placeholder text to the username/password fields (we were trying to create a slick, no-label login form).  But the actual input fields are generated ‘behind the scenes’ by Django.  Usually very useful, as then we don’t have to do it ourselves, but if there’s something it doesn’t include by default (like placeholder text), it can be tough to add it in (at least for a Python newbie like me).

I did some Googling and saw some smarter folks than I found a way to do it directly in the model (though it did look more complicated when using Django’s default admin panel log in), but my experience is mostly in Javascript, so that’s what I used.  It was really simple once I thought about it properly- just a call to the input field’s “placeholder” attribute to set it to “username” and “password” and we were good to go!

Sometimes it’s best to fall back on your strengths (at least, that’s what they tell me- and I tell myself JS is my strength!).

Platinum Album

Responsive design is kind of hard.

Tools like Bootstrap are awesome.  They make a developer’s life much easier, because it takes some of the design element questions away.  But there’s a lot of css in those Bootstrap files.  And trying to customize it can be quite tricky.

For example: we’re currently trying to upgrade our photo album feature.  The current setup is straight out of 2003.  A grid (created using tables) of tiny images- click one for a round trip to the server to get the large image, which may be 4000X3000 pixels, if the site admin didn’t feel like resizing.  Want the next or previous image?  Another trip to the server.  On the first image or last image?  No looping- sorry.

So, we’re taking advantage of Bootstrap’s awesome modal element.  It’s so smooth with just a few tweaks (found that the header/body traditional layout wasn’t going to work with the way our images displayed- too much vertical space lost, so we moved the ‘header’ to a right column instead.  Think Facebook’s image viewer layout).  After we added our own ajax setup to get the images, a little looping logic to allow users to cycle through, and a bit of responsive design (and extra ‘prettying’) of the default grid of images, we were just about good to go.

Then I checked my phone.

One of the main goals with all these upgrades is to bring everything mobile friendly.  A dedicated app may be in the future, but it seems like one direction things are going is into making an entire site work on mobile almost as smoothly as a native app does.  So, while upgrading the album feature, we are working in some mobile aspects.  The grid resize was fairly easy, but there are some stray styles on the modal that just won’t cooperate.  Mainly: when resized to a small device, our image automatically goes left-aligned (it’s vertical and horizontal centered in large view).  The modal also expands past 100% of the viewport on a phone, which has to be fixed.  I’m sure there’s some style in the bootstrap.css file that I need to overwrite, but it’s playing hard to get.

The other hurdle is touch events.  I thought jQuery touch would work- and it partly worked great, but it had some bad side effects when interacting with our system.  For some reason, it wanted to reload each page with an ajax fade in effect.  However, on our php-driven system, important info is often transported in the url string (like the id of the album we’re viewing).  When we enabled jQuery touch, this broke- links would fade the screen out, then in, but not change the actual content.

So we found an alternative: TouchSwipe – it’s working pretty well so far.  It’s not as responsive (in the action sense, not in the sizing sense) as a native app would be, but a user can swipe left or right to get the prev/next image.  The way we structured our JS functions, it was also super simple to add (just included a .swipe function call, with returns for swipeLeft and swipeRight).

So we’re getting there.  Not quite up to standard yet, but with this release, we’ll be another huge step forward.

:First!

The DOM Tree Of Life!
The DOM Tree Of Life!

One problem (of many) I ran into while adding validation checks on our request form feature was limited to IE8.  The code worked great in other browsers- my function used find() to get the correct error notice wrapper to display and switched it on if a field was blank or otherwise invalid.  But not in IE8.

In that world, the function would show the error notice wrapper for every field.  I made a little progress by fixing my PHP code- it originally inserted an error wrapper on each form field- even ones that weren’t required.  I figured it didn’t matter, as they’re all ‘display: none’ by default, but my first step was to add a conditional to my PHP to ensure that error wrappers only appear attached to required form fields.

That didn’t solve the problem- though at least it reduced the amount of red I saw on my test form.

Still- anytime a form was submitted with any unfilled (but required) field, any required field below that in the form was marked as invalid (even if it had a valid value).  Only in IE8.

The answer was to use the :first selector (https://api.jquery.com/first-selector/).  It looks like IE9 and later (and all other browsers) will stop at the first instance when using find(), but 8 will not- it will get all matches.  However, when I added the :first selector to my function that processed each error, 8 fell into line with the rest of them.  It stopped popping error messages all the way down the tree.

Another example of the notion that development can go so well for the majority of a project, and one little problem can stall for way too long.  Should I have thought of the :first selector earlier?  Probably, but because the code worked everywhere else, it was a bit of a head-scratcher for me.

Hope this helps anyone with a similar issue.  Actually- what I really hope is that everyone drops support for IE8 and no one has to read about this!

Stop Bugging Me!

We’re nearing completion on the request form feature validation, but I need a bug zapper.

We were so proud of ourselves early in the week.  Everything was working.  The functions were a nice mix of plain JS and jQuery.  Feedback given to a user while they filled in the fields of a form was informative without being frustrating (finding that line proved to be tricky, but hopefully we nailed it).  We though it would be a matter of some final testing and a push live.

Then I checked it in IE8. The rest of the week has been a frustrating, but informative, experience. Lessons learned:

  1. If you’re going to use jQuery, use it.  It seemed like we should try to use plain JS when possible, but in reality, if you’re targeting as much backward compatibility as possible… Well- there was a reason jQuery was created.  It smooths out the rough edges between ie, Firefox, and Chrome.  It makes things just work!
  2. Always test in an old browser early.  We’d really love to just drop support for IE8, and likely will eventually, but not like this.  The checks almost work, even in IE8, but are just flawed enough to make the feature very hard to use in that browser.
  3. Modern, updated browsers will tolerate multiple elements with the same id tag.  Older ones will not.

Point 3 was a tough one.  Because the form is being generated via a php/mysql backend, we don’t know what it will look like.  Therefore, all the validation checks have to be done with just a general knowledge of what the final form will look like.  For example- the main issue was with checkboxes.  There may be 4 required checkbox groups, and 2 non-required.  We found a way around this by using a wrapper div around a checkbox group and adding a ‘required’ class tag via php if that group is marked as required in the database.  Works great, but only if the wrapper div has the same id as the checkbox group.  Again, not a problem for most, but IE8 did not appreciate this at all (and I know, it’s also bad practice).  I think we found a way around it (by removing a possibly unnecessary id tag on a sub element), but it was not easy to find why some really odd bugs were popping up in IE8.

If I were to have a lesson #4, it would be that jQuery is quite awesome.  I know it’s not the new hotness that some js frameworks are, but it’s super useful.  I had a couple document.getElementsByClassName calls- they all failed in IE8.  Switch it out with a jQuery dollar sign and we’re money!  JQ also provides an awesome iterator function: .each().  That really helped, as again- we didn’t know how many of each type of field we would be checking.  It also smooths out the ‘this’ keyword- items within the .each() function have exactly the ‘this’ you would expect them to- none of the global window ‘this’ garbage.

Hopefully next week will be a wrap up of a successful launch.  Then maybe some different topics!

Arrays In Action

I know these form validation entries are getting dull.  But it’s a major project and has led to some interesting/frustrating issues.

For example-  we wanted to be able to automatically scroll a user directly to the spot on the form where they had the error.  The simple way is to use input.focus – works fine if there’s just one error.  But there were some drawbacks:
1) Can’t seem to ‘focus’ a checkbox or radio group.
2) If multiple errors, it could focus one field, then another, then another in quick succession- a very confusing user experience.
3) The focus option didn’t scroll the screen high enough for the user to see the field label.  Sure, it’s easy to scroll up a bit to see what they need to enter, but again, not good user flow.

The answer? Arrays in action!

We created a resultArray variable- on each check in the $(form).on(‘submit’) handler, if something failed, we pushed that jquery object to our resultArray.  Then, at the end of all the checks, we $(body, html).animate() to 50px above the entry at resultArray[0] (found by getting resultArray[0].offset().top – 50).

And it seems to work great!  The array holds all errors- we can then scroll directly to whatever one is first in that array.  The project is about a week away from being done- so probably only one or two more entries on this.  Next week- the process of inserting ‘live’ checks, so a user can get real time feedback on fields that initially gave an error, but may have been fixed.  It was an interesting balance of enough feedback to let them know that ‘this field is now good to go’ with ‘stop giving me an update every time I type a damn key’.  Hopefully we got it right.

Radio Check

Big(ish) victory over the radio option field type this week.  Still working on implementing legitimate validation checks for our custom request forms feature.  In the current process, a user’s submission is checked via a complicated process- php code ‘prints’ out javascript functions, so that it can use a variable snagged from the database to see if that field is required.  Seems to work, but it also seems to have 2 major drawbacks:

1) Only works with alert boxes- if we get much more complicated with it, it all breaks down
2) It doesn’t really check for valid forms.

#2 means that it checks a very basic form, but admins can create very complex forms.  They might have 4 non-required type=text fields, 2 required type=text fields, a required radio fieldset, a non-required checkbox set, and so on.  The current validation really only checks one level- if there’s a required field of a certain type, and there’s an entry in a required field of a certain type, it returns true.

But what if there are two required fields of the same type?  That’s where it gets tricky.  Seems to be ok on type=text, but with others (radio, checkbox, select box), it will return true if only one (of possibly many) fields is actually filled out.

So it’s been a bit of an ordeal to figure out.  First, we check if the field exists and contains a required property.  Then, we can use jquery to get a jq object of that field, and do whatever we need to do (in this case, turn the outline red and show the error div for that field).  Instead of printing javascript functions in order to have access to php to get variables from the database, we inserted a simple, tiny bit of php into each html element on the form:
<?php print ${$required_prop} ?>
That will print ‘required’ if the database tells us the admin has set that field as required, or nothing if not.  Then, we inserted the same php into the class definition of the parent element (for checkboxes and radio groups, a wrapper div)- that way we can grab it and outline the whole group if an error is returned.

Seems to be working well, but still a lot of testing to go.

Check that box

The checkbox field type on our custom request forms feature is acting up.  And by ‘acting up’ I mean ‘a major part of the advertised functionality doesn’t work at all’.  Acting up sounds better.

When an admin is setting up their form, they can choose the field type, add a label, and choose if it should be a required field to submit the form.  The checkbox type wasn’t recognizing the required tag- end users could just submit the form without choosing a checkbox.

Easy fix, right- just check for input[type=checkbox]:checked.length (I know that doesn’t work as typed, don’t worry- just shorthand).  If it === 0, return false.  But there were a couple complications.  Besides my own incompetence, for once.

The feature was coded back in 2003 and is a mixup of php and js- with the js validation checks being generated by (and depending on variables pulled from a database by), quite a bit of php code.  The other main issue is that there’s a different checkbox-driven field type admins can add- a ‘copy self on form’ option.  We didn’t want to include that with the validation on a required checkbox field, as it’s technically a different type.

As usual, I’m sure my answer wasn’t the best.  Or the prettiest.  But it seems to work (and I’ll try to pretty it up a bit before release).  We use the php variable (pulled from the db) to set the ‘required’ property on the field (php print the result of a conditional on the variable- if required, $required = ‘required’, else, $required = ”).  Then, we use the same php variable to add a class to the element’s label.  That way, I can use js to check if the element has the ‘required’ class.  If so, we do the :checked.length check.  That way, we’re only checking the correct set of checkboxes.

A roundabout way to do a simple task, but when you don’t know the fields that the form will include, it becomes a bit more complex.  Now let’s make it pretty…

Good Form

While working on a side project (a wedding site for a friend), I ran into an issue.  Bootstrap’s modal feature is awesome- super easy to set up- and I used it as my ‘contact’ link.  A user can click the contact button, a modal fades in with the form, they submit, and we’re good to go.

Worked great on most pages, but on a couple, I had other forms.  One is the guestbook (html form that sends to a php/mysql driven database to store/display comments).  The other is the rsvp form (hijacked Google doc form- submission inserts data directly into Google doc they’re using to track guest info.  I think my confusion started when I decided to ajax the forms in (so I could do some cool display stuff post-submission and stay on the same page).

Long story short- when I submitted the contact form, I could see the rsvp or guestbook jquery effect events firing in the background (on the main page).  I’d ‘prevent defaulted’ myself into trouble.

Of course, the answer was simple (though not simple to find).  I was calling to both forms by the basic ‘form’ tag instead of using ids for each form.  As soon as I switched my jquery function to grab each form individually by id, everything worked great.

Now if only I could get my email server to take less than 20 minutes to deliver the contact form, I’d be good to go!