Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery .hide() doesn't work in some browsers

We are using jQuery .hide() to hide options in select inputs - when there are less than 31 days in a month. It works fine with Google Chrome and FireFox, but it doesn't work in Internet Explorer, Opera and Safari. Here is the JavaScript code we are using:

$(function() {
    // Show and hide days according to the selected year and month.
    function show_and_hide_days(fp_form) {
        var select_year= $(fp_form).find("select.value_year");
        var select_month= $(fp_form).find("select.value_month");
        var select_day= $(fp_form).find("select.value_day");
        var selected_year= parseInt($(select_year).val());
        var selected_month= parseInt($(select_month).val());
        var selected_day= parseInt($(select_day).val());
        var days_in_month= new Date(selected_year, selected_month, 0).getDate();
        if ((days_in_month >= 28))
        {
            // If selected day is bigger than the number of days in the selected month, reduce it to the maximal day in this month.
            if (selected_day > days_in_month)
            {
                $(select_day).val(days_in_month);
            }
            // Show all the days in this month and hide days which are not in this month.
            $(select_day).find("option").each(function() {
                var day= parseInt($(this).val());
                if (day <= days_in_month)
                {
                    $(this).show();
                }
                else
                {
                    $(this).hide();
                }
            });
        }
    }

    // Show and hide all days in this page.
    function show_and_hide_all_days() {
        $("select.value_day").each(function() {
            var form= $(this).closest("form");
            // Show and hide days according to the selected year and month.
            show_and_hide_days(form);
        });
    }

    // Show and hide all days in this page.
    show_and_hide_all_days();

    $("select.value_year, select.value_month").live("change", function() {
        var form= $(this).closest("form");
        // Show and hide days according to the selected year and month.
        show_and_hide_days(form);
        return false;
    });
});

Here is the HTML code:

<select class="value_year">
    <option value="2000">2000</option>
    <option value="2001">2001</option>
    <option value="2002">2002</option>
    <option value="2003">2003</option>
    <option value="2004">2004</option>
    <option value="2005">2005</option>
    <option value="2006">2006</option>
    <option value="2007">2007</option>
    <option value="2008">2008</option>
    <option value="2009">2009</option>
    <option value="2010">2010</option>
    <option value="2011">2011</option>
    <option value="2012" selected="selected">2012</option>
    <option value="2013">2013</option>
</select>
/
<select class="value_month">
    <option value="1">01</option>
    <option value="2">02</option>
    <option value="3">03</option>
    <option value="4">04</option>
    <option value="5">05</option>
    <option value="6">06</option>
    <option value="7">07</option>
    <option value="8">08</option>
    <option value="9">09</option>
    <option value="10">10</option>
    <option value="11">11</option>
    <option value="12" selected="selected">12</option>
</select>
/
<select class="value_day">
    <option value="1">01</option>
    <option value="2">02</option>
    <option value="3">03</option>
    <option value="4">04</option>
    <option value="5">05</option>
    <option value="6">06</option>
    <option value="7">07</option>
    <option value="8">08</option>
    <option value="9">09</option>
    <option value="10">10</option>
    <option value="11">11</option>
    <option value="12">12</option>
    <option value="13">13</option>
    <option value="14">14</option>
    <option value="15">15</option>
    <option value="16">16</option>
    <option value="17">17</option>
    <option value="18" selected="selected">18</option>
    <option value="19">19</option>
    <option value="20">20</option>
    <option value="21">21</option>
    <option value="22">22</option>
    <option value="23">23</option>
    <option value="24">24</option>
    <option value="25">25</option>
    <option value="26">26</option>
    <option value="27">27</option>
    <option value="28">28</option>
    <option value="29">29</option>
    <option value="30">30</option>
    <option value="31">31</option>
</select>

