0

I am developing an application that allows user to create new item, edit existing item, or remove an item via corresponding icons that appear next to it.

For the existing item, the action icon appears well on hover well as event handler attached to it, for this case onClick event handler.

$(document).ready(function() {
  var ul = `
     <ul class="list-inline in-item" style="padding: 10px;">
       <li><a href="#"><i class="fa fa-plus-circle icon-add"></i></a></li>
       <li><a href="#"><i class="fa fa-pencil-square-o icon-edit"></i></a></li>
       <li><a href="#"><i class="fa fa-trash-o icon-remove"></i></a></li>
       <li><a href="#"><i class="fa fa-arrows-v icon-move"></i></a></li>
     </ul>
    `;

  $('.item').hover(
    function() {

      $(ul).insertBefore($(this).find('.item-head'));

    },
    function() {
      $(this).find('ul.list-inline').remove();
    });

  $('body').on('click', '.icon-add', function() {
    // Add Item
    items = `
    <div class="item">
      <h3 class="item-head" contenteditable>[Type Item Here] [label]</h3>
      <p contenteditable>[Type what it does]</p>
    </div>
   `;
    // $('body').append(item);
    $('.item-container').append(items);
    return false;
  });

  $('body').on('click', '.icon-edit', function() {
    // Edit on Item
  });

  $('body').on('click', '.icon-remove', function() {
    // Remove Item and its definition

  });

  $('body').on('click', '.icon-move', function() {
    // Move item to up or down
  });

})
.item-head {
  color: #365efe;
}

.action-icon {
  float: left;
  margin-top: 25px;
  margin-left: -40px;
}

.icon-add {
  color: #4caf50;
}

.icon-edit {
  color: #00bcd4;
}

.icon-remove {
  color: #f44336;
}

.icon-move {
  color: #9e9e9e;
}

.in-item {
  display: block;
}

.out-item {
  display: none;
}

.list-inline>li:last-child {
  padding-right: 25px;
}

.list-inline {
  float: left;
  background: trasparent;
  position: absolute;
  left: -110px;
  top: 12px;
  height: 40px;
}

