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

Old metabox handling and JS updating text fields #3975

Closed
maxxwv opened this issue Dec 13, 2017 · 14 comments · Fixed by #4184
Closed

Old metabox handling and JS updating text fields #3975

maxxwv opened this issue Dec 13, 2017 · 14 comments · Fixed by #4184
Labels
[Feature] Meta Boxes A draggable box shown on the post editing screen

Comments

@maxxwv
Copy link

maxxwv commented Dec 13, 2017

Issue Overview

When inserting a value via JavaScript into a text field in a form in the editor-meta-boxes-area div in Gutenberg doesn't trigger the changedMetaBoxState() function to mark the metabox-contained data dirty.

In this instance, I've created a gallery CPT - a meta box contains thumbnails of any previously selected images, add/edit/remove buttons, and a hidden field that contains a json-encoded string of selected image IDs. I use the wp.media.frames.file_frame update event to update the content of the hidden field with the IDs of the selected images. However, isDirty is not set to true when the value is updated. If I type directly into the field, the value of isDirty is updated as expected.

Steps to Reproduce (for bugs)

  1. Create a metabox (old-school style) with a text field.
  2. Update the value of the field via JavaScript.

Expected Behavior

isDirty is set to true and the value of the field is saved on Update.

Current Behavior

Nothing. IsDirty is not set to true and the editor doesn't know it needs to save the metabox data. Again, if you type directly into the field everything works as expected.

@maxxwv maxxwv changed the title Old metabox handling and hidden fields Old metabox handling and JS updating text fields Dec 13, 2017
@youknowriad
Copy link
Contributor

When inserting a value via JavaScript into a text field in a form in the editor-meta-boxes-area div in Gutenberg doesn't trigger the changedMetaBoxState() function to mark the metabox-contained data dirty.

Well we do call changedMetaBoxState on form change, we'll have to figure out why it's not being called in this case, might be related to the fact that it's a hidden field. Are you using ACF gallery or something else?

@youknowriad youknowriad added the [Feature] Meta Boxes A draggable box shown on the post editing screen label Dec 13, 2017
@maxxwv
Copy link
Author

maxxwv commented Dec 13, 2017

I had the same thought about it being a hidden field, so I've changed the field type from hidden to text for testing and it's still not updating for some reason.

It's a custom gallery plugin I wrote. Nothing more special than jQuery - not even using es6 syntax. The update event handler is this:

f.on('update', function(){
		resetUploadForm($, previewArea);
		var attachments = f.state().get('library');

		var ids = [];
		for(var i=0; i < attachments.length; i++){
			var img = new Image(attachments.models[i].attributes.sizes.thumbnail.height, attachments.models[i].attributes.sizes.thumbnail.width);
			img.src = attachments.models[i].attributes.sizes.thumbnail.url;
			img.alt = attachments.models[i].attributes.alt;
			img.title = attachments.models[i].attributes.title;
			img.dataset.id = attachments.models[i].attributes.id;
			img.style.padding = ".5rem";
			previewArea.append(img);
			ids.push(attachments.models[i].attributes.id);
		}

		$('#myGalleryImageIDs').val(JSON.stringify(ids));		

		$('#myImgEdit').removeClass('hidden');
		$('#myImgRemoveAll').removeClass('hidden');
		$('#myImgSelect').addClass('hidden');
	});

f is a wp.media.frames.file_frame instance.

@mkdgs
Copy link

mkdgs commented Dec 23, 2017

I have the same issue with input or textarea when i modify it programmatically.
I had tried different tricks but nothing work, also when i modify programmatically a simple (visible) input text.

@maxxwv
Copy link
Author

maxxwv commented Dec 23, 2017

I've tried triggering change and update events on the text field itself and the form as a whole, but it doesn't seem to do anything, whether the field is visible or hidden. Glad to know it's not just me at least!

@youknowriad
Copy link
Contributor

Oh! I looked into this and it looks like there's no way to detect a programmatically changed field.
We have two options here:

  • Disable dirty-checking, auto-saving and the confirmation message when leaving the editor with changes when we have metaboxes (not a great UX)
  • Force this kind of metaboxes to call a method to trigger the change event?

I guess in the old editor it's the first option that's used.

cc @aduth @BE-Webdesign @mtias

@maxxwv
Copy link
Author

maxxwv commented Dec 25, 2017

@youknowriad - as stated, I've tried triggering both change and update events on both the form and input elements, so if metaboxes need to trigger an event please make sure it's well documented.

@youknowriad
Copy link
Contributor

youknowriad commented Dec 25, 2017

@maxxwv Yes, we'll do so when we decide what to do here.

For now, we're watching on the onChange event of the parent form. If you trigger this event manually, it should work IMO but we'll make it clear once we decide what to do.

@BE-Webdesign
Copy link
Contributor

We could bring back in the DOM Mutation Observer, that would fix this problem. We just have to be careful when we instantiate the observer, because in the past it would trigger problems, where hidden fields would change on load, causing the post to be saved even if no changes had really been made other than the hidden field, which could trigger auto saves etc, for no good reason. I don't see a good way around that though.

@youknowriad
Copy link
Contributor

We could bring back in the DOM Mutation Observer

Actually, I tried it but it was not being triggered when I updated an input's value programmatically. Maybe I was doing something wrong?

@BE-Webdesign
Copy link
Contributor

Actually, I tried it but it was not being triggered when I updated an input's value programmatically. Maybe I was doing something wrong?

Hmm... no idea, but I am pretty sure the mutation observers will call their callback on input change. I think all you need to do is set ( subtree: true, attributes: true ) when you instantiate the observer. It used to trigger on Yoast updating a hidden field to a new value, so I believe it is possible ( maybe it is not possible and something else was at play ). Not sure why it wouldn't work, but if it doesn't work in what you have tried, we should try to figure something else out.

@maxxwv
Copy link
Author

maxxwv commented Dec 27, 2017

May or may not be an interesting observation - if I use jQuery to trigger a change event on the .metabox-location-normal form when the hidden ID field is updated, the isDirty index does not update. However, if I use plain JavaScript to trigger the event, it does update. I'm not overly familiar with React (working on it) so I'm not sure if that's expected behavior, but thought I'd mention it in case it helps.

@youknowriad
Copy link
Contributor

@maxxwv Thanks for digging into this. We're using regular events (not React ones) here so this is probably a jQuery issue. But anyway, I think our only option is to get rid of meta boxes dirty checking which I started to do in #4184

@maxxwv
Copy link
Author

maxxwv commented Dec 27, 2017

@youknowriad - I saw the PR, thanks for working on it. Just wanted to put that out there in case it made something a bit clearer.

@mkdgs
Copy link

mkdgs commented Jan 2, 2018

It's not really a jQuery issue, jQuery has his own internal event map and no real DOM event is triggered.
facebook/react#3249 (comment)

Triggering 'change' event from vanilla javascript on the form element work well
https://stackoverflow.com/questions/47941729/wordpress-gutenberg-how-activate-update-button-when-change-input-or-textarea/48061779#48061779

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Meta Boxes A draggable box shown on the post editing screen
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants