Closed mahsashadi closed 3 years ago
Try win.resizeFit(container)
where container
is the outer most container that overflows the window.
I use resizeFit in my code as below, But it didn't work.
createSettingDialog() {
const callbackRender = ($content, dialogWindow, dialog) => {
dialog.app = app({
// state
}, {
//actions
}, (state, actions) => {
//view
return dialog.createView([
h('div', {
class: 'outerBox',
}, [
//inner components of view are here
])
]);
}, $content);
};
// Values are passed down to the 'options' object
const callbackValue = dialog => dialog.app.getValues();
const callbackButton = (button, value) => {
if (button === 'ok') {
// some code
}
};
const options = {
buttons: ['ok', 'cancel'],
window: {
title: 'setting',
message: 'message',
//dimension: { width: 700, height: 800 },
resizeFit:document.getElementsByClassName('outerBox')
}
};
this.core.make('osjs/dialogs').create(options, callbackValue, callbackButton).render(callbackRender);
}
It's a method call, not a property.
So where should I call this method?
Two removeField
and addField
actions in guage.js file cause creating dynamic fields, which is returned to onWidgetTypeChange
action in index.js file to add its hyperapp to dialog
gauge.js
showAdvancedSetting (grafana) {
const state = {
// state
};
const actions = {
removeField: (index) => {
//some code
},
addField: (index) => {
//some code
}
//some other actions
};
const view = (state, actions) => (
h(Box, {
class: 'outer'
},[
// other view components inside outer box
])
);
return {state, actions, view};
}
index.js
createSettingDialog() {
const callbackRender = ($content, dialogWindow, dialog) => {
dialog.app = app({
// state
}, {
//actions
onWidgetTypeChange: (widgetTypeValue) => {
let div = document.getElementsByClassName('hidden-div');
div[0].style.display = 'inline';
advancedSetting = this.widget.showAdvancedSetting(this);
app(advancedSetting.state, advancedSetting.actions, advancedSetting.view, div[0]);
},
}, (state, actions) => {
//view
return dialog.createView([
h('div', {
class: 'outerBox',
}, [
//inner components of view are here
])
]);
}, $content);
};
const callbackValue = dialog => dialog.app.getValues();
const callbackButton = (button, value) => {
// some code
};
const options = {
//options
};
this.core.make('osjs/dialogs').create(options, callbackValue, callbackButton).render(callbackRender);
}
Try:
this.core
.make('osjs/dialogs')
.create(options, callbackValue, callbackButton)
.on('render', win => win.resizeFit(win.$content.querySelector('.outerBox')))
.render(callbackRender);
It didn't work. It causes the following error:
Uncaught TypeError: this.core.make(...).create(...).on is not a function
Ah. In the case of dialog instances it might have to be done like this:
const callbackRender = ($content, dialogWindow, dialog) => {
dialogWindow.on('render', win => win.resizeFit(win.$content.querySelector('.outerBox')))
// ...
}
Come to think of it you can probably just do it like this:
const callbackRender = ($content, dialogWindow, dialog) => {
dialog.app = app({}, {}, (state, actions) => {}, $content);
// Might need a setTimeout on this because rendering is defered
dialogWindow.resizeFit($content.querySelector('.outerBox'))
};
Unfortunately this doesn't fix the problem. The outerBox
still overflows the dialog window.
I had to take a look at this myself and found that in the case of these custom dialogs you have to override the CSS slightly:
dialogWindow.on("render", () => {
dialogWindow.$content.firstChild.style.bottom = "auto";
dialogWindow.resizeFit();
});
(without an argument in resizeFit, it will calculate with the first child of the inner contents, which is always fixed in a dialog -- hence the style change)
Full example here: https://codesandbox.io/s/osjs-custom-dialog-resize-fit-3ye2w?file=/src/package.js:1018-1157
Thank you. In this way, resizing happens every time the dialog is rendered. But I need auto resizing while it is open, according to its dynamic content (as Dynamic Field Example).
I've done some investegation into this, and the resizeFit
probably won't fit your needs.
So I updated the codesandbox example to show how to do this dynamically. Sadly it involves some custom maths, but it's the only way you can do it at this moment.
Notice I removed the previous example here, so the CSS change is no longer required! I just added an event when you add a new entry to a list that does some calculations and figures out the correct size within the dialog.
I'm going to make the resizeFit
a bit smarter to handle cases like this, but I need to think about it for a while.
Thanks a lot. It works.
Great!
I've opened an issue about improving this functionality so developers don't have to do all this calculation manually:
How dialog size could be changed according to its contents? I am using dynamic fields like Dynamic Field Example, inside my custom dialog.