views:

100

answers:

3

my code:

<html>

<head>

<script type="text/JavaScript" src="jquery-1.3.2.min.js"></script>
<script type="text/JavaScript" src="jquery.center.js"></script>
<script type="text/JavaScript">
    $(document).ready(function(){
        $('a').click(function(){
            popup_AskYN("Want me to tell you what 1 + 1 is?",function(){
                //popup_Info("It's 2, silly!");
            },function(){
                //popup_Info("I didn't want to, anyway!");
            });
        });
    });

    function popup_AskYN(msg,yes_fn,no_fn){
        $('body').append("<div id='popup'><p>"+msg+"</p><a id='popup_yes' href='#'>Yes!</a><a href='#' id='popup_no'>No.</a></div>");
        var yes_button = $('#popup_yes:last');
        var no_button = $('#popup_no:last');
        var popup = $('#popup:last');
        popup.center();

        yes_button.click(yes_fn);
        no_button.click(no_fn);

        yes_button.click(function(){
            popup.fadeOut('fast').remove();
        });
        no_button.click(function(){
            popup.fadeOut('fast').remove();
        });
    }

    function popup_Info(msg,callback){
        $('body').append("<div id='popup'><p>"+msg+"</p><a id='popup_ok' href='#'>Ok.</a></div>");
        var ok_button = $('#popup_ok:last');
        var popup = $('#popup:last');
        popup.center();

        ok_button.click(callback);

        ok_button.click(function(){
            popup.fadeOut('fast',function(){ $(self).remove(); });
        });
    }


</script>

<style type="text/css">
#popup {
    position:absolute;
    border:1px solid black;
}
#popup a {
    margin:10px;
}
</style>

</head>

<body>
<a href="#">Launch the popup!</a>
</body>

Now this works well..except for when i have more than one popups. What i've narrowed it down to is when-ever i create a new popup, it changes the value of yes_button,no_button,ok_button and popup. So when the previous popup tries to use these variables, they all point to the new popup and not the current one. since all the popup's have the same id, i don't have anything "unique" to identify each by. i figured simply storing the selector would be enough but thats not working. what can i do here?

edited, added proper id's, but still not working...:

<html>

    <head>
    <title>Call backs</title>

    <script type="text/JavaScript" src="jquery-1.3.2.min.js"></script>
    <script type="text/JavaScript" src="jquery.center.js"></script>
    <script type="text/JavaScript">
        $(document).ready(function(){
            $('a').click(function(){
                popup_AskYN("Want me to tell you what 1 + 1 is?",function(){
                    //popup_Info("It's 2, silly!");
                },function(){
                    //popup_Info("I didn't want to, anyway!");
                });
            });
        });

        var popup_AskYNId = 0;
        var popup_InfoId = 0;
        function popup_AskYN(msg,yes_fn,no_fn){
            popup_AskYNId = popup_AskYNId + 1;
            $('body').append("<div class='popup' id='"+popup_AskYNId+"popup_AskYN'><div class='popup_inner'><p>"+msg+"</p></div><div class='popup_options'><a class='popup_yes' id='"+popup_AskYNId+"popup_yes_AskYN' href='#'>Yes!</a><a href='#' class='popup_no' id='"+popup_AskYNId+"popup_no_AskYN' >No.</a></div></div>");
            popup = $('#'+popup_AskYNId+'popup_AskYN');
            yes_button = $('#'+popup_AskYNId+'popup_yes_AskYN');
            no_button = $('#'+popup_AskYNId+'popup_no_AskYN');

            popup.center();

            yes_button.click(yes_fn);
            no_button.click(no_fn);

            yes_button.click(function(){
                popup.fadeOut('fast').remove();
            });
            no_button.click(function(){
                popup.fadeOut('fast').remove();
            });
        }

        function popup_Info(msg,callback){
            $('body').append("<div id='popup'><div id='popup_inner'><p>"+msg+"</p></div><div id='popup_options'><a id='popup_ok' href='#'>Ok.</a></div></div>");
            ok_button = $('#popup_ok:last');
            popup = $('#popup:last');
            popup.center();

            ok_button.click(callback);

            ok_button.click(function(){
                popup.fadeOut('fast',function(){ $(self).remove(); });
            });
        }


    </script>

    <style type="text/css">

    .popup {
        position:absolute;
        border:1px solid black;
        padding:3px;
    }
    .popup_inner {
        border:1px solid black;
        padding:10px;
    }
    .popup_options {
        margin:0 auto;
    }
    .popup_options a {

        border:1px solid black;

        margin-top:3px;
        margin-left:3px;
        height:15px;
        width:75px;
        float:right;

        text-align:center;
        font-family:tahoma;
        font-size:0.8em;
        text-decoration:none;
        line-height:14px;
    }

    </style>

    </head>

    <body>
    <a href="#">Launch the popup!</a>
    </body>

