admin管理员组文章数量:1289874
This question is related to
Django: Best Way to Add Javascript to Custom Widgets
But is not the same.
The original question asks how to add supporting javascript to a custom django widget, and the answer is to use forms.Media
, but that solution does not work for me. My example is this:
The widget, when rendered in a form, creates a line which looks like (toy example) this:
<div id="some-generated-id">Text here</div>
Now, what I also want to add to the output is another line looking like this:
<script>
$('#some-generated-id').datetimepicker(some-generated-options)
</script>
The initial idea is that when the widget is rendered, both the div
and script
get rendered, but that does not work. The problem is that the structure of the html
document looks like:
-body
- my widget
- my widget's javascript
-script
-calls to static files (jQuery, datetimepicker,...)
At the time the widget's javascript code is loaded in the browser, jQuery and datetimepicker js files have not yet been loaded (they load at the end of the document).
I cannot do this using Media
, since the options and id I generate are vital to the function. What is the best way to solve this?
This question is related to
Django: Best Way to Add Javascript to Custom Widgets
But is not the same.
The original question asks how to add supporting javascript to a custom django widget, and the answer is to use forms.Media
, but that solution does not work for me. My example is this:
The widget, when rendered in a form, creates a line which looks like (toy example) this:
<div id="some-generated-id">Text here</div>
Now, what I also want to add to the output is another line looking like this:
<script>
$('#some-generated-id').datetimepicker(some-generated-options)
</script>
The initial idea is that when the widget is rendered, both the div
and script
get rendered, but that does not work. The problem is that the structure of the html
document looks like:
-body
- my widget
- my widget's javascript
-script
-calls to static files (jQuery, datetimepicker,...)
At the time the widget's javascript code is loaded in the browser, jQuery and datetimepicker js files have not yet been loaded (they load at the end of the document).
I cannot do this using Media
, since the options and id I generate are vital to the function. What is the best way to solve this?
- if code is wrapped in a ready event handler, it doesn't matter where the plugin files are being loaded within page – charlietfl Commented Aug 25, 2015 at 20:25
-
@charlietfl But the code wrapped in
$(document).ready()
does not run because jQuery is not yet loaded. I load all static files at the end of the document. – 5xum Commented Aug 25, 2015 at 20:44 - then you have to also load this code after jQuery...can't reference jQuery until it exists – charlietfl Commented Aug 25, 2015 at 20:45
- @charlietfl That's my whole point. How can I do that nicely? The thing is that the javascript code is part of the django custom widget. – 5xum Commented Aug 25, 2015 at 20:53
- I don't know what a django custom widget is so can't help much with that. Presumably it would have some sort of method to define library dependencies perhaps – charlietfl Commented Aug 25, 2015 at 21:41
4 Answers
Reset to default 5From the docs:
The order in which assets are inserted into the DOM is often important. For example, you may have a script that depends on jQuery. Therefore, bining Media objects attempts to preserve the relative order in which assets are defined in each Media class.
Consider this example:
class FooWidget(forms.TextInput):
class Media:
js = ('foo.js',)
class BarWidget(forms.TextInput):
class Media:
js = ('bar.js',)
class SomeForm(forms.Form):
field1 = forms.CharField(widget=BarWidget)
field2 = forms.CharField(widget=FooWidget)
def __init__(self, *args, **kwargs):
super(SearchForm, self).__init__(*args, **kwargs)
Now when you call form.media
, the scripts will render like this:
<script type="text/javascript" src="/static/bar.js"></script>
<script type="text/javascript" src="/static/foo.js"></script>
Why does bar.js
render before foo.js
? Because django renders them based on the order they were called on in the form, not the order that the classes were defined in. If you want to change the order in this example, simply swap the position field1
and field2
in SomeForm
.
How does this help you with jQuery? You can render your jQuery CDN script via your custom widget:
class FooWidget(forms.TextInput):
class Media:
js = ('https://code.jquery./jquery-3.4.1.js', 'foo.js',)
class BarWidget(forms.TextInput):
class Media:
js = ('https://code.jquery./jquery-3.4.1.js', 'bar.js',)
Now your form.media
will look like this:
<script src="https://code.jquery./jquery-3.4.1.js"></script>
<script type="text/javascript" src="/static/bar.js"></script>
<script type="text/javascript" src="/static/foo.js"></script>
Notice how /static/
wasn't appended to the jQuery CDN? This is because the .media
attribute checks whether the given filepaths contain http
or https
, and only appends your STATIC_URL
setting to filepaths that are relative.
Also note that duplicate file names are automatically removed, so I would say it's good practice to include a https://code.jquery./jquery-3.4.1.js
at the beginning of every widget that requires it. That way, no matter what order you render them in, the jQuery script will always appear before files that need it.
On a side note, I would be careful when including numbers in your filenames. As Django 2.2 there appears to be a bug when trying to order the scripts.
For example:
class FooWidget(forms.TextInput):
class Media:
js = ('foo1.js', 'foo2.js',)
class BarWidget(forms.TextInput):
class Media:
js = ('bar1.js', 'bar13.js',)
class SomeForm(forms.Form):
field1 = forms.CharField(widget=BarWidget)
field2 = forms.CharField(widget=FooWidget)
def __init__(self, *args, **kwargs):
super(SearchForm, self).__init__(*args, **kwargs)
Will look like:
<script type="text/javascript" src="/static/bar1.js"></script>
<script type="text/javascript" src="/static/foo1.js"></script>
<script type="text/javascript" src="/static/bar13.js"></script>
<script type="text/javascript" src="/static/foo2.js"></script>
I've tried various binations of names containing numbers, and I can't follow the logic, so I assume this is a bug.
Since the JavaScript is an inline script, you will need to use a the native DOMContentLoaded
event to wait for the jQuery to load.
<script>
window.addEventListener('DOMContentLoaded', function() {
(function($) {
$('#some-generated-id').datetimepicker(some-generated-options);
})(jQuery);
});
</script>
Alternately, if you can put your code into an external script file, you can use the defer
attribute of the script
tag.
<script src="myfile.js" defer="defer"></script>
See the MDN.
You want to execute some plugin script on added div. You need to add class to your element and associate a custom event to class. Which will execute your desire function or script.
To associate custom event to dynamically added node, please refer below code.
<!DOCTYPE html>
<html>
<head>
<title>adding javascript to custom widgets</title>
<script type="text/javascript" src="https://code.jquery./jquery-3.4.1.min.js"></script>
</head>
<body>
<section class="team">
<div class="container">
<div class="row">
<div class="container maxwidth">
<button data-tab="tab1" class="active">AA<span></span></button>
</div>
<div class="maincontent"></div>
</div>
</div>
</section>
<script>
$(function(){
$(".active").click(function(){
$(".maincontent").append("<div class='scroll'><h2>Hello</h2><div style='background:red; height:500px;'></div></div>")
$(".maincontent").find(".scroll").trigger('dynload');
});
$('.container').on('dynload', '.scroll', function(){
console.log("Append event fired");
// Additinal Script resource you want to load for plugin
$.getScript("Custom_Scrollbar.min.js") //script URL with abosolute path
.done(function() {
// Script loaded successfully calling of function
$(".scroll").mCustomScrollbar({
});
})
.fail(function() {
// Give you error when script not loaded in browser
console.log('Script file not loaded');
})
})
})
</script>
</body>
</html>
Hope this will help!
You should init JS as:
<script type="text/javascript">
$( document ).ready(function() {
var some-generated-options = {};
$('#some-generated-id').datetimepicker(some-generated-options);
});
</script>
Like you I did own custom widget that look as:
class DaysInput(TextInput):
def render(self, name, value, attrs=None):
result = super(DaysInput, self).render(name, value, attrs)
return u"""
%s
<script type="text/javascript">
$( document ).ready(function() {
$('a.id_days').click(function(e){
e.preventDefault();
$('input#id_days').val($(e.currentTarget).attr('attr-value'));
});
});
</script>
<a href="#" class="id_days" attr-value='1'>1d</a>
<a href="#" class="id_days" attr-value='2'>2d</a>
<a href="#" class="id_days" attr-value='3'>3d</a>
""" % result
class TestForm(forms.ModelForm):
days = forms.IntegerField(widget=DaysInput())
本文标签: jqueryAdding Javascript to Custom widgetsStack Overflow
版权声明:本文标题:jquery - Adding Javascript to Custom widgets - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741484618a2381342.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论