div.item {
  position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-T8Gy5hrqNKT+hzMclPo118YTQO6cYprQmhrYwIiQ/3axmI1hQomh7Ud2hPOy8SP1" crossorigin="anonymous">
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

<div class="col-sm-12">
  <div class="message"></div>
  <h3>Preview</h3>
  <div class="container" style="border: 1px solid #ccc;width: 70%;">
    <div class="row">
      <div class="col-xs-12 item-container">
        <div class="item">
          <h3 class="item-head" style="float: left;">Customer [form]</h3>
          <p style="clear: both;">Customer is module for recording information related to customer such as Name, Address, Date of Birth, Place of Birth, ID Number, etc.</p>
        </div>
        <div class="item">
          <h3 class="item-head">First Name English [label]</h3>
          <p class="definition">The name that was given to you when you were born and that comes before your family name. This field accept only English Character.</p>
        </div>
        <div class="item">
          <h3 class="item-head">Salutation [label]</h3>
          <p>A greeting in words or actions, or the words used at the beginning of a letter or speech. This field has values such as Mr, Ms, Miss.</p>
        </div>
      </div>
    </div>
  </div>
  </form>
</div>

However, the new item created from add icon does not have the attached action icons to it as well as the functionality as the existing icon, as it is already exact the same as existing item.

How can I make new created item works just as the existing item? Thanks

Houy Narun
  • 1,557
  • 5
  • 37
  • 86

2 Answers2

1

You don't need to append list dynamically. Write once, reuse it.

$(document).ready(function() {
  
$('.list-inline').mouseleave(function(){
  $(this).hide();
})

$('body').on('mouseenter', '.item', function(e){
  var topPosition = $(this).position().top + 10;
  $('.list-inline').show().css('top', topPosition);
  
})

  $('body').on('click', '.icon-add', function() {
    // Add Item
    items = `
    <div class="item">
      <h3 class="item-head" contenteditable>[Type Item Here] [label]</h3>
      <p contenteditable>[Type what it does]</p>
    </div>
   `;
    // $('body').append(item);
    $('.item-container').append(items);
    return false;
  });

  $('body').on('click', '.icon-edit', function() {
    // Edit on Item
  });

  $('body').on('click', '.icon-remove', function() {
    // Remove Item and its definition

  });

  $('body').on('click', '.icon-move', function() {
    // Move item to up or down
  });

})
.item-head {
  color: #365efe;
}

.action-icon {
  float: left;
  margin-top: 25px;
  margin-left: -40px;
}

.icon-add {
  color: #4caf50;
}

.icon-edit {
  color: #00bcd4;
}

.icon-remove {
  color: #f44336;
}

.icon-move {
  color: #9e9e9e;
}

.in-item {
  display: block;
}

.out-item {
  display: none;
}

.list-inline>li:last-child {
  padding-right: 25px;
}

.list-inline {
  background: trasparent;
  position: absolute;
  left: -110px;
  top: 12px;
  height: 40px;
}

div.item {
  position: relative;
  overflow: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-T8Gy5hrqNKT+hzMclPo118YTQO6cYprQmhrYwIiQ/3axmI1hQomh7Ud2hPOy8SP1" crossorigin="anonymous">
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

<div class="col-sm-12">
  <div class="message"></div>
  <h3>Preview</h3>
  <div class="container" style="border: 1px solid #ccc;width: 70%;">
    <div class="row" style="position:relative">
      <div class="col-xs-12 item-container">
      
      
      <!-- list here -->
          <ul class="list-inline in-item" style="display:none;padding: 10px;">
       <li><a href="#"><i class="fa fa-plus-circle icon-add"></i></a></li>
       <li><a href="#"><i class="fa fa-pencil-square-o icon-edit"></i></a></li>
       <li><a href="#"><i class="fa fa-trash-o icon-remove"></i></a></li>
       <li><a href="#"><i class="fa fa-arrows-v icon-move"></i></a></li>
     </ul>
          
          
          
        <div class="item">
          <h3 class="item-head" style="float: left;">Customer [form]</h3>
          <p style="clear: both;">Customer is module for recording information related to customer such as Name, Address, Date of Birth, Place of Birth, ID Number, etc.</p>
        </div>
        <div class="item">
          <h3 class="item-head">First Name English [label]</h3>
          <p class="definition">The name that was given to you when you were born and that comes before your family name. This field accept only English Character.</p>
        </div>
        <div class="item">
          <h3 class="item-head">Salutation [label]</h3>
          <p>A greeting in words or actions, or the words used at the beginning of a letter or speech. This field has values such as Mr, Ms, Miss.</p>
        </div>
      </div>
    </div>
  </div>
  </form>
</div>
Ibra
  • 906
  • 1
  • 7
  • 13
0

@Ibra, Thanks you so very much for your helpful answer I will accept it as the answer. Yet I would like to share what I'm finding regarding to my question.

According to this post: is-it-possible-to-use-jquery-on-and-hover, I figured out that the problem is with my event handler .hover() that I called it to populate the action icons.

Since .hover() does not work well on dynamic element created from JS as well as it is weird using .hover() on .on() handler, it prevent me from call my action icon from dynamic element.

Therefore from suggested answer in post above, it's working to replace .hover() with this:

$(".selector").on({
    mouseenter: function () {
        //stuff to do on mouse enter
    },
    mouseleave: function () {
        //stuff to do on mouse leave
    }
});

So I changed the .hover() handler to event handler .mouseenter() and .mouseleave() like this

/**
* Show Action Icons on Mouse over and hide it
* on Mouse out
*/
$('body').on({
    mouseenter: function () {
        //stuff to do on mouse enter
        $(ul).insertBefore($(this).find('.item-head'));
    },
    mouseleave: function () {
        //stuff to do on mouse leave
        $(this).find('ul.list-inline').remove();
    }
}, ".item");

So, my application turned out like this

$(document).ready(function() {
  var ul = `
     <ul class="list-inline in-item" style="padding: 10px;">
       <li><a href="#"><i class="fa fa-plus-circle icon-add"></i></a></li>
       <li><a href="#"><i class="fa fa-pencil-square-o icon-edit"></i></a></li>
       <li><a href="#"><i class="fa fa-trash-o icon-remove"></i></a></li>
       <li><a href="#"><i class="fa fa-arrows-v icon-move"></i></a></li>
     </ul>
    `;

  /**
   * Show Action Icons on Mouse over and hide it
   * on Mouse out
   */
  $('body').on({
    mouseenter: function() {
      //stuff to do on mouse enter
      $(ul).insertBefore($(this).find('.item-head'));
    },
    mouseleave: function() {
      //stuff to do on mouse leave
      $(this).find('ul.list-inline').remove();
    }
  }, ".item");

  $('body').on('click', '.icon-add', function() {
    // Add Item
    items = `
    <div class="item">
      <h3 class="item-head" contenteditable>[Type Item Here] [label]</h3>
      <p contenteditable>[Type what it does]</p>
    </div>
   `;
    // $('body').append(item);
    $('.item-container').append(items);
    return false;
  });

  $('body').on('click', '.icon-edit', function() {
    // Edit on Item
  });

  $('body').on('click', '.icon-remove', function() {
    // Remove Item and its definition

  });

  $('body').on('click', '.icon-move', function() {
    // Move item to up or down
  });

})
.item-head {
  color: #365efe;
}

.action-icon {
  float: left;
  margin-top: 25px;
  margin-left: -40px;
}

.icon-add {
  color: #4caf50;
}

.icon-edit {
  color: #00bcd4;
}

.icon-remove {
  color: #f44336;
}

.icon-move {
  color: #9e9e9e;
}

.in-item {
  display: block;
}

.out-item {
  display: none;
}

.list-inline>li:last-child {
  padding-right: 25px;
}

.list-inline {
  float: left;
  background: trasparent;
  position: absolute;
  left: -110px;
  top: 12px;
  height: 40px;
}

div.item {
  position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-T8Gy5hrqNKT+hzMclPo118YTQO6cYprQmhrYwIiQ/3axmI1hQomh7Ud2hPOy8SP1" crossorigin="anonymous">
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

<div class="col-sm-12">
  <div class="message"></div>
  <h3>Preview</h3>
  <div class="container" style="border: 1px solid #ccc;width: 70%;">
    <div class="row">
      <div class="col-xs-12 item-container">
        <div class="item">
          <h3 class="item-head" style="float: left;">Customer [form]</h3>
          <p style="clear: both;">Customer is module for recording information related to customer such as Name, Address, Date of Birth, Place of Birth, ID Number, etc.</p>
        </div>
        <div class="item">
          <h3 class="item-head">First Name English [label]</h3>
          <p class="definition">The name that was given to you when you were born and that comes before your family name. This field accept only English Character.</p>
        </div>
        <div class="item">
          <h3 class="item-head">Salutation [label]</h3>
          <p>A greeting in words or actions, or the words used at the beginning of a letter or speech. This field has values such as Mr, Ms, Miss.</p>
        </div>
      </div>
    </div>
  </div>
  </form>
</div>

Please kindly let me know if there is something missing or to add. Thanks

Houy Narun
  • 1,557
  • 5
  • 37
  • 86