Skip to content

Commit 4341ab6

Browse files
Merge pull request #19294 from faissaloux/query-generator-in-without-quotes
[Query Generator] simplify IN, NOT IN criteria text
2 parents 136f1db + 0a06314 commit 4341ab6

2 files changed

Lines changed: 77 additions & 17 deletions

File tree

‎resources/js/src/database/multi_table_query.ts‎

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ AJAX.registerTeardown('database/multi_table_query.js', function () {
3535

3636
$('#update_query_button').off('click');
3737
$('#add_column_button').off('click');
38+
$('body').off('click', 'input.add-option');
39+
$('body').off('click', 'input.remove-option');
3840
});
3941

4042
AJAX.registerOnload('database/multi_table_query.js', function () {
@@ -45,11 +47,8 @@ AJAX.registerOnload('database/multi_table_query.js', function () {
4547
var columnCount = 3;
4648
addNewColumnCallbacks();
4749

48-
function theHints () {
49-
return {
50-
'IN (...)': 'Separate the values by commas',
51-
'NOT IN (...)': 'Separate the values by commas',
52-
};
50+
function opsWithMultipleArgs (): string[] {
51+
return ['IN (...)', 'NOT IN (...)'];
5352
}
5453

5554
$('#update_query_button').on('click', function () {
@@ -200,22 +199,53 @@ AJAX.registerOnload('database/multi_table_query.js', function () {
200199
});
201200
});
202201

202+
const acceptsMultipleArgs: string[] = opsWithMultipleArgs();
203203
$('.criteria_op').each(function () {
204204
$(this).on('change', function () {
205-
showHint($(this));
205+
if (acceptsMultipleArgs.includes($(this).val().toString())) {
206+
showMultiFields($(this));
207+
} else {
208+
const options: JQuery<HTMLElement> = $(this).closest('table').find('.options');
209+
options.parent().prepend('<input type="text" class="rhs_text_val query-form__input--wide" placeholder="Enter criteria as free text"></input>');
210+
options.remove();
211+
}
206212
});
207213
});
208214

209-
function showHint (opSelect) {
210-
const hints = theHints();
211-
const value = opSelect.val();
212-
const criteriaInputCol = opSelect.closest('table').find('.rhs_text_val').parent();
213-
214-
criteriaInputCol.find('.rhs_hint').remove();
215+
function showMultiFields (opSelect: JQuery<HTMLElement>) {
216+
const criteriaInput: JQuery<HTMLElement> = opSelect.closest('table').find('.rhs_text_val');
217+
const criteriaInputCol: JQuery<HTMLElement> = criteriaInput.parent();
218+
const hasAtLeastOneOption: boolean = criteriaInputCol.find('.option').length > 0;
219+
220+
if (!hasAtLeastOneOption) {
221+
criteriaInputCol.append(`
222+
<div class="options">
223+
<div class="option">
224+
<input type="text" class="val" placeholder="Enter an option" value="${criteriaInput.val()}" />
225+
<input type="button" class="btn btn-secondary add-option" value="+" />
226+
</div>
227+
</div>
228+
`);
229+
}
215230

216-
Object.keys(hints).includes(value) && criteriaInputCol.append(`<p class="rhs_hint">${hints[value]}</p>`);
231+
criteriaInput.remove();
217232
}
218233

234+
$('body').on('click', 'input.add-option', function () {
235+
const options: JQuery<HTMLElement> = $(this).closest('.options');
236+
237+
options.find('.option').first().clone().appendTo(options);
238+
239+
const newAdded: JQuery<HTMLElement> = options.find('.option').last();
240+
241+
newAdded.find('input.val').val('');
242+
newAdded.append('<input type="button" class="btn btn-secondary remove-option" value="-" />');
243+
});
244+
245+
$('body').on('click', 'input.remove-option', function () {
246+
$(this).closest('.option').remove();
247+
});
248+
219249
function addNewColumnCallbacks () {
220250
$('.tableNameSelect').each(function () {
221251
$(this).on('change', function () {

‎resources/js/src/database/query_generator.ts‎

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,32 @@ function opsWithoutArg () {
4141
return ['IS NULL', 'IS NOT NULL'];
4242
}
4343

44+
function opsWithMultipleArgs (): string[] {
45+
return ['IN (...)', 'NOT IN (...)'];
46+
}
47+
4448
function isOpWithoutArg (op) {
4549
return opsWithoutArg().includes(op);
4650
}
4751

52+
function acceptsMultipleValues (op: string): boolean {
53+
return opsWithMultipleArgs().includes(op);
54+
}
55+
56+
function joinWrappingElementsWith (array: string[], char: string, separator: string = ','): string {
57+
let string: string = '';
58+
59+
array.forEach(function (option: string, index: number) {
60+
string += `${char}${option}${char}`;
61+
62+
if (index !== array.length - 1) {
63+
string += separator;
64+
}
65+
});
66+
67+
return string;
68+
}
69+
4870
function generateCondition (criteriaDiv, table) {
4971
const tableName = table.val();
5072
const tableAlias = table.siblings('.table_alias').val();
@@ -56,12 +78,20 @@ function generateCondition (criteriaDiv, table) {
5678
if (criteriaDiv.find('.criteria_rhs').first().val() === 'text') {
5779
if (isOpWithoutArg(criteriaOp)) {
5880
query += ' ' + criteriaOp;
59-
} else {
81+
} else if (acceptsMultipleValues(criteriaOp)) {
6082
const formatsText = getFormatsText();
83+
const valuesInputs = criteriaDiv.find('input.val');
84+
let critertiaTextArray = [];
6185

62-
if (!['IN (...)', 'NOT IN (...)'].includes(criteriaOp)) {
63-
criteriaText = escapeSingleQuote(criteriaText);
64-
}
86+
valuesInputs.each(function () {
87+
critertiaTextArray.push(escapeSingleQuote($(this).val()));
88+
});
89+
90+
criteriaText = joinWrappingElementsWith(critertiaTextArray, '\'');
91+
92+
query += window.sprintf(formatsText[criteriaOp], criteriaText);
93+
} else {
94+
const formatsText = getFormatsText();
6595

6696
query += window.sprintf(formatsText[criteriaOp], criteriaText);
6797
}

0 commit comments

Comments
 (0)