Skip to content

Commit

Permalink
implement custom adapters. ajax fields should work as expected now
Browse files Browse the repository at this point in the history
  • Loading branch information
lenadax committed Sep 26, 2024
1 parent c0ab963 commit 7a8c04f
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 83 deletions.
109 changes: 69 additions & 40 deletions js/src/bootstrap5/widget.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,66 @@

import $ from 'jquery';

// define custom adapters
$.fn.select2.amd.define('select2/data/singleValueAjaxAdapter',[
'select2/data/ajax',
'select2/utils'
],
function (AjaxAdapter, Utils) {
function SingleValueAjaxAdapter ($element, options) {
SingleValueAjaxAdapter.__super__.constructor.call(this, $element, options);
}
Utils.Extend(SingleValueAjaxAdapter, AjaxAdapter);

SingleValueAjaxAdapter.prototype.current = function (callback) {
let value = this.$element.val();
let vocab = this.$element.data('vocabulary');
function label(key) {
return (!vocab || !vocab[key]) ? key : vocab[key];
}
callback([{ id: value, text: label(value) }]);
};

SingleValueAjaxAdapter.prototype.select = function(data) {
this.$element.find('option[value="' + data.id + '"]').prop('selected', true);
AjaxAdapter.prototype.select.call(this, data)
};

return SingleValueAjaxAdapter;
});

$.fn.select2.amd.define('select2/data/multiValueAjaxAdapter',[
'select2/data/ajax',
'select2/utils'
],
function (AjaxAdapter, Utils) {
function MultiValueAjaxAdapter ($element, options) {
MultiValueAjaxAdapter.__super__.constructor.call(this, $element, options);
}
Utils.Extend(MultiValueAjaxAdapter, AjaxAdapter);

MultiValueAjaxAdapter.prototype.current = function (callback) {
let value = this.$element.val();
let vocab = this.$element.data('vocabulary');
function label(key) {
return (!vocab || !vocab[key]) ? key : vocab[key];
}
let data = [];
value.split(',').forEach((v) => {
data.push({ id: v, text: label(v) });
});
callback(data);
};

MultiValueAjaxAdapter.prototype.select = function(data) {
AjaxAdapter.prototype.select.call(this, data);
};

return MultiValueAjaxAdapter;
});
const singleValueAjaxAdapter=$.fn.select2.amd.require('select2/data/singleValueAjaxAdapter');
const multiValueAjaxAdapter=$.fn.select2.amd.require('select2/data/multiValueAjaxAdapter');

