ResponsiveBP / Responsive

:iphone: A super lightweight HTML, Sass, CSS, and JavaScript framework for building responsive websites
http://responsivebp.com
MIT License
866 stars 141 forks source link

Attaching modal event handler after initial load #70

Closed jsantari closed 9 years ago

jsantari commented 9 years ago

I've got a modal that is used to show a group of pictures for real estate listings. Works great on the list if it's used after the initial page load. If the user runs another search via ajax the list is replaced by the new results. At that point the modal no longer works and it just opens a new page when the link is clicked on one of the listings. This appears to happen because the new list no longer has the modal event handler attached. How do I get RBP to attach to the links after an ajax call like this?

JimBobSquarePants commented 9 years ago

Hi there,

Are you binding using the data api or via JavaScript?

jsantari commented 9 years ago

Using the data api

JimBobSquarePants commented 9 years ago

Latest version 4.0.3 yeah? I'll have a look and see if I can replicate it.

jsantari commented 9 years ago

Yes 4.0.3. I've changed it now to use api to load modal so the event is attached after the ajax call. Have a different problem now though. Each listing has a button to trigger the modal but when I click on the button no matter what listing it is it always displays the data from the first listing in the list using it's href values instead of the href from the correct row in my list?

JimBobSquarePants commented 9 years ago

I'll need to see some code. Sounds like you're not binding scope properly.

jsantari commented 9 years ago

