Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 12 of 12

Thread: Pop-up question

  1. #1
    New to the CF scene
    Join Date
    Dec 2016
    Posts
    5
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Pop-up question

    I have a button on a form with an onclick function:

    Code:
    function sanityCheck() { 
       var checked = false, radios = document.getElementsById('action');
          for (var i = 0, radio; radio = radios[i]; i++) { 
             if (radio.checked) {        
                if (confirm("Are you sure you want continue?") == true) {
                          // Do something
    	    }
    	    break;
            } else {
    	   alert("Pleast select a row");
    	}
       }					
    }
    The idea is that if a radio selector on the form is not selected, I don't want to continue with the form action.

    This code does not work.

    Any ideas

  2. #2
    Supreme Master coder! Philip M's Avatar
    Join Date
    Jun 2002
    Location
    London, England
    Posts
    19,377
    Thanks
    217
    Thanked 2,696 Times in 2,672 Posts
    document.getElementsById

    All the code given in this post has been tested and is intended to address the question asked.
    Unless stated otherwise it is not just a demonstration.

  3. #3
    Senior Coder deathshadow's Avatar
    Join Date
    Feb 2016
    Location
    Keene, NH
    Posts
    1,963
    Thanks
    2
    Thanked 288 Times in 278 Posts
    Quote Originally Posted by Philip M View Post
    document.getElementsById
    To clarify, what he's saying is there's no such thing. Id's are unique, they can only exist ONCE on a page. As such there is no such thing as getElementSbyId.

    ... and if you are using the same ID more than once on your form, your HTML is invalid gibberish.

    You should also be trapping 'submit' on the form, not 'click' on the submit... and without seeing the HTML this is applied to, we really can't tell you much of anything useful apart from the fact that your little function doesn't do anything to PREVENT the form from submitting...
    Last edited by deathshadow; 01-07-2017 at 05:09 PM.
    I would rather have questions that can't be answered, than answers that can't be questioned.
    http://www.cutcodedown.com

  4. #4
    New to the CF scene
    Join Date
    Dec 2016
    Posts
    5
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by deathshadow View Post
    To clarify, what he's saying is there's no such thing. Id's are unique, they can only exist ONCE on a page. As such there is no such thing as getElementSbyId.
    Interesting, because the code I finally arrived at ONLY works with getElementSbyId (see below)...

    Quote Originally Posted by deathshadow View Post
    ... and if you are using the same ID more than once on your form, your HTML is invalid gibberish.
    If I have a radio group, and an indeterminate number of buttons, then using a common ID and name is the only way it will work with getElementSbyId (which you say doesn't exist.)

    Code:
    function Validate() {
        var radios = document.getElementsByName('action');
        var radiocount = false;
        for (var i = 0; i < radios.length; i++) {
            if (radios[i].checked) {
                radiocount = true;
            } 				
        };
        if (radiocount == false) {
            // not checked, show error
            alert("Select a Lowlevel!");
            return false;
        } else {
            if (confirm("Are you sure you want\nto modify this Lowlevel?") == true) {
            // Do something
            } else {
                return false;
            }
        }
    }
    Works exactly as designed: Depending on a database pull, there is a variable number of rows, each with a radio button. Out of that group, one must be selected for the form to process. In addition to checking the radios using the non-existent getElementSbyId, I do a "sanity check" before the actual action, which is to delete a row.

    Here's the radio button code:

    Code:
    <input id='action' type='radio' name='action' value='32'>
    And here is the form button code:

    Code:
    <button name="deleteLL" value="deleteLL" onclick="return Validate()">Delete Lowlevel</button>
    And thank you, my HTML is not "invalid gibberish".

  5. #5
    New to the CF scene
    Join Date
    Dec 2016
    Posts
    5
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Doing some research, perhaps getElementsByName didn't used to be a function. But apparently it is now:

    getElementsById() - Development Cookbook

    And many others...

    Perhaps I could have also done something with getElementsByTagName.

    But if I'm using getElementsByName, and it functions the way I expect (and it does), then obviously it IS a valid function.

    I've tested this code in IE, FF, and Opera (though no one uses Opera anymore except anal geek nerds occasionally...

  6. #6
    Supreme Master coder! Philip M's Avatar
    Join Date
    Jun 2002
    Location
    London, England
    Posts
    19,377
    Thanks
    217
    Thanked 2,696 Times in 2,672 Posts
    The code you posted contained the invalid getElementsbyId()

    getElementsByName() is indeed valid. The getElementsByName() method returns a collection of all elements in the document with the specified name (the value of the name attribute), as a NodeList object.

    All the code given in this post has been tested and is intended to address the question asked.
    Unless stated otherwise it is not just a demonstration.

  7. #7
    New to the CF scene
    Join Date
    Dec 2016
    Posts
    5
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Philip M View Post
    The code you posted contained the invalid getElementsbyId()
    So you say, yet it functions the way one would suppose in the three major browsers (I've tested the code). Why would that be?

    Seriously: The function works. And it's not "valid"?

  8. #8
    Senior Coder jmrker's Avatar
    Join Date
    Aug 2006
    Location
    TX
    Posts
    3,596
    Thanks
    56
    Thanked 557 Times in 551 Posts

    Question

    Point of interest:
    Here's the radio button code:

    Code:
    <input id='action' type='radio' name='action' value='32'>
    Why are you using a radio button when there is only one choice available?
    Since it is not checked to begin with, then you can only press it once.
    Note, if the user changes there mind, the button can NOT be reset
    without reloading the entire page.

    You would be better off using a checkbox button that allows the yes/no response
    and allows the user to alter the value with much less logic checks.

  9. #9
    Senior Coder deathshadow's Avatar
    Join Date
    Feb 2016
    Location
    Keene, NH
    Posts
    1,963
    Thanks
    2
    Thanked 288 Times in 278 Posts
    Quote Originally Posted by ArtyZiff View Post
    So you say, yet it functions the way one would suppose in the three major browsers (I've tested the code). Why would that be?
    Are you running some sort of library or framework that's adding it? Is this a XML document parsing as XML and not a DOMDocument parsing as HTML?

    Because there is NO SUCH THING in any browser by default. PERIOD. For example if I were to run this:

    Code:
    <!DOCTYPE html><html><head>
    <title>getElementsById?!?</title>
    </head><body>
    <div id="test"></div>
    <script>
    alert(document.getElementsById('test'));
    </script>
    </body></html>
    It won't alert. Instead an error is logged in the console and script execution is halted.

    In Firefox 50.1.0:

    TypeError: document.getElementsById is not a function[Learn More] getElementsByIdWTF.html:6:13
    In Chrome 55.0.2883.87 m:

    Uncaught TypeError: document.getElementsById is not a function
    at getElementsByIdWTF.html:6
    In IE 11:

    SCRIPT438: Object doesn't support property or method 'getElementsById'
    File: getElementsByIdWTF.html, Line: 6, Column: 1
    In Opera 12.18 (the last Opera worth using, just to be anal)

    Uncaught exception: TypeError: 'document.getElementsById' is not a function
    Error thrown at line 6, column 0 in file://localhost/C:/xampp/htdocs/for_others/getElementsByIdWTF.html:
    alert(document.getElementsById('test'));
    It does not exist!!! Full stop, end of story. Check your error logs. The function does not even exist unless you're running something that adds it... though I suspect your not looking in the browser console for errors might have led you astray.

    With radio buttons they should all share the same NAME, they should ALL get UNIQUE ID's.

    What you are describing should not work -- it doesn't even make sense! That's why if you ran it past HTML validation it would spit out an error for every instance of the same ID past the first one!

    hence this:
    Code:
    <input id="action" type="radio" name="action" value="32">
    <input id="action" type="radio" name="action" value="64">
    <input id="action" type="radio" name="action" value="128">
    Is invalid gibberish markup. Do not pass go, do not collect a hundred dollars. You might not want to hear that, but that's the rules.

    https://www.w3.org/TR/2011/WD-html5-...e-id-attribute

    ... and I quote:
    The id attribute specifies its element's unique identifier (ID). The value must be unique amongst all the IDs in the element's home subtree
    Once, unique. That's it. "home subtree" in most cases meaning the live DOM the browser is displaying -- aka counting EVERY tag on the page or element added by scripting, you can only use the same ID ONCE!

    that's why if you ran a page that did something like that past this:
    https://validator.w3.org/

    It's gonna toss a wobbly about that!

    Hence this:

    Code:
    <input id="action1" type="radio" name="action" value="32">
    <input id="action2" type="radio" name="action" value="64">
    <input id="action3" type="radio" name="action" value="128">
    WOULD be valid markup. Same NAME, unique ID. If talking classic HTML+JS, aka "the safe way" of thinking about it, name should really only be used for what's sent server side, with ID being for on-page access. getElementsByName is also dangerous because in IE it will return both names and ID's, and that can get you in deep trouble which is why... well, keep reading.

    You should have LABELS with FOR attributes on there, with the FOR attribute pointing at the ID the label is... for?

    Code:
    <input id="action1" type="radio" name="action" value="32">
    <label for="action1">2^5</label>
    <br>
    <input id="action2" type="radio" name="action" value="64">
    <label for="action2">2^6</label>
    <br>
    <input id="action3" type="radio" name="action" value="128">
    <label for="action3">2^7</label>
    <br>
    Which is why you'd have ID's on them. If your labels (which you SHOULD have if you have a input the user can interact with) were to be wrapping those elements, you could lose the ID and the for attribute altogether.

    Code:
    <label>
    	<input type="radio" name="action" value="32">
    	2^5
    </label>
    <br>
    <label>
    	<input type="radio" name="action" value="64">
    	2^6
    </label>
    <br>
    <label>
    	<input type="radio" name="action" value="128">
    	2^7
    </label>
    <br>
    In any of those cases, I probably would not use the getElementsByName as it's "too new" for real world deployment and as I said above grabs both names and ID's which is often and undesired behavior (particularly since IE and Opera classic do this, but FF and chrome do not!). if these are related <input type="radio"> then they should be in a fieldset, that's what fieldsets are for (it's not for drawing a double line around it, that's just the default appearance!). As such I'd put an ID on that fieldset, then use getElementsByTagName('input') off that fieldset to get them -- instant backwards compatibility for little if any extra effort.

    Code:
    <fieldset id="exponents">
    	<legend>Choose your power of two</legend>
    	<label>
    		<input type="radio" name="action" value="32">
    		2^5
    	</label>
    	<br>
    	<label>
    		<input type="radio" name="action" value="64">
    		2^6
    	</label>
    	<br>
    	<label>
    		<input type="radio" name="action" value="128">
    		2^7
    	</label>
    </fieldset>
    Code:
    var actions = document.getElementById('exponents').getElementsByTagName('input');
    Which will work flawless all the way back to IE 5.x with no headaches. The above line of scripting to grab them would also work with the id+label for="" method.

    Bottom line on ID's, if you use the same ID more than once on a page, you don't know what ID's are or are for, and your HTML is invalid nonsense. I don't know what that "cookbook" site is, but it seems to be filled with nonsenscial gibberish that has NOTHING to do with the specifications. Might I suggest you try the MDN reference instead?

    Now that aside, your methodology is broken because

    1) your using the outmoded onevent attribute of onclick.
    2) you're trapping onclick on a button tag instead of onsubmit on the form, which means you could miss trapping the event properly.

    In modern scripting you should be using addEventListener to hook the form (with polyfill for attachEvent if you care about IE8/earlier) and hooking 'submit' on the form, not click on the button! The reason for this is that anything you can get out of the markup into an external file where it can be cached -- like JavaScript, you get it the blue blazes out of the markup! Has no business there.

    Let's say your form tag (your COMPLETE markup instead of some snippets might help) was something like:

    Code:
    <form action="something.php" method="post" id="doSomething">
    The scripting would be something along the lines of:

    Code:
    function doSomethingValidate(e) {
    	// window.event is for legacy IE
    	e = e || window.event;
    	var actions = document.getElementById('exponents').getElementsByTagName('input');
    	for (var i = 0, iLen = actions.length; i < iLen; i++) {
    		if (actions[i].checked) return;
    	}
    	// no match, so cancel the event
    	// again, returnValue is for legacy IE
    	e.preventDefault ? e.preventDefault() : (e.returnValue = false);
    }
    
    function eventAdd(e, event, callback) {
    	if (e.addEventListener) e.addEventListener(event, callback, false);
    	else e.attachEvent('on' + event, callback);
    }
    
    eventAdd(
    	document.getElementByid('doSomething'),
    	'submit',
    	doSomethingValidate
    );
    In theory a more robust version might try and use "e.target || window.srcElement" to try and target the form generically, perhaps pulling a data attribute off the form to know which fieldsets to check for what.

    But if you insist on 1990's style...

    Code:
    <form action="something.php" method="post" onsubmit="return doSomethingValidate();">
    Code:
    function doSomethingValidate(e) {
    	var actions = document.getElementById('exponents').getElementsByTagName('input');
    	for (var i = 0, iLen = actions.length; i < iLen; i++) {
    		if (actions[i].checked) return true;
    	}
    	return false;
    }
    Just beware that if any other scripting tries to hook it, it could override this. That's why addEventListener is now the preferred method, even if it does get a bit more technical to implement. That extra code is usually easily offset by caching models if again, you get it out of the HTML file and into a proper external .js where it belongs.

    Just remember the more separate external files you load, the slower the page, so combine those when possible!

    Naturally where the event cancel or false return is, you'd add your alert telling them things went awry -- your confirm would naturally go before the check. For both of those, let drop-through to false do your heavy lifting so you don't have to say the same cancel more than once.

    ... and of course, double-check it server side since you cannot guarantee that client-side scripting isn't bypassed, blocked, negated, told to sod off, or otherwise unavailable/nonfunctional. I shouldn't have to tell you that, but it's a good idea to mention it. NEVER trust client side scripting for checking values.

    Honestly, that's why I don't even bother with scripting for these types of checks anymore. If my markup is so huge that one request sent server side to check it and spitting a populated form back at the user on error (something that should be in place ANYWAYS for scripting off graceful degradation) is going to be some huge resource drain, there's something horrifyingly and terrifyingly WRONG with the code.

    Hope that helps... I think a bad learning source has led you greatly astray. Could we see your FULL form or a reasonable facsimile of it? If you've got misuse of ID this way, it's likely you've got other semantic errors that could alienate or exclude users thanks to accessibility woes, or just dig you a deeper hole on implementing things. Might be nice for you to get a handle on that before it buries you.
    Last edited by deathshadow; 01-08-2017 at 01:55 AM.
    I would rather have questions that can't be answered, than answers that can't be questioned.
    http://www.cutcodedown.com

  10. #10
    Regular Coder
    Join Date
    Sep 2010
    Location
    U S of A
    Posts
    210
    Thanks
    4
    Thanked 39 Times in 39 Posts
    Quote Originally Posted by deathshadow View Post
    Are you running some sort of library or framework that's adding it?
    Quote Originally Posted by ArtyZiff View Post
    Doing some research, perhaps getElementsByName didn't used to be a function. But apparently it is now:

    getElementsById() - Development Cookbook

    And many others...
    Code:
    /* getElementsById
        Retrieves all DOM objects with a similar id to the specified id.
        @environment ALL
        @param container - The container to search within. To search whole document, use null as value.
        @param tagName - The tag name to search within. To search all tags, use '*' as value.
        @param id - The specified id.
        @return An array of DOM objects.
    */
    function getElementsById( container, tagName, id ) {
        var returnElements = new Array();
    
        // Interpret Parameters to Establish Elements Array
        if( container == null ) { container = document; }
        else { container = document.getElementById( container ); }
        var elements = (tagName == "*" && container.all) ? container.all : container.getElementsByTagName( tagName );
        id = id.replace( /-/g, "\-" );
    
        var regExp = new RegExp( "(^|\s)" + id + "(\s|$)" );
    
        for( var i = 0; i < elements.length; i++ ) {
            var element = elements[i];
            if( element.id.indexOf( id ) != -1 ) {
                returnElements.push( element );
            }
        }
    
        return returnElements;
    } // getElementsById

  11. #11
    Master Coder Dormilich's Avatar
    Join Date
    Jan 2010
    Location
    Behind the Wall
    Posts
    5,323
    Thanks
    21
    Thanked 550 Times in 544 Posts
    getElementsById() != document.getElementsById().

    ... a function to solve a problem that shouldn't exist to begin with.
    The computer is always right. The computer is always right. The computer is always right. Take it from someone who has programmed for over ten years: not once has the computational mechanism of the machine malfunctioned.
    André Behrens, NY Times Software Developer

  12. #12
    Supreme Master coder! Philip M's Avatar
    Join Date
    Jun 2002
    Location
    London, England
    Posts
    19,377
    Thanks
    217
    Thanked 2,696 Times in 2,672 Posts
    Quote Originally Posted by deathshadow View Post
    Bottom line on ID's, if you use the same ID more than once on a page, you don't know what ID's are or are for, and your HTML is invalid nonsense. I don't know what that "cookbook" site is, but it seems to be filled with nonsenscial gibberish that has NOTHING to do with the specifications. Might I suggest you try the MDN reference instead?
    Redoubled in spades. It is silly to assign the name getElementsById() to a user-defined function when there is so much opportunity (as here) for misunderstanding and confusion.
    Last edited by Philip M; 01-09-2017 at 09:36 AM.

    All the code given in this post has been tested and is intended to address the question asked.
    Unless stated otherwise it is not just a demonstration.


 

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •