Issue #1095Opened May 8, 2018by Chilli-B0 reactions

[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)

Code SnippetTEXT
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)

artfMay 10, 20180 reactions

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,
}

Chilli-BMay 10, 20180 reactions
Code SnippetTEXT
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);
		}
	});
artfMay 14, 20180 reactions

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.

Paid Plugins That Match This Issue

Curated by issue keywords and label relevance to help you ship faster.

View all plugins

Loading paid plugin recommendations...

Browse Plugin Categories

Jump directly to plugin category pages on the marketplace.