Here is the listing html, modal binding code follows

  <div class="listing-header">
    <h3>Property Listings</h3>

    <div>
      (4 results)
    </div>
  </div>

  <div class="main-listings">
    <div class="row showmain" id="show_142669">
      <div class="col-s-2">
        <div class="showmain-img">
          <a class="modal-pics" data-modal-title="swipe to scroll photo's" data-modal-fit-viewport="false" data-modal-iframe-scroll="false" href="svc/svc_photos.php?uid=00022D4D&amp;lfc=20"><img src="http://images.realtyserver.com/photo_server.php?btnSubmit=GetPhoto&amp;board=wisconsin&amp;name=00022D4D.L01"></a> <a class="modal-pics" data-modal-title="swipe to scroll photo's" data-modal-fit-viewport="false" data-modal-iframe-scroll="false" href="svc/svc_photos.php?uid=00022D4D&amp;lfc=20"><button class="button-map">View <span style="font-size: .8em;">( 20 )</span></button></a>
        </div>
      </div>

      <div class="col-s-7">
        <div class="showmain-info">
          <div class="row item">
            <div class="col-xxs-3">
              <span class="title">MLS#:</span>
            </div>

            <div class="col-xxs-3">
              142669
            </div>

            <div class="col-xxs-3">
              <span class="title">Price:</span>
            </div>

            <div class="col-xxs-3">
              $36,900
            </div>
          </div>

          <div class="row item">
            <div class="col-xxs-3">
              <span class="title">Bedrooms</span>
            </div>

            <div class="col-xxs-3"></div>

            <div class="col-xxs-3">
              <span class="title">Bathrooms</span>
            </div>

            <div class="col-xxs-3"></div>
          </div>

          <div class="row item">
            <div class="col-xxs-3">
              <span class="title">Home SqFt <span style="font-size: .8em;">(total)</span>:</span>
            </div>

            <div class="col-xxs-3">
              0
            </div>

            <div class="col-xxs-3">
              <span class="title">Lot Acres <span style="font-size: .8em;">(calculated)</span>:</span>
            </div>

            <div class="col-xxs-3">
              17.63
            </div>
          </div>

          <div class="row item">
            <div class="col-xxs-3">
              <span class="title">County:</span>
            </div>

            <div class="col-xxs-3">
              Bayfield
            </div>

            <div class="col-xxs-3">
              <span class="title">City:</span>
            </div>

            <div class="col-xxs-3"></div>
          </div>
        </div>
      </div>

      <div class="col-s-3">
        <div class="showmain-info">
          <button class="button-success tell-me-more" data-mls="142669">Contact Us</button> <button class="map" data-addr="ON PAULSON RD , WI 54891">Map</button>
        </div>

        <div class="showmain-info">
          <button class="remarks-toggle" data-toggle="remarks_142669" data-mls="142669"><i class="fa fa-folder-o"></i> Remarks</button>
        </div>

        <div class="listing-office">
          <span class="title">Listing Office:</span><br>
          KITSLAAR REAL ESTATE
        </div>
      </div>
    </div>

    <div class="row">
      <div class="col-s-12">
        <div class="well well-default remarks-box" id="remarks_142669">
          Here is a great hunting and building parcel in an area with an excelent mix of timber and agriculture. The property is loaded with deer sign and heavy trails. There is lots of good bedding cover and a creek flowing through the property provides a great water source. There is good road access with power right at the road and many good building sites. The Town of Washburn is only minutes away and is located on the shores of the Chequamegaon Bay on Lake Superior. This area is known for it's great fishing and awesome scenic landscapes. If your looking for a nice affordable parcel in a great recreation area you have to check this one out. Call today to schedule a showing.
        </div>
      </div>
    </div>

    <div style="text-align: center;color: #999999;margin-bottom: -14px;">
      <i class="fa fa-caret-up fa-2x"></i>
    </div>
  </div>

  <div class="main-listings">
    <div class="row showmain" id="show_138509">
      <div class="col-s-2">
        <div class="showmain-img">
          <a class="modal-pics" data-modal-title="swipe to scroll photo's" data-modal-fit-viewport="false" data-modal-iframe-scroll="false" href="svc/svc_photos.php?uid=00021D0D&amp;lfc=9"><img src="http://images.realtyserver.com/photo_server.php?btnSubmit=GetPhoto&amp;board=wisconsin&amp;name=00021D0D.L01"></a> <a class="modal-pics" data-modal-title="swipe to scroll photo's" data-modal-fit-viewport="false" data-modal-iframe-scroll="false" href="svc/svc_photos.php?uid=00021D0D&amp;lfc=9"><button class="button-map">View <span style="font-size: .8em;">( 9 )</span></button></a>
        </div>
      </div>

      <div class="col-s-7">
        <div class="showmain-info">
          <div class="row item">
            <div class="col-xxs-3">
              <span class="title">MLS#:</span>
            </div>

            <div class="col-xxs-3">
              138509
            </div>

            <div class="col-xxs-3">
              <span class="title">Price:</span>
            </div>

            <div class="col-xxs-3">
              $120,000
            </div>
          </div>

          <div class="row item">
            <div class="col-xxs-3">
              <span class="title">Bedrooms</span>
            </div>

            <div class="col-xxs-3"></div>

            <div class="col-xxs-3">
              <span class="title">Bathrooms</span>
            </div>

            <div class="col-xxs-3"></div>
          </div>

          <div class="row item">
            <div class="col-xxs-3">
              <span class="title">Home SqFt <span style="font-size: .8em;">(total)</span>:</span>
            </div>

            <div class="col-xxs-3">
              0
            </div>

            <div class="col-xxs-3">
              <span class="title">Lot Acres <span style="font-size: .8em;">(calculated)</span>:</span>
            </div>

            <div class="col-xxs-3">
              80.00
            </div>
          </div>

          <div class="row item">
            <div class="col-xxs-3">
              <span class="title">County:</span>
            </div>

            <div class="col-xxs-3">
              Bayfield
            </div>

            <div class="col-xxs-3">
              <span class="title">City:</span>
            </div>

            <div class="col-xxs-3"></div>
          </div>
        </div>
      </div>

      <div class="col-s-3">
        <div class="showmain-info">
          <button class="button-success tell-me-more" data-mls="138509">Contact Us</button> <button class="map" data-addr="ON OTHER , WI 54832">Map</button>
        </div>

        <div class="showmain-info">
          <button class="remarks-toggle" data-toggle="remarks_138509" data-mls="138509"><i class="fa fa-folder-o"></i> Remarks</button>
        </div>

        <div class="listing-office">
          <span class="title">Listing Office:</span><br>
          COMPASS LAND CONSULTANTS, INC.
        </div>
      </div>
    </div>

    <div class="row">
      <div class="col-s-12">
        <div class="well well-default remarks-box" id="remarks_138509">
          Nice mixture of rolling terrain and tree cover makes this 80 acre property an outdoors lover's paradise. Thick pine cover and scattered small open areas combined with mature hardwoods creates ideal habitat for a variety of wildlife. This is deer, turkey and grouse heaven. A nice trail winds through for easy access. National forest lands are across the town road for even more elbow room. The parcel is surrounded by large tracts and has electricity. Adjoining 120 tract is also available.
        </div>
      </div>
    </div>

    <div style="text-align: center;color: #999999;margin-bottom: -14px;">
      <i class="fa fa-caret-up fa-2x"></i>
    </div>
  </div>

  <div class="main-listings">
    <div class="row showmain" id="show_138510">
      <div class="col-s-2">
        <div class="showmain-img">
          <a class="modal-pics" data-modal-title="swipe to scroll photo's" data-modal-fit-viewport="false" data-modal-iframe-scroll="false" href="svc/svc_photos.php?uid=00021D0E&amp;lfc=10"><img src="http://images.realtyserver.com/photo_server.php?btnSubmit=GetPhoto&amp;board=wisconsin&amp;name=00021D0E.L01"></a> <a class="modal-pics" data-modal-title="swipe to scroll photo's" data-modal-fit-viewport="false" data-modal-iframe-scroll="false" href="svc/svc_photos.php?uid=00021D0E&amp;lfc=10"><button class="button-map">View <span style="font-size: .8em;">( 10 )</span></button></a>
        </div>
      </div>

      <div class="col-s-7">
        <div class="showmain-info">
          <div class="row item">
            <div class="col-xxs-3">
              <span class="title">MLS#:</span>
            </div>

            <div class="col-xxs-3">
              138510
            </div>

            <div class="col-xxs-3">
              <span class="title">Price:</span>
            </div>

            <div class="col-xxs-3">
              $180,000
            </div>
          </div>

          <div class="row item">
            <div class="col-xxs-3">
              <span class="title">Bedrooms</span>
            </div>

            <div class="col-xxs-3"></div>

            <div class="col-xxs-3">
              <span class="title">Bathrooms</span>
            </div>

            <div class="col-xxs-3"></div>
          </div>

          <div class="row item">
            <div class="col-xxs-3">
              <span class="title">Home SqFt <span style="font-size: .8em;">(total)</span>:</span>
            </div>

            <div class="col-xxs-3">
              0
            </div>

            <div class="col-xxs-3">
              <span class="title">Lot Acres <span style="font-size: .8em;">(calculated)</span>:</span>
            </div>

            <div class="col-xxs-3">
              120.00
            </div>
          </div>

          <div class="row item">
            <div class="col-xxs-3">
              <span class="title">County:</span>
            </div>

            <div class="col-xxs-3">
              Bayfield
            </div>

            <div class="col-xxs-3">
              <span class="title">City:</span>
            </div>

            <div class="col-xxs-3"></div>
          </div>
        </div>
      </div>

      <div class="col-s-3">
        <div class="showmain-info">
          <button class="button-success tell-me-more" data-mls="138510">Contact Us</button> <button class="map" data-addr="ON OTHER , WI 54832">Map</button>
        </div>

        <div class="showmain-info">
          <button class="remarks-toggle" data-toggle="remarks_138510" data-mls="138510"><i class="fa fa-folder-o"></i> Remarks</button>
        </div>

        <div class="listing-office">
          <span class="title">Listing Office:</span><br>
          COMPASS LAND CONSULTANTS, INC.
        </div>
      </div>
    </div>

    <div class="row">
      <div class="col-s-12">
        <div class="well well-default remarks-box" id="remarks_138510">
          Nice mixture of undulating terrain and tree cover makes this 120 acre property an outdoors lover's paradise. Timbered about 10 years ago with some areas of thick pine cover &amp; scattered small open areas that create ideal habitat for a variety of wildlife or food plots. A nice trail winds through for easy access. National forest lands are across the road for even more elbow room. The parcel is surrounded by large tracts and is off a town road with electricity. Adjoining 80 tract is also available.
        </div>
      </div>
    </div>

    <div style="text-align: center;color: #999999;margin-bottom: -14px;">
      <i class="fa fa-caret-up fa-2x"></i>
    </div>
  </div>

  <div class="main-listings">
    <div class="row showmain" id="show_147822">
      <div class="col-s-2">
        <div class="showmain-img">
          <a class="modal-pics" data-modal-title="swipe to scroll photo's" data-modal-fit-viewport="false" data-modal-iframe-scroll="false" href="svc/svc_photos.php?uid=0002416E&amp;lfc=20"><img src="http://images.realtyserver.com/photo_server.php?btnSubmit=GetPhoto&amp;board=wisconsin&amp;name=0002416E.L01"></a> <a class="modal-pics" data-modal-title="swipe to scroll photo's" data-modal-fit-viewport="false" data-modal-iframe-scroll="false" href="svc/svc_photos.php?uid=0002416E&amp;lfc=20"><button class="button-map">View <span style="font-size: .8em;">( 20 )</span></button></a>
        </div>
      </div>

      <div class="col-s-7">
        <div class="showmain-info">
          <div class="row item">
            <div class="col-xxs-3">
              <span class="title">MLS#:</span>
            </div>

            <div class="col-xxs-3">
              147822
            </div>

            <div class="col-xxs-3">
              <span class="title">Price:</span>
            </div>

            <div class="col-xxs-3">
              $619,900
            </div>
          </div>

          <div class="row item">
            <div class="col-xxs-3">
              <span class="title">Bedrooms</span>
            </div>

            <div class="col-xxs-3">
              3
            </div>

            <div class="col-xxs-3">
              <span class="title">Bathrooms</span>
            </div>

            <div class="col-xxs-3">
              0
            </div>
          </div>

          <div class="row item">
            <div class="col-xxs-3">
              <span class="title">Home SqFt <span style="font-size: .8em;">(total)</span>:</span>
            </div>

            <div class="col-xxs-3">
              1,080
            </div>

            <div class="col-xxs-3">
              <span class="title">Lot Acres <span style="font-size: .8em;">(calculated)</span>:</span>
            </div>

            <div class="col-xxs-3">
              360.00
            </div>
          </div>

          <div class="row item">
            <div class="col-xxs-3">
              <span class="title">County:</span>
            </div>

            <div class="col-xxs-3">
              Bayfield
            </div>

            <div class="col-xxs-3">
              <span class="title">City:</span>
            </div>

            <div class="col-xxs-3"></div>
          </div>
        </div>
      </div>

      <div class="col-s-3">
        <div class="showmain-info">
          <button class="button-success tell-me-more" data-mls="147822">Contact Us</button> <button class="map" data-addr="53135 ASHLAND BAYFIELD RD , WI 54806">Map</button>
        </div>

        <div class="showmain-info">
          <button class="remarks-toggle" data-toggle="remarks_147822" data-mls="147822"><i class="fa fa-folder-o"></i> Remarks</button>
        </div>

        <div class="listing-office">
          <span class="title">Listing Office:</span><br>
          KITSLAAR REAL ESTATE
        </div>
      </div>
    </div>

    <div class="row">
      <div class="col-s-12">
        <div class="well well-default remarks-box" id="remarks_147822">
          360 manicured acres &amp; a 3 bedroom cabin overlooking a stocked pond creates the Ultimate Sportsman's Paradise. No expense has been spared in making this property the best hunting property that it can be. An elaborate road system makes navigating all corners of the property easy, there are approximately 30 acres of professionally installed food plots, large sanctuary areas &amp; numerous stand sites. There is excellent timber value with no government forest programs so the timber will provide a buyer with a consistent income source and return on investment. The cabin is very well kept and sits perched on a hill overlooking the acreage and stocked pond. The cabin is run off of an LP Kohler generator, has a drilled well, three bedrooms plus loft, shower and sauna room and a large garage for equipment storage. So much value I can't mention it all here. Call for details.
        </div>
      </div>
    </div>

    <div style="text-align: center;color: #999999;margin-bottom: -14px;">
      <i class="fa fa-caret-up fa-2x"></i>
    </div>
  </div>

