-1

Am trying to access a particular element from DOM, which is created dynamically. On Hover of that element I want to access the respective element attribute. like,

// element creation inside render function
$.each(profiles, function(i,x){
  <span data-name={x.name} rel="tooltip">Name<span>
});

// tooltip initialization in componentDidMount function
var self = this;
$('body').tooltip({
        selector: '[rel=tooltip]',
        title: self.tooltipMsg
 });

and the function is like,

tooltipMsg: function(element){
   return $(this).attr('data-name'); // this code is return undefined, since this refers to ReactClass
}

How can I get the particular element inside the tootipMsg function without using this or Is there any alternative for "this" reference, which should refers the particular element.

If it is static element I can use "ref" https://facebook.github.io/react/docs/more-about-refs.html#the-ref-string-attribute But in my case the ref is dynamic.

Thanks in advance.

Viuu -a
  • 108
  • 1
  • 12
  • 2
    Not a ReactJS question. What is the value of `element` in the `tooltipMsg` function ? – Bruno Grieder Oct 30 '15 at 11:35
  • how about creating the ref dynamic too. But anyway I dont think creating child's with jquery is "react way" you should nest elements. https://facebook.github.io/react/docs/multiple-components.html#dynamic-children – svenhornberg Oct 30 '15 at 11:36
  • @Bruno Grieder, http://getbootstrap.com/javascript/#tooltips please refer title option in the link. If we use function for title, it will be called with this reference. but in my case it is coming as undef – Viuu -a Oct 30 '15 at 11:54
  • @fuubah, If we create ref dynamic. how will I know the ref value, when the tooltip function is triggered? Basically I want to know which element triggered the tooltipMsg function. Moreover the span tag will be created along with dynamic table . I mentioned a sample code only here. – Viuu -a Oct 30 '15 at 11:59
  • @Viuu-a may you have a unique id or hash logic, so you may know how the ref will be calculated. – svenhornberg Oct 30 '15 at 12:11
  • Thank you for reply. Yes if it is dynamic id how we will know which element triggers the event or which elemnt called the function. I need something like window.event(but this will not work in FF). If u see my code $(this).attr('data-name'). To be simple, my question is I need alternative for "this"(should refer to element instead of react object) – Viuu -a Oct 30 '15 at 12:22
  • `const el = ReactDOM.findDOMNode(this); $(el).find('whatever')` but honestly, either I misunderstand your problem or you can do simpler and more efficient than this – Bruno Grieder Oct 30 '15 at 12:52
  • Thank you. I tried this already but it is giving the top element i.e., div(the top element of the page). Its not giving the particular element, which called the tooltipMsg function. – Viuu -a Oct 30 '15 at 14:01
  • You never answered my first question... – Bruno Grieder Oct 30 '15 at 16:04
  • @Bruno, I answered at first itself, getbootstrap.com/javascript/#tooltips please refer title option in the link. If we use function for title, the function will be called with this reference. but in my case the element is coming as undef. If we use the same code in normal javascript(without React) the element will be the particular DOM element which triggers the function. – Viuu -a Nov 02 '15 at 05:33

2 Answers2

1

If I understand the question (and comment dialogue) correctly, you want to

  • create multiple tooltip elements
  • have some sort of toolTipMsg() function to read the content of the shown tooltip

The current setup looks like a long roundtrip:

  • inside react render function, use jQuery to create multiple tooltip elements, and pass each a HTML data-name attribute
  • inside react componentDidMount, use jQuery to fetch tooltips from DOM and attach listeners
  • listener fires function that reads again from DOM to fetch tooltip HTML data-name attribute.

Mixing jQuery and react for reading DOM (or - worse - manipulating DOM) is generally not a good idea.

UPDATE: so there are 2 possible routes to solve:

a. React-only solution (NO jQuery, NO Bootstrap) Within react it is good practice to avoid using refs if they are not needed. And it looks like you do not need them.

You could bind the variable to the toolTipMsg(), and use that. And set up a MouseOver listener on the parent of the tooltip.

React-style code would look more or less like:

// tooltip element creation inside render function 
// of individual tooltip parent element
return 
  <div className="alwaysVisibleToolTipParent" 
    onMouseOver={this.toolTipMsg}>
    <p>someOtherContent</p>
    <span className="my-awesome-tooltip">{this.props.tooltipname}</span>
  </div>
});

// no need for componentDidMount: listener covered in initial render

// the function is much simpler now
tooltipMsg: function(){
   console.log(this.tooltipname);
}

You need to roll your own tooltip with styling for this (so unfortunately no benefit from jQuery)

b. Alternatively: Use Bootstrap and jQuery only (NO react) Bootstrap tooltip fires its own events that you can listen to. (documentation here).

In your code, you would somewhere:

$('#myToolTipParent').on('shown.bs.tooltip', function () {
  // 'this' is now the element (parent of the tooltip)
  tooltipMsg(this);
})

And your tooltipMsg() function would read:

function tooltipMsg(element) {
  // the text of the tooltip == the title attribute of the parent element of the tooltip
  console.log(element.getAttribute("title"));
}
wintvelt
  • 13,855
  • 3
  • 38
  • 43
  • Thank you for answer @wintvelt. You are correct this what Am trying to do in my code. But in your solution you are using onMouseOver function. But the bootstrap tooltip will do this binding if we specify function for title option. If we are using our explicit call then no need of using the bootstrap tooltip. still I didn't get the answer to get the "this"(specific DOM element) reference – Viuu -a Nov 02 '15 at 05:41
  • One more thing, the div(tooltip) will be inside each funciton to create dynamic tooltip (based on condition tooltip will be created for particular rows). – Viuu -a Nov 02 '15 at 06:00
0

I found a working code based on @wintvelt solution, But the problem in this solution is the tooltip message will not be shown on first time, since the title is set only inside the tooltipMsg

//custom function inside createClass
tooltipMsg: function(disabled_by, dest, event) {
    $(event.target).attr("data-original-title", disabled_by);
     ..
},

// tooltip initialization inside componentDidMount
$('body').tooltip({
        selector: '[rel=tooltip]',
        template: '<div class="tooltip custom_tooltip"><div class="tooltip-arrow custom_tooltip-arrow"></div><div class="tooltip-inner custom_tooltip-inner"></div></div>',
});

// span tag creation inside each in render function
$.each(profiles, fucntion(i, profile) {
    var disabled = (profile.disabled) ? <span className="label label-important" data-toggle="tooltip" data-placement="right" onMouseOver={react_obj.tooltipMsg.bind(null,profile.Disabled_by)} rel="tooltip">Disabled</span>)
            : null
    <tr> 
        <td> {profile.Name}
            <br/>
            {disabled}
        </td>
    </tr>
});
Viuu -a
  • 108
  • 1
  • 12