How to change the Gutenberg Group Block's "Inner blocks use content width" Toggle to Off/False as Default - wordpress

When you wrap a new set of blocks in the core/group block the "Inner blocks use content width" toggle switch defaults to true. There is an object attribute showing called layout for that block. I'm assuming that I can update the settings on the layout attribute like I can with the align attribute.
Here is how I'm updating the align attribute:
const { addFilter } = wp.hooks;
const { assign, merge } = lodash;
function filterCoverBlockAlignments(settings, name) {
if (name === 'core/group') {
return assign({}, settings, {
attributes: assign( {}, settings.attributes, { align: {
type: 'string', default: 'wide'
} } ),
});
// console.log({ settings, name });
}
return settings;
}
addFilter(
'blocks.registerBlockType',
'intro-to-filters/cover-block/alignment-settings',
filterCoverBlockAlignments,
);
The above works so I assume updating the layout's default would be similar, but either I don't have the syntax for an object type correct, or possibly you can't update the layout object like you can update the align string. This is what I tried for the function:
function filterCoverBlockAlignments(settings, name) {
if (name === 'core/group') {
return assign({}, settings, {
attributes: assign( {}, settings.attributes, { layout: {
type: 'object', [{
type: 'default'
}]
} } ),
});
// console.log({ settings, name });
}
return settings;
}
In short I'm trying to get the blocks layer attribute (which is an object and not a string) have it's attribute of type to default to "default" instead of "constrain".

I mean yes, you could solve it by filtering. What I would suggest however, is making a block-variation. Then setting that block-variation as the default. That block variation then can have any of your settings you like to set. Quite simple in theory.
By default, all variations will show up in the Inserter in addition to the regular block type item. However, setting the isDefault flag for any of the variations listed will override the regular block type in the Inserter.
source: https://developer.wordpress.org/block-editor/reference-guides/block-api/block-variations/
wp.blocks.registerBlockVariation( 'core/group', {
name: 'custom-group',
// this one is important, so you don't end up with an extra block
isDefault: true,
// and here you add all your attributes
attributes: { providerNameSlug: 'custom' },
} );
Here is a slightly cleaner variant (using destructuring), if you have more code:
// extract the function from wp.blocks into a variable
const { registerBlockVariation } = wp.blocks;
// register like above
registerBlockVariation();

Related

tiptap / prosemirror access to clientHeight or getBoundingClientRect

I ve been wondering is there is a way to get tiptap or Prosemirror node's height and insert those values into arrtibutes.
So best case scenario would bo to be able to use either
getBoundingClientRect
or
clientHeight
and get them inside every update cycle for instance in custom node extenstion addAttributes
So I imagine that the below code could look like that, but of course it's not returning any value ....
addAttributes() {
return {
height:
{ default: null,
parseHTML: element => element.clientHeight,
renderHTML: attributes => {
return { 'data-height': attributes.height,
style:height: ${attributes.height
},
}
},
},
}
},

Extjs beforerender to set async-obtained variable

