Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a displayField property to the relation widget #594

Closed

Conversation

medfreeman
Copy link

@medfreeman medfreeman commented Sep 12, 2017

- Summary

closes #591

- Test plan

Actually there's no tests for widgets ? should i make some anyway ?

- Description for the changelog

Add a displayField property to the relation widget, that allows displaying a different field that the linked valueField to the user.

- A picture of a cute animal (not mandatory but encouraged)

Cutie pie

@medfreeman medfreeman changed the title Relation widget display field Add a displayField property to the relation widget Sep 12, 2017
const searchFields = [...new Set(
[
...field.get('searchFields').toJS(),
field.get('valueField'),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain the decision to move to a Set and to pass in the value field?

Copy link
Author

@medfreeman medfreeman Sep 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The move to a set (casted to an array) is just a way to ensure unique values in the array, since searchFields could contain valueField.

The actual initial search (prior to my mods) is to find a search match on the stored value.
Is its purpose to preserve relations when the target field has changed a bit ?

i.e. I change my page collection item title from "Job offers" to "Job listings".
A menu collection item that has a relation set to the "Job offers" page title field has a now a broken relation.
When i go to edit the menu, the initial search is performed and let's say an unique match is made on "Job listings" (probably because it's the only page containing the word "Job"). The relation value field will be automatically set to "Job Listings".
This behavior is not really ideal, since in this case the relation entry shows an automagically fixed relation, that is not even correct until saved, and it is really misleading.
I hope i make sense on this.

I think this behavior could be changed to only perform the search in valueField, and get the exact match needed to get the displayValue.
I really think that the main use cases of relations should be implemented by linking to a unique constant field per item, or face broken relations, and that broken relations should not be automatically corrected.

This code was just a mix of both approaches, getting the displayValue on an exact match while preserving the old behavior on a partial match.
Do you think we should keep the actual behavior ?
Or that i should change this code to

const searchFields =  [ field.get('valueField') ];

to only get the initial displayValue and be done with it ?

return (
<div>
<input {...otherInputProps} value={displayValue} />
<input type="hidden" id={id} value={value} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need some explanation on this too.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The single input field was replaced by two input fields.

The first is the visible one, displaying the displayValue to the user. {...otherInputProps} is needed to preserve the field accessibility.

The second stores the value, in order for it to be saved.

@erquhart
Copy link
Contributor

erquhart commented Sep 15, 2017

@medfreeman just took a look - some of the changes made straightforward code a bit less straightforward, and the purpose wasn't clear when skimming. In those cases we try to use source comments for clarity. Mind adding those?

@medfreeman
Copy link
Author

Sure, i'll add comments. I didn't see so much use of comments througout the codebase, so i restrained, but it's never a bad thing imo.

@erquhart
Copy link
Contributor

Yeah, comments are certainly lacking throughout, but I've been working to change that. The editor came with a ton of comments, for example.

const suggestion = nextProps.queryHits.get(this.controlID);
if (suggestion && suggestion.length === 1) {
const val = this.getSuggestionValue(suggestion[0]);
this.props.onChange(val, { [nextProps.field.get('collection')]: { [val]: suggestion[0].data } });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems pretty intentional, do we know what purpose it was serving?

@@ -71,6 +71,7 @@ Property | Accepted Values | Description
`collection` | string | name of the collection being referenced
`searchFields` | list | one or more names of fields in the referenced colleciton to search for the typed value
`valueField` | string | name a field from the referenced collection whose value will be stored for the relation
`displayField` | string | name a field from the referenced collection whose value will be displayed to the user for the relation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prepend with:

optional, ...

Append:

..., defaults to match `valueField`

@@ -68,6 +68,7 @@ collections: # A list of collections the CMS should be able to edit
collection: "posts"
searchFields: ["title", "body"]
valueField: "title"
displayField: "title"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

displayField should default to value of valueField so that existing implementations don't break. These examples changes can then be removed.

import { connect } from 'react-redux';
import { debounce } from 'lodash';
import { Loader } from '../../components/UI/index';
import { query, clearSearch } from '../../actions/search';


function escapeRegexCharacters(str) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch :)

this.props.onChange(val, { [nextProps.field.get('collection')]: { [val]: suggestion[0].data } });
// store query results
const matches = nextProps.queryHits.get(this.controlID);
// if there is only one item found
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We haven't officially set a code style guide, but I do want to keep comments looking proper. Please update the comments to follow Airbnb's comment guidelines, which I've also been loosely following (exception being that I use the multi-line style for all comments, but that isn't required).

return (
<div>
<input {...otherInputProps} value={displayValue} />
<input type="hidden" id={id} value={value} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still not understanding what this guy is doing. Can you clarify? Makes it seem like the forID prop value is getting real responsibility here, and I'm concerned it won't hold up, e.g. when nested.

@erquhart
Copy link
Contributor

Closing due to lack of activity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow displaying a different field that the linked valueField in Relation widget
2 participants