mirror of
https://github.com/Hopiu/django-select2.git
synced 2026-03-30 11:50:24 +00:00
commit
a853ae52a9
5 changed files with 665 additions and 804 deletions
|
|
@ -492,6 +492,7 @@ class HeavySelect2FieldBaseMixin(object):
|
|||
# could have directly set field_id on it.
|
||||
if hasattr(self, 'field_id'):
|
||||
self.widget.field_id = self.field_id
|
||||
self.widget.attrs['data-select2-id'] = self.field_id
|
||||
|
||||
# Widget should have been instantiated by now.
|
||||
self.widget.field = self
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
if (!window['django_select2']) {
|
||||
// This JS file can be included multiple times. So, as not to overwrite previous states, we run this only once.
|
||||
|
||||
var django_select2 = {
|
||||
window.django_select2 = {
|
||||
MULTISEPARATOR: String.fromCharCode(31), // We use this unprintable char as separator,
|
||||
// since this can't be entered by user.
|
||||
get_url_params: function (term, page, context) {
|
||||
|
|
@ -59,14 +59,14 @@ if (!window['django_select2']) {
|
|||
updateText: function ($e) {
|
||||
var val = $e.select2('val'), data = $e.select2('data'), txt = $e.txt(), isMultiple = !!$e.attr('multiple'),
|
||||
diff;
|
||||
|
||||
|
||||
if (val || val === 0) { // Means value is set. A numerical 0 is also a valid value.
|
||||
if (isMultiple) {
|
||||
if (val.length !== txt.length) {
|
||||
txt = [];
|
||||
jQuery(val).each(function (idx) {
|
||||
var i, value = this, id;
|
||||
|
||||
|
||||
for (i in data) {
|
||||
id = data [i].id;
|
||||
if (id instanceof String) {
|
||||
|
|
@ -109,12 +109,12 @@ if (!window['django_select2']) {
|
|||
return [val, txt];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (res) {
|
||||
txt = [];
|
||||
jQuery(val).each(function (idx) {
|
||||
var i, value = this;
|
||||
|
||||
|
||||
for (i in res) {
|
||||
if (res[i].id == value) {
|
||||
val[idx] = res[i].id; // To set it to correct data type.
|
||||
|
|
|
|||
2
django_select2/static/js/heavy_data.min.js
vendored
2
django_select2/static/js/heavy_data.min.js
vendored
|
|
@ -1 +1 @@
|
|||
if(!window.django_select2){var django_select2={MULTISEPARATOR:String.fromCharCode(31),get_url_params:function(c,e,b){var d=$(this).data("field_id"),a={term:c,page:e,context:b};if(d){a.field_id=d}return a},process_results:function(d,c,b){var a;if(d.err&&d.err.toLowerCase()==="nil"){a={results:d.results};if(b){a.context=b}if(d.more===true||d.more===false){a.more=d.more}}else{a={results:[]}}if(a.results){$(this).data("results",a.results)}else{$(this).removeData("results")}return a},onValChange:function(){django_select2.updateText($(this))},prepareValText:function(d,a,c){var b=[];$(d).each(function(e){b.push({id:this,text:a[e]})});if(c){return b}else{if(b.length>0){return b[0]}else{return null}}},updateText:function(b){var f=b.select2("val"),d=b.select2("data"),a=b.txt(),c=!!b.attr("multiple"),e;if(f||f===0){if(c){if(f.length!==a.length){a=[];$(f).each(function(g){var h,j=this,k;for(h in d){k=d[h].id;if(k instanceof String){k=k.valueOf()}if(k==j){a.push(d[h].text)}}})}}else{a=d.text}b.txt(a)}else{b.txt("")}},getValText:function(b){var g=b.select2("val"),c=b.data("results"),a=b.txt(),e=!!b.attr("multiple"),d,h=b.attr("id");if(g||g===0){if(!e){g=[g];if(a||a===0){a=[a]}}if(a===0||(a&&g.length===a.length)){return[g,a]}d=b.data("userGetValText");if(d){a=d(b,g,e);if(a||a===0){return[g,a]}}if(c){a=[];$(g).each(function(f){var j,k=this;for(j in c){if(c[j].id==k){g[f]=c[j].id;a.push(c[j].text)}}});if(a||a===0){return[g,a]}}}return null},onInit:function(b,f){b=$(b);var d=b.attr("id"),a=null,c=b.select2("val");if(!c&&c!==0){c=b.data("initVal")}if(c||c===0){a=django_select2.getValText(b);if(a&&a[0]){a=django_select2.prepareValText(a[0],a[1],!!b.attr("multiple"))}}if(!a){b.val(null)}f(a);django_select2.updateText(b)},createSearchChoice:function(a,b){if(!b||$(b).filter(function(){return this.text.localeCompare(a)===0}).length===0){return{id:a,text:a}}},onMultipleHiddenChange:function(){var b=$(this),d=b.data("valContainer"),a=b.data("name"),c=b.val();d.empty();if(c){c=c.split(django_select2.MULTISEPARATOR);$(c).each(function(){var e=$('<input type="hidden">').appendTo(d);e.attr("name",a);e.val(this)})}},initMultipleHidden:function(a){var b;a.data("name",a.attr("name"));a.attr("name","");b=$("<div>").insertAfter(a).css({display:"none"});a.data("valContainer",b);a.change(django_select2.onMultipleHiddenChange);if(a.val()){a.change()}},convertArrToStr:function(a){return a.join(django_select2.MULTISEPARATOR)},runInContextHelper:function(a,b){return function(){var c=Array.prototype.slice.call(arguments,0);return a.apply($("#"+b).get(0),c)}},logErr:function(){if(console&&console.error){args=Array.prototype.slice.call(arguments);console.error.apply(console,args)}}};(function(b){if(b){for(var a in django_select2){var c=django_select2[a];if(typeof(c)=="function"){django_select2[a]=(function(d,e){return function(){console.log("Function "+d+" called for object: ",this);return e.apply(this,arguments)}}(a,c))}}}}(false));(function(a){a.fn.txt=function(b){if(typeof(b)!=="undefined"){if(b){if(b instanceof Array){if(this.attr("multiple")){b=django_select2.convertArrToStr(b)}else{b=b[0]}}this.attr("txt",b)}else{this.removeAttr("txt")}return this}else{b=this.attr("txt");if(this.attr("multiple")){if(b){b=b.split(django_select2.MULTISEPARATOR)}else{b=[]}}return b}}})(jQuery)};
|
||||
if(!window.django_select2){window.django_select2={MULTISEPARATOR:String.fromCharCode(31),get_url_params:function(c,e,b){var d=$(this).data("field_id"),a={term:c,page:e,context:b};if(d){a.field_id=d}return a},process_results:function(d,c,b){var a;if(d.err&&d.err.toLowerCase()==="nil"){a={results:d.results};if(b){a.context=b}if(d.more===true||d.more===false){a.more=d.more}}else{a={results:[]}}if(a.results){$(this).data("results",a.results)}else{$(this).removeData("results")}return a},onValChange:function(){django_select2.updateText($(this))},prepareValText:function(d,a,c){var b=[];$(d).each(function(e){b.push({id:this,text:a[e]})});if(c){return b}else{if(b.length>0){return b[0]}else{return null}}},updateText:function(b){var f=b.select2("val"),d=b.select2("data"),a=b.txt(),c=!!b.attr("multiple"),e;if(f||f===0){if(c){if(f.length!==a.length){a=[];$(f).each(function(g){var h,j=this,k;for(h in d){k=d[h].id;if(k instanceof String){k=k.valueOf()}if(k==j){a.push(d[h].text)}}})}}else{a=d.text}b.txt(a)}else{b.txt("")}},getValText:function(b){var g=b.select2("val"),c=b.data("results"),a=b.txt(),e=!!b.attr("multiple"),d,h=b.attr("id");if(g||g===0){if(!e){g=[g];if(a||a===0){a=[a]}}if(a===0||(a&&g.length===a.length)){return[g,a]}d=b.data("userGetValText");if(d){a=d(b,g,e);if(a||a===0){return[g,a]}}if(c){a=[];$(g).each(function(f){var j,k=this;for(j in c){if(c[j].id==k){g[f]=c[j].id;a.push(c[j].text)}}});if(a||a===0){return[g,a]}}}return null},onInit:function(b,f){b=$(b);var d=b.attr("id"),a=null,c=b.select2("val");if(!c&&c!==0){c=b.data("initVal")}if(c||c===0){a=django_select2.getValText(b);if(a&&a[0]){a=django_select2.prepareValText(a[0],a[1],!!b.attr("multiple"))}}if(!a){b.val(null)}f(a);django_select2.updateText(b)},createSearchChoice:function(a,b){if(!b||$(b).filter(function(){return this.text.localeCompare(a)===0}).length===0){return{id:a,text:a}}},onMultipleHiddenChange:function(){var b=$(this),d=b.data("valContainer"),a=b.data("name"),c=b.val();d.empty();if(c){c=c.split(django_select2.MULTISEPARATOR);$(c).each(function(){var e=$('<input type="hidden">').appendTo(d);e.attr("name",a);e.val(this)})}},initMultipleHidden:function(a){var b;a.data("name",a.attr("name"));a.attr("name","");b=$("<div>").insertAfter(a).css({display:"none"});a.data("valContainer",b);a.change(django_select2.onMultipleHiddenChange);if(a.val()){a.change()}},convertArrToStr:function(a){return a.join(django_select2.MULTISEPARATOR)},runInContextHelper:function(a,b){return function(){var c=Array.prototype.slice.call(arguments,0);return a.apply($("#"+b).get(0),c)}},logErr:function(){if(console&&console.error){args=Array.prototype.slice.call(arguments);console.error.apply(console,args)}}};(function(b){if(b){for(var a in django_select2){var c=django_select2[a];if(typeof(c)=="function"){django_select2[a]=(function(d,e){return function(){console.log("Function "+d+" called for object: ",this);return e.apply(this,arguments)}}(a,c))}}}}(false));(function(a){a.fn.txt=function(b){if(typeof(b)!=="undefined"){if(b){if(b instanceof Array){if(this.attr("multiple")){b=django_select2.convertArrToStr(b)}else{b=b[0]}}this.attr("txt",b)}else{this.removeAttr("txt")}return this}else{b=this.attr("txt");if(this.attr("multiple")){if(b){b=b.split(django_select2.MULTISEPARATOR)}else{b=[]}}return b}}})(jQuery)};
|
||||
|
|
|
|||
|
|
@ -10,62 +10,6 @@ from django.utils.encoding import force_unicode
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class JSVar(unicode):
|
||||
"""
|
||||
A JS variable.
|
||||
|
||||
This is a simple Unicode string. This class type acts as a marker that this string is a JS variable name,
|
||||
so it must not be quoted by :py:func:`.convert_py_to_js_data` while rendering the JS code.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class JSFunction(JSVar):
|
||||
"""
|
||||
A JS function name.
|
||||
|
||||
From rendering point of view, rendering this is no different from :py:class:`JSVar`. After all, a JS variable
|
||||
can refer a function instance, primitive constant or any other object. They are still all variables.
|
||||
|
||||
.. tip:: Do use this marker for JS functions. This will make the code clearer, and the purpose more easier to
|
||||
understand.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class JSFunctionInContext(JSVar):
|
||||
"""
|
||||
A JS function name to run in context of some other HTML DOM element.
|
||||
|
||||
Like :py:class:`JSFunction`, this too flags the string as JS function, but with a special requirement. The JS function
|
||||
needs to be invoked in the context of a HTML DOM, such that, ``this`` inside the function refers to that DOM instead of
|
||||
``window``.
|
||||
|
||||
.. tip:: JS functions of this type are wrapped inside special another JS function -- ``django_select2.runInContextHelper``.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def render_js_script(inner_code):
|
||||
"""
|
||||
This wraps ``inner_code`` string inside the following code block::
|
||||
|
||||
<script type="text/javascript">
|
||||
jQuery(function ($) {
|
||||
// inner_code here
|
||||
});
|
||||
</script>
|
||||
|
||||
:rtype: :py:obj:`unicode`
|
||||
"""
|
||||
return u"""
|
||||
<script type="text/javascript">
|
||||
jQuery(function ($) {
|
||||
%s
|
||||
});
|
||||
</script>""" % inner_code
|
||||
|
||||
|
||||
def extract_some_key_val(dct, keys):
|
||||
"""
|
||||
Gets a sub-set of a :py:obj:`dict`.
|
||||
|
|
@ -86,110 +30,6 @@ def extract_some_key_val(dct, keys):
|
|||
return edct
|
||||
|
||||
|
||||
def convert_to_js_str(val):
|
||||
val = force_unicode(val).replace('\'', '\\\'')
|
||||
return u"'%s'" % val
|
||||
|
||||
def convert_py_to_js_data(val, id_):
|
||||
"""
|
||||
Converts Python data type to JS data type.
|
||||
|
||||
Practically what this means is, convert ``False`` to ``false``, ``True`` to ``true`` and so on.
|
||||
It also takes care of the conversion of :py:class:`.JSVar`, :py:class:`.JSFunction`
|
||||
and :py:class:`.JSFunctionInContext`. It takes care of recursively converting lists and dictionaries
|
||||
too.
|
||||
|
||||
:param val: The Python data to convert.
|
||||
:type val: Any
|
||||
|
||||
:param id_: The DOM id of the element in which context :py:class:`.JSFunctionInContext` functions
|
||||
should run. (This is not needed if ``val`` contains no :py:class:`.JSFunctionInContext`)
|
||||
:type id_: :py:obj:`str`
|
||||
|
||||
:rtype: :py:obj:`unicode`
|
||||
"""
|
||||
if type(val) == types.BooleanType:
|
||||
return u'true' if val else u'false'
|
||||
elif type(val) in [types.IntType, types.LongType, types.FloatType]:
|
||||
return force_unicode(val)
|
||||
elif isinstance(val, JSFunctionInContext):
|
||||
return u"django_select2.runInContextHelper(%s, '%s')" % (val, id_)
|
||||
elif isinstance(val, JSVar):
|
||||
return val # No quotes here
|
||||
elif isinstance(val, dict):
|
||||
return convert_dict_to_js_map(val, id_)
|
||||
elif isinstance(val, list):
|
||||
return convert_to_js_arr(val, id_)
|
||||
else:
|
||||
return convert_to_js_str(val)
|
||||
|
||||
|
||||
def convert_dict_to_js_map(dct, id_):
|
||||
"""
|
||||
Converts a Python dictionary to JS map.
|
||||
|
||||
:param dct: The Python dictionary to convert.
|
||||
:type dct: :py:obj:`dict`
|
||||
|
||||
:param id_: The DOM id of the element in which context :py:class:`.JSFunctionInContext` functions
|
||||
should run. (This is not needed if ``dct`` contains no :py:class:`.JSFunctionInContext`)
|
||||
:type id_: :py:obj:`str`
|
||||
|
||||
:rtype: :py:obj:`unicode`
|
||||
"""
|
||||
out = u'{'
|
||||
is_first = True
|
||||
for name in dct:
|
||||
if not is_first:
|
||||
out += u", "
|
||||
else:
|
||||
is_first = False
|
||||
|
||||
out += u"%s: " % convert_to_js_str(name)
|
||||
out += convert_py_to_js_data(dct[name], id_)
|
||||
|
||||
return out + u'}'
|
||||
|
||||
|
||||
def convert_to_js_arr(lst, id_):
|
||||
"""
|
||||
Converts a Python list (or any iterable) to JS array.
|
||||
|
||||
:param lst: The Python iterable to convert.
|
||||
:type lst: :py:obj:`list` or Any iterable
|
||||
|
||||
:param id_: The DOM id of the element in which context :py:class:`.JSFunctionInContext` functions
|
||||
should run. (This is not needed if ``lst`` contains no :py:class:`.JSFunctionInContext`)
|
||||
:type id_: :py:obj:`str`
|
||||
|
||||
:rtype: :py:obj:`unicode`
|
||||
"""
|
||||
out = u'['
|
||||
is_first = True
|
||||
for val in lst:
|
||||
if not is_first:
|
||||
out += u", "
|
||||
else:
|
||||
is_first = False
|
||||
|
||||
out += convert_py_to_js_data(val, id_)
|
||||
|
||||
return out + u']'
|
||||
|
||||
|
||||
def convert_to_js_string_arr(lst):
|
||||
"""
|
||||
Converts a Python list (or any iterable) of strings to JS array.
|
||||
|
||||
:py:func:`convert_to_js_arr` can always be used instead of this. However, since it
|
||||
knows that it only contains strings, it cuts down on unnecessary computations.
|
||||
|
||||
:rtype: :py:obj:`unicode`
|
||||
"""
|
||||
lst = [convert_to_js_str(l) for l in lst]
|
||||
return u"[%s]" % (",".join(lst))
|
||||
|
||||
|
||||
### Auto view helper utils ###
|
||||
|
||||
from . import __ENABLE_MULTI_PROCESS_SUPPORT as ENABLE_MULTI_PROCESS_SUPPORT, \
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue