5

What is the best way to create the following div element in jQuery?

<div class="btn-group">
  <button class="btn dropdown-toggle" title="Manage" data-toggle="dropdown">
    <span class="caret"></span>
  </button>
</div>

I've tried multiple formats, but I can't seem to get it right.

  var itemsButtonsDiv = $('<div><button><span></span></button></div>')
    .addClass("btn-group")
    .attr({
      title: "Manage",
      "data-toggle": "dropdown"
    })
    .find("button")
      .addClass("btn dropdown-toggle")
      .find("span")
        .addClass("caret")
  ;


  var itemsButtonsDiv = $("<div><button><span></span></button></div>", {
    "class": "btn-group",
    html: "  ??  Does everything else go here as one long text string  ??  "
  });

I realize that I have to append the element separately after I create it, but I can't get the creation right.

Andy G
  • 19,232
  • 5
  • 47
  • 69
Simpler
  • 1,317
  • 2
  • 16
  • 31

3 Answers3

5

If I may suggest a traditional approach, I'd do something like this:

var group = document.createElement("div");
group.className = "btn-group";

var btn = document.createElement("button");
btn.className = "btn dropdown-toggle";
btn.title = "Manage";
btn.setAttribute("data-toggle","dropdown");

var caret = document.createElement("span");
caret.className = "caret";

btn.appendChild(caret);
group.appendChild(btn);

If you want to make a jQuery element out of the dom element, you can do $(group).

I believe that this traditional approach has several advantages:

  • It's very straightforward what's happening, even if you're not 100% familiar with the jQuery API.
  • It's native, so it's likely faster since it doesn't have to invoke any parser.
  • Every element is defined first, and the relationships are defined later, so I think it's clearer.

If you find that too long, and more generally - this sort of code should be extracted to a method

function buildButtonGroup(){
    // rest of the code here
    return group;
}
Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
  • In case you care, [The other solutions are over 90% slower](http://jsperf.com/create-native-or-jquery) - that should not be a big consideration on its own though. – Benjamin Gruenbaum Sep 01 '13 at 01:55
0

I may choose something like

var $div = $('<div />', {
    class: 'btn-group'
});
var $btn = $('<button />', {
    class: 'btn dropdown-toggle'
}).appendTo($btn)
$('<span />', {
    class: 'caret'
}).appendTo($div)

For a more complex dom structure I may choose a template like underscore or jsrender

Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
  • I haven't verified this, but I'm pretty certain that you have to quote `'class'`, since it's a [reserved word](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Reserved_Words) in JavaScript. – David Thomas Sep 01 '13 at 02:51
  • @DavidThomas, This method is very slow in comparison to `$div.append(""):` choose wisely. – Starx Sep 01 '13 at 03:03
  • @Starx: okay, but why are you telling me..? – David Thomas Sep 01 '13 at 03:17
  • @DavidThomas, Oh.. I thought you were the OP ha ha. Good Laugh!! – Starx Sep 01 '13 at 04:22
  • 1
    @DavidThomas only in old implementations. It's perfectly legal in ES5 (so expect OLD IE to crap its pants) - but modern browsers will gladly let you stuff like `class:` in an object literal. – Benjamin Gruenbaum Sep 01 '13 at 11:22
0

This should work, however you can also just construct an html string and convert it with $(html);;

var btnGroup = $("<div/>", {"class": "btn-group"});

var btn = $('<button/>', {
      'class': 'btn dropdown-toggle',
      title: "Manage",
      "data-toggle": "dropdown"
    });
btn.append($('<span/>', {'class': 'caret'});
btnGroup.append(btn);

This is also acceptable :

var btnGroup = $('<div class="btn-group"> <button class="btn dropdown-toggle" title="Manage" data-toggle="dropdown"> <span class="caret"></span> </button> </div>');
OneOfOne
  • 95,033
  • 20
  • 184
  • 185