0

Information:

So I have created a page on my site that will act as a contact page/org chart for my department. I have a SharePoint List that stores all the relevant data such as name, dept, title, email, phone, ect.

I wrote some JavaScript to get the data from the List, create the code, and append it to the page. This part works fine and I have no problem with it; however, I also have a section of JS that will expand and collapse the additional contact information of the individual by clicking a button

Problem:

The section of JavaScript that expands and collapses the contact information will not work. I'm not sure if I'm just overlooking something or what.

(This problem is independent of the browser... It does not work in IE, Chrome, or FF)

Full Code: (within the script tags of the page)

$('.expand').click(function() {
        $(this).parent(".contact-box").toggleClass('expanded');
        $(this).siblings('.information').find('.phone, .email').toggleClass('show');
    });

$(document).ready(function() {
    $().SPServices({
            operation: "GetListItems",
            async: false,
            listName: "The Team",
            CAMLViewFields: "<ViewFields><FieldRef Name='FullName'/><FieldRef Name='JobTitle'/><FieldRef Name='Location'/><FieldRef Name='Email'/><FieldRef Name='Phone'/><FieldRef Name='ContactPhoto'/></ViewFields>",
            completefunc: function (xData, Status) {
                $(xData.responseXML).SPFilterNode("z:row").each(function() {
                    $('' +
                        '<div class="contact-box">' +
                        '   <div class="contact-img round">' +
                        '       <img class="portrait bottom"  src="'+$(this).attr("ows_ContactPhoto")+'" alt="Image">' +
                        '   </div>' +
                        '   <hr/>' +
                        '   <div class="information">' +
                        '       <p class="name">'+$(this).attr("ows_FullName")+'</p>' +
                        '       <p class="position">'+$(this).attr("ows_JobTitle")+'</p>' +
                        '       <p class ="location"><span class="fa fa-map-marker icons"></span>'+$(this).attr("ows_Location")+'</p>' +
                        '       <p class="email show"><span class="fa fa-envelope icons"></span><a href="mailto:'+$(this).attr("ows_Email")+'"></a>'+$(this).attr("ows_Email")+'</p>' +
                        '       <p class="phone show"><span class="fa fa-phone icons"></span>'+$(this).attr("ows_Phone")+'</p>' +
                        '   </div>' +
                        '   <div class="expand"><span class="fa fa-angle-down" aria-hidden="true"></span></div>' +
                        '</div>').appendTo('.container-box');
                });
            }
        });
    });

Problem Code:

This is the code that will not run on the page. If anyone can see what I'm doing wrong or if there is something within SharePoint that will not allow me to do this, I would appropriate the feedback.

$('.expand').click(function() {
    $(this).parent(".box").toggleClass('expanded');
    $(this).siblings('.information').find('.phone, .email').toggleClass('show');
});
1
  • you need to have that probably in the $(document).ready(), you are calling objects that may have not loaded on the page yet.
    – Mike
    Jun 26, 2017 at 15:34

2 Answers 2

2

The problem is that you are binding the click event function to your .expand divs before they are present on the page, since you are creating them dynamically after an async call to SharePoint.

$('.expand').click(function() {
    // it doesn't matter what you put here, because at the time this code runs,
    // there are no elements present that match the selector.
});

What you need to do is use jQuery's on() function to bind the click events to an element that is already there, and you can tell it to only respond to clicks that originated / bubbled up from an element with a different selector. For example:

$('.container-box').on('click', '.expand', function() {
    // you may have to modify your code slightly
    // because "this" may be different that what you expect using this method
});
3
  • Thanks for your help. I was able to fix my problem by implementing this solution as well as adding my script into the $(document).ready() as suggested by Mike in the comments Jul 11, 2017 at 14:27
  • Great! If it worked for you, consider marking it as the accepted answer. Jul 11, 2017 at 14:52
  • Oops... I up voted but forgot to accept. Jul 11, 2017 at 14:56
0

It seems your events are binding before the contacts bind operations. In jQuery, when you use .click function way to bind events it will apply to only the elements in the DOM but not for dynamic elements. In you code, the contacts are binding dynamically after the .click events executed.

In the new version of the jQuery library (>= 1.9) you can use following way to bind events for dynamic elements.

$('.container-box').on("click", '.expand', function(e) {
   //your code
}

In the older versions (<1.9)

$('.expand').live("click", function(e) {
   //your code
}

You can choose one of the ways depending on the version of the library you are using.

Let me know if I am missing any of your points.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.