1

I'm using the tooltipster plugin to show fields's hints and also another tooltip at bottom to show errors from jquery validate plugin, but for some reason all the messages updates are happening on the first error tooltip.

What am I missing?

$(document).ready(function () {
  // initialize tooltipster on text input elements
  $('input').tooltipster();
  var tooltipsterErrorMsg = [];
  
  // initialize validate plugin on the form
  $('#myform').validate({
    showErrors: function(errorMap, errorList) {
      // Clean up any tooltips for valid elements
      $.each(this.validElements(), function (index, element) {
        if (index < tooltipsterErrorMsg.length) {
         tooltipsterErrorMsg[index].hide();
        }
      });
     
      // Create new tooltips for invalid elements
      $.each(errorList, function (index, error) {
        if (index === tooltipsterErrorMsg.length) {
          var tooltipObject = $(error.element).tooltipster({
            trigger: 'custom',
            multiple: true,
            position: 'bottom'
          });
          
          tooltipsterErrorMsg.push(tooltipObject[0]);
        }
        tooltipsterErrorMsg[index].content(errorList[index].message).show();
     });
    },
    rules: {
      field1: {
        required: true,
        email: true
      },
      field2: {
        required: true,
        minlength: 5
      }
    },
    submitHandler: function (form) { // for demo
      alert('valid form');
      return false;
    }
  });

});
#myform {
    margin: 100px;
}
input {
    margin: 20px;
}
a {
    display: block;
    position: absolute;
    bottom: 0;
}

.error {
  color: #900;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/tooltipster/3.3.0/css/tooltipster.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tooltipster/3.3.0/js/jquery.tooltipster.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>
<form id="myform">
    <input type="text" name="field1" title="Tooltip teste 1" />
    <input type="text" name="field2" title="Tooltip teste 2" />
    <br/>
    <input type="submit" />
</form>

Here's the fiddle: http://jsfiddle.net/macmessa/m368ntxw/

Marco
  • 1,279
  • 1
  • 15
  • 26
  • [Look at the sample code in the answer of the duplicate I flagged](http://stackoverflow.com/questions/14741688/how-to-display-messages-from-jquery-validate-plugin-inside-of-tooltipster-toolti). Basically, your main mistake is trying to use the `showErrors` function... that is only intended for making a centralized list of errors and would have nothing to do with something like this. You simply need to properly employ the `errorPlacement` and `success` functions. – Sparky Mar 17 '16 at 15:16
  • I've started using this sample that you've linked, but I do want to use the tooltip as a hint for the field and another one as a the error message. I can't see that in the sample code you said. – Marco Mar 17 '16 at 16:21
  • The sample code fixes the jQuery Validation integration. As far as the hover hints, simply integrate your own working code into the example. – Sparky Mar 17 '16 at 16:32
  • I re-opened the question and posted an answer below. – Sparky Mar 17 '16 at 16:55

2 Answers2

1

Two issues...

  1. You're using the showErrors function improperly. It was only intended for constructing an error list, not for individual error placement. Employ the errorPlacement and success functions for showing & hiding the individual tooltip bubbles.

    errorPlacement: function(error, element) {
        var lastError = $(element).data('lastError'),
            newError = $(error).text(); // current error message
    
        $(element).data('lastError', newError); // keep track of the error
    
        if (newError !== '' && newError !== lastError) { // new error?
            $(element).tooltipster('content', newError); // replace message
            $(element).tooltipster('show');  // show bubble
        }
    },
    success: function(label, element) {
        $(element).tooltipster('hide'); // hide bubble when error clears
    },
    
  2. You're trying to initialize and re-initialize ToolTipster on the same element for showing two different bubbles on the same element at the same time. Although I'm not clearly seeing the described issue in your demo, I can see how it would lead to problems and confusion.

Here's a workaround.

Surround the input elements with a container element.

<div title="Tooltip teste 1">
    <input type="text" name="field1" />
</div>

BTW: you don't need the data-rule-required attribute when you've already declared required within .validate().

Then you can initialize ToolTipster on the input[type="text"] elements for validation error messages...

$('input[type="text"]').tooltipster({
    trigger: 'custom', // default is 'hover' which is no good here
    onlyOne: false,    // allow multiple tips to be open on the page
    position: 'right'
});

And then separately initialize another ToolTipster instance on the parent container for the hints...

$('input[type="text"]').parent().tooltipster();

(I'm being more specific with the target here. By targeting only input, you would also match the type="submit" element.)

Proof-of-concept DEMO: http://jsfiddle.net/2xgcyg6w/

Sparky
  • 98,165
  • 25
  • 199
  • 285
  • 1
    - I rewrote my code using the callbacks you've suggested; - The data-rule-required was something that I forgot to remove when I posted the code; - I have to re-initialize but setting it to another object, because the first initialization is for the hover event and the other one is triggered by the validation. Thanks, I appreciate the time you spent helping me. – Marco Mar 17 '16 at 17:47
0

Well, I achieved exactly what I needed using the errorPlacement and success as Sparky recommended, I kind of mixed what I did with his example:

$(document).ready(function () {
  // initialize tooltipster on text input elements
  $('input').tooltipster({position: 'top'});
  var tooltipsterErrorMsg = [];
  
  // initialize validate plugin on the form
  $('#myform').validate({
    errorPlacement: function (error, element) {
      if ($(element).index() === tooltipsterErrorMsg.length) {
        var tooltipObject = $(element).tooltipster({
          trigger: 'custom',
          multiple: true,
          position: 'bottom'
        });
    
        tooltipsterErrorMsg.push(tooltipObject[0]);
      }
      tooltipsterErrorMsg[$(element).index()].content($(error).text()).show();
    },
    success: function (label, element) {
      tooltipsterErrorMsg[$(element).index()].hide();
    },
    submitHandler: function (form) { // for demo
      alert('valid form');
      return false;
    }
  });
});
#myform {
    margin: 100px;
}
input {
    margin: 20px;
}
a {
    display: block;
    position: absolute;
    bottom: 0;
}

.error {
  color: #900;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/tooltipster/3.3.0/css/tooltipster.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tooltipster/3.3.0/js/jquery.tooltipster.min.js"></script>

<form id="myform">
    <input type="text" name="field1" title="Tooltip teste 1" data-rule-required="true" data-rule-email="true" />
    <input type="text" name="field2" title="Tooltip teste 2" data-rule-required="true" data-rule-minlength="5" />
    <br/>
    <input type="submit" />
</form>
Marco
  • 1,279
  • 1
  • 15
  • 26
  • Please notice how your ToolTipster bubble is re-rendering itself after every keyup event as opposed to mine where the bubble only re-renders itself IF/when the message changes. – Sparky Mar 17 '16 at 22:14
  • You're still targeting all `input` elements with this selector, `$('input')`. As mentioned in my answer, that also includes the `input type="submit"` element. You should be using a more specific selector such as `$('input[type="text"]')`. – Sparky Mar 19 '16 at 15:37
  • I'll alter my code to use your new and last error msg. About the target elements, it's just for tests, I'll target only the needed elements. Thanks – Marco Mar 21 '16 at 11:10