2

Fueled by this question, I've been trying to do something that i've never tried before.

Using the latest method of creating new HTML elements, i did the following:

$(function() {
  var $element = $('<select>', {
    class: 'form-control',
    name: 'dropdownmenu',
    text: function() {
      var $test = $('<option>', {
        value: '1',
        text: '1'
      });

      return $test;
    }
  });

  $('p').after($element);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
</p>
<p>
</p>
<p>
</p>
<p>
</p>
<p>
</p>

But, as you can see, i couldn't get to insert a "real" <option> to the created <select> text attribute. All i get in return is [object Object].

I even tried returning .get(0), but it didn't work either.

I'm not very experienced with JavaScript yet, so i'm just wondering if this is possible. If it is, what can i do to achieve the desired behaviour?

apires
  • 917
  • 1
  • 9
  • 18

1 Answers1

3

You're on the right track, but you need to use html not text if you want to insert nested html. See the below snippet:

$(function() {
  var $element = $('<select>', {
    class: 'form-control',
    name: 'dropdownmenu',
    html: function() {
      var $teste = $('<option>', {
        value: '1',
        text: '1'
      });

      return $teste;
    }
  });

  $('p').after($element);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
</p>
<p>
</p>
<p>
</p>
<p>
</p>
<p>
</p>

Edit - Followup question (multiple options)

You can map over the desired options with minimal change to your code - see the below snippet:

var options = [1, 2, 3, 4, 5];

$(function() {
  var $element = $('<select>', {
    class: 'form-control',
    name: 'dropdownmenu',
    html: options.map(function(option) {
      return $('<option>', {
        value: option,
        text: option
      })
    })
  });

  $('p').after($element);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
</p>
<p>
</p>
<p>
</p>
<p>
</p>
<p>
</p>
Damon
  • 4,216
  • 2
  • 17
  • 27
  • I see! Do you know where can i learn all attributes i could set when using this method of creation? I've looked in jQuery documentation, but there's nothing specific about it. Also, what could i do to create more than one option inside this callback? Is a `for` loop the best approach? – apires Jun 09 '17 at 20:56
  • 1
    @doutriforce [`jQuery(html, attributes)`](http://api.jquery.com/jquery/#jQuery-html-attributes) at documentation. See also [How to pass options objects as parameters to method set at second parameter of jQuery()?](https://stackoverflow.com/questions/35526060/how-to-pass-options-objects-as-parameters-to-method-set-at-second-parameter-of-j) – guest271314 Jun 09 '17 at 20:59
  • ^ This. As the docs specify any attributes, events, or (jQuery) methods – Damon Jun 09 '17 at 21:04
  • 1
    Note that `class` *should* be quoted, as it's a keyword – adeneo Jun 09 '17 at 21:19
  • @adeneo Quoted for disambiguation, though not technically necessary, correct? Though have quoted `"class"` since the topic was queried at [Do reserved words need to be quoted when set as property names of javascript objects?](https://stackoverflow.com/questions/40209367/do-reserved-words-need-to-be-quoted-when-set-as-property-names-of-javascript-obj) – guest271314 Jun 09 '17 at 21:23
  • @guest271314 - Well, `class` is a reserved keyword in both ES5 and ES6, so it absolutely **should** be quoted, but it would work most of the time without the quotes, because it's a property name. The jQuery [documentation](http://api.jquery.com/jquery/) actually says it **must** be quoted. – adeneo Jun 09 '17 at 21:29
  • @adeneo _"not quoting it is an error, even if it works."_ Curious what you mean here? The potential for an error? At that context `class` is only a property of an object literal, no? – guest271314 Jun 09 '17 at 21:31
  • 3
    @guest271314 - removed that part, as it's not an error – adeneo Jun 09 '17 at 21:32
  • It should also be noted that this answer only works because `after` clones the element. There's only one select created, but `after` clones it, and the function isn't needed for `html`, using `html: $(' – adeneo Jun 09 '17 at 21:37
  • Thanks for all the replies, mates. Only one question left. If i had to create more than one option, the best approach would be the good old `for` loop? Or is there a "prettier", more dinamyc, practical way? – apires Jun 10 '17 at 01:38
  • 1
    @doutriforce I added another snippet. Cleanest way would be to use `map` imo. Also you should take the above advice, it's pretty on point (but "class" doesn't need to be quoted since ES5 so don't worry about that part). – Damon Jun 10 '17 at 15:29