views:

62

answers:

3

I have a problem with my form querystring being too long.

I plan on solving this problem by simply disabling all un-used form elements before submit. But I need help on making this js function...

You need to know that I have a js-function which shows sub-categories whenever a main-category is chosen. This happens "onChange" on a drop-list. So "onChange" of the category drop-list, the correct DIV is made visible by using javascript, and therefore making subcategories visible for the user to specify (users may chose color, make, year etc etc in subcategories).

For instance, if you chose "Cars" from the main category drop list, the js function will make the DIV which contains all "Cars" options visible (color, make, year etc). Then if you chose another category, say "Trucks", "Cars" is made invisible, and the "Trucks" DIV is made visible. Simple.

However, my problem is that even if the DIVs are not visible at the moment, the form elements inside them gets submitted anyways. This is completely unneccessary. So, I need a javascript function which could be integrated into the already existing function which hides/shows the sub-category DIVs, which would disable all elements inside unused DIVs.

Here is the function which shows/hides sub-category DIVs, and is triggered onChange of the main category drop-list:

var category=document.nav_form_main.nav_category_list.value;
(category=="Cars")?byId("nav_sub_cars").style.display='block' :  byId("nav_sub_cars").style.display='none';
(category=="Trucks")?byId("nav_sub_trucks").style.display='block' :  byId("nav_sub_trucks").style.display='none';

I would like something like this:

(category=="Cars")?byId("nav_sub_cars").style.display='block' :  disableDiv("nav_sub_cars");

function disableDiv(divId){
    Disable all form elements inside divId 
    AND 
    make divId invisible.
}

NOTE: The divs contain only form elements, and tables. In other words, I don't care if all elements inside the div are disabled. By form elements, I mean: Text inputs, Select lists, Checkboxes and Radios.

I don't know much js at all, so any help in making this function which shouldn't be too hard is appreciated...

Thanks

+2  A: 

This code should do the trick. I've tested it in IE6 and FF3.6. The loopThroughItems function isn't essential I just didn't want to repeat the loop. You should also take a look at using jQuery if it's a viable option - you'd have improved cross browser compatibility and it would only be a few lines of code.

function loopThroughItems(items, func){
    var i;
    for(i = 0; i <= items.length; i++){
        func(items[i]);
    }
}

// Change test to ID of your div.
var div = document.getElementById("test");

loopThroughItems(div.getElementsByTagName("input"), function(input){
    if (!input || input.type.toLowerCase() == "submit") return;
    input.disabled = true;
});

loopThroughItems(div.getElementsByTagName("select"), function(select){
    if (!select) return;
    select.disabled = true;
});

    // Hide div.
div.style.display = "none";

With jQuery the syntax would roughly be something like this. I haven't tested this and you'd have to changed the selector so it excluded the submit input. Either way your code will be more compact, concise and would have improved cross browser compatibility.

$("#divId").find("input, select").attr("disabled", "disabled");
$("#divId").hide();
Castrohenge
I will look into this. +1 for taking the time and giving me a direct answer :)
Camran
@Kiearanmaine: Could you explain the "func(items[i])" part above in the loopThroughItems function please?
Camran
The func parameter is assumed to be a function. By putting brackets after the func parameter - func(items[i]) - I'm executing the function that has been passed into loopThroughItems and passing an item from the array, to that function. Here's a link to explain functions as parameters in a bit more detail http://www.cristiandarie.ro/asp-ajax/Delegate.html. Hope that clarifies things.
Castrohenge
A: 

How about moving that div to another element outside of the form:

HTML:

<form> 
   <div id="div1">
      ...some input, select button etc here....
   </div>
</form>

<div id="temp-div1" style="display:none;">

</div>

JS function:

function disableDiv(divId){
    var src = byId(divId);
    var dst = byId('temp-' + divId);

    var htm = src.innerHTML; //assigned it first to temp to avoid duplicate elements on dom
    src.innerHTML = '';
    dst.innerHTML = htm;    
}

function enableDiv(divId){
    var dst= byId(divId);
    var src= byId('temp-' + divId);

    var htm = src.innerHTML; //assigned it first to temp to avoid duplicate elements on dom
    src.innerHTML = '';
    dst.innerHTML = htm;    
}

Quite nasty but this will do the trick.

jerjer
+1  A: 

I think the best solution will be to create static results pages for each search. Use POST for the initial form submission, process it on the server-side, store the results somehow in the database, then redirect the user to a page displaying the results.

You see this often on forum software, you get redirected to a page like search.php?id=123.


One other solution that may be simpler is to generate all the options with Javascript when you choose Cars or Trucks, then completely remove the other fields that you do not wish to submit. (See here for a tutorial on adding and removing elements with Javascript)

DisgruntledGoat
I have thought about your second solution, but decided to go with disabling and enabling inputs instead. Seems less work for me. In the future, I will go with filling out a div based on category chosen instead of having alot of divs already filled out...
Camran