diff --git a/resources/js/src/database/multi_table_query.ts b/resources/js/src/database/multi_table_query.ts index a80c2b8f5a..c3fdd63da0 100644 --- a/resources/js/src/database/multi_table_query.ts +++ b/resources/js/src/database/multi_table_query.ts @@ -35,6 +35,8 @@ AJAX.registerTeardown('database/multi_table_query.js', function () { $('#update_query_button').off('click'); $('#add_column_button').off('click'); + $('body').off('click', 'input.add-option'); + $('body').off('click', 'input.remove-option'); }); AJAX.registerOnload('database/multi_table_query.js', function () { @@ -45,11 +47,8 @@ AJAX.registerOnload('database/multi_table_query.js', function () { var columnCount = 3; addNewColumnCallbacks(); - function theHints () { - return { - 'IN (...)': 'Separate the values by commas', - 'NOT IN (...)': 'Separate the values by commas', - }; + function opsWithMultipleArgs (): string[] { + return ['IN (...)', 'NOT IN (...)']; } $('#update_query_button').on('click', function () { @@ -200,22 +199,53 @@ AJAX.registerOnload('database/multi_table_query.js', function () { }); }); + const acceptsMultipleArgs: string[] = opsWithMultipleArgs(); $('.criteria_op').each(function () { $(this).on('change', function () { - showHint($(this)); + if (acceptsMultipleArgs.includes($(this).val().toString())) { + showMultiFields($(this)); + } else { + const options: JQuery = $(this).closest('table').find('.options'); + options.parent().prepend(''); + options.remove(); + } }); }); - function showHint (opSelect) { - const hints = theHints(); - const value = opSelect.val(); - const criteriaInputCol = opSelect.closest('table').find('.rhs_text_val').parent(); + function showMultiFields (opSelect: JQuery) { + const criteriaInput: JQuery = opSelect.closest('table').find('.rhs_text_val'); + const criteriaInputCol: JQuery = criteriaInput.parent(); + const hasAtLeastOneOption: boolean = criteriaInputCol.find('.option').length > 0; - criteriaInputCol.find('.rhs_hint').remove(); + if (!hasAtLeastOneOption) { + criteriaInputCol.append(` +
+
+ + +
+
+ `); + } - Object.keys(hints).includes(value) && criteriaInputCol.append(`

${hints[value]}

`); + criteriaInput.remove(); } + $('body').on('click', 'input.add-option', function () { + const options: JQuery = $(this).closest('.options'); + + options.find('.option').first().clone().appendTo(options); + + const newAdded: JQuery = options.find('.option').last(); + + newAdded.find('input.val').val(''); + newAdded.append(''); + }); + + $('body').on('click', 'input.remove-option', function () { + $(this).closest('.option').remove(); + }); + function addNewColumnCallbacks () { $('.tableNameSelect').each(function () { $(this).on('change', function () { diff --git a/resources/js/src/database/query_generator.ts b/resources/js/src/database/query_generator.ts index 2ddf88de7d..40b7f1152a 100644 --- a/resources/js/src/database/query_generator.ts +++ b/resources/js/src/database/query_generator.ts @@ -41,10 +41,32 @@ function opsWithoutArg () { return ['IS NULL', 'IS NOT NULL']; } +function opsWithMultipleArgs (): string[] { + return ['IN (...)', 'NOT IN (...)']; +} + function isOpWithoutArg (op) { return opsWithoutArg().includes(op); } +function acceptsMultipleValues (op: string): boolean { + return opsWithMultipleArgs().includes(op); +} + +function joinWrappingElementsWith (array: string[], char: string, separator: string = ','): string { + let string: string = ''; + + array.forEach(function (option: string, index: number) { + string += `${char}${option}${char}`; + + if (index !== array.length - 1) { + string += separator; + } + }); + + return string; +} + function generateCondition (criteriaDiv, table) { const tableName = table.val(); const tableAlias = table.siblings('.table_alias').val(); @@ -56,13 +78,21 @@ function generateCondition (criteriaDiv, table) { if (criteriaDiv.find('.criteria_rhs').first().val() === 'text') { if (isOpWithoutArg(criteriaOp)) { query += ' ' + criteriaOp; + } else if (acceptsMultipleValues(criteriaOp)) { + const formatsText = getFormatsText(); + const valuesInputs = criteriaDiv.find('input.val'); + let critertiaTextArray = []; + + valuesInputs.each(function () { + critertiaTextArray.push(escapeSingleQuote($(this).val())); + }); + + criteriaText = joinWrappingElementsWith(critertiaTextArray, '\''); + + query += window.sprintf(formatsText[criteriaOp], criteriaText); } else { const formatsText = getFormatsText(); - if (!['IN (...)', 'NOT IN (...)'].includes(criteriaOp)) { - criteriaText = escapeSingleQuote(criteriaText); - } - query += window.sprintf(formatsText[criteriaOp], criteriaText); } } else {