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"}
});
})
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
I solved it like this. I have same code processed during two different events.
I would appreciate if you know some better, nicer solution to write it as answer,
Thank you
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