1

I am trying to get the pause button to work in each span separately. Each time the user clicks the "add" button (code not shown), a new <span class="emailform">set of these elements is appended to the <div class="email">. I don't know how to attach the click event handler to the pause button in the newly added span of elements. I have attached images so that you can see what I'm trying to do. (I'm prolly using trigger() wrong as well trying to call my own function.)

I've also included a fiddle here.

Thanks for your help!

html:

<div class="email">
     <span class="emailform">
              <label for="vs-email" class="use-email" >Via email:</label>
              <input type="text" class="text-input" />
              <input type="button" class="pause" />
              <input type="button" class="remove"  value="remove" />
      </span>
</div>

jQuery:

$(".pause").on('click', function(e){
     $(e.target).closest("span").trigger(pauseRestore());   
});

function pauseRestore(){
     var oddClick = $(this).data("oddClick");
     $(this).data("oddClick", !oddClick);
     if(!oddClick) {
          pauseAction(); 
     }else {
          restoreAction();
     }
}

Original start (good)

originalstate

Another added after clicking 'add' button (good)

added a new span

Click to pause first only (good)

select to pause first span

Click to pause new added (BAD, nothing happens)

select to pause new added

Click pause button in first span (BAD -- both are now selected and paused)

both selected

This is the result I want. When user clicks on the pause button in the new added span, only this is paused, not any others. Each one is separate.

individual behavior

Barlas Apaydin
  • 7,233
  • 11
  • 55
  • 86
Chris22
  • 1,973
  • 8
  • 37
  • 55

2 Answers2

2

There are numerous problems with your approach which you are making overly complicated.

I'll try to itemize issues first:

  1. $(".use-email") will include all elements in page with that class. You want to isolate the individual instance based on button clicked.
  2. trigger() can not be used for calling named functions. Suggest you review jQuery API and get better understanding of how to use for events and custom events.
  3. Suggest you change classes rather than changing inline css. Is usually less code and far easier to undo
  4. $(".pause").removeClass("btn-pause").addClass("btn-pause"); - removes the class then adds it again, makes no sense
  5. You can delegate event handlers to account for future elements.
  6. SHould use prop() method not attr() to change properties like disabled

Following does what I think you need and reduces code significantly:

$(".add").click(function(){
        addItem();
    });
/* delegate handler for future elements*/
$(document).on('click','.pause', function(e){      
    /* using "this" to isolate instance*/
    var $pauseButton=$(this);
    var $emailForm=$pauseButton.closest('.emailform').toggleClass('paused');

   /* clear other paused elements*/
    $('.emailform.paused').not($emailForm)
                          .removeClass('paused')
                          .find( ".text-input").prop("disabled", false) ; 

    var isPaused=$emailForm.hasClass('paused');
    /* use "find()" to look within instance only*/
    $emailForm.find(".text-input").prop("disabled", isPaused);  

});

function addItem(){
   $('div.email').append('html string....'); 
}

DEMO: http://jsfiddle.net/vVG3x/3/

charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • +1 Thanks, charlietfl for explaining my errors, and writing a different way of doing this! Your code is simplified and comments really help. There are many methods in the API, and while I read through them, it is not always apparent how to combine them with others in correct syntax...at least not for me always. – Chris22 Feb 08 '13 at 19:54
1

You have few issues here:

1) trigger() is used to execute event handler functions (such as 'click'), not call arbitrary functions. If you want to call a function and pass along the object, just call the function with a parameter in the function definition:

$(".pause").on('click', function (e) {
    myspan = $(e.target).closest("span");
    pauseRestore(myspan);
});

...

function pauseRestore(myspan) {
    var oddClick = myspan.data("oddClick");
    myspan.data("oddClick", !oddClick);
    ...
}

2) The way you are using .on only applies to .pause items that exist at the time you call .on. To apply to all future instances of .pause items, you must attach the handler to a parent object, and filter on the selector you want:

$(".email").on('click', '.pause', function (e) {
    ....
}

3) Similarly, you are using selectors for all .use-email items, instead of the one in the span you care about, so you are modifying all items:

$(".use-email").css("color", "#b1b1b1");

Instead, you need the following, where myspan contains the span object:

myspan.find(".use-email").css("color", "#b1b1b1");

Putting it all together you get this fiddle:

http://jsfiddle.net/umukT/

Jeff B
  • 29,943
  • 7
  • 61
  • 90
  • +1 Thank you, Jeff B. I marked this as answer since you modified code written. this helped to understand how to correct without re-writing from scratch. I wish I could mark two answers as both solved my problem and helped me very much. – Chris22 Feb 08 '13 at 19:56
  • Jeff B, how is that your newly added span elements are aligned correctly? I can not get mine to correctly align. I noticed in Charlietfl's fiddle, the alignement result is like mine. I've look at using firebug, but still unable to resolve this. Thanks! – Chris22 Feb 15 '13 at 22:20
  • 1
    @Chris22, your first span is hard-coded into the page, and the additional spans are added by the JS, which uses different HTML than the first. I simply made the hard-coded HTML and the JS-produced HTML match. Another way around this would be to have a hidden span that acts as your template, and clone it as you add spans. That way, if you modify something, you only have to do it once. http://jsfiddle.net/jtbowden/umukT/2/ – Jeff B Feb 15 '13 at 22:57
  • .@Jeff B, thank you for answering and providing the fiddle. I looked through firebug in the `DOM` and you are right, I saw that the newly added `spans` had a context ([http://brandonaaron.net/blog/2009/06/24/understanding-the-context-in-jquery]) of index.html, not the div I was appending to, so the styles were off. I'm going to follow your suggestion of using `.clone()` method. Excellent example of "how to"! – Chris22 Feb 18 '13 at 17:40