[FEATURE REQUEST] Preselect a trait select option
Question
Hello,
I'd like you to add to the options array of a select trait a third parameter next to 'name' and 'value', which is 'selected' in order to pre-select one of the trait options.
In detail: I extended the header component by a select trait for all header types h1 through h6. Now I'd like to add something to the event function 'component:selected' so that when the component is clicked, the trait select for the header type is directly switching to the fitting option as far as a header tag is included (for example h2 tag is clicked => 2nd select option is pre-selected)
I was wondering if there's a possibility to do this inside grapesJS, as alternatively I would need to go over the DOM and use jQuery for this, but that isn't a very elegant and future-proof solution, to my opinion.
Something like this:
editor.on('component:selected', function(arg) {
//reset all options
arg[1].get('traits').where({name: 'header-type'})[0].attributes.options.filter((el) => typeof el.selected!='undefined').forEach((el) => el.selected = false);
//set new selected option
var tagName = arg[1].attributes.tagName;
arg[1].get('traits').where({name: 'header-type'})[0].attributes.options.find(function(opt) {
return opt.value==tagName;
}).selected = true;
});Answers (3)
Hi @Chilli-B it would be better if you provide a live example of what you're trying to accomplish. BTW, if the trait is correctly created it should be synced with the component model, for example:
{
type: 'select',
options: [
{ value: 'h1', name: 'H1'},
{ value: 'h2', name: 'H2'},
],
label: 'TAG',
// Set the same name as the model's property and add changeProp
name: 'tagName',
changeProp: 1,
}
Hi @artf , thanks for your reply. Below is how I created the trait by extending the text model for the header component.
The problem is not the syncronization. The problem is, when I'm adding complete layouts to the canvas, which are including h2 or h3 tags (or any others), and I'm clicking on them, the header type select in the settings (traits) always stays at "Headline 1", as this is the first option in the select and there's no possibility to give any of the select options the attribute 'selected'.
var txtType = domComps.getType('text');
var txtModel = txtType.model;
var txtView = txtType.view;
domComps.addType('head', {
model: txtModel.extend({
defaults: Object.assign({}, txtModel.prototype.defaults, {
tagName: 'h1',
traits: [
{
type: 'select',
label: 'Type',
name: 'header-type',
changeProp: 1,
options: [
{value: 'h1', name: 'Headline 1'},
{value: 'h2', name: 'Headline 2'},
{value: 'h3', name: 'Headline 3'},
{value: 'h4', name: 'Headline 4'},
{value: 'h5', name: 'Headline 5'},
{value: 'h6', name: 'Headline 6'},
]
},
'title'
]
}),
init: function() {
this.listenTo(this, 'change:header-type', this.updElem);
},
updElem: function() {
var newElem = $('<div />').append($('<'+this.changed['header-type']+' />').append(this.view.el.innerText));
this.view.model.set('content',newElem.html());
this.view.el.innerHTML = newElem.html();
this.attributes.tagName = this.changed['header-type'];
editor.store();
}
},
{
isComponent: function(el) {
if (el.tagName == 'h1' || el.tagName == 'h2' || el.tagName == 'h3' || el.tagName == 'h4' || el.tagName == 'h5' || el.tagName == 'h6') {
return {type: 'head'};
}
},
}),
view: txtView,
});
For usability reasons it would be better to show the current settings there - for h2 tags logically 'Headline 2'.
Below is how I solved that for now. I searched for the select using jQuery. However, that doesn't work as soon as the traits for one component are including several different select fields, because the trait name (or any other possible reference) is not part of the html output in the form of class names or attributes, so there's a leck of possibility to reference the correct select. Further on it would be much better to do this 'natively', as it is definitely the cleaner solution.
editor.on('component:selected', function(arg) {
if (arg[1].get('traits').where({name: 'header-type'}).length > 0) {
var tagName = arg[1].attributes.tagName;
setTimeout(function () {
$('div.gjs-trt-trait select').val(tagName);
}, 0);
}
});The problem is not the synchronization. The problem is, when I'm adding complete layouts to the canvas, which are including h2 or h3 tags (or any others), and I'm clicking on them, the header type select in the settings (traits) always stays at "Headline 1", as this is the first option in the select and there's no possibility to give any of the select options the attribute 'selected'
This the exactly the type of synchronization I was talking about... Have you tried my example???
Related Questions and Answers
Continue research with similar issue discussions.
Issue #1714
auto select componet in RTE
When I add a link from RTE, it is not selected as the link component, I have to deselect the parent component that is the TEXT and select a...
Issue #544
Add select with optgroup
Hello @artf I have recently started using grapeJs and found it awesome. Can you please help me on How can I add dropdown(select) with optgr...
Issue #639
Re-render Component on Canvas when tagName has changed
I'm trying to build a basic Header component that lets you select H1 to H6 with a trait. But when an option is selected, the canvas doesn't...
Issue #1586
[Question] update Trait select option dynamically
I tried this to update trait selection. var updateTrait = function(id, name) { var typeTrait = model.get('traits').where({name: 'type'})[0]...
Paid Plugins That Match This Issue
Curated by issue keywords and label relevance to help you ship faster.
Loading paid plugin recommendations...
Browse Plugin Categories
Jump directly to plugin category pages on the marketplace.