jsoneditor icon indicating copy to clipboard operation
jsoneditor copied to clipboard

On finish edit a field

Open dougn7 opened this issue 6 years ago • 14 comments

Its not a issue, its more a sugestion: Should be interesting have a callback function when a field finishes a edition (its text changed or a checkbox updated the field content), onFinishEdit, or something like that..

dougn7 avatar Feb 06 '19 20:02 dougn7

Thanks for your suggestion @dougn7. Just curious, can you explain your use case where you need this?

Maybe we can extend onEvent which currently only supports click events with a new type blur.

josdejong avatar Feb 09 '19 12:02 josdejong

Sorry for not answer you before.. Well, usually Json Editor has callbacks for every update, like a char insertion. This new callback should be a after enter all content, after a 'Enter' input or blur off that sinalizes the end of it. • Another addition shoud be a option to finalizes the field edition with a 'Enter' key input, not just a blur off.

dougn7 avatar Feb 20 '19 15:02 dougn7

Maybe the current onChange and onChangeJSON events should simply fire on blur of a field that is edited?

Can you explain what is the reason why you are concerned about this, why you would want an "Enter" input? What is you use case?

josdejong avatar Feb 20 '19 19:02 josdejong

"Maybe the current onChange and onChangeJSON events should simply fire on blur of a field that is edited?" - Yes. I did this way: element.find( '.jsoneditor .jsoneditor-value' ).on( 'focusout', function(){ verifyChange() }) If instead of doing all this, including filtering by classes, defining a 'onFinishEdit' could solve it with less code. 'Enter' input could be a option. While you typing, and want to go to the next field for edition, just pressing 'enter' finish current and jump to next field.

dougn7 avatar Feb 20 '19 20:02 dougn7

So I think we have two ideas here:

  1. Go to the next value by pressing Enter, the same as Alt+Arrow down currently does. I was thinking about it and I like the idea. Currently, pressing enter will in the end result in a \n being added to your code but I don't think this is a common case.
  2. The onChange event currently doesn't fire when jumping to the next field or leaving a field (ie. on blur/focusout of a changed field), you get (in the worst case) a change event 150ms after the last change. It's quite easy to implement triggering onChange when leaving a changed field.

Would that address your concern?

josdejong avatar Feb 23 '19 14:02 josdejong

  1. I didn't know that it works that way. Usually, on Excell for example, you have to press Alt+Enter (I think) for a new line.
  2. Ok, I understand. I did the way I told you. Thanks a lot for the reply!

dougn7 avatar Feb 23 '19 15:02 dougn7

as the focused element changes while using jsoneditor in the most general way I had to track it in order to attach the focusout event.

let onValueChangedByUserCallback = function() {

  document.activeElement.focusout = function() {
    myCustomReaction()
  }
};

var options = {
        enableTransform: false,
        modes: ['code', 'tree', 'text', 'view'],
        onChange: onValueChangedByUserCallback,
      };

any thoughts on this? The infamous _ onFinishEdit_ event would simplify...

masciugo avatar Apr 10 '19 15:04 masciugo

I'm very curious about this issue. I want to send the new JSON object somewhere when I've edited a "contenteditable" element, but when I pinpoint elements with that attribute, attach a listener for the 'blur' event and apply some logic, it doesn't actually seem to do anything. I actually attached my listener to the container, so the editor. I don't think that's the problem though.

Is there a way to achieve this logic with the current state of this project? Here is a step by step:

  • Click on a field
  • Change the data
  • Focus out of that field
  • On focusing out; send the new data (the whole JSON) somewhere

tomkcey avatar Jun 18 '19 21:06 tomkcey

Thanks for your input Thomas, your explanation exactly pinpoints what we would like to have: full control over the changes.

The issue however is only in that the onChange has a delay before firing. You can just to listen to focus out, and on focusout, call editor.get(). This will return the latest, updated version of the JSON. 150ms later, the onChange event will fire with the same update, but you could simply ignore that.

If you want, you can test the behavior more easily by changing the delay in the onChange:

// change the delay in onChange to 2 seconds
Object.getPrototypeOf(editor.node).DEBOUNCE_INTERVAL = 2000 // default is 150 ms

// reload the editor contents to apply the new debounce interval
editor.set(editor.get())

josdejong avatar Jun 22 '19 08:06 josdejong

Actually, validating the event.type equals 'blur' in the onEvent wrapper works perfectly. So, I was able to find a solution to this specific problem.

tomkcey avatar Jun 23 '19 00:06 tomkcey

:+1:

josdejong avatar Jun 23 '19 06:06 josdejong

I am trying to do this with Typescript and it seems that the onEvent callback's event parameter type is defined as string instead of a generic Event. I created an issue @DefinatelyTyped Thank you!

Amiryy avatar Oct 15 '19 15:10 Amiryy

For reference: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/39147

josdejong avatar Oct 15 '19 19:10 josdejong

Sorry for reviving an ancient issue. Hope it's useful.

Here's how I achieved 'on finish edit':

handleEvent({value}, event) {
  if (
    (typeof value === 'boolean' && event.type === 'click') ||
    (['string', 'number'].includes(typeof value) && event.type === 'blur')
  ) {
    this.handleEditorChange(); // app logic here
  }
}

this.jsonEditor = new JSONEditor(this.jsoneditor.current, {
  onEvent: this.handleEvent,
  colorPicker: true,
  onColorPicker: (parent, color, onChange) => {
    ReactDOM.render(
      <div className="absolute right-[-2px]">
        <SketchPicker
          color={color}
          onChange={(c) => {
            this.handleEditorChange();
            return onChange(c.hex);
          }}
        />
      </div>,
      parent
    );
  },
  mode: 'form',
});

So this would fire on:

  • clicking on the checkbox
  • picking a color
  • blurring text input

But just entering a character into a text field would not fire the event. Would be great if there was an event that does all that. Seems like a basic need.

BTW this code is not perfect - the color picker has intermittent funny behavior.

dmt0 avatar Jul 30 '23 01:07 dmt0