0

I am using ES6 and have a problem, showCarOnMap() that a part of instance is not accessible inside $(document).delegate() or $(document).click()

Actually I have a table and found the row number after click through $(document).delegate() by "$(this).index()" and I want to call showCarOnMap() function after founding the clicked row number. but this time 'this' is not having showCarOnMap();

Please see the comments for better understanding.

import {Page} from './framework/page.js';
import {DataTable} from './ui/data-table.js';
import {application} from './app.js';
import {GoogleMap} from './ui/google-map.js';
import {Button} from './ui/button.js';


export class CarsPage extends Page{
    constructor(){
        super('Cars');
    }

    createElement(){
        super.createElement();
        //passing headers and data to genrate the table of car
        let headers = 'License Make Model Miles Track'.split(' ');
        let t = new DataTable(headers, application.dataService.cars); 
        t.appendToElement(this.element);

        /* Poblem Start here*/
        $(document).delegate("tr", "click", function(e) {
            let index = $(this).index(); // getting right index   
            this.showCarOnMap(index); // BUT: not getting showCarOnMap() 
            //Uncaught TypeError: this.showCarOnMap is not a function
        });
    }

    showCarOnMap(index){
        // car on map
        let mapArray = [];
        mapArray.push(application.dataService.cars[index]);
        let centerOfMap = {lat: 40.783661, lng: -73.965883};
        let carLabelObject = {titleOfCar:'Car', titleOfDrone:'Drone'};
        let carMap = new GoogleMap(centerOfMap, mapArray, carLabelObject);
        carMap.appendToElement(this.element);
    }

    getElementString(){
        return '<div style="margin:20px;"><h3>Cars</h3></div>';
    }
}

I tried one another way- But not working

$(document).delegate("tr", "click",(e)=>{
    let index = $(this).index();  // wrong: index always -1
    this.showCarOnMap(index); // founded in this });
Ankit Pandey
  • 608
  • 4
  • 17
  • `this` is not both `tr` element and `CarsPage` instance at the same time – guest271314 Sep 19 '17 at 19:12
  • @guest271314 Yes, I know but to resolve this problem. Please help – Ankit Pandey Sep 19 '17 at 19:15
  • `this` is also `document` within arrow function – guest271314 Sep 19 '17 at 19:15
  • @guest271314 Actually when I call directly showCarOnMap(0) or showCarOnMap(1) then this is fine. But according to my flow of project how can I solve this problem. – Ankit Pandey Sep 19 '17 at 19:18
  • createElement(){ super.createElement(); //passing headers and data to genrate the table of car let headers = 'License Make Model Miles Track'.split(' '); let t = new DataTable(headers, application.dataService.cars); t.appendToElement(this.element); showCarOnMap(1); } This is working fine. – Ankit Pandey Sep 19 '17 at 19:19
  • Use `event.target` within event handler arrow function to reference current `` element – guest271314 Sep 19 '17 at 19:21
  • what. Why would you expect `this` to be both the table row that was clicked AND an instance of the class? it can only be one or the other.. – Kevin B Sep 19 '17 at 19:24
  • @KevinB Actually I want to call showCarOnMap(clickedTrNumber) Or I want to click on row and find that ow number and and call showCarOnMap(clickedTrNumber) How can I achieve. Please help – Ankit Pandey Sep 19 '17 at 19:34
  • @KevinB Dear do you have any idea about how to achieve the solution of my problem – Ankit Pandey Sep 19 '17 at 19:48
  • Yes, access `this` correctly, and access the clicked element correctly. problem solved – Kevin B Sep 19 '17 at 19:48
  • How? Could you please write a piece of code. – Ankit Pandey Sep 19 '17 at 19:50
  • There's no reason for me to, one has already been provided by someone else. – Kevin B Sep 19 '17 at 19:58

1 Answers1

0

You can use event.target.parentElement or .closest() to reference clicked <tr> element.

Or, as suggested by @KevinB, event.currentTarget

  $(document).on("click", "tr", event => {
    // or `$(event.target).closest("tr").index()`
    // or `$(event.currentTarget).index()`
    let index = $(event.target.parentElement).index();
    this.showCarOnMap(index);
  });
guest271314
  • 1
  • 15
  • 104
  • 177
  • @KevinB _"no it isn't."_ Yes, it is, given code at OP http://plnkr.co/edit/fUi2O8NMc0QIJTvaZpm2?p=preview – guest271314 Sep 19 '17 at 19:33
  • @KevinB Just noticed that. `this` would still not be `tr` element http://plnkr.co/edit/fUi2O8NMc0QIJTvaZpm2?p=preview. The solution is still to use `event.target` to reference clicked `` element. See updated post, removed erroneous portion of Answer – guest271314 Sep 19 '17 at 19:35
  • Index always 0 but yes able to call showCarOnMap(clickedTrNumber) – Ankit Pandey Sep 19 '17 at 19:39
  • 1
    @AnkitPandey See updated post. The clicked element was the `` element. To reference `` element you can use `event.target.parentElement` or `$(event.target).closest("tr").index()` – guest271314 Sep 19 '17 at 19:44
  • why is parentElement needed? wouldn't jquery set the event target to the tr in this case? – Kevin B Sep 19 '17 at 19:49
  • @KevinB No, evidently not. `event.target` can be a `` child element of parent `` element http://plnkr.co/edit/fUi2O8NMc0QIJTvaZpm2?p=preview at version 3 – guest271314 Sep 19 '17 at 19:50
  • 1
    you are correct. it's [`e.currentTarget`](http://api.jquery.com/event.currentTarget/) that i was thinking about, which would be equivalent to `this` in the non-arrow function version. – Kevin B Sep 19 '17 at 19:54
  • @guest271314 $(event.target).closest("tr").index() is working fine for me Thanks a lot. – Ankit Pandey Sep 19 '17 at 19:57
  • @KevinB Updated post to reflect the inclusion of `event.currentTarget` option – guest271314 Sep 19 '17 at 19:57