Search code examples
jqueryhtmlcsseventsundefined

Why doesn't the jQuery event ".on" have any event argument


The following code doesn't work:

var moveDownBtnHTML = '<a href="#" class="moveDown"> down </a>',
    moveUpBtnHTML = '<a href="#" class="moveUp"> up </a>';

function reloadBtns()
{
   $(".cats .cat .moveUp").add(".cats .cat .moveDown").remove();
   $(".cats .cat").children("input").after(moveDownBtnHTML + moveUpBtnHTML);
   $(".cat:first-child .moveUp").add(".cat:last-child .moveDown").remove();
}

$( document ).ready(function() {
   $(".cats").on('click', '.moveDown .moveUp', function(evt){
      if(evt.target.attr("class") == ".moveDown")
      {
         var i = $(".cat").index(evt.target.parent()),
             ctm = "<div class='cat'>"+$(".cat").eq(i).html()+"</div>";
                    
         $(".cat").eq(i).remove();
         $(".cat").eq(i).after(contentToMove);
   
          reloadBtns();
      }
      else if(evt.target.attr("class") == ".moveUp")
      {
         var i = $(".cat").index(evt.target.parent()),
             ctm = "<div class='cat'>"+$(".cat").eq(i).html()+"</div>";
                            
         $(".cat").eq(i).remove();
                    
         $(".cat").eq(i - 1).after(contentToMove);
                    
         reloadBtns();
      }
   });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<h2>Categories editor</h2>
<div class="cats">
  <div class="cat"><input type="text" name="cate[]" value="Category 1" readonly/><a href="#" class="moveDown"> down </a></div>
  <div class="cat"><input type="text" name="cate[]" value="Category 2" readonly/><a href="#" class="moveDown"> down </a><a href="#" class="moveUp"> up </a></div>
  <div class="cat"><input type="text" name="cate[]" value="Category 3" readonly/><a href="#" class="moveUp"> up </a></div>
</div>

It's normally in a form to make a kind of database with multiple categories which contains data but it isn't very important...

I don't know how to pass a event data information in argument to know which "button" activated the event to know if I need to up the category or if I need to down it. I tested a lot of methods but I finally decided to get back to you. I have just lost 2 days with that form!

I have seen on this forum that in [selector.on(trigger, selector, function(event){}] the event argument will contain a jQuery event. Why doesn't it work?

How can I do it the most simply?


Solution

  • the problem you had, is that you compare class name with dot on it, and after you re-add the links to go up or go down, don't assign the event clicks. i moved the functionality of links to a function, so after adding the buttons, i re-assign the functionality to the new buttons. to move up, the code needed a little fix, to get the actual position it should be moved.

    in jquery to get the element that launched the event you can access it through "$(this)"

    if i'm missing something in the answer just comment, and i'll explain.

    var moveDownBtnHTML = '<a href="#" class="moveDown"> down </a>',
        moveUpBtnHTML = '<a href="#" class="moveUp"> up </a>',
        template = '<div class="cat"><input type="text" name="cate[]" value="Category __number__"/></div>';
    
    function reloadBtns()
    {
       $(".cats .cat .moveUp").add(".cats .cat .moveDown").remove();
       $(".cats .cat").children("input").after(moveDownBtnHTML + moveUpBtnHTML);
       $(".cat:first-child .moveUp").add(".cat:last-child .moveDown").remove();
       assignEvent();
    }
    
    function assignEvent() {
        $(".cats .moveDown, .cats .moveUp").on('click', function(){
          var that = $(this); //for precaution $(this) have the object that started the event
          if( that.attr("class") == "moveDown")
          {
             var i = $(".cat").index(that.parent());
             contentToMove = "<div class='cat'>"+$(".cat").eq(i).html()+"</div>";
             $(".cat").eq(i).remove();
              $(".cat").eq(i).after(contentToMove);
       
             reloadBtns();
          }
          else if(that.attr("class") == "moveUp")
          {
             var i = $(".cat").index(that.parent());
             contentToMove = "<div class='cat'>"+$(".cat").eq(i).html()+"</div>";
             $(".cat").eq(i).remove();
             $(".cat").eq(i-1).before(contentToMove);
    					
             reloadBtns();
          }
       });
    }
    
    $( document ).ready(function() {
       assignEvent();
        
       $('.addnew').click(function(e) {
           e.preventDefault();
           howmany = $('.cats').children().length;
           newcat = template.replace(/__number__/, howmany+1);
           $('.cats').append(newcat);
           reloadBtns();
       });
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
    <h2>Categories editor</h2>
    <div class="cats">
      <div class="cat"><input type="text" name="cate[]" value="Category 1" readonly/><a href="#" class="moveDown"> down </a></div>
      <div class="cat"><input type="text" name="cate[]" value="Category 2" readonly/><a href="#" class="moveDown"> down </a><a href="#" class="moveUp"> up </a></div>
      <div class="cat"><input type="text" name="cate[]" value="Category 3" readonly/><a href="#" class="moveUp"> up </a></div>
    </div>
    <a href="#" class="addnew">Add new</a>