My ExtJS application displays certain UI elements depending on a boolean variable.
This boolean variable, however, is the result of calling an async function. As a result, the boolean is set to a Promise that is fulfilled, rather than true or false proper. This affects whether the UI elements are actually displayed (a Promise is not exactly a boolean, after all).
The code looks like this:
Ext.define('userDefinedComponent', {
extend: 'Ext.Container',
requires: ['someHelperFile'],
initComponent: function () {
var me = this,
var enabled = someHelperFile.someAsyncFunc() // enabled is a boolean that is returned as fulfilled Promise instead
Ext.apply(me, {
// layout and padding
items: [
{
xtype: 'internallyDefinedForm',
fieldConfigs: {
// other fields
'someFormField': {
hidden: !enabled, // depends on enabled
}
}
},
{
xtype: 'internallyDefinedGrid',
columnConfigs: {
// other columns
'someColumn': {
hidden: !enabled, // deends on enabled
}
},
}
]
})
}
})
I want the field enabled to really be a boolean rather than a Promise. In other words, I want to wait for the someAsyncFunc to run the result, before setting hidden property of the internallyDefinedForm and internallyDefinedGrid.
What are my possibilities? I was thinking of using a beforerender, like below:
Ext.define('userDefinedComponent', {
extend: 'Ext.Container',
requires: ['someHelperFile'],
initComponent: function () {
var me = this;
Ext.apply(me, {
// layout and padding
items: [
{
xtype: 'internallyDefinedForm',
fieldConfigs: {
// other fields
'someFormField': {
hidden: !me.enabled, // depends on enabled
}
}
},
{
xtype: 'internallyDefinedGrid',
columnConfigs: {
// other columns
'someColumn': {
hidden: !me.enabled, // deends on enabled
}
},
listeners: {
beforerender: function() { // this is the beforerender
me.enabled = someHelperFile.someAsyncFunc();
console.log("beforerender triggered in grid");
}
},
}
]
})
}
})
And in fact, using the beforerender for the internallyDefinedGrid only, I can see the text "beforerender triggered in grid" triggered very early. However, the fact remains that the behavior that I observe does not correspond to what I expect: although the async someAsyncFunc should return true based on the API response it gets, such that me.enabled is true, the actual UI associated with the internallyDefinedGrid behaves as if me.enabled is false instead. I observe that the column on the UI is hidden, and this is only possible when me.enabled is false, such that the column someColumn does not appear on the grid. After all, the hidden field of someColumn is set to !enabled.
I am confident that the UI for the grid behaves not like what I expect it to, so there is a problem with the async behavior. But I'm really lost as to how to set the asynchronously obtained enabled or me.enabled field adequately.
Any help is appreciated.
I would suggest to use a View Model and binding, as explained here.
Basically you define what your UI is depending on, under the data tag in the View Model (you can set the initial value here):
Ext.define('MyApp.TestViewModel', {
extend: 'Ext.app.ViewModel',
data: {
something: false,
},
}
Then you bind the visibility to this value in the view:
bind: {
hidden: '{something}'
}
or
bind: {
hidden: '{!something}'
}
You fetch the async data, and once you have the result, set the value in the View Model (this can be either the view or the controller):
this.getViewModel().set('something', RESULT_OF_ASYNC)
With binding ExtJS takes care of refreshing the visibility of your component every time when the value in the View Model is changed. There are good examples at the link I provided. This is a very powerful and complex feature of ExtJS, worth learning.

Get information and attributes from other gutenberg blocks

Is it possible to get information, such as the block attributes, from other blocks from within a registerBlockType call?
E.g. if I have a block with InnerBlocks as the content, is it possible to get attributes from the blocks inside that InnerBlocks, or vice versa?
Yes it is possible if you manages your own store inside Gutenberg which is actually a Redux store. #wordpress/data
It is recommended to keep logic of your multiple blocks separately in their own attributes (that's why they are blocks). For re-usability purpose you can make React components which can be used inside different blocks, in this way attributes of your block can be passed to the props of React Component.
You could also use Block context to achieve this.
In your parent block, map the attribute you want to use in your child block using providesContext. So if you would like to map the recordId property, your parent block configuration would look like this:
registerBlockType('my-plugin/parent-block', {
// ...
attributes: {
recordId: {
type: 'number',
},
},
providesContext: {
'my-plugin/recordId': 'recordId',
},
// ...
}
The child block can then "consume" the context by adding the following useContext line to your child block configuration:
registerBlockType('my-plugin/child-block', {
// ...
usesContext: ['my-plugin/recordId'],
// ...
}
In your child block's edit and save methods, you can then access the context like this:
registerBlockType('my-plugin/child-block', {
// ...
edit(props) {
const { context } = props;
const { "my-plugin/recordId": recordId } = context;
return (
<p>{ recordId }</p>
);
},
save(props) {
const { context } = props;
const { "my-plugin/recordId": recordId } = context;
return (
<p>{ recordId }</p>
);
}
// ...
}

Vue js custom select - binding to the

I have a custom select box.
<select-box :options="['Male', 'Female', ]"
title="Gender"
v-bind:value="selected"
v-model="person.gender"
>
</select-box>
The .vue code
<script>
export default {
props:['title', 'options'],
data () {
return {
selected: this.title,
dropdownVisible: false,
}
},
methods: {
toggleOptions() {
this.dropdownVisible = !this.dropdownVisible
},
selectValue(option) {
this.selected = option;
this.toggleOptions();
}
}
}
How can I bind the selected value directly to the model (person.gender)?
I assume that above .vue code belongs to select-box component.
Because I saw you use v-model, to bind value directly to v-model, you need to $emit inside children component.
You can change your selectValue function
selectValue(option) {
this.selected = option;
this.$emit('input', option);
this.toggleOptions();
}

Bind constraints in Input control of SAPUI5

My rest service expose me a group of fields: each filed has a value and a list of attributes: enabled, maxLength (in case of string), minLength (in case of string), decimals (number of decimal digits - in case of float).
In OpenUi5 I have:
value and enabled are properties of Input control Link (Good!! I can bind properties with model contains the attributes)
maxLength and decimals are optionsof String type and Float type (Link) but I can't bind options with a model :-/
minLength I can't find a property/option
I would like map (bind) each attribute with component so that automatically the library control for me without writing more code.
there is a property called maxLength for Input Control.
So the only problem I see is binding minLength and decimals for which there is little bit effort is needed.
Solution
Create your own input control by extending the existing Input
Control.How to achieve it?
Sample Code Structure:
jQuery.sap.require("sap.m.Input");
jQuery.sap.declare("sap.m.ComplexInput");
sap.m.Input.extend("sap.m.ComplexInput", {
metadata: {
properties: {
minLength: {
type: "int"
},
decimals: {
type: "int"
},
events: {
//define your own events like checkMinLength,checkDecimals
}
},
onInit: function () {
//on init do something
},
onAfterRendering: function () {
//called after instance has been rendered (it's in the DOM)
},
_somePrivateMethod: function () {
/*do someting...*/
},
somePublicMethod: function () {
/*do someting...*/
},
}
});
sap.m.ComplexInput.prototype.exit = function () {
/* release resources that are not released by the SAPUI5 framework */
//do something
};
Adding CustomData and using wherever you want to.
Then you can access custom data in validation process or on liveChange or so..
Bind the other properties to the value of customData
var input = new sap.m.Input({
value: '{value}',
enabled: '{enabled}',
maxLength: '{maxLength}',
customData: [
new sap.ui.core.CustomData({
key: 'minLength',
value: '{minLength}'
}),
new sap.ui.core.CustomData({
key: 'decimals ',
value: '{decimals}'
})
],
change: function(oEvent) {
var src = oEvent.getSource();
var minLen = src.getCustomData()[0].getValue();
var decimals = src.getCustomData()[1].getValue();
if (src.getValue() && src.getValue().length > minLen) {
src.setValueState('Success');
} else {
src.setValueState('Error');
}
}
});

Resources