skip to Main Content

I am doing dynamic dropdown menu but I have problem to keep it after page refreshing.

I use maybe old way and if user choose some option in first select, I am sending ajax request to php page and show options on current page in second select.

I store all values of fields via localstorage, but problem is that selects (inputs) added dynamically by ajax are not visible on load of page.

So I decide to send my data to php page directly in request sent after refreshing.

My code is something like this:

    $(window).on('load', function() {
        // Send cat id to add.php to change select options in html according to cat id
        $.ajax({
            url: 'add.php',
            headers: {"X-Test-Header": "test-value"}
        });
    })

I am attaching image flow.
enter image description here

So my problem is that if I refresh page and do not send SUBCAT_ID then Filters section is not created in ADD.PHP.

I want to know way how to send SUBCAT_ID in request sent by page refreshing action.

This is my code for dropdown menu:


    /* SELECT REPLACED BY DIV JS */

    var select = $('.add-item__select').hide(); // Hide original select options

    // Replace each select by div
    select.each(function() {
        var selectVal = $(this).find('.add-item__select-main').text(),
            name = $(this).attr('name');

        newDropdownDiv = $('<input class="add-item__input-select" name="' + name + '" placeholder="' + selectVal + '" readonly required><i class="arrow down"></i></input>')
            .insertAfter($(this))
            .css({paddingLeft: '0.3em', cursor: 'pointer'});
    });

    /* SELECT CATEGORIES AND FILTER CONNECTIONS*/

    // Declare variables
    var inputSelectCat = $("input[name=category]"),
        inputSelectSubCat = $("input[name=subcategory]"),
        section = $('.section'),
        arrowDown = inputSelectSubCat.next(),
        catNameOld;

    if (inputSelectSubCat.val() === '') {
        inputSelectSubCat
            .addClass('stop') // Defaultly setup subcategory input as disable until category is not chosen
            .next().hide(); // Defaultly hide arrowdown of input subcategory until category is not chosen
    }

    // Do not hide placehoder after focusin
    inputSelectSubCat.on('focusin', function() {
        inputSelectSubCat.addClass('black-color-placeholder');
    })

    // Get old value of input
    inputSelectCat.on('focusin', function() {
        catNameOld = $(this).val();
    })

    // If change value of category then change options of subcategory
    inputSelectSubCat.on('focusout', function() {

        var subCatNameNew = $(this).val();

        // Send cat id to add.php to change select options in html according to cat id
        $.ajax({
            url: 'add.php',
            type: 'post',
            data: {
                subcat_name_js: subCatNameNew
            }
        }).done(function(html) {
            var filterOptionsNew = $(html).find('#section-filters').find('.add-item__form-data'),
                filterOptionsCurrent = $('#section-filters');

            // Replace current select by new one - data for dropdown list are loaded from select
            filterOptionsCurrent.html(filterOptionsNew);

            // Replace each select by div
            var filtersSelect = $('#section-filters').find('select');

            // Create dropdown list for all new inputs in filter section
            filtersSelect.each(function() {
                var selectVal = $(this).find('.add-item__select-main').text(),
                    name = $(this).attr('name');

                newDropdownDiv = $('<input class="add-item__input-select" name="' + name + '" placeholder="' + selectVal + '" readonly required><i class="arrow down"></i></input>')
                    .insertAfter($(this))
                    .css({paddingLeft: '0.3em', cursor: 'pointer'});
            });

            // Show filters section
            $('#filters, #section-filters').show();

            // Hide all select elements inside filters section
            $('#section-filters').find('select').hide();

            // Count all added fields
            var filtersInputs = $('#section-filters').find('.add-item__input-select');

            filtersInputs.each(function() {

                // Count inputs
                if ( ($(this).val() === "") && $(this).is(':required') && !localStorage.getItem('allFieldsCount') ) {
                    allFieldsCount += 1;
                }
            })

            // Save modified field count in local storage
            localStorage.setItem('allFieldsCount', allFieldsCount);
        })
    });

    // Allow subcategory input always if category is chosen and value is not empty
    $( window ).on('load', function() {
         console.log(inputSelectCat.val());
        if (inputSelectCat.val() !== '') {
            arrowDown.show();
            inputSelectSubCat.removeClass('stop black-color-placeholder');
        }
    })

    //localStorage.clear();

    // If change value of category then change options of subcategory
    inputSelectCat.on('focusout', function() {

        var catNameNew = $(this).val(),
            arrowDown = inputSelectSubCat.next();

        // Send cat id to add.php to change select options in html according to cat id
        $.ajax({
            url: 'add.php',
            type: 'post',
            data: {
                cat_name_js: catNameNew
            }
        }).done(function(html) {

            var subCatMenuNew = $(html).find('select[name=subcategory]'),
                subCatMenuCurrent = $('#section-info').find('select[name=subcategory]');

            // Replace current select by new one - data for dropdown list are loaded from select
            subCatMenuCurrent.html(subCatMenuNew);
        })

        // Allow subcategory input always if category is chosen and value is not empty
        if (catNameNew !== '') {
            arrowDown.show();
            inputSelectSubCat.removeClass('stop black-color-placeholder');
        }

        // If different category is chosen, then clear input value
        if (catNameOld !== catNameNew) {
            inputSelectSubCat.val('');
        }

    });

    /* SELECT REPLACED BY DIV JS */

    var inputSelect = $('.add-item__input-select');

    // Add new div with options after click on select
    section.on('click','.add-item__input-select', function(event) {

        event.preventDefault();

        var currentNewDropdown = $(this).next(),
            currentInput = $(this),
            currentSelect = $(this).parent().find('select');

        // Do not allow to add dropdown list for subcategory if it has class 'stop'
        if ( !currentInput.hasClass('stop')) {

            // Check if new div dropdown already exists if not add new one
            if ( !currentNewDropdown.hasClass('add-item__custom-select-box') ) {
                var newDropdown = $('<div/>') // create new div element
                    .addClass('add-item__custom-select-box') // with class NewDropdown
                    .insertAfter($(this)); // and append it to page
            }
        }

        // If select was already clicked on, then do not create new dropdown list
        if ( !currentInput.hasClass('added') ) {

            // Check each option value and attach it to new dropdown as div
            currentSelect.find('option').each(function(index, element) {

                var option = $(this); // this is the option from the original select
                    currentNewDropdown = $(this).parent().next();

                // If option is disabled do not append it to new dropdown list
                if (!option.prop('disabled')) {
                    // Create dropdown list as copy of original select list
                    var newOption = $('<div/>') // create new div element
                        .addClass('add-item__custom-select-box-items') // with class NewDropdown-item
                        .html(option.html()) // copy content from original option
                        .data('value', option.val()) // copy value from original option
                        .appendTo(newDropdown); // append it to the new dropdown
                }
            })

            // Show new dropdown options after click on select
            if ( !currentInput.hasClass('stop')) {
                currentNewDropdown = $(this).next();
                currentNewDropdown.show();
                currentInput.addClass('added');
            }
        }

    });

    // Remove dropdown list if focusout without value chosen
    section.on('focusout','.add-item__input-select', function() {
        var newDropdown = $(this).parent().find('.add-item__custom-select-box'),
            inputValue = $(this).val();

        newDropdown.remove();
        inputSelect.removeClass('added');
        inputSelect.addClass('black-text');
    });

    // Add value of clicked element to original option
    section.on('mousedown','.add-item__custom-select-box-items', function() {
        var clickedOptionText = $(this).text(), // Get choosen otion text
            clickedOptionVal = $(this).data('value'), // Get choosen option value
            currentInput = $(this).parent().prev(),
            currentSelect = $(this).parent().parent().find('select'),
            newDropdown = $(this).parent();

        currentSelect.val(clickedOptionVal); // Set up value of original select
        currentInput.val(clickedOptionText); // Show chosen value in input
        newDropdown.remove();
        currentInput.removeClass('added');
        currentInput.addClass('black-text');
    });

