How to add CSS via the Update function?

I’ve been following @eli 's phenomenal video tutorials on how to build a dropdown element - they are possibly the best resource out there for aspiring plugin builders.

However, I cannot figure out how to allow users to styles (i.e. font colors, border colors etc.) to the element.

I have a field called “font_color”:

This is my initialize function

function(instance, context) {

// create an ID
const getID = () => {return Math.random().toString(36).substr(2,9)},
      id = 'searchabledropdown' + getID();

console.log ('html id: ' + id);

// add dropdown element to canvas
$(instance.canvas).append(`<select id="${id}" class="slim-dropdown"></select>`)
console.log(instance.data.nextStyle);

// apply SlimSelect
instance.data.select = new SlimSelect({
    select: `#${id}`});
}

But I just can’t figure out how to dynamically update the CSS in the “Update” function. I’ve previously asked a similar question and got several helpful responses @rico.trevisan @vladimir.pak @pork1977gm, but still not able to figure it out.

Hoping someone can help me with this more tangible example?

Hi,

Do you want to apply inline styles, like <div style=“background:black”>, or via dynamic stylesheet, like
<style>
myclass.div {
background:black;
}
</style>

<body>
<div class=“myclass”>

</div>
</body>
?

Thanks for replying @vladimir.pak! I think inline styles would work best - any idea how I might apply using my “font_color” field?

something like
instance.canvas.children(`#${id}`).css({“font-color”: properties[“font_color”] })

const mainContainer = document.createElement('div');
mainContainer.style.backgroundColor = '#333';
mainContainer.style.width = properties.bubble.width;
mainContainer.style.height = properties.bubble.height;
mainContainer.style.color = '#fff';    

instance.canvas.append(mainContainer);

mainContainer.style.color = ‘#fff’; is where you’d stick your properties.font_color

so a correct implementation might look like
mainContainer.style.color = properties.font_color ? properties.font_color : ‘#fff’;

1 Like

or

const mainDiv = document.createElement('div');
mainDiv.innerHTML = `
    <div style="width: ${properties.bubble.width}px;
                height: ${properties.bubble.height}px;
                min-width: ${properties.bubble.min_width_css};
                max-width: ${properties.bubble.max_width_css};
                min-height: ${properties.bubble.min_height_css};
                max-height: ${properties.bubble.max_height_css};
                background-color: ${properties.bubble.bgcolor};
                margin-top: ${properties.bubble.margin_top}px;
                margin-bottom: ${properties.bubble.margin_bottom}px;
                margin-left: ${properties.bubble.margin_left}px;
                margin-right: ${properties.bubble.margin_right}px;
                display: ${properties.bubble.collapse_when_hidden ? 'none' : 'block'};">
        <!-- Your content goes here -->
    </div>`;

// Handle background styles
if (properties.bubble.background_style === 'gradient') {
    mainDiv.firstChild.style.background = properties.bubble.background_gradient_style();
    mainDiv.firstChild.style.backgroundImage = `${properties.bubble.background_gradient_direction}(${properties.bubble.background_gradient_from}, ${properties.bubble.background_gradient_to})`;
    mainDiv.firstChild.style.backgroundImage += ` ${properties.bubble.background_gradient_mid}`;
} else if (properties.bubble.background_style === 'radial_gradient') {
    mainDiv.firstChild.style.background = `${properties.bubble.background_radial_gradient_shape}-gradient`;
    mainDiv.firstChild.style.backgroundImage = `radial-gradient(${properties.bubble.background_radial_gradient_shape} ${properties.bubble.background_radial_gradient_size} at ${properties.bubble.background_radial_gradient_xpos()}% ${properties.bubble.background_radial_gradient_ypos}%`;
    mainDiv.firstChild.style.backgroundImage += `, ${properties.bubble.background_gradient_from}, ${properties.bubble.background_gradient_to}`;
} else if (properties.bubble.background_style === 'image') {
    mainDiv.firstChild.style.background = properties.bubble.background_color_if_empty_image;
    mainDiv.firstChild.style.backgroundImage = `url('${properties.bubble.background_image}')`;
    if (properties.bubble.center_background) {
        mainDiv.firstChild.style.backgroundPosition = 'center';
    }
    if (properties.bubble.background_size_cover) {
        mainDiv.firstChild.style.backgroundSize = 'cover';
    }
    if (properties.bubble.crop_responsive) {
        mainDiv.firstChild.style.backgroundRepeat = 'no-repeat';
        mainDiv.firstChild.style.backgroundSize = '100% auto';
    }
    if (properties.bubble.repeat_background_vertical) {
        mainDiv.firstChild.style.backgroundRepeat = 'repeat-y';
    }
    if (properties.bubble.repeat_background_horizontal) {
        mainDiv.firstChild.style.backgroundRepeat = 'repeat-x';
    }
}

// Set the font styles
mainDiv.firstChild.style.fontSize = `${properties.bubble.font_size}px`;
mainDiv.firstChild.style.textAlign = properties.bubble.font_alignment;
if (properties.bubble.bold) {
    mainDiv.firstChild.style.fontWeight = 'bold';
}
if (properties.bubble.italic) {
    mainDiv.firstChild.style.fontStyle = 'italic';
}
if (properties.bubble.underline) {
    mainDiv.firstChild.style.textDecoration = 'underline';
}
mainDiv.firstChild.style.color = properties.bubble.font_color;
mainDiv.firstChild.style.fontFamily = properties.bubble.font_face;

