Marco
Marco

Reputation: 1349

Tooltipster for both showing tooltips for fields and showing errors in Jquery validation

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/

Upvotes: 1

Views: 1697

Answers (2)

Marco
Marco

Reputation: 1349

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>

Upvotes: 0

Sparky
Sparky

Reputation: 98718

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/

Upvotes: 1

Related Questions