Plus code for localstorage:

    /* SAVE FORM DATA TO LOCAL STORAGE - presistent - saved until submit is not clicked  */

    // The unload event is sent to the window element when the user navigates away from the page for ex. page refresh
    $(window).on('unload', function() {

        // Save values of form fields to local storage
        $(':file, :checkbox, select, textarea, input').each(function() {

            // Due to JS added input instead of select, need to get value from input + add to storage just checked items
            if ( !$(this).hasClass('add-item__select') && !$(this).is(':checkbox') ) {

                // Save value of field to local storage
                localStorage.setItem($(this).attr('name'), $(this).val());

            } else if ( $(this).is(':checked') ) {

                // Save just name of checkbox which is checked
                localStorage.setItem($(this).attr('name'), $(this).val());

            }
        })
    });

    // Get values form local storage if page is refreshed
    $(window).on('load', function() {

        // Save values of form fields to local storage
        $(':file, :checkbox, select, textarea, input').each(function() {

            // Set values for input elements
            if ( !$(this).hasClass('add-item__select') && ( !$(this).is(':checkbox' ) && !$(this).is(':file') ) ) {
                // Get value of field
                fieldValue = localStorage.getItem($(this).attr('name'));

                // Show value of field if fieldValue is not empty
                if (fieldValue.length !== 0) {
                    // Fill value of element by value from from localstorage - all filled fileds must have class counted to be not conted again
                    $(this).val(fieldValue).addClass('black-text counted');

                    // Add label, bcz it is checked just on focusout event
                    $('<label class="add-item__form-label-JS">' + $(this).attr('placeholder') + '</label>').insertBefore($(this));
                    $('.add-item__form-label-JS').css({color: '#888'});
                }

            // Done action just for checkbox
            } else if ( $(this).is(':checkbox') ) {

                // Get value of field
                fieldValue = localStorage.getItem($(this).attr('name'));

                // All filled fileds must have class counted to be not conted again
                // If chekcbox name is same as saved in local storage then set as checked
                if ( fieldValue === $(this).val() ) {
                    $(this).prop('checked', true);
                    $(this).parent().parent().addClass('counted');
                }

                // Remove checkbox value in localstorage each time - bcz of change checked checkboxes
                localStorage.removeItem(fieldValue);

            }
        })
    });

