0

I have 3 questions about the same thing that I need to solve:

1

How can I make a loop inside the another loop to get price_history from .json file and populate the modal with the 7 results following the template inside the priceHistoryModal variable?

I've had tried some ways, but all returns me undefined.

2

Only the first button "Price History" on'click' shows all modal <div> at the same time. How can I open his parent modal only (inside the same <article>)?

3

Why the last modal don't close? As the same with button, just the first one calls the modal.

This is the .json file:

{
  "hotels": [
    {
      "name": "Super 8 Speedway/University",
      "description": "Just off Interstate 85, this hotel features free Wi-Fi and a daily continental breakfast with hot waffles. The Charlotte Motor Speedway is a 15 minute drive from the hotel.",
      "image": "http://www.raphaelfabeni.com.br/rv/test-resources/hotels/super-8.jpg",
      "rate": 3,
      "price": 180,
      "price_history": [
        { "month": "Jan", "value": 146 },
        { "month": "Feb", "value": 182 },
        { "month": "Mar", "value": 130 },
        { "month": "Apr", "value": 119 },
        { "month": "May", "value": 171 },
        { "month": "Jun", "value": 154 },
        { "month": "Jul", "value": 163 }
      ]
    },
    {
      "name": "Omni Charlotte Hotel",
      "description": "The Omni Charlotte Hotel envelopes you in ultimate comfort with a signature touch of genuine North Carolina hospitality.",
      "image": "http://www.raphaelfabeni.com.br/rv/test-resources/hotels/omni-charlotte.jpg",
      "rate": 4,
      "price": 280.50,
      "price_history": [
        { "month": "Jan", "value": 302 },
        { "month": "Feb", "value": 219 },
        { "month": "Mar", "value": 300 },
        { "month": "Apr", "value": 229 },
        { "month": "May", "value": 272 },
        { "month": "Jun", "value": 249 },
        { "month": "Jul", "value": 239 }
      ]
    }

And the .js file with the my issue section:

$(".searchHotels").on('click', function() {

  //Get JSON Data
  $.getJSON('http://www.raphaelfabeni.com.br/rv/hotels.json', function(data) {

    //Start loop
    $.each(data.hotels, function(k, v) {
      //Stars rating template
      var span = '<span id="hotelStars" class="fa fa-star starRating-' + this['rate'] + '"></span>';


      var priceHistoryModal = '<div>' +
        '<p>Price History</p>' +

        //Question #1

        //Need to show all 7 months
        '<p>Month:' + this.price_history[0]['month'] + '</p>' +
        //Need to show all 7 month prices
        '<p>Price:' + this.price_history[0]['value'] + '</p>' +
        '<p>Click to close</p>' +
        '</div>';
      // Hotel Results Template
      var html = '<article id="hotelInfo" class="hotelInfoWrapper" data-rating="' + this['rate'] + '" data-price="' + this['price'] + '" style="position: relative;">' +
        '<div class="modalCtn" style="width: 450px; height: 300px; background: #79BD1A; position: absolute; display: none; margin-left: 20%;">' +

        //Question #2

        //Here I need do another loop and get the price history: month and value of each hotel result (data.hotels) from the loop above.
        //And append the priceHistoryModal as template
        priceHistoryModal + //its correct?

        '</div>' +
        '<div class="imgCtn"><img src="' + this['image'] + '" alt=""></div>' +
        '<div class="hotelInfo">' +
        span +
        '<h1>' + this['name'] + '</h1>' +
        '<p>' + this['description'] + '</p>' +
        '<button class="bookNow">Book now</button>' +
        '<button id="showPriceHistory" class="priceHistory">Price history</button>' +
        '</div>' +
        '<div class="hotelPrice">' +
        '<small>Total</small>' +
        '<h2 class="price">$' + this['price'] + '</h2>' +
        '</div>' +
        '</article>';

      //Question #3

      //This button calls the modal with price history container
      //But just the first button works and call all modals at the same time
      //On click need to call only the modal inside the same button container
      $("#showPriceHistory").on('click', function() {
        $(".modalCtn").fadeIn();
      });
      //Just for close modal
      $(".modalCtn").on('click', function() {
        $(this).fadeOut();
      });
      //Append the html template  variable to the hotel list
      $(html).hide().appendTo("#hotelList").fadeIn(400);
    }); //End Loop
  }); //End Ajax
}); //End Button Search Hotels Event
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="hotelList"></div>

Thank you!

Community
  • 1
  • 1
  • What's confusing you? `$.each` passes in the index, element to the method. You can easily use `$.each` again inside that context off of a key on that element such as `element.price_history`. – Taplar Nov 01 '17 at 17:56
  • What's the context off you mean? Outside my html template variable? I think that I dont know how to append the results in the `.modalCtn` as a `
    ` with the 7 months and values. I've tried this: ` $.each(this.price_history, function(k, v){ $('div .modalCtn').append('

    '+this['month']+'

    '); console.log(k); });` And this load the data, but load all months in the same `
    ` Could you explain me? Thanks!
    – Felipe Vegners Nov 01 '17 at 18:33
  • `$('div.modalCtn')` will only find elements that currently exist in the DOM. If you haven't yet attached the elements in your html variable to the DOM, they won't exist to be found. You are constructing your html variable that you are later appending to the hotelList. Not sure why you are not continuing to append to that variable. – Taplar Nov 01 '17 at 18:35
  • "context off of a key" `$.each(data.hotels, function(index, element) { $.each(element.price_history, function(index, history){ ....do stuff... }); });` – Taplar Nov 01 '17 at 18:49
  • Thank a lot for your explanation. I've had tried to do this loop inside the `html` template. So when print the values the loop pass through the another loop and show me the same result several times. Now, I create a loop, but the last one result button don't trigger when click. Have any idea? The developer tools in chrome shows me that this button don't have the click function. I don't know why. – Felipe Vegners Nov 01 '17 at 23:08
  • "last result button" ? – Taplar Nov 01 '17 at 23:11
  • The @headmax solution helps me to fix the loop. But when the results come on (12 hotels) the last button to call the modal don't work. I compare with the another 11 buttons (all the 11 its working) this last one don't trigger the modal .fadeIn() and if I force the modal by display block, this modal (the last as well) don't close. – Felipe Vegners Nov 01 '17 at 23:17

1 Answers1

0

i use each inside the json data to store the history, is you got any other question.

$(".searchHotels").on('click', function() {

  //Get JSON Data
  $.getJSON('http://www.raphaelfabeni.com.br/rv/hotels.json', function(data) {

    //Start loop
    $.each(data.hotels, function(k, v) {
      //Stars rating template
      var span = '<span id="hotelStars" class="fa fa-star starRating-' + this['rate'] + '"></span>';


      var priceHistoryModal = '<div>' +
        '<p class="title_p">Price History</p>';

        //Question #1

        //Need to show all 7 months
        $(this.price_history).each(function(){
                 //console.log(this.month)
                priceHistoryModal += '<p>Month:' + this.month + '</p>' +
        //Need to show all 7 month prices
        '<p>Price:' + this.value + '</p>';
        });
        
         
        priceHistoryModal += '<p class="close_p">Click to close</p>' +
        '</div>';
      // Hotel Results Template
      var html = '<article id="hotelInfo" class="hotelInfoWrapper" data-rating="' + this['rate'] + '" data-price="' + this['price'] + '" style="position: relative;">' +
        '<div id="modal_' + k + '" class="modalCtn" style="width: 450px; height: auto; background: #79BD1A; position: absolute; display: none; margin-left: 20%;">' +

        //Question #2

        //Here I need do another loop and get the price history: month and value of each hotel result (data.hotels) from the loop above.
        //And append the priceHistoryModal as template
        priceHistoryModal + //its correct?

        '</div>' +
        '<div class="imgCtn"><img src="' + this['image'] + '" alt=""></div>' +
        '<div class="hotelInfo">' +
        span +
        '<h1>' + this['name'] + '</h1>' +
        '<p>' + this['description'] + '</p>' +
        '<button class="bookNow">Book now</button>' +
        '<button value="' + k + '" id="showPriceHistory" class="priceHistory">Price history</button>' +
        '</div>' +
        '<div class="hotelPrice">' +
        '<small>Total</small>' +
        '<h2 class="price">$' + this['price'] + '</h2>' +
        '</div>' +
        '</article>';

      //Question #3

      //This button calls the modal with price history container
      //But just the first button works and call all modals at the same time
      //On click need to call only the modal inside the same button container
      $("body").on('click', '.priceHistory', function() {
        $("#modal_" + $(this).prop('value')).fadeIn();
      });
      //Just for close modal
      $("body").on('click', '.modalCtn', function() {
        $(this).fadeOut();
      });
      //Append the html template  variable to the hotel list
      $(html).hide().appendTo("#hotelList").fadeIn(400);
    }); //End Loop
  }); //End Ajax
}); //End Button Search Hotels Event
div p{
clear:left;
height:auto;
text-align:left;
margin:4px;
display:table;
}

.title_p{
 color:white;
 padding-bottom:20px;
 font-size:20px;
}

.close_p{
 color:red;
 font-size:20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" class="searchHotels" value="search"/>
<div id="hotelList"></div>
  • That's solve my problem. I run trough the code and mind the way that you use to do another $.each. I've tried get the values passing the same first $each method. But the last button and the last modal (button value=11 and #modal_11) don't working. You have any idea why?? Thank you! – Felipe Vegners Nov 01 '17 at 19:24
  • Any idea about the why the button inside the last result doesn't trriger the modal? – Felipe Vegners Nov 01 '17 at 23:10
  • oh i looking about that i didn't really tested :) –  Nov 02 '17 at 00:10
  • Debuging with developer tools I found that this last generated button don't get the `onClick` attribute. My `.json` returns 12 results but just 11 works well. There's anything to do with ID? I'm figuring out about the id is a string and value is number... – Felipe Vegners Nov 02 '17 at 00:17
  • 1
    There's: [the solution](https://stackoverflow.com/questions/9344306/jquery-click-doesnt-work-on-ajax-generated-content). – Felipe Vegners Nov 02 '17 at 00:22
  • sorry i forgot you ;) did you tested something? –  Nov 02 '17 at 00:38
  • @FelipeVegners i known this bug when you doesn't create a element html when the body is loading but after need to trigger the click from body and then you got a 2 params where you put the class or id or pseudo classes ... etc this post is solved can you add valid for people who got the same problem, ty ;). gl for the next. I gave you a +10. –  Nov 02 '17 at 00:43
  • I blasted my brain today with it, anyway thanks you for help me :) – Felipe Vegners Nov 02 '17 at 00:49