Add .css() to prepended div
Asked Answered
S

3

5

This prepend function adds a div with the "colorBox" class, but I'm having trouble setting the css for the newly created div. I don't know if my syntax is quite right, but I'm trying to use the data-background value in the parent (li) tag.

I'm using this to add color boxes to multiselect options, and the plugin that I'm using converts each option into a <li> that is structured like the HTML I've included below.

JS

$(function(){
    $("li span").prepend('<div class="colorBox"></div>').css('background-color', $(this).parent().attr("data-background"));   
});

HTML

<ul>
    <li data-background="#C11B17">
        <input type="checkbox" name="color[]" value="Brick_Red">
        <span>Brick Red</span>
    </li>
</ul>
Sapless answered 16/4, 2013 at 3:11 Comment(2)
JSFiddle: jsfiddle.net/Bushwazi/vjWzQEvaginate
@JasonLydon - I think this might be slightly off because it's showing the text instead of setting the .cssSapless
D
6

Try splitting your code up a bit. It's failing because .css() is actually being called on the parent and this is referring to window in your context.

jsFiddle

$(function(){
    // Get all elements matching selector 'li span'
    var spans = $("li span");
    // Loop for each element in spans
    spans.each(function () {
        // Create the new element as a jQuery object
        var elem = $('<div class="colorBox">test</div>');
        // Set the new element's background-color to the attribute on the parent
        // of the span
        elem.css('background-color', $(this).parent().attr("data-background"));
        // Prepend the new element to the span (insert it as the first child)
        $(this).prepend(elem);
    });
});

If you mean to wrap "Brick Red" in the div then you will need to use .wrap() or .wrapInner().

jsFiddle

$(this).wrap(elem);

Update

If you're after custom checkboxes, I suggest a more css-driven approach which takes advantage of the <label> tag.

jsFiddle

HTML

<ul>
    <li data-background="#C11B17">
        <input type="checkbox" name="color[]" value="Brick_Red" id="checkbox1" />
        <label for="checkbox1">
            <span>Brick Red</span>
        </label>
    </li>
</ul>

CSS

input[type=checkbox] {
    display:none;
}

input[type=checkbox] + label:before {
    display:inline-block;
    content:"";
    width:1em;
    height:1em;
    background-color:#CCC;
}

input[type=checkbox]:checked + label:before {
    background-color:#C11B17;
}

Note that this method will work in IE8+ without any polyfills.

Dative answered 16/4, 2013 at 3:14 Comment(16)
I'm new to the world of append/prepend so I'm having a little trouble following the logic. Can I trouble you to add a few comments so that I'll understand the principle behind it?Sapless
Updated, prepend means insert as first child, append means insert as last child.Dative
How do I get it to display a checkbox instead of a textbox? I figured it would be helpful to post a fiddle with the basic layout I'm going for to address that and your question about wrapping the text jsfiddle.net/chayacooper/NCSPE/1 (I still have to play around with the position to get the colorbox to the left of the checkbox).Sapless
Updated the fiddle, your markup at the top has a quote issue <input "type=checkbox" the quotes should only be around checkbox.Dative
@ChayaCooper is this what you were after? jsfiddle.net/FzfEG This prepends it to the li instead of li span.Dative
Oops :-( I think that's a sign that I've spent too many hours trying to figure this out today ;-)Sapless
I want to include it inside the <li> :-) I'm actually combining this with some additional code so that I can have the color boxes replace the checkboxesSapless
@ChayaCooper I updated my answer with a suggestion for custom checkboxes.Dative
OMG! You're awesome :-D And that's so much cleaner than the script I was using :-) Is there a simple way to set the background color to equal the data-attribute or should I use a script similar to the approach I was taking earlier?Sapless
The way I would do the colors would be to add a color class to one of your elements and use CSS to apply that there. This way all the colors are in your CSS where they belong. jsfiddle.net/htbH8Dative
Out of curiosity, is there an easy way to connect the background-color to both the checked & unchecked state? I need to display it in both (I just toggle the opacity for the background color and the visibility of the checkmark). The way I was doing it is so much more cumbersome than your method :-)Sapless
Target without :checked to specify the unchecked state jsfiddle.net/htbH8/1Dative
I'd assumed it would be easier to specify it inline since I'm going to be using this for 300+ values (about 65 are background colors, and the rest are images), but now you've got me thinking that I might be able to use arrays instead of creating separate classes for each one. And I already have arrays set up connecting the element's value and the associated hex color or image :-) Do you happen to know how I could do that?Sapless
I would suggest using find and replace in that case, you can't specify the colours in JS and apply them to selectors in your CSS file. You would need to do it on the click event.Dative
Unfortunately I don't think that will work because I also have to show the colors/images when the checkbox is in the unchecked state (the unchecked & checked states both use the same value, just with a different opacity)Sapless
I figured out the opacity so I only have to specify the colors once, and I have a feeling that it might make it easier to use arrays now :-) jsfiddle.net/chayacooper/htbH8/5Sapless
E
4

If your going to use .css() instead of css, then why not just set it using style?

var color = $('li').attr('data-background');
$("span").prepend('<div class="colorBox" style="background:' + color + '"></div>');
Evaginate answered 16/4, 2013 at 3:22 Comment(11)
I didn't know that I could do that :-DSapless
Note that this will use the same color for every span. If your lis have different colors this method won't work.Dative
They do have different colors, but I'm assuming that I can structure it slightly differently so that it will refer to that <li>.Sapless
But for some reason the code isn't changing the background color :-( Would you mind taking a look at this fiddle? jsfiddle.net/chayacooper/NCSPE/2Sapless
Your missing the hash in the color. <li data-background="#C11B17">Evaginate
oops :-( I think that's a sign that I've spent too many hours trying to figure this out today ;-)Sapless
@ChayaCooper in your jsfiddle, change <li data-background="C11B17"> to <li data-background="#C11B17">Timid
To Daniel's point, why not just use css + classes for all of them? So that they are not all the same. ==> jsfiddle.net/Bushwazi/WmPwgEvaginate
I'm going to be using this for a lot of different elements, and that might be a good idea to consider for some of them :-) The ones I'm working on right now use either background colors or images and I have a feeling that it'll be easier for me to continue defining it inline since there are 300+ valuesSapless
I'm actually starting to rethink that, and I'm realizing that you might be right :-) But I'm definitely glad that I understand now how to apply styles to prepend because I'm sure I'll need to use it in lots of other situations :-) Out of curiosity, do you know how I would structure the function so that it refers to that specific <li> so that it would work with more than one value?Sapless
You mean like a for each loop or something? You could use a for each, start it at 0 and use .eq(i) to run thru each one.Evaginate
S
0

In jQuery the this word is about the last object in the chain. in your example $("li span") is the last object so when you use the 'this' word it'll be about $("li span"). To avoid this you can simply use a prependTo instead. This should do the trick:

jQuery(function(){
  jQuery('<div class="colorBox"></div>').prependTo(jQuery('#aaaa')).css(
  'background-color',jQuery(this).parent().attr("data-background"));   
});
Selectee answered 11/12, 2014 at 18:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.