Dear ACF and JS developers,
Work on our upcoming version 5.7 is now entering it's final stages! If you are not yet up to speed on the new changes, please read our ACF PRO 5.7.0 – New Architecture for New Features blog post.
Whilst we tidy up the remaining bugs, testing, beta releases and documentation, we would love to get your opinions, feedback and help in reviewing our JS library.
At the center of this library is the acf.Field
class. This is what will be used the most by conditional logic, 3rd party developers and other core logic when interacting with a field.
Example
For example, you can find a field on the screen like so:
var field = acf.getField('field_123456');
You can then get it's value like so:
var val = field.val();
This is all pretty basic stuff, but each field type requires different logic due to it's unique Markup and functionality. What we have tried to do is break down these actions into easy to customize functions allowing for rapid development.
Breaking down .val()
For example, the val()
function is broken down into getValue()
and setValue()
depending on if a value parameter is defined.
These functions call getInput()
to find the field's "jQuery input element" and return it's jQuery .val()
.
This means that when creating the Select field type, all we needed to do for all conditional logic support was define the getInput()
function to look like this:
var Field = acf.Field.extend({
type: 'select',
getInput: function(){
return this.$('select');
},
// ...
});
acf.registerFieldType( Field );
The BIG question
We are quite happy with the acf.Field
class in terms of its usability and functionality, but are still not 100% sure we nailed the naming conventions.
For now, lets focus on the getInput()
function, but keep in mind that each field has other elements too which need to be 'standardized'. This includes the:
- Label wrap: "> .acf-label"
- Input wrap: "> .acf-input"
- input control: ".acf-repeater:first" or ".acf-date-picker"
To help decide, we have put together some choices. Each have their own pros and cons. We have tested them all, and the performance between them are almost the same, so we are more interested in "what is the current standard" or "what is best for our developers".
Idea 1. Store on initialization
Each field is initialized once (either on page load or when the HTML is newly appended). This is used to initialize field specific functionality such as .sortable()
or .datepicker()
.
During initialization, we currently set the field jQuery object to the field.$el
property. It would be easy enough to also set the $input, $control and any other $elements.
The field object would then look like so:
var field = {
$el: jQueryElement,
$input: jQueryElement,
$control: jQueryElement,
// ...
}
The upside to this, is that all jQuery elements are distinctly found with the prefix '$' which would help "console log debugging". For example, field.search = function(){};
and field.$search = jQueryElement;
The downside is this will add unnecessary "jQuery searching" during initialization to find elements.
Idea 2. Stick with getElement
As we currently have it, elements are found using get
prefixed functions.
The field object looks like so:
var field = {
$el: jQueryElement,
getInput: function(){ return jQueryElement; },
getControl: function(){ return jQueryElement; },
// ...
}
The upside of this is that during initialization, there is no unnecessary "jQuery searching".
The downside is that without documentation, it is not clear these functions return jQuery elements.
For example, field.getValue()
returns the field's value, but and field.getInput()
returns a jQuery element.
Idea 3. A mixture of both
We have also tried a version that mixes both ideas together and looks like so:
var field = {
$el: jQueryElement,
$input: function( return jQueryElement; ),
$control: function( return jQueryElement; ),
// ...
}
The upside of this is that these functions are easy to identify as jQuery element functions. You would use them like so:
field.$control().addClass('has-value')
;
Idea 4. Find
Throughout the new JS library, we have used the prefix "find" when returning jQuery elements, and "get" when returning native JS types. For example:
// returns a collection of jQuery field elements
var $fields = acf.findFields();
// returns an array of `acf.Field` instances.
var fields = acf.getFields();
Following in these footsteps we could use the same principles like so:
var field = {
$el: jQueryElement,
findInput: function(){ return jQueryElement; },
findControl: function(){ return jQueryElement; },
// ...
}
The upside to this is a much more coherent JS library.
How to contribute
Please leave your comments below, we would love to hear from you. Please remember to be diplomatic and helpful in our conversation. Everyone is entitled to their own opinion, and we are looking for positive ideas, suggestions and feedback.
Thanks
Elliot