1

I am using jquery in my one of the form. where on click of submit button i call one function QuoteDetailValidation(). In which i validate fields. But after validate that fields i try to get all fields which have errorActive class. But unfortunately i can't get it.

See my code

$('#saveQuote').on('click', function(event) {

    var descriptionData1 = $('input[name=\"QuoteDetail[description][]\"]');
    QuoteDetailValidation(descriptionData1);

    var selectors = document.querySelectorAll('#quote-quoteItems-form .errorActive').length;

    alert(selectors);
    return false;
});

function QuoteDetailValidation(descriptionData1) {

    for (var i = 0; i < descriptionData1.length; i++) {

        var id = descriptionData[i].id;
        var value = descriptionData[i].value;
        var costid = costData[i].id;
        var costValue = costData[i].value;

        $.ajax({
            type: 'GET',
            url: "<?php echo Yii::app()->createUrl('QuoteData/validatedata'); ?>",
            data: 'descvalue=' + value + '&Descname=description&costValue=' + costValue + '&costName=cost&descId=' + id + '&costId=' + costid,
            success: function(data) {
                var obj = $.parseJSON(data);
                var cost = obj.cost;
                var desc = obj.desc;

                if (desc != '' || cost != '') {

                    if (cost != '') {

                        $('#' + costid).addClass('errorActive');
                        $('#' + costid).prev().addClass('error');
                        $('#' + costid).next().remove();
                        $('#' + costid).after(cost);
                        $('#' + costid).parent().removeClass('success');
                        $('#' + costid).parent().addClass('error');

                    }

                }
            },
            error: function(data) {
                alert('Your data has not been submitted..Please try again');
            }


        });
    }
}

Now What happens, When there is error QuoteDetailValidation() append errorActive class to fields.

By var selectors = document.querySelectorAll('#quote-quoteItems-form .errorActive').length; i try to get length of the fields which have errorActive class. but in alert of selectors, it always gives 0. But when i alert something before getting all errorActive Class then alert selectors give me perfect count. i think there is delay because of alert before getting class errorActive. so that it give me count. How to use it. Any help please. Thanks in advance.

Dhara
  • 1,431
  • 4
  • 29
  • 47

2 Answers2

4

You need to do this on your success callback of the QuoteDetailValidation method, because the $.ajax runs async and after invoking the method it still hasn't completed.

    $.ajax({
        type: 'GET',
        url: "<?php echo Yii::app()->createUrl('QuoteData/validatedata'); ?>",
        data: 'descvalue=' + value + '&Descname=description&costValue=' + costValue + '&costName=cost&descId=' + id + '&costId=' + costid,
        success: function(data) {
            var obj = $.parseJSON(data);
            var cost = obj.cost;
            var desc = obj.desc;

            if (desc != '' || cost != '') {
                if (cost != '') {
                    $('#' + costid).addClass('errorActive');
                    $('#' + costid).prev().addClass('error');
                    $('#' + costid).next().remove();
                    $('#' + costid).after(cost);
                    $('#' + costid).parent().removeClass('success');
                    $('#' + costid).parent().addClass('error');
                }
            }
            // Here you know that the elements will have the necessary classes.
            var selectors = $('#quote-quoteItems-form .errorActive').length;
            alert(selectors);
        },
        error: function(data) {
            alert('Your data has not been submitted..Please try again');
        }
    });
Konstantin Dinev
  • 34,219
  • 14
  • 75
  • 100
  • it gives perfect count but i want this count outside `$.ajax`. because if i get error count 0 then form submitted otherwise stop submission. that's why i use QuoteDetailValidation. – Dhara Jun 02 '15 at 13:39
  • @Jazz Call the form.submit() after you've validated the form and always prevent the default submission. Another way is to make the call sync. – Konstantin Dinev Jun 02 '15 at 13:40
  • Dinevi make the call sync. and it works perfect. thanks for your good suggestion. – Dhara Jun 02 '15 at 13:43
4

You can determine the exact delay required for selectors to be initailized properly. Whatever we add as delay will be assumption and can be short for some scen One options using below in your ajax request

async: false

like below:-

$.ajax({
            type: 'GET',
            async: false,
            url: "<?php echo Yii::app()->createUrl('QuoteData/validatedata'); ?>",
            data: 'descvalue=' + value + '&Descname=description&costValue=' + costValue + '&costName=cost&descId=' + id + '&costId=' + costid,
            success: function(data) {}});

Setting async to false means that the statement you are calling has to complete before the next statement in your function can be called. If you set async: true(it is default) then that statement will begin it's execution and the next statement will be called regardless of whether the async statement has completed yet. Helpful question

But I still will advise you to move selectors part in success of ajax like below:-

$.ajax({
            type: 'GET',
            url: "<?php echo Yii::app()->createUrl('QuoteData/validatedata'); ?>",
            data: 'descvalue=' + value + '&Descname=description&costValue=' + costValue + '&costName=cost&descId=' + id + '&costId=' + costid,
            success: function(data) {
                var obj = $.parseJSON(data);
                var cost = obj.cost;
                var desc = obj.desc;

                if (desc != '' || cost != '') {

                    if (cost != '') {

                        $('#' + costid).addClass('errorActive');
                        $('#' + costid).prev().addClass('error');
                        $('#' + costid).next().remove();
                        $('#' + costid).after(cost);
                        $('#' + costid).parent().removeClass('success');
                        $('#' + costid).parent().addClass('error');

                    }

                }
var selectors = document.querySelectorAll('#quote-quoteItems-form .errorActive').length;
alert(selectors);
//some logice here or move the above in some function and call it here

            },
            error: function(data) {
                alert('Your data has not been submitted..Please try again');
            }


        });

or use call back functions.

Update: try something like below It will keep async as true and keep the count logic outside $.ajax.

function QuoteDetailValidation(descriptionData1,submitFormOrAddError) {

    for (var i = 0; i < descriptionData1.length; i++) {

        var id = descriptionData[i].id;
        var value = descriptionData[i].value;
        var costid = costData[i].id;
        var costValue = costData[i].value;

        $.ajax({
            type: 'GET',
            url: "<?php echo Yii::app()->createUrl('QuoteData/validatedata'); ?>",
            data: 'descvalue=' + value + '&Descname=description&costValue=' + costValue + '&costName=cost&descId=' + id + '&costId=' + costid,
            success: function(data) {
                var obj = $.parseJSON(data);
                var cost = obj.cost;
                var desc = obj.desc;

                if (desc != '' || cost != '') {

                    if (cost != '') {

                        $('#' + costid).addClass('errorActive');
                        $('#' + costid).prev().addClass('error');
                        $('#' + costid).next().remove();
                        $('#' + costid).after(cost);
                        $('#' + costid).parent().removeClass('success');
                        $('#' + costid).parent().addClass('error');

                    }

                }
                submitFormOrAddError(data);
            },
            error: function(data) {
                alert('Your data has not been submitted..Please try again');
            }


        });
    }
}

Call it like this:

$('#saveQuote').on('click', function(event) {

    var descriptionData1 = $('input[name=\"QuoteDetail[description][]\"]');
    QuoteDetailValidation(descriptionData1);


    QuoteDetailValidation(descriptionData1,function(output){
            // here you use the output
            var selectors = document.querySelectorAll('#quote-quoteItems-form .errorActive').length; //This line is excuted only after call completes
            alert(selectors);
            //form submit here if error is zero.
        });

        alert("hii");//this  line is executed without waiting for above call..
        return false;
});
Community
  • 1
  • 1
Viraj Nalawade
  • 3,137
  • 3
  • 28
  • 44