// Handle visibility
if (!properties.bubble.is_visible) {
    mainDiv.firstChild.style.visibility = 'hidden';
}

Or my fav

    instance.canvas.empty();

var newDiv = $('<div/>', {
    id: 'myNewDiv',
    text: 'Hello, World!'
});

instance.canvas.append(newDiv);

// Apply CSS
newDiv.css({
    'width': properties.bubble.width + 'px',
    'min-width': properties.bubble.min_width_css,
    'max-width': properties.bubble.max_width_css,
    'height': properties.bubble.height + 'px',
    'min-height': properties.bubble.min_height_css,
    'max-height': properties.bubble.max_height_css,
    'margin-top': properties.bubble.margin_top + 'px',
    'margin-bottom': properties.bubble.margin_bottom + 'px',
    'margin-left': properties.bubble.margin_left + 'px',
    'margin-right': properties.bubble.margin_right + 'px',
    'background-color': properties.bubble.bgcolor,
    'font-size': properties.bubble.font_size + 'px',
    'text-align': properties.bubble.font_alignment,
    'color': properties.bubble.font_color,
    'font-family': properties.bubble.font_face,
    'display': properties.bubble.is_visible ? 'block' : 'none'
});
1 Like

Hi all, thanks for the input on this. Feel like I’m getting closer, but still not quite there. My main problem seems to be accessing the element I’m creating in the intialize function in the update function.

@vladimir.pak I kept running into syntax errors using your suggested approach for inline styles

Code for Initialize Function

function(instance, context) {
    
    // create an ID
    const getID = () => {return Math.random().toString(36).substr(2,9)},
          id = 'searchabledropdown' + getID();
    
    console.log ('html id: ' + id);
    
    // add dropdown element to canvas
    $(instance.canvas).append(`<select id="${id}" class="slim-dropdown"></select>`)
    console.log(instance.data.nextStyle);
    
    // apply SlimSelect
    instance.data.select = new SlimSelect({
        select: `#${id}`});
    
}

Code for Update Function

function(instance, properties, context) {
    
    // getting the id of slimselect dropdown from initalize function
    let select = instance.data.select;
    
	instance.canvas.children(`#${select}`).css("font-color", "red");
}

This is the error I’ve gotten:

@doug.burden I particularly like your approach of using the .ccs(), but it won’t work for me as I’m defining my “select” (equivalent to newDiv in your example) in the “initalize” function and then applying the CSS in the “update” function.

Code for Initialize Function

function(instance, context) {
    
    // create an ID
    const getID = () => {return Math.random().toString(36).substr(2,9)},
          id = 'searchabledropdown' + getID();
    
    console.log ('html id: ' + id);
    
    // add dropdown element to canvas
    $(instance.canvas).append(`<select id="${id}" class="slim-dropdown"></select>`)
    console.log(instance.data.nextStyle);
    
    // apply SlimSelect
    instance.data.select = new SlimSelect({
        select: `#${id}`});
    
}

Code for Update function

function(instance, properties, context) {
    
    // getting the id of slimselect dropdown from initalize function
    let select = instance.data.select;
    
    // add css to style font color
    select.css({'color': properties.bubble.font_color});
}

I get the following error:

So I suspect the issue is in accessing the slimselect dropdown element itself, rather than how I’m applying the CSS?

If either of you (or anyone else) has any thoughts on what I’m doing wrong I would really appreciate it.

It would have to be a jquery object. If your object has an id you could just

let newDiv = $(‘#some-value’);

newDiv.css({
‘color’: properties.font_color,:
});

And maybe

let newDiv = $(`${instance.data.select}`);
1 Like

Thanks for this @doug.burden - very much appreciated.

My issue now is how to access elements I’ve created in the initialize function in my update function.

Kind of a separate issue, so I’ve created a separate thread for clarity for any future plugin builders that stumble across this.

Thanks again for your assistance.

What you’d do is, in your initialize func

let slimeyBoi = $('div', {
id: 'slimey-grimey-boi',
});

slimeyBoi.css({
'width': '100%',
'height': '100%',
});

instance.canvas.append(slimeyBoi);

Update func

let slimeyBoi = $('#slimey-grimey-boi');

slimeyBoi.css({
'background-color': properties.bubble.bgColor,
'color': properties.font_color,
});
1 Like

You seem to miss the concept of objects and properties in javascript. When you access instance.data.select property in update function you get object created with new SlimSelect(…) constructor (i’m not aware what it is). In update function select variable is assigned to this object instance. And when you try to filter children using `#${select}`, it is evaluated to #[object Object] because an object created with new SlimSelect(…) has default toString method that just returns a string value of [object Object]. This value is not a valid selector, that’s why instance.canvas.children(…) method fails with the error unrecognized expression.
To understand it you need to spend some time reading about jQuery:
jQuery Syntax (w3schools.com)
jQuery API Documentation
And I’d suggest reading some tutorials about javascript objects and properties, there are lots of them available on the net for free.

1 Like

Thanks @vladimir.pak - spent sometime going through jQuery tutorials and it’s a lot clearer to me now. Appreciate all the assistance :slight_smile: