Skip to content
This repository has been archived by the owner on Feb 7, 2022. It is now read-only.

editable fields #3

Open
ksmth opened this issue May 26, 2015 · 13 comments
Open

editable fields #3

ksmth opened this issue May 26, 2015 · 13 comments

Comments

@ksmth
Copy link

ksmth commented May 26, 2015

hey, thanks for developing the component :)

my app needs to to display, search and modify json object. do you have anything planned for this? if not, would you accept a proper pull request including such a feature?

@Lapple
Copy link
Owner

Lapple commented May 26, 2015

Hello, there is already something in place that might help you: each key and primitive property renders a hidden input that could become visible once that block is focused – much like it's done in Chrome DevTools:

Editable fields

To enable that, add the following to your CSS:

.json-inspector__selection {
    display: block;
    position: absolute;
    top: 0;
    left: -3px;
    right: 0;
    z-index: 1;
    padding: 0 3px;

    font: 11px/1 Menlo, Consolas, monospace;
    outline: none;
    border: none;
    opacity: 0;
    box-shadow: 3px 3px 4px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(0, 0, 0, 0.3);
    color: #222;
}

.json-inspector__selection:focus {
    opacity: 1;
}

The component is located in lib/selection.js, for now it's a readonly input. I believe, it could be extended to handle modification (i.e. save on Enter, discard on blur). On the other hand, we could allow for this sort of extended functionality to be passed as an option to the whole inspector component – much like it's already done for searchBar component. What do you think?

@ksmth
Copy link
Author

ksmth commented May 26, 2015

I'd really like to have the same behavior as the dev tools, esp. the response to tabs. I'm certain, you're familiar, but just to be explicit and on the same page:

{
  attr : 'val',
  attr2 : 'val2'
}

attr is focused / editable. [tab] and now val is editable. another three tabs would create a new key / value pair.

Regarding the read / write, I think it'd be a good idea to not modify the data by default. Similar to how React handles the input values with it's controlled component concept:

<Inspector data={this.state.data} onCommit={this.handleCommit} />
handleCommit(keyPath, value)

You could also enable "in place" editing:

<Inspector defaultData={this.state.data} />

That'd copy the provided JSON object and then modify that directly.

@Lapple
Copy link
Owner

Lapple commented May 28, 2015

I agree, working tabs would be really nice, need to figure out cheaper solution to that.

Also agree that component should not modify the original data itself, it's better done through intent callbacks, like onCommit. What I'm thinking more about is that we can keep the component less sophisticated if the edition feature is externalised. Imagine that you create your own implementation of Selection component that would accept onCommit callback. Then you compose it with Inspector component and along with that have a parent component that would control both:

// editor.js
// ...
render: function() {
    var data = this._getData(); // gets either the original data or the modified one

    // FIXME: Figure out a good name for the prop name, callback name and the passed component.
    var inputComponent = <CustomInput onSubmit={ this._onCommit } />
    return <Inspector data={data} selection={ inputComponent } />
},
_onCommit: function(keypath, changedValue) {
    this._setData(
        applyPatch(this._getData(), keypath, changedValue)
    );
}

As for naming, we can call this component labelInput, sorry this is best I could come up with.

@ksmth
Copy link
Author

ksmth commented May 28, 2015

Ok, I think I get your approach and I think that'd also enable all kinds of cool editor fields - any custom element, which is really nice. So whenever a field gets focus, this component will get rendered, receive a value as a prop and then when the editing is done, its onSubmit will be called. Sounds very good to me. 👍

@Lapple
Copy link
Owner

Lapple commented Jun 4, 2015

Added interactiveLabel option in e299f38, pass in component factory that would receive value prop. Released as 5.0.0.

@Lapple
Copy link
Owner

Lapple commented Jun 6, 2015

I completely overlooked the fact that I wasn't passing current keypath or any other relevant information to the interactive label. Since 682c7ed it now receives:

  • value, either stringified property value or key value that is being interacted with,
  • originalValue, either the original property value or key value,
  • isKey, boolean flag to differentiate between interacting with keys or properties,
  • keypath, keypath of the node being interacted with, will be the same for keys and properties

Hope it will help better. Released as 5.0.2.

@ksmth
Copy link
Author

ksmth commented Jun 6, 2015

How is it intended to be used in the above use case? Right now the inputs are always shown when the factory is provided. The onClick handler on the Inspector can't cancel the expansion of a node, so implementing a handler for that is currently not an option.

I suppose you're aware of the fact, that you can't add any new properties to object right now, but I still wanted to mention it, just in case. :)

Thanks for the work so far!

@Lapple
Copy link
Owner

Lapple commented Jun 6, 2015

The way I used it before was rendering an invisible, yet focusable input, and revealing it when focused. Check if it works for your case.

As for adding new keys, do you want to mimic the Chrome DevTools interaction (double-click on empty area, Enter or Tab from last available field) or have explicit visual control, e.g. 'Add key' button?

@ksmth
Copy link
Author

ksmth commented Jun 6, 2015

How would they gain focus? The labels wrapping the inputs are targeted at the radios and tabbing through the whole application to eventually focus one of the fields is not really all that user friendly.

For adding new keys I'm fine with either.

@Lapple
Copy link
Owner

Lapple commented Jun 6, 2015

I have just put -1 tab index to those radios and pushed a small example on how those inputs can be revealed, (there's some necessary styling): either tab through or click on any field you want to edit. Let me know if I misunderstood something 😄

@ksmth
Copy link
Author

ksmth commented Jun 6, 2015

Ahhh, no - you understood perfectly, it was me who was a little bit slow. ☺️ Thank you for the example, I'm up and running now.

@Lapple
Copy link
Owner

Lapple commented Jun 8, 2015

Hi, there was a bug when updating a property value would not rerender the corresponding node, it's fixed in 5.0.3. Just thinking that this bug could affect the feature you are working on.

@antilect
Copy link

Beautiful!

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

No branches or pull requests

3 participants