0

I have a method that is supposed to loop over all of the controls on my page and return false if any one of them has a value other than empty string / null. This gets called as part of an OnSaveValidation. If the form is empty, they should be able to save.

function IsFormEmpty()
{
    var ancestor = document.getElementById('PAIQIFunc'); //PAIQIFunc is the id of a div
    var descendents = ancestor.getElementsByTagName('*');

    var i = 0;
    for (i = 0; i < descendents.length; ++i)
    {
        var e = descendents[i];

        try
        {
            var eVal = $("#" + e).val();

            // just check to make sure eVal has *some* value
            if (eVal != '' || eVal != undefined || eVal != null)
                return false;
        }
        catch (err){
            //simply move on to next control...   
        }
    }

    return true;
}

In most cases, var eVal = $("#" + e).val(); throws an exception because it's a div or something like that. I'm only interested in the 108 drop down menus and 1 textbox on my form.

I set a breakpoint on my if statement and it was never hit. But descendents has like 1200 elements in it; I couldn't possibly step through it all trying to find what I'm looking for...

How else could I modify the code to check each control on the page?

EDIT: I should note that the web application is a C# / ASP.NET project using Razor views and we're using Telerik's Kendo web UI controls, not "vanilla" .NET controls if that makes a difference. So all of the controls are defined in the .cshtml file like so:

@(Html.Kendo().DropDownListFor(m => m.SomeProperty).HtmlAttributes(new { id = "cmbSomeProperty", @class = "k-dropdown-width-30", @tabIndex = "1", style = "width:60px" }).BindTo(ViewBag.SomePropertyDataSource).OptionLabel(" "))
Community
  • 1
  • 1
sab669
  • 3,984
  • 8
  • 38
  • 75
  • 1
    You're using query already, so why not simply use it to select all the form elements (and only those) to begin with? `$('#PAIQualityIndicatorFunctionalV14 input, #PAIQualityIndicatorFunctionalV14 select, #PAIQualityIndicatorFunctionalV14 whateverelseyoumighthave')` – CBroe Jun 09 '16 at 18:46
  • @CBroe Sorry, I'm not sure what you mean. I'm still quite new to jquery / js in general. I don't know what you're trying to show in your code snippet. – sab669 Jun 09 '16 at 18:52
  • @sab669 - because you don't understand an answer does not make it not the correct answer. Why not go read up on jQuery and understand it. SO is not for spoon feeding API tutorials. You comment/question makes this **off-topic:too broad** because now the question is *"I don't know jquery and I want you to explain fundamental basic stuff to me because I am too lazy to read the instructions**. –  Jun 09 '16 at 18:57
  • 1
    @JarrodRoberson I never said it *wasn't* the correct answer, I'm simply asking for an elaboration. You are correct; SO is not a place for "spoon fed answers", but a good answer *should* also explain what the code is doing. I already looked around on how to find all child controls within an element, his post doesn't give me anything to search for to try and understand it on my own. – sab669 Jun 09 '16 at 19:00
  • I think the first comment by @CBroe is suggesting to let jquery do the heavy lifting. you could do something like var formControls = $('#PAIQualityIndicatorFunctionalV14 input, '#PAIQualityIndicatorFunctionalV14 select); and then just loop through the formControls to check the value of each. – terpinmd Jun 09 '16 at 19:05

1 Answers1

2

You could try the following:

var hasValue = false;
var div = document.getElementById('PAIQIFunc');

$(div).find('input')
    .each(function() { // iterates over all input fields found
        if($.trim($(this).val()).length != 0) {
            hasValue = true; // if field found with content
            break;
        }
    });

if(hasValue === false) {
    // save logic here
}

Hope this helps.

Sandman
  • 2,247
  • 1
  • 13
  • 26
  • Nice job. Why not use `$("#PAIQIFunc")` directly, instead of `getElementById` and then `$(div)`? – Hanlet Escaño Jun 09 '16 at 19:11
  • Thanks! No particular reason, I have just got myself into the habit of caching DOM elements to optimise performance, which isn't particularly a bad thing I guess. – Sandman Jun 09 '16 at 19:25
  • Thanks! Between figuring out what CBroe meant in his comment and this I was able to figure it out. Had to add a second segment for `find('select')` but otherwise this worked perfectly! – sab669 Jun 09 '16 at 19:31
  • 1
    _"Had to add a second segment for `find('select')`"_ - you can use any valid CSS selector in find, so you can simply do `.find('input, select')` – CBroe Jun 09 '16 at 19:42