11

Here's a short piece of code:

var $el = $("#something").find(".test"); if (!$el.length) { $("#something").append('<div class="test">somecontent</div>'); } else { $el.replaceWith('<div class="test">somenewcontent</div>'); } 

I couldn't find a method appendOrReplaceWith or anything similar.

Any ideas how can I make it shorter?

I believe that:

$("#something").appendOrReplace('<div class="test">sometext</div>'); 

would be much easier to read, but no such method is available yet.

3
  • 4
    What's wrong with that? Commented Apr 9, 2014 at 18:56
  • 4
    Life isn't about codegolf - it's about quality. Commented Apr 9, 2014 at 18:56
  • 2
    @RUJordan quality != readability Commented Apr 9, 2014 at 18:57

5 Answers 5

6

Just remove it first then append.

$rootElement = $("#something"); $originalElement = $rootElement.find('.test'); if($originalElement.length) { $originalElement.after('<div class="test">somecontent</div>'); $originalElement.remove() } else { $rootElement.append('<div class="test">somecontent</div>'); } 
Sign up to request clarification or add additional context in comments.

1 Comment

This would guarantee the element always appeared as the last child which is not the same as replacing it in its current position
2

Mandatory vanilla answer. It may not be shorter, but it's faster.

Get the element, grab all subelements with the class "test", create your div, check the subelements length, and if length is truthy, set the innerHTML to the div. Else, append it.

var el = document.getElementById("something"); var subel = el.getElementsByClassName("test"); var div = document.createElement("div"); div.className = "test" if (subel.length) { div.textContent = "somenewcontent"; while(el.hasChildNodes()) el.removeChild(el.lastChild); //remove child nodes el.appendChild(div); } else { div.textContent = "somecontent"; el.appendChild(div); } 

5 Comments

"Any ideas how can I make it shorter?"
@f00bar shorter is not always better.
@RokoC.Buljan icwutudidthere :O
@f00bar I never said your answer was bad. I just like to advocate pure JS on jQuery questions -- I can't tell you how many times I've seen jQuery answers when all I wanted was a JS answer.
@RokoC.Buljan still agree .. giving you +1 because I did not satisfy the question apparently :/
2

Adding a method like findOrAppend to jQuery could be useful:

$.fn.findOrAppend = function(selector, content) { var elements = this.find(selector); return elements.length ? elements : $(content).appendTo(this); } 

Then you can chain text, replaceWith, empty etc. as needed:

$("#something") .findOrAppend(".test", "<div class='test'>") .text("newcontent"); 

Comments

0

First of all you should cache your selectors:

var $som = $('#something'); var $ele = $(".test",$som); var newHtml = '<div class="test">somecontent</div>'; if (!$el[0]) $som.append( newHtml ); else $ele.replaceWith( newHtml ); 

but you already did it really fine, (beside not caching repeated selectors), and me, trying to make it smaller could be a**-kicked for not using {} for my if and else :)

Comments

0

I would do this

var $s = $("#something"), $t = $s.find(".test"), c = 'New content'; ( $t[0] ? $t:$s)[( $t[0] ? 'html':'append')](( $t[0] ? c :$('<div>',{class:'test'}).append(c))); 

11 Comments

(+1) Or even shorter [!$el[0]?'append':'html']
I don't know how readable it is, not sure I'd use it, but I like it.
@EdPlunkett it's perfectly readable if you know about the Conditional Operator (which is elementary in JS) so yes. +1
This is incorrect, you will replace the whole content with the html method, I want to replace only the div with class test.
@RokoC.Buljan for the record. I'd fail the code in this answer in a code review. Also, I'd fail op's code, OP has an xy problem.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.