*Neos features already a great inline editor: www.neos.io
Neos CMS Plugin for live inspector editing:
(the most non-advertising name - but thats what happening)
composer require mhsdesign/liveinspectordomchange
Demo Video: thanks, @Sebobo for https://github.com/Sebobo/Shel.Neos.ColorPicker
A basic (standalone) nodeType with a select box (nothing special in here)
'Vendor.Site:Content.Example':
superTypes:
'Neos.Neos:Content': true
ui:
icon: 'icon-internet-explorer'
label: 'Example'
# this will remove the Neos not inline editable overlay.
inlineEditable: true
inspector:
groups:
settings:
label: 'Settings'
properties:
height:
type: string
ui:
# not need to explicitly state it since its the default:
# reloadIfChanged: false
label: 'Height'
inspector:
group: settings
editor: 'Neos.Neos/Inspector/Editors/SelectBoxEditor'
editorOptions:
allowEmpty: true
values:
# your css classes as key.
height-sm:
label: 'Small'
height-md:
label: 'Medium'
height-lg:
label: 'Large'
This Fusion will allow to change the class:
prototype(Vendor.Site:Content.Example) < prototype(Neos.Neos:ContentComponent) {
height = ${q(node).property('height')}
heightClassChanger = ${Editable.attributes(node, 'height', 'changeClass')}
renderer = afx`
<div class={props.height} {...props.heightClassChanger}></div>
`
}
The EEL Helper Editable.attributes
will return an array of attributes which need to be applied via Fusion @apply or as AFX spread on the HTML element that should be updated live.
(Those spreads work exacly like in Js World: <p {... {'key': 'value'} }></p>
will be rendered as <p key="value"></p>
)
The EEL Helper will render those attributes only in the backend into your markup.
just add two spreads on the same HTML element.
<div {...Editable.attributes()} {...Editable.attributes()}></div>
you can also concat them beforehand via:
Array.concat(Editable.attributes(), Editable.attributes())
and apply this as a spread to your HTML element.
note that multiple editable attributes on one HTML element must come from the same node!
${Editable.attributes(node, propName, changerFunction, changerArguments=null)}
node
(NodeInterface): The current node which has the property.propName
(string): Name of the property - must be the same name as in the CR (Yaml declaration) and belong to thenode
otherwise an exception is thrown.changerFunction
(string) Name of the function to execute. (Key of the JsliveChangeFunctions
object)changerArguments
(mixed) Additional arguments for the JavaScript function. Can be of any type as long as they can be Json encoded. Note: if null is provided it will be converted in JavaScript to an empty array to allow nested default parameters.
All functions must be 'registered' on the global object liveChangeFunctions
.
Predefined functions:
changeClass
changerArguments
: none- example:
${Editable.attributes(node, 'height', 'changeClass')}
changeStyle
changerArguments
: string and a valid property ofHTMLElement.style
- example:
${Editable.attributes(node, 'color', 'changeStyle', 'color')}
changeText
changerArguments
: none- example:
${Editable.attributes(node, 'color', 'changeStyle', 'color')}
clientEval
changerArguments
: string, which will evaluated via JavaScript eval*.el, propName, newVal, oldVal
are usable.- example:
${Editable.attributes(node, 'color', 'clientEval', 'el.textContent = newVal; console.log(oldVal);')}
* yes I'm evil for using eval.
Add this to your JavaScript in the backend iframe.
liveChangeFunctions.myFunctionName = ({el, propName, newVal, oldVal, arguments}) => {
el // is the current dom element.
el.textContent = newVal
}
Use it like:
${Editable.attributes(node, 'something', 'myFunctionName')}
see #1
- It doesnt work for images, as 'Redux Cr node' doesnt know about an image uri. (it would probably work to use an endpoint but then complex server operations like responsive images via Fusion wont work easily.
reloadIfChanged: true
is a better option.) - It doenst work yet for toggling HTML elements. But you could build yourself a Fusion Vendor:Toogle Object, which will accept a condition and in the backend sets the style to display:none and for live toggling implements a JS helper. Or use a custom web component and use el.customFunction() on the web component in a customChanger.
- You cant have two nodes controlling one HTML element.
The live updates are evaluated via the nodes contextPath. that means that as long as you specify the right node as parameter to the Editable.attributes, it will work.
for more information look at the tests ;) ./Tests/JavaScript/ ./Tests/Unit/
run the phpunit tests from your flow root:
./bin/phpunit -c ./Build/BuildEssentials/PhpUnit/UnitTests.xml ./Packages/Application/MhsDesign.LiveInspectorDomChange/Tests
run the JavaScript jest test in the location ./Tests/JavaScript
# optional
# nvm install && nvm use
# npm install --global yarn
yarn install
yarn test
this Package relies on the Package MhsDesign.LiveInspectorJsEvents https://github.com/mhsdesign/MhsDesign.LiveInspectorJsEvents. Which sends the JavaScript events to the iframe.