</html>

solution was found, but i modified it a little bit so that yes and no accepted functions like the old version..

    $(function() {
  $('a').click(function(e) {
    e.preventDefault();

    var num1 = Math.floor(Math.random()*11),
    num2 = Math.floor(Math.random()*11);

    popup_AskYN(
        "Want me to tell you what 1 + 1 is?",
        function(){
            $('body').append('its 2');
        },function(){
            $('body').append('Fine.');
        });;
  });

  $('.popup_yes').live('click', function(e) {
    e.preventDefault();

    $(this).closest('.popup').fadeOut('fast', function() {
      $(this).remove();
    });
  });
  $('.popup_no').live('click', function(e) {
    e.preventDefault();

    $(this).closest('.popup').fadeOut('fast', function() {
      $(this).remove();
    });
  });

});

function popup_AskYN(msg, yes, no){
  $('body').append("<div class='popup'><div class='popup_inner'><p>"+msg+"</p></div><div class='popup_options'><a class='popup_yes' href='#'>Yes!</a><a href='#' class='popup_no'>No.</a></div></div>");
  var yes_button = $('.popup_yes:last');
  var no_button = $('.popup_no:last');
  var popup = $('.popup:last');

  yes_button.click(yes);

  no_button.click(no);
}
+1  A: 

I see you keep appending a div to the document with id=popup and a lot of other stuff with hardcoded ID. In HTML IDs must be unique throughout the whole document and a particular ID (eg 'popup') must only appear once. What happens when two elements share the same ID is undefined and the browser can return anything the browser's developer feel like.

So your query $('#popup:last') does not do what you think it means.

In cases like this regular DOM methods work much better than jQuery-ism:

// shortcut. I hate typing document...
function newElement (tag, spec) {
    var el = document.createElement(tag);
    for (var n in spec) {
        el[n] = spec[n];
    }
    return el;
} 

function popup_AskYN(msg,yes_fn,no_fn){
    // because we get the references directly we don't need to
    // assign ids and therefore avoid id collisions:

    var popup = $(newElement('div')).append($(newElement('p')).append(msg));
    var yes_button = $(newElement('a',{href:'#'})).append('Yes!');
    var no_button = $(newElement('a',{href:'#'})).append('No.');

    popup.append(yes_button).append(no_button);
    popup.center();

    yes_button.click(yes_fn);
    no_button.click(no_fn);

    yes_button.click(function(){
        popup.fadeOut('fast').remove();
    });
    no_button.click(function(){
        popup.fadeOut('fast').remove();
    });

    $('body').append(popup);
}
slebetman
edited: showing you that you don't need ids.
slebetman
can not get your example to work.. sorry. new to this..
Prodigga
Ahh... sorry, forgot to add `$('body').append(popup)`.
slebetman
A: 

You can create a unique identifier using the number of existing popups.

var popupId =  $("#popup").size();

Then create the new popup using the id and reference it for the buttons as well.

$('body').append("<div id='" + popupId + "'><p>"+msg+"</p><a id='popup_ok' href='#'>Ok.</a></div>");
Sam Tyson
but i've got popup's being created and deleted. so the number of them changes.
Prodigga
Store and increment a value then...var id = $("body").data(popupID);$("body").data(popupID, id++);
Sam Tyson
i've added what i've now got to my first post. buttons still stuff up when there is more than one popup. what it appears to be doing is using the current value of popup_AskYNId for the selectors whenever i click a button. i know this because when i have 2 popups, popup 2 works fine, but not 1. when i have 5, 5 works fine, but not the others.
Prodigga
+1  A: 

This works fine for me if I simply change all the IDs to classes. Centering the popups absolutely on the screen doesn't lend itself to having multiple instances of a popup, though, if that's what you're after. I had to comment out the centering/positioning code to see that it was working.

