1

I want to use the Jquery Validate combined with Tooltipster in a similar way to the example provided by Sparky here.

The difference is that I need to show those error messages on controls that I create dynamically and as it is shown is this jsfiddle, it only works for static html controls(the input and textarea shown before the "Return Details" fieldset)

HTML code:

<form id="myform">
    <table align="center" style="width: 100%">
        <tr>
            <td>
                <input id="title" type="text" name="title" class="required tooltip" />
                <br>
                <textarea id="comments" name="comments" class="required tooltip"></textarea>
            </td>
        </tr>
        <tr>
            <td>
                <table align="center" style="width: 70%" cellpadding="0" cellspacing="0">
                    <tr>
                        <td>
                            <fieldset>
                                <legend>Return Details</legend>
                                <input id="addRow" type="button" value="+ Add Frame " class="button small blue" style="height: 20px;" />
                                <table id="tbRetornosModelos" class="tabla-retorno" width="100%" border="0">
                                    <tbody></tbody>
                                </table>
                            </fieldset>
                        </td>
                    </tr>
                </table>
                <table id="tbStructures" align="center" style="width: 70%" cellpadding="0" cellspacing="0">
                    <tbody></tbody>
                    <tfoot>
                        <tr>
                            <td>
                                <input type="button" id="btnEnviar" value="Send" />
                            </td>
                        </tr>
                    </tfoot>
                </table>
            </td>
        </tr>
    </table>
</form>

JS CODE

$(document).ready(function () {
    var counter = 0; // Counter for number of rows
    var c_NombreRetorno = null;
    var c_TipoRetorno = null;

    $("#addRow").on('click', function () {
        counter = counter + 1;

        var newNombreRetorno = "NombreRetorno" + counter;
        var newTipoRetorno = "TipoRetorno" + counter;
        //Cambiar               
        var newEnlaceEstruct = "tbExp_s1_e" + counter;
        var newRow = '<tr><td style="font-weight:bold; width:100px;">Return # ' + counter + ':  </td>' +
            '<td>' + '  Name</td>' +
            '<td><input type="text" id="' + newNombreRetorno + '" name="' + newNombreRetorno + '" class="required tooltip"/>' + '</td>' +
            '<td>Data Type</td>' +
            '<td><select name="select" id="' + newTipoRetorno + '" class="required tooltip"> <option value="" selected>Seleccione...</option> <option value="Number" >Number</option><option value="Text">Text</option></select></td>' +
            '<td><input type="button" value="-Remove" class="button small blue deleteFila"  style="height:20px;"></td>' +
            '<td><input type="hidden" id="enlace' + counter + '" value="' + newEnlaceEstruct + '" /></td>' +
            '</tr>';
        $('table.tabla-retorno >tbody').append(newRow);



        var iEst = counter;
        $('#tbStructures >tbody').append('<tr id="r' + iEst + '"></tr>');
        $('#r' + iEst).append('<td><fieldset id="e' + iEst + '"><legend>Estructure(Frame) For Retorno # ' + iEst + '</legend></fieldset></td>')
        var idEst = 'e' + iEst;
        var idSent = 's1_' + idEst;
        $('#' + idEst).append('<div><span>Expression Type</span><select id="tipoExp_' + idEst + '"></select></div><hr><fieldset id="' + idSent + '"></fieldset>');
        var idDivEst = 'div_' + idSent;
        $('#' + idSent).append('<div><select id="subTipoExp_' + idSent + '"></select></div></div><br/><div id="' + idDivEst + '"></div>');
        var idTbSent = 'tbExp_' + idSent;
        $('#' + idDivEst).append('<table id ="' + idTbSent + '" class="order-list" align="center" cellpadding="0" cellspacing="0"></table>');
        $('#' + idTbSent).append('<tbody></tbody><tfoot></tfoot>');
        var fila_1 = '<tr><td><span class="rightAlig">IF</span>(<input type="text" id="exp1_' + idTbSent + '" name="exp1_' + idTbSent + '" class="conditionInput required tooltip" /></td>';
        fila_1 += '<td>:<input type="text" id="ret1_' + idTbSent + '" name="ret1_' + idTbSent + '" class="required tooltip" />)</td><td></td></tr>';
        $('#' + idTbSent + ' > tbody').append(fila_1);

        var filas_footer = '<tr><td colspan="3" style="text-align: left;"><input type="button" id="btnAñadir_' + idTbSent + '" value="+ Add" class="button small blue agregarCond" /></td></tr>';
        filas_footer += '<tr><td colspan="3"><span>Else</span>(<input type="text" id="else_' + idTbSent + '" name="else_' + idTbSent + '" class="required tooltip" />)<input type="hidden" id="c_' + idTbSent + '" value="1" /></td></tr>';
        $('#' + idTbSent + ' > tfoot').append(filas_footer);

        addEventNewRow('btnAñadir_' + idTbSent);
        $(".deleteFila").on("click", function (event) {
            $(this).closest("tr").remove();
        });
    });

    function addEventNewRow(elemId) {
        elem = $("#" + elemId);
        elem.on('click', function () {

            var tbId = $(this).closest("table").attr("id");
            var IDs = tbId.split("_");
            var estId = IDs[2];
            var c_tb = $('input[id="c_' + tbId + '"]');
            var c_condiciones = parseInt(c_tb.val());
            c_condiciones = c_condiciones + 1;
            var newCondition = "exp" + c_condiciones + "_" + tbId;
            var newTrueValue = "ret" + c_condiciones + "_" + tbId;
            var idBtnQuitar = "btnQuitar_" + c_condiciones + "_" + tbId;

            var newRow = '<tr><td><span>ELSE IF</span>(<input type="text" id="' + newCondition + '" name="' + newCondition + '" class="conditionInput required tooltip"/>) </td>';
            newRow += '<td>:<input type="text" id="' + newTrueValue + '" name="' + newTrueValue + '" class="required tooltip"/>)</td>';
            newRow += '<td><input type="button" id="' + idBtnQuitar + '" value="-Remove" class="button small blue"></td></tr>';
            $('#' + tbId + ' >tbody').append(newRow);

            //update counter "c_condiciones"
            c_tb.val(c_condiciones);

            $('#' + idBtnQuitar).addClass('deletRow');

            $(".deletRow").on("click", function (event) {

                $(this).closest("tr").remove();


            });
        });
    }
    //$('#myform input[type="text"]').tooltipster({
    $('.tooltip').tooltipster({
        trigger: 'custom', // default is 'hover' which is no good here
        onlyOne: false, // allow multiple tips to be open at a time
        position: 'right' // display the tips to the right of the element
    });
    var dialogFormValidator = $("#myform").validate({
        // any other options & rules,
        errorPlacement: function (error, element) {
            $(element).tooltipster('update', $(error).text());
            $(element).tooltipster('show');
        },
        success: function (label, element) {
            $(element).tooltipster('hide');
        },
        submitHandler: function (form) {
            form.submit();
        }
    });

    $("#btnEnviar").click(function () {
        var valid = dialogFormValidator.form();
        if (valid) {
            alert("valid!!")
        } else {
            alert("invalid!!!");
        }
    });


});