export class Select2Widget {

static initialize(context) {
Expand Down Expand Up @@ -35,56 +95,25 @@ export class Select2Widget {
options.ajax = {
url: options.ajaxurl,
dataType: 'json',
data: function (params) { // `params` replaces `term` in Select2 v4.x
data: function (params) {
return { q: params.term };
},
processResults: function (data) { // `processResults` replaces `results`
processResults: function (data, params) {
if (options.tags && !data.length) {
data.push({
id: params.term,
text: params.term
});
}
return { results: data };
let results = data.map(item => ({ id: item.id, text: item.text || item.id }));
return { results: results };
}
};
$.fn.select2.amd.require(["select2/data/select"], function(Select) {
let CustomDataAdapter = Select;

CustomDataAdapter.prototype.current = function (callback) {
console.log('current')
let value = this.$element.val();
console.log(value)

let vocab = this.$element.data('vocabulary');
function label(key) {
return (!vocab || !vocab[key]) ? key : vocab[key];
}

if (options.multiple) {
console.log('multi')
let data = [];
$(this.$element.val().split(",")).each(function() {
data.push({ id: this, text: label(this) });
});
callback(data);
} else {
console.log('single')
callback([{ id: 'foo', text: value }]);
}
};

let originalSelect = CustomDataAdapter.prototype.select;
CustomDataAdapter.prototype.select = function (data) {
console.log(data)
// Your own code
// Call the original function while keeping 'this' context
originalSelect.bind(this)(data);
};

// Finally, use the custom data adapter
options.dataAdapter = CustomDataAdapter;
});
if (options.multiple) {
options.dataAdapter = multiValueAjaxAdapter;
} else {
options.dataAdapter = singleValueAjaxAdapter;
}
}

options.theme = 'bootstrap-5';
Expand Down
21 changes: 14 additions & 7 deletions src/yafowil/widget/select2/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,31 +255,38 @@ def get_example():
})
select2_6_routes = {'yafowil.widget.select2.json': json_response}

return [{
return [
{
'widget': select2_1,
'doc': DOC_SELECT2_1,
'title': TITLE_SELECT2_1
}, {
},
{
'widget': select2_2,
'doc': DOC_SELECT2_2,
'title': TITLE_SELECT2_2
}, {
},
{
'widget': select2_3,
'doc': DOC_SELECT2_3,
'title': TITLE_SELECT2_3
}, {
},
{
'widget': select2_4,
'routes': select2_4_routes,
'doc': DOC_SELECT2_4,
'title': TITLE_SELECT2_4
}, {
},
{
'widget': select2_5,
'routes': select2_5_routes,
'doc': DOC_SELECT2_5,
'title': TITLE_SELECT2_5
}, {
},
{
'widget': select2_6,
'routes': select2_6_routes,
'doc': DOC_SELECT2_6,
'title': TITLE_SELECT2_6
}]
}
]
94 changes: 59 additions & 35 deletions src/yafowil/widget/select2/resources/bootstrap5/widget.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,57 @@
var yafowil_select2 = (function (exports, $) {
'use strict';

$.fn.select2.amd.define('select2/data/singleValueAjaxAdapter',[
'select2/data/ajax',
'select2/utils'
],
function (AjaxAdapter, Utils) {
function SingleValueAjaxAdapter ($element, options) {
SingleValueAjaxAdapter.__super__.constructor.call(this, $element, options);
}
Utils.Extend(SingleValueAjaxAdapter, AjaxAdapter);
SingleValueAjaxAdapter.prototype.current = function (callback) {
let value = this.$element.val();
let vocab = this.$element.data('vocabulary');
function label(key) {
return (!vocab || !vocab[key]) ? key : vocab[key];
}
callback([{ id: value, text: label(value) }]);
};
SingleValueAjaxAdapter.prototype.select = function(data) {
this.$element.find('option[value="' + data.id + '"]').prop('selected', true);
AjaxAdapter.prototype.select.call(this, data);
};
return SingleValueAjaxAdapter;
});
$.fn.select2.amd.define('select2/data/multiValueAjaxAdapter',[
'select2/data/ajax',
'select2/utils'
],
function (AjaxAdapter, Utils) {
function MultiValueAjaxAdapter ($element, options) {
MultiValueAjaxAdapter.__super__.constructor.call(this, $element, options);
}
Utils.Extend(MultiValueAjaxAdapter, AjaxAdapter);
MultiValueAjaxAdapter.prototype.current = function (callback) {
let value = this.$element.val();
let vocab = this.$element.data('vocabulary');
function label(key) {
return (!vocab || !vocab[key]) ? key : vocab[key];
}
let data = [];
value.split(',').forEach((v) => {
data.push({ id: v, text: label(v) });
});
callback(data);
};
MultiValueAjaxAdapter.prototype.select = function(data) {
AjaxAdapter.prototype.select.call(this, data);
};
return MultiValueAjaxAdapter;
});
const singleValueAjaxAdapter=$.fn.select2.amd.require('select2/data/singleValueAjaxAdapter');
const multiValueAjaxAdapter=$.fn.select2.amd.require('select2/data/multiValueAjaxAdapter');
class Select2Widget {
static initialize(context) {
$('.select2', context).each(function (event) {
Expand All @@ -22,9 +73,6 @@ var yafowil_select2 = (function (exports, $) {
throw `Failed to initialize select2: ${error}`;
}
elem.data('yafowil-select2', this);
if (this.elem.val()) {
this.elem.trigger('change');
}
}
init_options(options) {
for (let name in options) {
Expand All @@ -37,46 +85,22 @@ var yafowil_select2 = (function (exports, $) {
data: function (params) {
return { q: params.term };
},
processResults: function (data) {
processResults: function (data, params) {
if (options.tags && !data.length) {
data.push({
id: params.term,
text: params.term
});
}
return { results: data };
let results = data.map(item => ({ id: item.id, text: item.text || item.id }));
return { results: results };
}
};
$.fn.select2.amd.require(["select2/data/select"], function(Select) {
let CustomDataAdapter = Select;
CustomDataAdapter.prototype.current = function (callback) {
console.log('current');
let value = this.$element.val();
console.log(value);
let vocab = this.$element.data('vocabulary');
function label(key) {
return (!vocab || !vocab[key]) ? key : vocab[key];
}
if (options.multiple) {
console.log('multi');
let data = [];
$(this.$element.val().split(",")).each(function() {
data.push({ id: this, text: label(this) });
});
callback(data);
} else {
console.log('single');
callback([{ id: 'foo', text: value }]);
}
};
let originalSelect = CustomDataAdapter.prototype.select;
CustomDataAdapter.prototype.select = function (data) {
console.log(data);
console.log('ARHGHHGGH');
originalSelect.bind(this)(data);
};
options.dataAdapter = CustomDataAdapter;
});
if (options.multiple) {
options.dataAdapter = multiValueAjaxAdapter;
} else {
options.dataAdapter = singleValueAjaxAdapter;
}
}
options.theme = 'bootstrap-5';
options.selectionCssClass = "select2--medium";
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 7a8c04f

Please sign in to comment.