Little Johnny Angular Has Trouble Focusing in Class

Short post this week, but working on a longer one in the next couple weeks regarding Google’s new Puppeteer project.  Spoiler- I think it’s pretty cool.

I have worked with latest generation angular for a couple years now.  It’s generally great, occasionally frustrating, and often interesting.  However, until this past week, I hadn’t really had a need to work with directives.  Specifically, attribute directives, but it turns out they can be very useful!

The challenge: I was creating a search feature for a new website.  I had the actual search function working well (and the data being searched over was small enough to include in an in-memory JSON structure, so it’s a nice and fast search as you type setup).  All that was left was to put a UI on this thing.  I put together a nice full screen display with large input element that fires the search function as a user types.  It will show/hide based on an ngIf conditional.  All simple enough in Angular land- and something we do all the time (by the way, I also tried this with the [hidden] element attribute, but ran into the same difficulty below).

So, click the search icon, the background fades in and search input slides down.  The user can search and results pop right up.  All great- but the input field autofocus was not cooperating.  It would fire properly the very first time ngIf became true, but never again after that.  If a user closed the search display, then opened again for another search, no autofocus.

Not a huge deal- but an inconvenience for users, and something that I should be able to make work.  It makes sense- the built in autofocus attribute was probably only ever designed to fire on a page load- but that only happens once (ideally) with an angular application.  I tried firing a .focus() event in my controller, but it didn’t seem to have any effect.

The answer was a directive.  Specifically, an attribute directive.  Directives were all over angular V1, but in latest generation, you can usually get away with just having components and services.  In this case, I could just make a super simple directive that grabs a reference to the element (the angular way!) and fires the .focus() in the right lifecycle hook (some references said it would work in onInit, but I had to use afterViewInit).

Boom- the search input element gets focused every time the search display opens!

 

Advertisements

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!

 

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…