We are using jQuery v1.8.3 (I upgraded to this version to test if it fixes the problem, but it doesn't).

Thanks, Uri.

like image 747
Uri Avatar asked Dec 18 '12 10:12

Uri


People also ask

What does hide () do in jQuery?

jQuery hide() Method The hide() method hides the selected elements. Tip: This is similar to the CSS property display:none. Note: Hidden elements will not be displayed at all (no longer affects the layout of the page). Tip: To show hidden elements, look at the show() method.

How do you do show hide in jQuery?

Syntax: $(selector).hide(speed,callback); $(selector).show(speed,callback); The optional speed parameter specifies the speed of the hiding/showing, and can take the following values: "slow", "fast", or milliseconds.

What is the opposite of hide in jQuery?

version added: 1.0jQuery( ":visible" ) Elements that are not in a document are considered hidden; jQuery does not have a way to know if they will be visible when appended to a document since it depends on the applicable styles. This selector is the opposite of the :hidden selector.

Can we use a jQuery method to hide an HTML element?

By using show( ) and hide( ) methods you can show and hide HTML elements in jQuery.


2 Answers

it's a browser issue you can't hide options in some browser because $('.selector').hide(); is similar to $('.selector').css('display', 'none'); some browser can't hide it

you need to use $('.selector').remove(); and $('.selector').append();

change the codes from

 if ((days_in_month >= 28))
        {
            // If selected day is bigger than the number of days in the selected month, reduce it to the maximal day in this month.
            if (selected_day > days_in_month)
            {
                $(select_day).val(days_in_month);
            }
            // Show all the days in this month and hide days which are not in this month.
            $(select_day).find("option").each(function() {
                var day= parseInt($(this).val());
                if (day <= days_in_month)
                {
                    $(this).show();
                }
                else
                {
                    $(this).hide();
                }
            });
        }

to

// Remove days 29 - 31
$(select_day).find("option[value='29'], option[value='30'], option[value='31']").remove();
var daysOptions = "";

if (days_in_month >= 29) {
    daysOptions += '<option value="29">29</option>';
}
if (days_in_month >= 30) {
    daysOptions += '<option value="30">30</option>';
}
if (days_in_month == 31) {
    daysOptions += '<option value="31">31</option>';
}

$(select_day).append(daysOptions);

http://jsfiddle.net/sL4jY/10/ tested in IE chrome and Firefox

like image 187
Nerdroid Avatar answered Oct 19 '22 23:10

Nerdroid


Thank you for your answer, I used your code but I changed it a little bit to handle months with 28 and 29 days (February). Here is the function again:

// Show and hide days according to the selected year and month.
function show_and_hide_days(fp_form) {
    var select_year= $(fp_form).find("select.value_year");
    var select_month= $(fp_form).find("select.value_month");
    var select_day= $(fp_form).find("select.value_day");
    var selected_year= $.parse_int($(select_year).val());
    var selected_month= $.parse_int($(select_month).val());
    var selected_day= $.parse_int($(select_day).val());
    var days_in_month= new Date(selected_year, selected_month, 0).getDate();
    // If the number of days in the selected month is less than 28, change it to 31.
    if (!(days_in_month >= 28))
    {
        days_in_month= 31;
    }
    // If the selected day is bigger than the number of days in the selected month, reduce it to the last day in this month.
    if (selected_day > days_in_month)
    {
        selected_day= days_in_month;
    }
    // Remove days 29 to 31, then append days 29 to days_in_month.
    for (var day= 31; day >= 29; day--)
    {
        $(select_day).find("option[value='" + day + "']").remove();
    }
    for (var day= 29; day <= days_in_month; day++)
    {
        $(select_day).append("<option value=\"" + day + "\">" + day + "</option>");
    }
    // Restore the selected day.
    $(select_day).val(selected_day);
}

It now works with all the five browsers I tested (I didn't test with previous versions of Internet Explorer).

I added a plugin to jQuery called $.parse_int - this returns parseInt with radix 10 if not specified. Here is the code of the plugin:

// Add functions to the jQuery object.
(function( $ ) {
    // Return parseInt with radix 10 if not specified.
    $.parse_int= function(fp_string, fp_radix) {
        var radix= ((typeof(fp_radix) !== "undefined") ? fp_radix : 10);
        return parseInt(fp_string, radix);
    };
})( jQuery );

Uri.

like image 40
Uri Avatar answered Oct 20 '22 00:10

Uri