I have two functions that generate DOM elements. They both attempt to create the same container element. (I'd prefer not to enforce a specific run order for these functions, or tightly couple them to the side-effect of creating this element). I've been trying to discover a method that would get an element if it exists, or create a single instance of it if it doesn't, and return a jQuery object containing that element or all the matched elements if they already exist.

I haven't found this to exist in searching through jQuery documentation, but I thought I'd ask here to see if anyone else has encountered a similar problem and has suggestions.

Let's put the convenience in convenience method (in addition to keeping a separation of concerns!! Here's an jQuery function titled upsert that will either locate an existing element or create a new element if none exist.

So just include this jQuery anywhere:

<!-- language: lang-js -->
$.fn.upsert = function(selector, htmlString) {
  // upsert - find or create new element
  // find based on css selector   	https://api.jquery.com/category/selectors/
  // create based on jQuery()       http://api.jquery.com/jquery/#jQuery2
  var $el = $(this).find(".message");
  if ($el.length == 0) {
    // didn't exist, create and add to caller
    $el = $("<span class='message'></span>");
    $(this).append($el);
  }

  return $el;
}; 

Then you could use like this:

<!-- language: lang-js -->
$("input[name='choice']").click(function(){
  var $el = $(this).closest("form").upsert(".message", "<span class='message'></span>");
  // guaranteed to have element - update if we want
  $el.html("You've chosen "+this.value)
})

Ideally, it would be nice to simply pass in a selector and have jQuery create an element that matches that selector automatically, but it doesn't seem like there's a light weight vehicle for creating an element based off the CSS Selector syntax (based on Question 1 & Question 2).

Some further enhancements might provide more fine tuned control for DOM insertion instead of just always using .append().

Demo in jsFiddle | Demo in Stack Snippets:

<!-- begin snippet: js hide: true console: false babel: false --> <!-- language: lang-js -->
$.fn.upsert = function(selector, htmlString) {
  // upsert - find or create new element
  // find based on css selector   	https://api.jquery.com/category/selectors/
  // create based on jQuery()       http://api.jquery.com/jquery/#jQuery2
  var $el = $(this).find(".message");
  if ($el.length == 0) {
    // didn't exist, create and add to caller
    $el = $("<span class='message'></span>");
    $(this).append($el);
  }

  return $el;
}; 

$("input[name='choice']").click(function(){
  var $el = $(this).closest("form").upsert(".message", "<span class='message'></span>");
  // guaranteed to have element - update if we want
  $el.html("You've chosen "+this.value)
});
<!-- language: lang-html -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<form action="">
  <div>
    <input type="radio" id="ca" name="choice" value="A" /><label for='ca'>A</label>
    <input type="radio" id="cb" name="choice" value="B" /><label for='cb'>B</label>
    <input type="radio" id="cc" name="choice" value="C" /><label for='cc'>C</label>
  </div>
</form>
<!-- end snippet -->