0

Hi I am trying to create a list that is partially shown and if you click read more you will be able to see all the list. I have found this plugin: https://github.com/solarmosaic/jquery-show-first

However when I try to use it on newly inserted HTML from javascript it does not work. It works if the HTML is in the HTML file in the beginning.

Here is part of my code:

var associatedEntities = associated[a].split("|");
                var personDone = false;
                var placeDone = false;
                var keywordDone = false;
                var itemDone = false;
                for (var d = 0; d<associatedEntities.length; d++){
                    if(associatedEntities[d].includes("@")){
                        var contents = associatedEntities[d].split('@'); 
                        if(associatedEntities[d].includes('person/')){
                            if(personDone == false){
                                associatedWithHTML+="<ul class = \"show-first\" data-show-first-count=\"3\">";
                                personDone = true;
                            }
                            associatedWithHTML+="<li><a target=\"_blank\" href=\"PersonResult.html?id="+contents[0].trim()+"\" >"+contents[1]+"</a><br></li>";

                        }else if (associatedEntities[d].includes('place/')){    
                            if(placeDone == false){
                                associatedWithHTML+="<ul class = \"show-first\" data-show-first-count=\"3\">";
                                placeDone = true;
                            }
                            associatedWithHTML+="<li><a target=\"_blank\" href=\"PlaceResult.html?id="+contents[0].trim()+"-"+contents[1]+"\" >"+contents[1]+"</a><br></li>";

                        }else if (associatedEntities[d].includes('item/')){
                            if(itemDone == false){
                                associatedWithHTML+="<ul class = \"show-first\" data-show-first-count=\"3\">";
                                itemDone = true;
                            }
                            associatedWithHTML+="<li><a target=\"_blank\" href=\"ItemResult.html?id="+contents[0].trim()+"\" >"+contents[1]+"</a><br></li>";
                        }
                    }else{
                        if(keywordDone == false){
                            associatedWithHTML+="<ul class = \"show-first\" data-show-first-count=\"3\">";
                            keywordDone = true;
                        }
                        associatedWithHTML+="<li><span>"+associatedEntities[d]+"</span><br></li>";  


                    }
                }
            }
            associatedWithHTML+="</ul><hr></div>";

            document.getElementById("DeedDate").innerHTML+=newHTML+associatedWithHTML+"</div>";             
Martha
  • 111
  • 7
  • could you explain this "It works if the HTML is in the HTML file in the beginning"? – Rahul R. Mar 18 '19 at 18:10
  • If I insert the list in this case in the main document manually instead from javascript, the plugin works fine – Martha Mar 18 '19 at 18:11

1 Answers1

0

HTML inserted after page load will NOT have any javascript events/listeners applied to it that would normally be applied to elements with matching ids/selectors on page load (unless you use mutator events).

you must set up event listeners in a certain way to "dynamically" add events whenever the DOM node is inserted.

//Jquery: Instead of this for attaching an event
$(".my-element").click(function() {

   //Some code here...

});

//Jquery: You will need to do this to catch all elements
$(document).on("DOMNodeInserted", ".my-element", function() {

     $(this).click(function() {

         //Some code here...

     });

});

//Vanilla javascript
document.addEventListener("DOMNodeInserted", function (e) 
{

     if(e.target.classList.contains("my-element")) {

         e.target.addEventListener("click", function() {

             //Some code here...

         });

     }

}, false);

Now, you are asking this question from the context of a plugin, but this is what is happening. The plugin is not applying its events to things on node insertion, but at page load. You can modify the supplied code to do this, or add something on your side that registers required events on node insertion into the DOM.

Note: Chose only ONE of the two example solutions above that use DOMNodeInserted. This replaces the normal "click" event registration for that element. Do NOT have a click event registered in addition to adding DOMNodeInsert events registered for the same selector.

Asyranok
  • 950
  • 1
  • 7
  • 17
  • So I can use the second or third method or simultaneously? Do I apply it straight after insertion? – Martha Mar 18 '19 at 18:18
  • You can use either the second or third method, but not both. The above DOMNotInserted event handlers would go in the exact same spot that you would add a normal "element.click()" event registration logic. However, if you were to put a breakpoint inside these events, and do whatever makes the new html get inserted onto the page, you would see the breakpoint hit immediately. At that moment, the actual "click" event is being registered on the newly-inserted html.Then, once you click that element, it will launch your expected click event. – Asyranok Mar 18 '19 at 18:22