Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct Way to Dynamically Add Semantic UI Controls?

I'm trying to wrap my head around Semantic UI and I understand how everything is controlled by what class you give to a DOM element, but I can't really get that to work when adding new DOM elements dynamically. It seems like the semantic ui javascript is only getting run on first page load and not on those new elements when I add them. Currently, this is just done via:

$("#target").html("<new elements here>")

Is there are correct way to do this? I cannot find any documentation about this on the Semantic UI site.

Update: To give a better example...

Say I have this layout:

<div class="right menu" id="rightMenu">
    <div class="ui dropdown link item">
      Courses
      <i class="dropdown icon"></i>
      <div class="menu">
        <a class="item">Petting</a>
        <a class="item">Feeding</a>
        <a class="item">Mind Reading</a>
      </div>
    </div>
    <a class="item">Library</a>
    <a class="item">Community</a>
  </div>
</div>

And this code is run:

var menu = '<div class="ui dropdown link item"> \
  Test \
  <i class="dropdown icon"></i> \
  <div class="menu"> \
    <a class="item" href="http://google.com">Google</a> \
    <a class="item" href="http://amazon.com">Amazon</a> \
  </div> \
</div>';

$("#rightMenu").append(menu)

The new menu item appears just fine... BUT it doesn't actually dropdown like it should, until I run this:

$('.ui.dropdown')
  .dropdown({
    on: 'hover'
  });

After that, it opens on hover just fine. But is there a way to not have to rerun that every time?

like image 541
Adam Haile Avatar asked May 29 '15 13:05

Adam Haile


3 Answers

There are few ways of adding elements to DOM. html (would empty the container and then insert new elements) is one of them. You can also use append to append new elements to an existing set. But, your problem is about events not being triggered on dynamically added elements. The solution for this is event delegation. Read more about it here.

From the jQuery doc: Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, you can use delegated events to avoid the need to frequently attach and remove event handlers.

Here is a quick demo I'd set up about adding new elements, event delagation etc. Hope that helps.

var $container = $("#container");
var count = 3;

$container.on("click", 'button', function() {

    alert ("You've clicked on " + $(this).text() );
});

$("#addButtons").on("click", function() {

    $container.append("<button>Button" + (++count) + "</button>");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
    <button>Button1</button>
    <button>Button2</button>
    <button>Button3</button>
</div>

<button id="addButtons">Add a few more!</button>

EDIT: Even for dynamically adding Semantic UI elements, the rule remains the same as it's just an element. I am not sure if there are other problems on your page. Look at the updated demos below.

1) Using append

2) Using html

EDIT: So, that's how the Semantic UI Dropdown is supposed to work as the dropdown is created/rendered by Javascript. Therefore, when new options/dropdowns are added the related method ($('.ui.dropdown').dropdown({on: 'hover'});) needs to be re-triggered. Another workaround is to add the simple class to the newly created dropdown, i.e. var menu = '<div class="ui simple dropdown link item"> \ which would trigger the dropdown when you mouseover, but. it's with no animation!

Hope that helps.

like image 84
lshettyl Avatar answered Sep 25 '22 02:09

lshettyl


You can put your semantics jquery call in a function and call it in a callback after an appendTo like

$(menu).appendTo("#rightMenu").each(function() {
activateSemantics();
});
function activateSemantics(){
     $('.ui.dropdown')
  .dropdown({
      on: 'hover'});
}
like image 36
loli Avatar answered Sep 23 '22 02:09

loli


After adding elements via JQuery like LShetty said, for semantic UI dropdown, you need to initialize it. But it seems your concern is your re-initializing the other dropdowns as well with different, or added settings. In that case, just initialize that one added dropdown.

Note that it's not the case for every Semantic UI elements, probably just dropdown elements and a few others.

var menu = '<div class="ui dropdown link item"> \
  Test \
  <i class="dropdown icon"></i> \
  <div class="menu"> \
    <a class="item" href="http://google.com">Google</a> \
    <a class="item" href="http://amazon.com">Amazon</a> \
  </div> \
</div>';

$("#rightMenu").append(menu)

menu.find(".ui.dropdown")
  .dropdown({
    on: 'hover'
  });
like image 27
MTran Avatar answered Sep 26 '22 02:09

MTran