Unable to click on meta-bind fields when inside a callout
Please fill out these Check-boxes
- [X] I checked for existing similar issues
- [X] I checked that the plugin is up to date
- [X] The issue persist with all other plugins and themes disabled
Plugin Version
1.1.3
This Issue Occurs on
- [X] Windows
- [ ] Linux
- [ ] macOS
- [ ] Android
- [ ] iOS
Debug Info
SYSTEM INFO:
Obsidian version: v1.6.7
Installer version: v1.5.3
Operating system: Windows 10 Home 10.0.19045
Login status: logged in
Catalyst license: none
Insider build toggle: off
Live preview: on
Base theme: adapt to system
Community theme: none
Snippets enabled: 0
Restricted mode: off
Plugins installed: 1
Plugins enabled: 1
1: Meta Bind v1.1.3
RECOMMENDATIONS:
Community plugins: for bugs, please first try updating all your plugins to latest. If still not fixed, please try to make the issue happen in the Sandbox Vault or disable community plugins.
Describe the Issue
Can't interact with input fields when they're placed inside of callouts in Live Preview mode.
Steps to Reproduce
- Place an input field inside of a callout.
- Try to interact with said field while in Live Preview Mode.
Expected Behavior
I used to be able to interact with the field in Live Preview Mode. So, I expected the field to be interactable without having to switch to Reading View.
Reference: #291
https://github.com/mProjectsCode/obsidian-meta-bind-plugin/issues/291#issuecomment-2251944924
Work Around Script that is Referenced in the above comment for anyone who is interested. Should Be Set to Run on Note Open Modified 8/22/24 To ONLY Work in Callout Elements
(() => {
console.log("Meta Bind Input in Live Preview script for callouts is running");
function setupListeners() {
function handleClick(e) {
if (e.target instanceof HTMLElement) {
let parent = e.target;
// Check if the clicked element is inside a callout
const callout = parent.closest('[data-callout]');
if (!callout) {
return; // Exit if not in a callout
}
while (parent !== null) {
if (parent.classList.contains('mb-input') || parent.classList.contains('editor-input')) {
e.stopPropagation();
e.preventDefault();
const editorInput = parent.closest('.editor-input');
if (editorInput) {
const textarea = editorInput.querySelector('textarea');
const displayDiv = editorInput.querySelector('div.svelte-1tfnqy0');
if (textarea && displayDiv) {
// Get the original Markdown content from the textarea
const originalContent = textarea.value;
// Hide the display div and show the textarea
displayDiv.style.display = 'none';
textarea.style.display = 'block';
textarea.value = originalContent;
textarea.focus();
// Set up events to handle the editing
textarea.onblur = () => {
textarea.style.display = 'none';
displayDiv.style.display = 'block';
};
}
}
break;
}
parent = parent.parentElement;
}
}
}
function handleKeydown(e) {
if (e.target instanceof HTMLElement && e.target.tagName === 'TEXTAREA') {
// Check if the textarea is inside a callout
const callout = e.target.closest('[data-callout]');
if (!callout) {
return; // Exit if not in a callout
}
let parent = e.target;
while (parent !== null) {
if (parent.classList.contains('mb-input') || parent.classList.contains('editor-input')) {
e.stopPropagation();
break;
}
parent = parent.parentElement;
}
}
}
document.addEventListener('click', handleClick, true);
document.addEventListener('keydown', handleKeydown, true);
console.log("Event listeners for callouts attached");
}
// Delay setup slightly to ensure DOM is ready
setTimeout(setupListeners, 2000);
// Return a cleanup function
return () => {
document.removeEventListener('click', handleClick, true);
document.removeEventListener('keydown', handleKeydown, true);
console.log("Event listeners for callouts removed");
};
})();
I had a fix for this a while back, but that broke interaction with some input fields on android in LP.
I had a fix for this a while back, but that broke interaction with some input fields on android in LP.
I would like for them to be segregated, and have their own fork. Just android, not ios?
No, I am absolutely not interested in maintaining a fork for mobile. The major reasons are:
- Extra time investment
- There is no way to distribute a plugin as mobile-only
However since this plugin is open source under the GPL-3.0 license, you are free to fork it and do whatever you want.
Regarding the other issue, I only got reports for Android and none for iOS.
Updated Script that will work with 1.2.1
(() => {
console.log("Meta Bind Input in Live Preview script for callouts is running");
function setupListeners() {
function handleClick(e) {
if (e.target instanceof HTMLElement) {
let parent = e.target;
// Check if the clicked element is inside a callout
const callout = parent.closest('[data-callout]');
if (!callout) {
return; // Exit if not in a callout
}
while (parent !== null) {
if (parent.classList.contains('mb-input') || parent.classList.contains('editor-input')) {
e.preventDefault(); // Avoid triggering unwanted events
// Manually trigger focusIn() on the editor input field if it's clicked
const editorComponent = parent.closest('.mb-editor-input');
if (editorComponent) {
// Access the Svelte component and trigger focusIn
const focusInFn = editorComponent.__svelte__?.focusIn;
if (focusInFn) {
focusInFn();
}
}
break;
}
parent = parent.parentElement;
}
}
}
function handleKeydown(e) {
if (e.target instanceof HTMLElement && e.target.tagName === 'TEXTAREA') {
// Check if the textarea is inside a callout
const callout = e.target.closest('[data-callout]');
if (!callout) {
return; // Exit if not in a callout
}
let parent = e.target;
while (parent !== null) {
if (parent.classList.contains('mb-input') || parent.classList.contains('editor-input')) {
e.stopPropagation();
break;
}
parent = parent.parentElement;
}
}
}
document.addEventListener('click', handleClick, true);
document.addEventListener('keydown', handleKeydown, true);
console.log("Event listeners for callouts attached");
}
// Delay setup slightly to ensure DOM is ready
setTimeout(setupListeners, 2000);
// Return a cleanup function
return () => {
document.removeEventListener('click', handleClick, true);
document.removeEventListener('keydown', handleKeydown, true);
console.log("Event listeners for callouts removed");
};
})();
@LynetteCullens thanks for providing a fix, I am struggling to understand how to use your script. Is this a patch for the plugin??
I tested around a bit more. preventDefault on the click event will prevent the callout from going into "edit" mode, but it also breaks some input fields like the date and time inputs.
I don't know how to prevent the callout from going into edit mode without breaking some input fields. I am open to suggestions and PRs if someone has an idea.
@LynetteCullens thanks for providing a fix, I am struggling to understand how to use your script. Is this a patch for the plugin??
No, it is just a javascript code that runs every time I open a new note using RunJs plugin. I haven't tested it since 1.2.1 though. I've been working in iOS Obsidian since 1.2.1 so that I will be less inclined to pitchfork them.
I am not in a great place to test things out myself right now but you can try event.stopPropagation(). It stops the event from propogating upwards (bubbling up) to the elements higher in the tree that can handle the same event. This might prevent the callout from taking the input while not breaking other behaviours that event.preventDefault() would break.
That, sadly, does not work. It was one of the first things I tried, but event.preventDefault() is needed to stop the callout from unfolding. event.stopPropagation() and event.stopImmediatePropagation() are not enough.
Fair enough, I'll try to dig into it once I'm done with my move.
I am finding this behavior with input controls inside of tables as well.
I'd really like to see this fixed for tables as well. Should that be a separate issue?
No. It's the same underlying issue.
Running into the same problem. A fix would be quite nice!
My "solution" is to stuff it inside of an embed, this way it works fine (PC, Windows). But I have done no real testing.
My "solution" is to stuff it inside of an embed, this way it works fine (PC, Windows). But I have done no real testing.
I've tried doing that in version 1.1.3, and it did not work for me. I will try again using the newer update.
My "solution" is to stuff it inside of an embed, this way it works fine (PC, Windows). But I have done no real testing.
I've tried doing that in version 1.1.3, and it did not work for me. I will try again using the newer update.
You are using Meta-bind-embed, right?
My "solution" is to stuff it inside of an embed, this way it works fine (PC, Windows).
Doesn't fix it for me.
I tested this on obsidian 1.8.10, (also Windows PC), still behaves the same. Trying to click an interactive element opens the callouts edit mode instead of interacting with it.
My "solution" is to stuff it inside of an embed, this way it works fine (PC, Windows).
Doesn't fix it for me.
I tested this on obsidian 1.8.10, (also Windows PC), still behaves the same. Trying to click an interactive element opens the callouts edit mode instead of interacting with it.
mmm, you need to embed full callout, rather then embed the meta-bind. i am using 1.4.2 meta-bind, windows and 1.8.10.
You creates a meta-bind inside a callout, then embed it in another note using special meta-bind-embed. Unless there multiple similar problems it worked for me.
you need to embed full callout, rather then embed the meta-bind.
That does indeed work. Interesting.
But it also mostly defeats the purpose as I specifically want (potentially multiple levels of) callouts to groups stuff...
you need to embed full callout, rather then embed the meta-bind.
That does indeed work. Interesting.
But it also mostly defeats the purpose as I specifically want (potentially multiple levels of) callouts to groups stuff...
You can have any number of callouts, in any configuration of levels inside another note. It just that they all have to be there.
I personally using it with TabSidian and that is a lot of callouts.
So unless you want to frequently change the content outside of the meta-bind inputs, there doesn't seem to be a limit.
And even then, if you need a changeable text field you technically can use editor INPUT for that.
(Also as meta-bind-embed works, you can embed same data structure into any number of notes and populate using properties)
I suspect the reason it dose work, is because meta-bind-embed dose not have any reaction on left click as it is a code block.
I suspect the reason it dose work, is because meta-bind-embed dose not have any reaction on left click as it is a code block
see https://github.com/mProjectsCode/obsidian-meta-bind-plugin/issues/403#issuecomment-2466710482
The problem is that plugins cannot properly stop the event propagation and obsidian will always get the event, even if a meta-bind component is the closes object and declares its handling it. So the "unfolding" of the callout always triggers
My "solution" is to stuff it inside of an embed, this way it works fine (PC, Windows).
Doesn't fix it for me. I tested this on obsidian 1.8.10, (also Windows PC), still behaves the same. Trying to click an interactive element opens the callouts edit mode instead of interacting with it.
mmm, you need to embed full callout, rather then embed the meta-bind. i am using 1.4.2 meta-bind, windows and 1.8.10.
You creates a meta-bind inside a callout, then embed it in another note using special meta-bind-embed. Unless there multiple similar problems it worked for me.
My issue is that I can't get a specific callout to embed. I can only get the entire page. Are you working with page embeds instead of callout embeds? Do you have one callout per page? I also could not get more than one callout to display when embedding an entire page. It just duplicates the first callout for every callout.
My "solution" is to stuff it inside of an embed, this way it works fine (PC, Windows).
Doesn't fix it for me. I tested this on obsidian 1.8.10, (also Windows PC), still behaves the same. Trying to click an interactive element opens the callouts edit mode instead of interacting with it.
mmm, you need to embed full callout, rather then embed the meta-bind. i am using 1.4.2 meta-bind, windows and 1.8.10. You creates a meta-bind inside a callout, then embed it in another note using special meta-bind-embed. Unless there multiple similar problems it worked for me.
My issue is that I can't get a specific callout to embed. I can only get the entire page. Are you working with page embeds instead of callout embeds? Do you have one callout per page? I also could not get more than one callout to display when embedding an entire page. It just duplicates the first callout for every callout.
It is correct that meta-bind-embed only supports page embeds, there is an open feature request to change that. Still, page embeds do work correctly, so I honestly have no idea, why it repeats the same callout for you.
I do indeed use "one callout per page", relatively speaking.
If you want some help, feel free to contact me on discord I am - mistmage
Found a fix. We can simply add an interactive-child class to the input field, and Obsidian's click handler will ignore clicks within the element with the class. Not sure if this is new in Obsidian 1.9.0 with bases or has existed in earlier versions.
I will implement the fix properly and make a new release within the next few days.
Found a fix. We can simply add an
interactive-childclass to the input field, and Obsidian's click handler will ignore clicks within the element with the class. Not sure if this is new in Obsidian 1.9.0 with bases or has existed in earlier versions.I will implement the fix properly and make a new release within the next few days.
Yayyyy!!!! I will be celebrating. Whew.....My dopamine levels have increased....WOW
I just realized that the fix isn't release jet, but most of the inline elements are actually already working fine for me in Obsidian v1.9.12:
> [!note] working inputs:
> number: `INPUT[number:exampleNumProperty]`
> text: `INPUT[text:exampleTextProperty]`
> inlineSelect: `INPUT[inlineSelect(option(apple), option(banana), option(lemon)):exampleOptionProperty]`
> slider: `INPUT[slider(addLabels):exampleSliderProperty]`
> inlineList: `INPUT[inlineList:exampleListProperty]`
> toggle: `INPUT[toggle:exampleBoolProperty]`
What still isn't working are buttons and inputs like date-picker which open a modal (probably also buttons...)