I had to help a friend solving a very common problem for, for example, booking websites.
The example is basically the selection of options based on two
<select>s
elements: number of adults and number of children for a possible booking.
So, what we are going to do is to create a very simple HTML with two selects and one button, with the chance to remove an already selected combination before submitting it.
The HTML:
<select id="adults"> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> </select> <select id="children"> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> </select> <button id="add">Add</button> <div id="output">Here the combination of selected values</div> <br/> <button id="submit">Send via AJAX</button>
Now, we are going to create a Javascript to handle this:
function Selection() { this.SELECTOR_ADULTS = '#adults'; this.SELECTOR_CHILDREN = '#children'; this.OUTPUT_SELECTOR = '#output'; this.SUBMIT_SELECTOR = '#submit'; this.selected = {}; } /** Create a label for the given item **/ Selection.prototype.labelForSelected = function(item) { let out = item.adults + " Adults "; const childrenNumber = parseInt(item.children); if (childrenNumber > 0) { out += item.children + ((childrenNumber === 1) ? " Child" : " Children"); } return out; } /** Add the selected item to output **/ Selection.prototype.selectedToOutput = function() { const keys = Object.keys(this.selected); jQuery(this.OUTPUT_SELECTOR).html(''); for (let i = 0; i < keys.length; i++) { let key = keys[i]; const outerDiv = jQuery("<div>"); const span = jQuery("<span>", { text: this.labelForSelected(this.selected[key]) }); const button = jQuery("<button>", { 'class': 'remove', id: key, text: 'X' }); jQuery(outerDiv).append(span); jQuery(outerDiv).append(button); jQuery(this.OUTPUT_SELECTOR).append(outerDiv); } } /** Remove an item from the selected options */ Selection.prototype.removeFromSelected = function(item) { let aux = {}; const keys = Object.keys(this.selected); for (let i = 0; i < keys.length; i++) { if (keys[i] === item) { continue; } aux[keys[i]] = this.selected[keys[i]]; } this.selected = aux; this.selectedToOutput(); } /** Init events **/ Selection.prototype.initEvents = function() { const _this = this; jQuery(document).ready(function() { jQuery("#add").click(function() { const selOne = jQuery(_this.SELECTOR_ADULTS).val(); const selTwo = jQuery(_this.SELECTOR_CHILDREN).val(); const key = selOne + selTwo; const newItem = { adults: selOne, children: selTwo }; _this.selected[key] = newItem; _this.selectedToOutput(); }); jQuery(_this.OUTPUT_SELECTOR).on( "click", ".remove", function(e) { const id = $(this).attr('id'); _this.removeFromSelected(id); }); jQuery(_this.SUBMIT_SELECTOR).click(function() { _this.submitByAJAX(); }); }); } Selection.prototype.submitByAJAX = function() { const keys = Object.keys(this.selected); console.log("Submitting", keys); } var mySelection = new Selection(); mySelection.initEvents();
The initEvents function binds the function for the HTML elements to the respective methods.
Note that for the .remove class we cannot use a simple click() because the elements are added dynamically.
The selectedToOutput method creates with jQuery the simple HTML elements to be added to the output.
A working demo is present on my Codepen.