In that jsfiddle I use a class tooltip to attach the tooltip message to all those controls that I want to validate. I also try using type selectors like Sparky used in his example , but it didn't work either.

Does anybody know how can I get tooltipster to work with dynamic control or can show me where I am going wrong?

Thanks in advance.

Community
  • 1
  • 1
eddy
  • 4,373
  • 16
  • 60
  • 94

1 Answers1

0

1) I noticed that your dynamic <select> element contains name="select". The jQuery Validate plugin requires that each input element contains a unique name attribute. You'll have to fix this or only the first instance of name="select" will be validated.

2) Tooltips are not working on dynamic elements because .tooltipster() is only attached to the existing input elements upon DOM ready. If you're going to dynamically create new input elements, then you'll also need to attach .tooltipster() to these new elements after they're created. This is the only way, unless/until the .tooltipster() developer provides a method of delegation.

// dynamically add new input elements
$('#add').on('click', function () {
    $('#myform').append('your new html:  <input class="new" type="text" />');
    $('.new').tooltipster({  // initialize tooltips on new elements
        trigger: 'custom',
        onlyOne: false,
        position: 'right'
    });
});

Here is a "proof" that shows you can use Tooltipster on dynamically created fields.

http://jsfiddle.net/dCyj8/

However, Tooltipster has a minor flaw in that any open tooltip will not visually shift when you dynamically change the page layout. In other words, if a tooltip is already open when you add a new field, the existing tooltip will not shift up/down the page along with its target element. In the demo, click submit to trigger the two tooltips, then add the new field. The two tooltips are not shifted down along with their two target fields. Then if you hit submit again, you'll have a third tooltip sitting exactly on top of an existing tooltip. You can see them correct to their proper positions as you enter data and then delete data from the various fields.

The Tooltipster developer has been very responsive in the past. I suggest you point out these issues to him.

  • Method to delegate .tooltipster() to attach to dynamically created elements?
  • Dynamically shift tooltips along with dynamically shifted layout?
Sparky
  • 98,165
  • 25
  • 199
  • 285