1

Update: problem solved:

Since 'problematic' elements were being created after the moment the page loadad, event delegation made sure all of them were bound to the jQuery event.

Original post:

I got this piece of code:

while ($row=mysqli_fetch_array($res)){
    if($cont>3){
       $cont=1;
       $txt=$txt.'</tr><tr>';
    }
    $txt=$txt.'<td>'; 
    $txt=$txt.'<figure><img src="'.$row['picture'].'"/></figure>';
    $txt=$txt.'<figcaption>'.$row['pictureDesc'].'</figcaption>'; 
    $txt=$txt.'<div class="dialogInfoOpener" style="border:solid red 1px;">Details</div>'; 
    $txt=$txt.'</td>';    
    $cont++; 
}   
$txt=$txt.'</tr>';
echo $txt;

It is part of a PHP file that works along with a JS file (Ajax) in order to "construct" a table by rows of 3 cells, by concatenating strings. For each cell, some data is loaded from a database. Each cell places a div with a given class (dialogInfoOpener) and certain inline style. The div element should be clicked on in order to open a jquery Dialog box - this where the problem begins.

The code for my Dialog box:

HTML

<div id="dialogInfo" title="Product description">Info to be put in here.</div>

jQuery

$("#dialogInfo").dialog({ 
    autoOpen: false,
    buttons:[{
        text: "Close", click : 
        function(){
            $(this).dialog("close");
        }
    }]
});


$(".dialogInfoOpener").click(function(event){</s>
    $("#dialogInfo").dialog("open");</s>
});</s>

The code works wonderfully for any element with class dialogInfoOpener that is found on the page, EXCEPT for any div elements that belong to the table that was just constructed. When clicking on these divs, it won't do anything (class and style attributes are set correctly for each cell). It appears that jQuery is not responding to the class names given to the divs. Why?

I hope it is clear.

I'd appreciate any helpful suggestions.

absay
  • 187
  • 2
  • 15

3 Answers3

1

As these elements were dynamically created, you could use event delegation, e.g:

$(document).on("click", ".dialogInfoOpener", function(event){
    $(".dialogInfo").dialog("open");
});

There's usually a better selector to use than document - find a consistent parent element of .dialogInfoOpener elements and use that instead.

Also, I think you may have a typo - your HTML mentions elements with #dialogInfo, but inside your click function you are using .dialogInfo? Remember that ID's need to be unique, if you have more than one, just use a class.

dsgriffin
  • 66,495
  • 17
  • 137
  • 137
  • Yes, it was a typo. Edited the post, thank you. `#dialogInfo` is the id of the dialog itself and `.dialogInfoOpener` is the class name of the divs inside the cells. I have tried out your suggestion: it still doesn't work (not even with document); the next consistent parent is the `table` and then a `section` and finally the `body`. No success with any of them. – absay Mar 10 '14 at 22:19
  • @absay Are you receiving any errors in the console? Unless there's a loading problem I can't see how it doesn't work :/ – dsgriffin Mar 10 '14 at 22:25
  • Thank you. No, I'm not getting any errors in the console. I also have learned about what event delegation is and it seems it _is_ the right answer, though in my code it doesn't work (if I undestrood well, `on()` will bind the event to any elements, with a specific selector, created in any moment, right?). – absay Mar 10 '14 at 22:53
  • @absay Indeed, it is for binding events to elements that may not be present when the page originally loads. Is there a possibility of creating a jsFiddle example replacating your problem? – dsgriffin Mar 10 '14 at 23:04
  • 1
    Nevermind, event delegation _was_ the answer. I replicated the problem and tested it elsewhere, saw it worked fine, then, after seriously considering entering my local mental hospital tomorrow morning, I used a VERY specific selector in my actual function (`table#mainTable tbody td.dialogInfoOpener`) and it worked like a charm. Still, I'm not going to drop the idea of the mental hospital though, as more weird work awaits, lol. Thank you @null, you rule! – absay Mar 10 '14 at 23:32
0

Rerun the code that wires up the click event AFTER your Ajax call completes. try unbind/bind so you don't get duplicate events fired.

tulde23
  • 398
  • 1
  • 6
  • Thank you. I have tried event delegation. No success. I don't understand what you mean by re-running the code after de ajax completes, though it sounds it makes sense. Care to elaborate a little bit more, please? Should I enclose the jquery code within a function and then call that function at the ende of the Ajax js function? – absay Mar 10 '14 at 22:59
0

You've mixed Ids and Classes.

$("#dialogInfo").dialog({ uses an ID but $(".dialogInfo").dialog("open"); uses a class. If you make these the same, you'll fix it.

earl3s
  • 2,393
  • 1
  • 23
  • 24