Closed broncha closed 7 years ago
Hi, I think I am getting a hold of this now. I made a custom component for product list, which has a trait for the category. I can select the category from the dropdown in the panel. Thats great. But I dont want the components inside the product list (like images, text etc) to be editable. How do I do this? The entire component is generated dynamically, and the user should only be able to add/remove the entire component, not child components
Hi @broncha you can update Component properties by using data-gjs-*
attributes, so, for example, in your case you might want to add this to your child components
<div data-gjs-removable="false" data-gjs-draggable="false" data-gjs-copyable="false" ...></div>
...
Hi @artf, thanks! I figured that out. Now this is what I have
<div data-gjs-type="categoryList" data-gjs-editable="false" data-gjs-draggable=".container-fluid">
<h2 data-gjs-editable="false" data-gjs-badgable="false" data-gjs-removable="false" data-gjs-draggable="false" data-gjs-droppable="false" data-gjs-stylable="false" data-gjs-highlightable="false" data-gjs-copyable="false">Browse by Category</h2>
<div class="row" data-gjs-editable="false" data-gjs-badgable="false" data-gjs-removable="false" data-gjs-draggable="false" data-gjs-droppable="false" data-gjs-stylable="false" data-gjs-highlightable="false" data-gjs-copyable="false">
<div class="col-xs-4 html-content-block" data-gjs-badgable="false" data-gjs-editable="false" data-gjs-removable="false" data-gjs-draggable="false" data-gjs-droppable="false" data-gjs-stylable="false" data-gjs-highlightable="false" data-gjs-copyable="false">
<div class="html-content-animation" data-gjs-badgable="false" data-gjs-editable="false" data-gjs-removable="false" data-gjs-draggable="false" data-gjs-droppable="false" data-gjs-stylable="false" data-gjs-highlightable="false" data-gjs-copyable="false"></div>
<a href="http://demo-shop.pasls.dev/category/sasd" data-gjs-badgable="false" data-gjs-editable="false" data-gjs-removable="false" data-gjs-draggable="false" data-gjs-droppable="false" data-gjs-stylable="false" data-gjs-highlightable="false" data-gjs-copyable="false"> <img data-gjs-editable="false" data-gjs-badgable="false" data-gjs-removable="false" data-gjs-draggable="false" data-gjs-droppable="false" data-gjs-stylable="false" data-gjs-highlightable="false" data-gjs-copyable="false" src="http://demo-shop.pasls.dev/media/cache/demo-shop/d_cat_thumb/u/59003a416d97a_category_top_4.jpg" alt="" class="img-responsive"> </a>
</div>
<div class="col-xs-4 html-content-block" data-gjs-badgable="false" data-gjs-editable="false" data-gjs-removable="false" data-gjs-draggable="false" data-gjs-droppable="false" data-gjs-stylable="false" data-gjs-highlightable="false" data-gjs-copyable="false">
<div class="html-content-animation" data-gjs-badgable="false" data-gjs-editable="false" data-gjs-removable="false" data-gjs-draggable="false" data-gjs-droppable="false" data-gjs-stylable="false" data-gjs-highlightable="false" data-gjs-copyable="false"></div>
<a href="http://demo-shop.pasls.dev/category/shoes" data-gjs-badgable="false" data-gjs-editable="false" data-gjs-removable="false" data-gjs-draggable="false" data-gjs-droppable="false" data-gjs-stylable="false" data-gjs-highlightable="false" data-gjs-copyable="false"> <img data-gjs-editable="false" data-gjs-badgable="false" data-gjs-removable="false" data-gjs-draggable="false" data-gjs-droppable="false" data-gjs-stylable="false" data-gjs-highlightable="false" data-gjs-copyable="false" src="http://demo-shop.pasls.dev/media/cache/demo-shop/d_cat_thumb/u/5900419537180_category_top_4.jpg" alt="" class="img-responsive"> </a>
</div>
</div>
<div class="vert-space-30" data-gjs-badgable="false" data-gjs-editable="false" data-gjs-removable="false" data-gjs-draggable="false" data-gjs-droppable="false" data-gjs-stylable="false" data-gjs-highlightable="false" data-gjs-copyable="false"></div>
</div>
Bear with me here. That is quite a lot duplicated attributes there. Its entire block, which is dynamically generated. I dont need any of the children to be editable or highlightable. Now I cannot select the component. I have disabled all properties in the children. The blue border still appears when I hover over the children.
How can I make it so that, clicking inside the Component (any of the children too) selects the component?
As you can see, I have to carefully hover over the empty space to select the entire component. And even when all the children are not editable, highlightable etc., they react to hover.
Still didn't get which is your final goal but you can append your children as a static content, eg.
blockManager.add('some-block', {
...
content: {
type: 'your-custom-type',
...
// This will parse, create and append models to the structure
components: '<div...>...',
// This will just add the content as a plain HTML, no models (therefore you can't select them)
// here you don't need model attributes
content: '<div ..',
}
})
but take into account that those elements, added via content
, are not selectable but are may still blocking the pointer from selecting the parent, the solution is to add pointer-events: none
to the container of your children
editor.DomComponents.addType('your-custom-type', {
...
view: ... {
...
render() {
// ... call the parent render and other stuff
// Make your content wrapped inside some container so it will be the firstChild
this.el.firstChild.style.pointerEvents = 'none';
}
}
})
I think I got what I needed using
<div data-gjs-..... style="pointer-events: none;" >
But the data attributes in all the child elements are still I think, redundant. This is a valid use case no? For builders who have widgets and all.
@broncha if you use content
you don't need any of those data attributes
@artf Thanks. Ill try that out. Could you help me with one last thing? How can i get a reference to the components added? I will not be storing the html, rather the json object that describes the component and the traits. Later the page will be generated from the json. For example, here in category list, i will have a trait, say number of categories to show. Now since the exact categories to show will be dynamic, i need to get the list of components/blocks added and their traits.
You can get components via DomComponents
module
const dc = editor.domComponents;
const wrapper = dc.getWrapper();
// Iterate children
wrapper.get('components').each(component => {
const traits = component.get('traits'); // trait collection
traits.each(trait => ...);
// go deeper
component.get('components').each(....)
})
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Hi. First of all, thank you for putting all your hard work on this. This definitely is a great library. I am thinking of integrating this as a layout manager for a product we have. Its like Shopify where you can customise the layout of the store. Now we can have many blocks and component which are rendered dynamically. For example, we can have a block that shows few cards with products from a specific category. We use a twig file to render that particular block. All that the block needs to know is the category its rendering the product from, and the HTML is generated dynamically.
How would I do this with the component in GrapeJS. I have gone through the component documentation and I cant seem to find a way to do this.
Heres what I have in mind,
So far so good. Now I need this information to be saved, so in the live site, the block is rendered properly. I don't know the workflow of the GrapeJS internally. But is there a way, that the block could be represented by a twig block (we use twig templating), or some shortcode (like in WordPress), in the final output of the canvas, but the canvas itself shows the evaluated version of that placeholder?
Cheers