If POST data are not sent in same request BUT in request after page refresh THEN code for filling data from localstorage is not working for filter section* bcz it was not visible during loading.

Thanks

2

Answers


  1. Chosen as BEST ANSWER

    I solved it like this. I have same code processed during two different events.

    1. after option is chosen -> focusout event
        // If change value of category then change options of subcategory
        inputSelectSubCat.on('focusout', function() {
    
            var subCatNameNew = $(this).val();
    
            // Send cat id to add.php to change select options in html according to cat id
            $.ajax({
                url: 'add.php',
                type: 'post',
                data: {
                    subcat_name_js: subCatNameNew
                }
            }).done(function(html) {
                var filterOptionsNew = $(html).find('#section-filters').find('.add-item__form-data'),
                    filterOptionsCurrent = $('#section-filters');
    
                // Replace current select by new one - data for dropdown list are loaded from select
                filterOptionsCurrent.html(filterOptionsNew);
    
                // Replace each select by div
                var filtersSelect = $('#section-filters').find('select');
    
                // Create dropdown list for all new inputs in filter section
                filtersSelect.each(function() {
                    var selectVal = $(this).find('.add-item__select-main').text(),
                        name = $(this).attr('name');
    
                    newDropdownDiv = $('<input class="add-item__input-select" name="' + name + '" placeholder="' + selectVal + '" readonly required><i class="arrow down"></i></input>')
                        .insertAfter($(this))
                        .css({paddingLeft: '0.3em', cursor: 'pointer'});
                });
    
                // Show filters section
                $('#filters, #section-filters').show();
    
                // Hide all select elements inside filters section
                $('#section-filters').find('select').hide();
    
                // Count all added fields
                var filtersInputs = $('#section-filters').find('.add-item__input-select');
    
                filtersInputs.each(function() {
    
                    // Count inputs
                    if ( ($(this).val() === "") && $(this).is(':required') && !localStorage.getItem('allFieldsCount') ) {
                        allFieldsCount += 1;
                    }
                })
    
                // Save modified field count in local storage
                localStorage.setItem('allFieldsCount', allFieldsCount);
    
            })
        });
    
    
    1. after page is loaded -> load event I read value of select after refresh page from localstorage -> send to add.php -> and show filter section with filled data
        $( window ).on('load', function() {
        // If change value of category then change options of subcategory
    
            var subCatNameNew = localStorage.getItem('subcategory');
    
            // Send cat id to add.php to change select options in html according to cat id
            $.ajax({
                url: 'add.php',
                type: 'post',
                data: {
                    subcat_name_js: subCatNameNew
                }
            }).done(function(html) {
                var filterOptionsNew = $(html).find('#section-filters').find('.add-item__form-data'),
                    filterOptionsCurrent = $('#section-filters');
    
                // Replace current select by new one - data for dropdown list are loaded from select
                filterOptionsCurrent.html(filterOptionsNew);
    
                // Replace each select by div
                var filtersSelect = $('#section-filters').find('select');
    
                // Create dropdown list for all new inputs in filter section
                filtersSelect.each(function() {
                    var selectVal = $(this).find('.add-item__select-main').text(),
                        name = $(this).attr('name');
    
                    newDropdownDiv = $('<input class="add-item__input-select" name="' + name + '" placeholder="' + selectVal + '" readonly required><i class="arrow down"></i></input>')
                        .insertAfter($(this))
                        .css({paddingLeft: '0.3em', cursor: 'pointer'});
                });
    
                // Show filters section
                $('#filters, #section-filters').show();
    
                // Hide all select elements inside filters section
                $('#section-filters').find('select').hide();
    
                // Count all added fields
                var filtersInputs = $('#section-filters').find('.add-item__input-select');
    
                filtersInputs.each(function() {
    
                    // Count inputs
                    if ( ($(this).val() === "") && $(this).is(':required') && !localStorage.getItem('allFieldsCount') ) {
                        allFieldsCount += 1;
                    }
                })
    
                // Save modified field count in local storage
                localStorage.setItem('allFieldsCount', allFieldsCount);
    
                // Save values of form fields to local storage
                $(':file, :checkbox, select, textarea, input').each(function() {
    
                    // Set values for input elements
                    if ( !$(this).hasClass('add-item__select') && ( !$(this).is(':checkbox' ) && !$(this).is(':file') ) ) {
                        // Get value of field
                        fieldValue = localStorage.getItem($(this).attr('name'));
    
                        // Show value of field if fieldValue is not empty
                        if (fieldValue.length !== 0) {
                            // Fill value of element by value from from localstorage - all filled fileds must have class counted to be not conted again
                            $(this).val(fieldValue).addClass('black-text counted');
    
                            // Add label, bcz it is checked just on focusout event
                            $('<label class="add-item__form-label-JS">' + $(this).attr('placeholder') + '</label>').insertBefore($(this));
                            $('.add-item__form-label-JS').css({color: '#888'});
                        }
                    }
                })
            })
        });
    

    I would appreciate if you know some better, nicer solution to write it as answer,

    Thank you


  2. I think you want a second dropdown option on the base of the first selection.
    To send an ajax call on the change value of the dropdown, use jquery on the change event

     $('#FirstdropdownID').('change', function() {
      // Send an AJAX request when First dropdown is changed/select
     // Send an AJAX request to the add.php page
    $.ajax({
      url: 'add.php',
      type: 'POST',
      data: {
        catId: $('#FirstdropdownID').val()
      },
      success: function(response) {
         // for the current scenario
         // Update the select box with the new options
         $('#secondDropdownID').html(response);
       }
      });
    });
      
    
    ** code for Php File add.php**
    
    
    <?php
      // Get the cat id from the request
      $catId = $_POST['catId'];
    
      // Generate the HTML for the new select options
      
    
    $optionsHtml = '';
      foreach ($catOptions as $option) {
        $optionsHtml .= "<option value='".$option['value']."'>".$option['label']." 
       </option>";
      }
    
      // Return the HTML to the client
      echo $optionsHtml;
    ?>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search