html-forms
html-forms copied to clipboard
[WIP] - Add 'data-select-if' feature
This is a WIP.
Regular fields like text field already allow for setting a default value based on the URL parameters / user settings etc, but the dropdown and check/radio options don't have such ability.
Right now I'm in need of a way to pass a param in the URL and auto-select one of the options in the dropdown.
To resolve this I was thinking of adding a data-select-if
conditional attribute for the dropdown, and similar data-check-if
for the radio and input fields. It works very similar to the conditional fields, but besides being able to set conditions based on the other fields, you can also pass the {{url_params.plugin}}
template variable.
The data-select-if
fully works now, the data-check-if
will be build in if you think this is a useful feature for the plugin and will be merged 😄
Setup:
<select class="form-control" name="I_HAVE" required>
<option data-select-if="{{url_params.type}}:purchased">Purchased</option>
<option data-select-if="{{url_params.type}}:presale">A pre-sale question</option>
</select>
Hey @JeroenSormani,
Can you submit this PR with the changes in /assets/browserify
subdirectory instead of in the /assets/js
dir?
I should probably stop committing the compiled assets but I like having a downloadable plugin on GitHub at all times. 🤷♀️ 😉
Sure, was just a concept to get your thoughts anyways ;-) (plus I hadn't look into the whole browserify setup)
If you think this will be a good addition to the HF Core I'll move things to the proper files / finalize it for the other fields too.
@JeroenSormani Definitely think this should be in HF somehow, but not yet sure about the exact implementation details.
Having multiple data-select-if
(one for each <option>
element) seems a little redundant at first, but I think it also probably is the most flexible approach, allowing for multiple values and dependency on other fields. I will have to play with this to know for sure!
Made the changes in the browserify/conditional-elements.js
file.
This now also includes the data-check-if
attribute for the radio/check fields.
I did end up separating those in separate functions etc. Could also be in one, but I found no good unibody way for check-select that works on all three field types. This seemed the simplest way to keep things as simple/clearly as possible.
Form for testing:
<p>
<label>Your name</label>
<input type="text" name="NAME" placeholder="Your name" required value="{{user.first_name}}"/>
</p>
<p>
<label>Your email</label>
<input type="email" name="EMAIL" placeholder="Your email" required value="{{ user.email }}" />
</p>
<p>
<label>
<input type="checkbox" name="[]" value="One" data-check-if="{{url_params.check}}:yes" /> <span>One</span>
</label>
<label>
<input type="checkbox" name="[]" value="Two" data-check-if="EMAIL" /> <span>Two</span>
</label>
</p>
<p>
<label>Phonetic</label>
<label>
<input type="radio" name="PHONETIC" value="Alpha" data-check-if="{{url_params.phonetic}}:alpha" /> <span>Alpha</span>
</label>
<label>
<input type="radio" name="PHONETIC" value="Beta" data-check-if="{{url_params.phonetic}}:beta" /> <span>Beta</span>
</label>
<label>
<input type="radio" name="PHONETIC" value="Charlie" data-check-if="{{url_params.phonetic}}:charlie" /> <span>Charlie</span>
</label>
</p>
<p>
<label>Numbers</label>
<select name="NUMBERS">
<option data-select-if="{{url_params.number}}:one">One</option>
<option data-select-if="{{url_params.number}}:two">Two</option>
<option data-select-if="{{url_params.number}}:three">three</option>
</select>
</p>
<p>
<input type="submit" value="Send" />
</p>
Params for sampling: ?number=three&phonetic=beta&numbers=two&check=yes
@dannyvankooten ping!
Did you have a chance to look into this / get some further thoughts?
Hey Jeroen!
I'm not quite ready to merge this as I am not entirely sold on the logic just yet. My gripe is that this relies on the PHP template tags but then outputs a static conditional string (eg one:one
) whereas the Conditional Elements component uses a field name as the first parameter.
So while this adds two more special data-if
attributes to remember and support indefinitely, it also works differently from the other data-if
attributes already present in the plugin.
I do see how something like this would be useful though, so to get closer to the actual end result I've committed d655cc11914986215cbae287e218c05174394c13 which allows you to pre-fill form elements from URL parameters directly.
For example, visiting ?NUMBERS=One
would pre-select that option for you, based on your example HTML earlier on this page.
Gotcha. It indeed outputs a static string depending on the form configuration / current URL params. With my code its also possible to use a field name as the first param if wanted, just doesn't rely on it as its sole source as I don't think those are the only use cases.
Would it make more sense to you if we sync the data-if
tag to also support the template tags (just strings) as a conditional key? I'm also thinking of use cases for example where fields can appear for users with meta {user.meta.continent}:EU
or user role {user.role}:gold-member
.
Now I don't have a use case myself for that.. but may be interesting for flexibility.
Your commit would work for my use case, so I can't really complain on that part. Would the edge case need to be considered where a URL param is set that was not intended to be filled?
Would it make more sense to you if we sync the data-if tag to also support the template tags (just strings) as a conditional key? I'm also thinking of use cases for example where fields can appear for users with meta {user.meta.continent}:EU or user role {user.role}:gold-member. Now I don't have a use case myself for that.. but may be interesting for flexibility.
Hmm, that may be nice. Perhaps we'd be better off slightly changing the format if we were to do this but it would indeed allow for some cool stuff based on data coming from the server. Perhaps prefixing field name identifiers with field:
or something... Not sure, just thinking out loud.
<div data-show-if="field:NAME:Danny">
:thinking: It is more verbose, but does make things look a little more complex... We could always check for field name existence first and if there is no such field, treat it as a static string but I'm afraid we may end up regretting that.
Would the edge case need to be considered where a URL param is set that was not intended to be filled?
Yeah, I wondered about that too. Thought about making this optional or turning it off by default, but then I figured it would perhaps be easier to leave it on by convention and tell users to use more unique field names if this happens where they don't want it to. Will have to see how this holds up once it's out there...
I agree that adding a field:
prefix would probably be a decision to be regretted.
In my code I've allowed for field values / the server values by checking if the field exists first and take that value if it does; https://github.com/ibericode/html-forms/pull/29/files#diff-443a517b39b7e9578a9e2a4a24689ca5R88
Not 100% foolproof though as in the edge case of a template tag that would output a string that is the same as a form field name it would conflict.
Maybe a data-if=
and a data-if-field=
? Not ideal but foolproof and without the increased complexity of checking for attribute contents.
Yeah, I wondered about that too. Thought about making this optional or turning it off by default, but then I figured it would perhaps be easier to leave it on by convention and tell users to use more unique field names if this happens where they don't want it to. Will have to see how this holds up once it's out there...
One of the things I love about HF is the simplicity of all things. Keeping the settings to the bare minimum is one of the things that comes to mind immediately (probably also why I didn't prefer the form submission thing as a settings 😅). What you've decided sounds like the better call indeed.