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>
Chaya Cooper
  • 2,566
  • 2
  • 38
  • 67

3 Answers3

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.

Daniel Imms
  • 47,944
  • 19
  • 150
  • 166
  • 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? – Chaya Cooper Apr 16 '13 at 03:18
  • 1
    Updated, prepend means insert as first child, append means insert as last child. – Daniel Imms Apr 16 '13 at 03:21
  • 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 http://jsfiddle.net/chayacooper/NCSPE/1/ (I still have to play around with the position to get the colorbox to the left of the checkbox). – Chaya Cooper Apr 16 '13 at 03:35
  • Updated the fiddle, your markup at the top has a quote issue ` – Daniel Imms Apr 16 '13 at 03:41
  • @ChayaCooper is this what you were after? http://jsfiddle.net/FzfEG/ This prepends it to the `li` instead of `li span`. – Daniel Imms Apr 16 '13 at 03:47
  • Oops :-( I think that's a sign that I've spent too many hours trying to figure this out today ;-) – Chaya Cooper Apr 16 '13 at 03:48
  • I want to include it inside the
  • :-) I'm actually combining this with some additional code so that I can have the color boxes replace the checkboxes
  • – Chaya Cooper Apr 16 '13 at 03:51
  • 1
    @ChayaCooper I updated my answer with a suggestion for custom checkboxes. – Daniel Imms Apr 16 '13 at 04:01
  • 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? – Chaya Cooper Apr 16 '13 at 04:08
  • 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. http://jsfiddle.net/htbH8/ – Daniel Imms Apr 16 '13 at 04:14
  • 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 :-) – Chaya Cooper Apr 16 '13 at 04:23
  • 1
    Target without `:checked` to specify the unchecked state http://jsfiddle.net/htbH8/1/ – Daniel Imms Apr 16 '13 at 04:26
  • 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? – Chaya Cooper Apr 16 '13 at 04:45
  • 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. – Daniel Imms Apr 16 '13 at 04:59
  • 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) – Chaya Cooper Apr 16 '13 at 05:13
  • 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/5 – Chaya Cooper Apr 16 '13 at 07:40