here is my modal binding

            $('.modal-pics').modal(
              {
                fitViewport: false,
                iframeScroll: false,
                title: 'swipe to scroll photos'
              }
            );
JimBobSquarePants commented 9 years ago

That's a pretty big block of code!

It's difficult to see what is happening to be honest but it looks like you are combining both the Data-API and the JavaScript API. You need to choose between them or else you are going to get an attempted double bind, where the second instance, your JavaScript invoked one, will fail.

Am I right in seeing some Bootstrap in their also? data-toggle

jsantari commented 9 years ago

Not Bootstrap I'm just using that attribute name to attach my own event handler in jquery.

I removed the in-line rbp data attributes but get the same results. I pulled out some stuff to make it smaller and here is the important part of the listing code, which still doesn't work.

  <div class="main-listings">
    <div class="row showmain" id="show_147509">
      <div class="col-s-2">
        <div class="showmain-img">
          <a class="modal-pics" href="svc/svc_photos.php?uid=00024035&amp;lfc=14"><img src="http://images.realtyserver.com/photo_server.php?btnSubmit=GetPhoto&amp;board=wisconsin&amp;name=00024035.L01"></a> <a class="modal-pics" href="svc/svc_photos.php?uid=00024035&amp;lfc=14"><button class="button-map">View <span style="font-size: .8em;">( 14 )</span></button></a>
        </div>
      </div>

      <div class="col-s-7"></div>

      <div class="col-s-3"></div>
    </div>
  </div>

  <div class="main-listings">
    <div class="row showmain" id="show_133890">
      <div class="col-s-2">
        <div class="showmain-img">
          <a class="modal-pics" href="svc/svc_photos.php?uid=00020B02&amp;lfc=12"><img src="http://images.realtyserver.com/photo_server.php?btnSubmit=GetPhoto&amp;board=wisconsin&amp;name=00020B02.L01"></a> <a class="modal-pics" href="svc/svc_photos.php?uid=00020B02&amp;lfc=12"><button class="button-map">View <span style="font-size: .8em;">( 12 )</span></button></a>
        </div>
      </div>

      <div class="col-s-7"></div>

      <div class="col-s-3"></div>
    </div>
  </div>