I would also recommend that when someone clicks the yes or no links in a popup, the answer replaces the original popup's content instead of creating a new popup. I see that you're attempting to have the question fade out before the answer appears, but notice that in your current implementation, the original popup question is removed before the animation finishes, so there's no advantage to removing the question and creating a new popup window with the answer as opposed to just replacing the content.

If you want the question to fade out before the answer appears, one option would be to only remove the question popup after the animation completes, which you can do with fadeOut's second parameter, which is a callback to be executed when the animation completes. Again, this doesn't lend itself to having multiple instances of popup questions, though. The reason is because the answer popup is disassociated from the question popup with your method of removing the question and appending the answer to the body. This would also be solved by simply replacing the question with the answer. If you still want the same fade effect, you can fade the popup out, then change its contents, then fade it back in.

Here is a version of your code that works and changes it as I suggest:

<html>
<head>
  <script type="text/JavaScript" src="http://code.jquery.com/jquery.js"&gt;&lt;/script&gt;
  <script type="text/JavaScript">
    $(function() {
      $('a').click(function(e) {
        e.preventDefault();

        var num1 = Math.floor(Math.random()*11),
        num2 = Math.floor(Math.random()*11);

        popup_AskYN(
          "Want me to tell you what " + num1 + " + " + num2 + " is?",
          "It's " + (num1 + num2) + ", silly!",
          "I didn't want to, anyway!"
        );
      });

      $('.popup_ok').live('click', function(e) {
        e.preventDefault();

        $(this).closest('.popup').fadeOut('fast', function() {
          $(this).remove();
        });
      });
    });

    function popup_AskYN(msg, yes, no){
      $('body').append("<div class='popup'><p>"+msg+"</p><a class='popup_yes' href='#'>Yes!</a><a href='#' class='popup_no'>No.</a></div>");
      var yes_button = $('.popup_yes:last');
      var no_button = $('.popup_no:last');
      var popup = $('.popup:last');

      yes_button.click(function() {
        popup.html('<p>' + yes + '<a class="popup_ok" href="#">Ok.</a>');
      });

      no_button.click(function() {
        popup.html('<p>' + no + '<a class="popup_ok" href="#">Ok.</a>');
      });
    }
  </script>

  <style type="text/css">
  .popup {
    border:1px solid black;
    margin-bottom: 10px;
  }
  .popup a {
    margin:10px;
  }
  </style>
</head>

<body>
  <a href="#">Launch the popup!</a>
</body>
Jimmy Cuadra
how comes the ID does not work? what am i doing wrong?
Prodigga
i just tried it, and the same problem persists. i printed out the ID of the popup into the popup, stopped centering and made it position:relative so they get placed in different rows. regardless of whichever button i press, the last popup and only the last one will ever disapear.
Prodigga
I added code to my original answer to show you what I mean. Using IDs doesn't work because, as slebetman noted, each ID must be unique. As it turns out, there is no need for IDs here so it works fine just be changing them to classes.
Jimmy Cuadra
well i still cant figure out what i was doing wrong. heh. the solution here is what i'm looking for. had to modify it a little bit so that it would still accept functions being passed for yes and no. i've added the fixed version of this to my post for whoever wants it. thanks mate
Prodigga
the reason i wanted to pass functions is because im going to use the popups for more than just displaying an answer like this. what you suggested makes sense (and makes the script more efficient if this was its sole purpose) but i plan on using this for other stuff too. what for, im not too sure yet. but its always good to keep your options open i guess. besides, its good fun.
Prodigga
sigh - after fiddling with it further, i still get the error. in your example, the strings are concentrated and then sent to the function. we know the value of num1 + num2 now. however, what i do is for the yes function, i put in $('body').append('its '+num3); (Where num3 is just num1+num2, calculated inside this fn). so when i make a new popup without answering yes or no to the first, the values of num1 and num2 change. and then when i go to click yes on the first popup, it is using the values of the new num1 and num2, rather than the old ones..
Prodigga
thats the problem i thought i had at the start (thats what i ment by going out of scope etc...?). not sure how to prevent this.. i figured the num1 and num2 vars would just be read as the values i had called them as.
Prodigga
Add your new code to your original question and I'll take a look.
Jimmy Cuadra