Typing into a field should offer what you have already recorded: company, location, found via #261
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Postulo/postulo#261
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Adding an application asks for a company by name, and the box is empty every time. Type
Acmetoday andAcme Ltdnext month and there are two employers, two sets of postings,two rows in the companies table, and a funnel that quietly counts them apart.
The three fields on the intake form that are typed every single time —
company_name,locationandsource("Found via") — offer nothing at all(
applications/forms.py:43,46,57). They are plainCharFields.This is not only convenience
get_or_create_companymatches onname__iexact, and its docstring says exactly what thatis for: "Matching loosely on the way in avoids ending up with 'Acme', 'acme' and 'ACME' as
three separate employers after a few weeks of typing."
Case folding catches the variation it was written for and nothing else.
Acme Ltd,ACME Inc.,Acme GmbHand a trailing space with a different spelling all create a newemployer, silently, at the moment somebody is busy doing something else. A suggestion list
is the other half of that defence and the better half, because it works before the
record exists rather than trying to reconcile two afterwards.
"Found via" is the same argument with a shorter list. Everybody has four or five answers —
a job board, a friend, the company's own page — and types them out in full, differently,
forever.
Do it with
<datalist>firstThis project already does this twice and the pattern is settled: a text input carrying
attrs={"list": "…-suggestions", "autocomplete": "off"}and a<datalist>beside it —industries on the company form (
jobs/forms.py:69) and departments on the contact form(
jobs/forms.py:420). The same shape, with the options coming from this person's ownrecords instead of a fixed vocabulary, covers everything asked for here.
Three reasons it should be the first attempt rather than a hand-rolled typeahead:
most often got wrong —
aria-expanded,aria-activedescendant, a listbox relationship,arrow keys, a touch keyboard, and all of it again in RTL. A
<datalist>has that fromthe platform, in every language Postulo ships.
app.jsbuilds one dynamically for the labels chips, soeven the scripted case has prior art.
A live endpoint becomes necessary when somebody has enough companies that rendering them
all is silly. That threshold should be measured rather than assumed — a few hundred
names is a few kilobytes — and when it arrives,
core:searchand the ninja API are bothalready there to build on.
What must not go wrong
classic shape of an isolation leak: a suggestion endpoint where typing
ahands backevery company on the instance. Everything here must go through
for_user, and if a liveendpoint is built it belongs in the isolation sweep #232 already asks for.
company_nameis free text deliberately: acompany you have never recorded is exactly what a new application usually is. The field
stays a text box that happens to suggest — not a select, not a validation error.
Acme LtdwhileAcmeexists, the honest answer is to ask which they meant. That is a different changefrom offering a list, it carries the risk of merging two employers that really are
separate subsidiaries, and it should be decided on its own rather than smuggled in here.
Where it pays
Company, location and "Found via" on the intake form; the same company field on the capture
review, which #179 built keys for because it is worked through forty times in a row, and
which therefore gains the most; contact names where a person is attached to an application.
Industries and departments already have theirs.
#262 proposes adopting Basecoat as the component vocabulary, which brings a Combobox and a Command component with it. It does not override the decision here: the argument for
<datalist>— no script, and the browser supplyingaria-expanded,aria-activedescendant, arrow keys, the touch keyboard and RTL — does not stop applying because a library offers the widget. Recorded on both sides so neither is quietly contradicted later.