jsantari commented 9 years ago

Ok clearly the problem is in rbp event attachment - if I look at the network tab the ajax call always gets made to the first href value in the list though each one has a different href as seen above. Since rbp is firing the click event it's attaching ok but for some reason every button is attached to the event for the first one in the list. Worked fine on the initial load when I was using the data- attributes, but not with manual attachment. Any ideas on this - I'm kind of stuck on the project at this point with out having a way to resolve this. Thanks.

JimBobSquarePants commented 9 years ago

You're really gonna have to help me to help you here.

I need a JsFiddle or equivalent with code showing what you are trying to do. I can't tell whether the second .main-listings is to be loaded dynamically or what.

JimBobSquarePants commented 9 years ago

Ok so I think I have figured out what is going wrong. It looks to me like you are reusing the same initializer or at least options object for multiple instances.

When a modal is bound the code looks for a target property on the given object and if there is not one then it will try to assign one from a href attribute. Since the same object is being reused that target property is never getting updated.

I have a working example of what I think you are trying to do here

https://dl.dropboxusercontent.com/u/78716633/Modal-Example/index.html

In my initialisation code I am creating a new options object on each binding call.

(function ($) {

    var bindModal = function () {
        $(".modal-pics").modal({
            image: true,
            title: "swipe to scroll photos"
        });
    };

    $(document).on("ready", function () {
        bindModal();
    });

    $(document.body).on("click", ".button-map", function () {
        var $main = $("#main-listings");
        var url = "items.html #list-items";

        $main.load(url, null, function (responseText, textStatus) {

            if (textStatus === "error") {
                $main.html(textStatus);
            }

            bindModal();
        });
    });

}(jQuery))

