views:

389

answers:

4

Hi all,

Is there a simple way to iterate over the child elements in an element, say a div, and if they are any sort of input (radio, select, text, hidden...) clear their value?

TIA for any helpful links or advice.

David

Edit to add link to example solution code. Many thanks to Guffa and the other respondents! I learned from this! Peace.

+1  A: 

Karim's answer works well. Using jQuery, I believe it'll go something like this:

$(#myDiv").each(function(){
   if($(this).type == "input")
      $(this).val('');
});

Actually, come to think of it, you may also try:

$(#myDiv input").val('');
Traveling Tech Guy
I have some Scriptaculous effects alreay in this page. Would it create conflicts to also load in jQuery?
jerrygarciuh
you can use the following to avoid clashes: add jQuery.noConflict();to the top of your page, and substitute every '$' with the word jQuery when calling a jQuery function. More here: http://docs.jquery.com/Using_jQuery_with_Other_Libraries
Traveling Tech Guy
Thanks TTG! I will look into this now!1
jerrygarciuh
+3  A: 

I suppose that you want to clear all children, not only the direct children, so it would have to be recursive. As different input elements is cleared differently, you have to check their type so that you know what to do with them. I suppose that you want to clear textareas also, but leave buttons unchanged:

function clearChildren(element) {
   for (var i = 0; i < element.childNodes.length; i++) {
      var e = element.childNodes[i];
      if (e.tagName) switch (e.tagName.toLowerCase()) {
         case 'input':
            switch (e.type) {
               case "radio":
               case "checkbox": e.checked = false; break;
               case "button":
               case "submit":
               case "image": break;
               default: e.value = ''; break;
            }
            break;
         case 'select': e.selectedIndex = 0; break;
         case 'textarea': e.innerHTML = ''; break;
         default: clearChildren(e);
      }
   }
}

Call it with a reference to the element:

clearChildren(document.getElementById('IdOfTheDiv'));

Edit:
Forgot the select...

Edit 2:
Some corrections: childNodes.length, handling elements without tagName and uppercase tagName values.

Guffa
+1, I like this too
karim79
Good assumption about needing it to work on children's children, however you don't need recursion to grab descendant nodes.
Crescent Fresh
Thank you for the reply!! I am trying to implement this and have a strange symptom. There is no visible effect on a simple test form. If I get alert to print element I get [object HTMLDivElement] (good..) If I get alert() to print element.childNodes it has [object nodeLIst] (good again) but if I get alert() to echo the value of i inside the for() it never fires so it seems like it does not iterate over the nodes? Code like: function clearChildren(element) { for (var i = 0; i < element.childNodes; i++) { var e = element.childNodes[i]; alert('i:'+i);
jerrygarciuh
Changed for (var i = 0; i < element.childNodes; i++) to for (var i = 0; i < element.childNodes.length; i++) and got iteration working. Still not clearing values but working to see why now
jerrygarciuh
ah, it needed to be case 'INPUT': not case 'input':w00t!1 Working now, thanks!!!
jerrygarciuh
@crescentfresh: Yes, you don't *need* recursion. Actually you never do, there is always a different way to solve it, but it works well with nested elements. :)
Guffa
@jerrygarciuh: I made some corrections above, including handling elements that doesn't have a tagName at all (i.e. textnodes).
Guffa
+2  A: 

Oh boy, this would be a one liner with jQuery:

$(':input:not(:button)', div).val([])

Without jQuery you've got to account for <select> fields, text fields, password fields and radio/checkbox fields:

function clearFields(container) {
    var selects = container.getElementsByTagName('select');

    for(var i=0, len=selects.length; i < len; i++) {
        selects[i].selectedIndex = -1;
    }

    var fields = container.getElementsByTagName('input');
    for(var i=0, len=fields.length; i < len; i++) {
        var field = fields[i];
        switch(field.type)
        {
            case 'radio':
            case 'checkbox':
                field.checked = false;
                break;

            case 'text':
            case 'password':
            case 'hidden':
                field.value = ''
        }
    }

    var fields = container.getElementsByTagName('textarea');
    for(var i=0, len=fields.length; i < len; i++) {
        fields[i].value = ''
    }
}
Crescent Fresh
+1, I like this
karim79
The jQuery solution doesn't handle checkboxes or radio buttons, and it clears the text of buttons...
Guffa
@Guffa: jQuery solution works properly now ;)
Crescent Fresh
A: 

Very simple with JQuery:

$('#myDiv').children().find('input,select').each(function(){

$(this).val('');

});

you can put as many tags in the "find" call.

haresh
Thanks Haresh! What an excellent addition to this thread!
jerrygarciuh