In my index page I have the following markup:

<div id="main-listings">
    <div class="row">
        <div class="col-s-2">
            <a class="modal-pics" href="https://placehold.it/550x550">
                <img src="https://placehold.it/150x150">
            </a>
            <button class="button-map">
                Click to load a new modal
            </button>
        </div>
    </div>
</div>

And in my items page I have the following markup:

<div id="list-items">
    <div class="row" id="show_147510">
        <div class="col-s-2">
            <a class="modal-pics" href="https://placehold.it/552x553">
                <img src="https://placehold.it/151x151">
            </a>
        </div>
    </div>
</div>

In the future I'm going to change the code so that the original options object is never altered and is reusable.

jsantari commented 9 years ago

Let me try to clarify it a bit (by the way thanks for your efforts on this). This is a real estate web site being developed to be single page. You can see the test site here: canre.nwhost.com. I have trimmed the listing display template to make it easier to view the code. The idea is that when a search (ajax) is viewed the slideshow (not rbp) displays as does the first 50 listings that matched the search criteria. Users can then click on the the thumbnail image of the view button which should then make the ajax call to the service routine (using the href of the button) that sends back the proper html for the modal to show the other property images as a slide show. It was working great with in-line modal attributes from the first ajax call but would not attach events when another query is viewed which replaces the listings in the dom. After the first time if I clicked on the image or button to view the slide show it executes the link as a normal link and runs the service routine as if it was a page submit. Does that answer your question? I was thinking that the modal attachment would simply trigger the modal and pickup the correct href from the button being clicked since that would be current context (as it would be if I attached a jquery event to the same class).

JimBobSquarePants commented 9 years ago
$('a.modal-pics').modal({
    fitViewport: false,
    iframeScroll: false,
    title: 'swipe to scroll photos',
    external: true,
    target: this.href // <-- This is wrong.
} );

In your code the keyword this is scoped to the success function that will not have a href property. If you drop that property from your initializer options it should work as the plugin will assign the target from the href attribute of the element.

jsantari commented 9 years ago

I put that in and it still doesn't work. Just uses the href from the first button in the display. As an aside I am able to get it to work if I use jquery like this after the list is loaded into the dom.

  $('.modal-pics').off();
  $('.modal-pics').on('click', function(e) {
    e.preventDefault();
      $(this).modal(
      {
        fitViewport: false,
        iframeScroll: false,
        immediate: true,
        title: 'swipe to scroll photos'
      }
      );
  })
JimBobSquarePants commented 9 years ago

Ok...I've just pushed an updated build of the plugin to the feature/equal-height branch. https://github.com/ResponsiveBP/Responsive/tree/feature/equal-height/build

That looks like it's working. Could you switch out the JavaScript file (that only, not the css) and give it a test?

jsantari commented 9 years ago

Great! - it's works fine now, thanks. I really like rpb as a framework. Two things I think would help would be a good menu system and some good starter layout templates. I think having a starter point for a layout would make it easier for newbies to fbp to get on board.

JimBobSquarePants commented 9 years ago

Excellent! :smile:

Glad you like it. I'm working on a menu. I'm also making the grid simpler to use so the whole thing is easier to pick up. Templates will come soon eventually but it's a lot of work putting it all together.

I'm gonna keep this issue open until the next release so I can track it so don't close it for now.