I'm trying to implement Ajax functionality into my website. This seems to be a moderately common problem, but all solutions to it I've found online have been simple, like forgetting something in the tutorial. The error message appears in the JavaScript console.
I'm trying to follow this tutorial: http://django-dajaxice.readthedocs.org/en/latest/installation.html
My actions:
I used pip install django_dajaxice for install
I copy-pasted the settings.py and urls.py code in the tutorial into my own:
from dajaxice.core import dajaxice_autodiscover, dajaxice_config
dajaxice_autodiscover()
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns = patterns('',
# AJAX
url(dajaxice_config.dajaxice_url, include('dajaxice.urls')),
)
urlpatterns += staticfiles_urlpatterns()
and
STATICFILES_FINDERS = ( ... ) # Exact copy paste from tutorial
TEMPLATE_LOADERS = ( ... ) # Exact copy paste from tutorial
TEMPLATE_CONTEXT_PROCESSORS = ( ... ) # Exact copy paste from tutorial
I included the template tags in my base.html, the actual html file inherits from that
Then Quickstart: http://django-dajaxice.readthedocs.org/en/latest/quickstart.html
I created content/ajax.py (content is my app). Code inside is simple:
from dajax.core import Dajax
from content import models
from dajaxice.decorators import dajaxice_register
#dajaxice_register
def fav(request):
dajax = Dajax()
return dajax.json()
Finally, the JS and HTML code which instantiates the AJAX:
<script type="text/javascript" src="{{ STATIC_URL }}dajaxice/dajaxice.core.js"></script>
function js_callback(data) {
Dajax.process(data);
alert(data.message);
}
<a onClick="Dajaxice.content.fav(js_callback);">Favorite</a>
You need to run collectstatic again to regenerate dajaxice.core.js.
And maybe you should remove the static files has been collected before.
Related
I am trying to learn how a small routing library for javascript apps works - page.js
So I made one very tiny app for my own learning purposes but for some reason i can't make it work properly.
The app is really as simple as it gets - one folder named test-routing with one file and one folder
in it - index.html and src; the src folder has also one file - app.js and another folder-
views, with 3 files in it - home.js, page1.js and page2.js
The html file has empty body tag and in the head tag I wrote this:
<script src="./src/app.js" type="module"></script>
In the app.js there is this:
import page from '../node_modules/page/page.mjs';
import { home } from './views/home.js';
import { page1 } from './views/page1.js';
import { page2 } from './views/page2.js';
page('/',home);
page('/first',page1);
page('/second/:id',page2);
page.start();
Each of the three files in the views folder has one line of code:
home.js
export function home(){ console.log('HOME PAGE'); }
page1.js
export function page1(){ console.log('PAGE ONE'); }
page2.js
export function page2(context, next){ console.log('PAGE TWO', context.params.id); }
Together with page.js I also installed locally live-server. I ran it and it started
working properly on port 8080.
My expectations were that when I go to http://localhost:8080 I would find
'HOME PAGE' in the console and that was indeed the case.
But when I tried with http://localhost:8080/first and http://localhost:8080/second/2,
I received in both cases 404 (Not Found) in the console instead of 'PAGE ONE' and 'PAGE TWO 2'
and it was also printed in the web page itself 'Cannot GET /first' and 'Cannot GET /second/2'
respectively.
Can anyone tell me where I went wrong, please?
Thank you very much in advance!
You may need to think about push state technique
pushState
I struggle to properly configure and set up my own JS files that contain JS functions for specific tasks.
I went through some articles and found that I need to place my custom JS to the JS packs folder -> app/javascript/packs/currency_calculations.js:
currency_calculations.js:
function convert_curr(from, to) {
...
}
function show_convertion(curr) {
...
}
...
and then I try to add this custom JS file to app/javascript/packs/application.js:
import Rails from "#rails/ujs";
import "#hotwired/turbo-rails";
import * as ActiveStorage from "#rails/activestorage";
import "channels";
import "controllers";
Rails.start();
ActiveStorage.start();
import "stylesheets/application";
// my custom JS file
import "packs/currency_calculations" // I also tried import "currency_calculations" -- same result
I also tried to add the following to the application.html.erb file:
= javascript_pack_tag 'currency_calculations'
It didn't work either.
I am still getting this error:
Uncaught Error: Cannot find module 'currency_calculations'
and when trying to call a function from a view, then:
Uncaught ReferenceError: convert_curr is not defined
What is the correct way to wire this up? I am used from Rails 5 to put all my JS functions to a js file and this file just to add to a app/assets/javascripts/application.js like this:
//= require currency_calculations
and then, in a view, I am able to simply call the wanted JS function like convert_curr("a", "b").
Thank you in advance.
There's a couple of ways to do this in Rails 6.
The first would be to create a custom directory and require it in the application.js file. In this case you could create a directory like this:
app/javascript/custom/currency_calculations.js
Then you would need to require it in your application.js file as such:
// app/javascript/packs/application.js
// ...
require("#rails/ujs").start()
require("turbolinks").start()
require("#rails/activestorage").start()
require("channels")
require("custom/currency_calculations")
That same method could also be streamlined if you, say, named your custom folder "currency" and then named the .js file index.js.
You could then just call it like this:
require("currency")
Require will look for the index file by default in the folder. But in that scenario, an index file must be present, or it will fail.
The other way to do this, in the event you don't want that JS to be compiled with everything else, is to use the javascript_pack_tag.
In that case, add the js file to your app/javascript/packs directory. Then use the pack tag helper where you need it such as:
<%= javascript_pack_tag 'currency_converter' %>
The last thing I would mention... are you sure there's no other library needed to make it work (such as JQuery)? In that case you would need to install and import that library to your application.js before you called the js file you're trying to execute.
I think the problem is you are not exporting anything in your js file. Try doing this in currency_calculations.js
const funcs = {
convert_curr() { console.log('foo') },
show_convertion() { console.log('bar') },
}
export default funcs;
And then in your code you call them with funcs.convert_curr()
Also it seems that currency_calculation shouldn't be it's own pack (you can think of a pack kinda like what application.js was in sprockets), so better be just a standalone js file outside the packs dir. (could be javascript/currency_calculations.js or javascript/utils/currency_calculations.js)
Some comments that may help you:
1 ) when you put a js file at /packs, it's going to be compiled as a standalone asset you can reference using javascript_pack_tag, so you don't need to add it to the application.js pack
you have two options depending on what you want:
move the file to javascript/src/currency_calculations.js and import it in your application.js as import 'src/currency_calculations' or import '../src/currency_calculations'
use it as a pack, remove it from application.js and use load it like javascript_pack_tag 'currency_calculations'
(you can have the file loaded both in application.js and as a standalone pack, but you'll have the code twice)
2 ) if you want to access the functions from that file in your view, you can't do it just like sprocket does. sprockets adds the content of that file in the global scope while webpacker contains the functions in the bundle context. If you want the functions to be available globally from your views, you have to make them global doing something like
global.convert_curr = function(from, to) {
...
}
(you can also use window.convert_curr = ...)
I am trying to add Custom css and js in my django admin. But CSS is working but js is not working. I have checked my code. I don't think there is any error in my code.
my admin.py
from django.contrib import admin
from .models import Blog
# Register your models here.
class BlogAdmin(admin.ModelAdmin):
class Media:
css = {
"all": ('css/main.css',)
}
JS = ('js/blog.js',)
admin.site.register(Blog, BlogAdmin)
my blog.js
console.log("This is blog.js");
let sc = document.createElement('script')
sc.setAttribute('src', 'https://cdn.tiny.cloud/1/no-api-key/tinymce/5/tinymce.min.js')
document.head.appendChild(sc);
document.addEventListener("DOMContentLoaded", function (event) {
console.log("This is blog.js");
let sc = document.createElement('script')
sc.setAttribute('src', 'https://cdn.tiny.cloud/1/no-api-key/tinymce/5/tinymce.min.js')
document.head.appendChild(sc);
sc.onload = ()=>{
tinymce.init({
selector: '#id_content'
});
}
});
In the first line of js I have written a code console.log("This is blog.js");. But while inspecting the page I didn't see "This is blog.js" in console. It means my js is not loading in Django admin.
Please look into this issue. Thanks in advance.
Is the static file management done properly?
Is there a STATIC_URL and a STATIC_ROOT defined in your
settings.py file
Also, have you properly set up the server to deliver the static files?
Finally, if you have done everything, check whether changes happen when you make changes in the original file rather than one created after running the command python3 manage.py collectstatic
Use this code, my friend, it works. Took me a long time to figure this out. I was also stuck on the same .
$( document ).ready(function() {
let sc = document.createElement('script')
sc.setAttribute('src','https://cdn.tiny.cloud/1/no-api-key/tinymce/5/tinymce.min.js');
document.head.appendChild(sc);
sc.onload = ()=>{
tinymce.init({
selector: '#id_content'
});
}
});
I've been using Python for my ML/DL projects. However, I recently started a project in JavaScript to visualize my works.
I would like to import modules (.js files) from the main.js for conciseness. (I had already checked [1], [2], [3] but couldn't get the right answer for my case.)
I have JS files like below which should be imported like this to put all the helper functions in util.js
main.js --> tree.js, polygon.js, graph.js, ... --> util.js
Currently, I am able to import the models from main.js like below. However, I am not able to import util.js module from the imported modules (tree.js, ...).
index.html
<script type="module" defer src="main.js"></script>
main.js
import Tree from './tree.js';
var tree = new Tree(...);
...
tree.js [QUESTION!]
import * as util from './util.js'; <-- ("This is not properly working")
util.helperFunc();
...
export default Tree;
util.js
function helperFunc() { ... }
export {helperFunc, ...};
1) Is the above structure violates the JavaScript / TypeScript convention? (It looks right to me as a Python user.)
2) How can I import util.js from tree.js (tree.js is imported from main.js)?
3) I saw a lot of answers which use node.js, is it not recommended to just use a simple server like below?
python3 -m http.server 8080
I get really confused about django and file locations a lot, and I'm on django 1.10. But in my static/(django-proj-name)/js/ folder (just showing the way I have my main.js file and I need to call a python script, in conjunction with the jquery tokeninput plugin. Lets call the script keywords.py
This script is going to need to call all instances of a model, Keyword, so I need to be able to import from my models file.
Im' a bit inexperienced with django, but from reviewing some of the projects I've seen over the summer I was startinng to believe that including the line, from (django-proj-name).models import * was the main way to import from models. This at least works for all of the files that I have in my /management/commands/ folder.
But i tried putting keywords.py in my static folder just because I know at the very least I can use the {% static %} template tag to find the file in html. I ran the file without manage.
Traceback (most recent call last):
File "../../management/commands/import_statements.py", line 5, in <module>
from gtr_site.models import *
ImportError: No module named gtr_site.models
Though I have the same importation line, again, in /management/commands/. And that doesn't cause any problems.
So I didn't put the file in the "correct" file location... I didn't put keywords.py in a place where
I know how to import from my models.py file from the keywords.py script's location
My javascript file can find it and run it without crashing. This script needs to be able to successfully import from models.
so where am I supposed to put this script, or how can I specify a location for it?
Let's say you have a js library that expects data in the following format:
{"results": [
{"name": "Foo", "number": 1},
...,
{"name": "Bar", "number": 999}
]}
You started an application called myapi:
$ django manage.py startapp myapi
And suppose you have a Model like this at myapi/models.py:
from django.db import models
class Foo(models.Model):
name = models.CharField(max_lenght=100),
number = models.IntegerField()
In myapp/views.py define the following view:
from django.http import JsonResponse
from django.views import View
from .models import Foo
class FooList(View):
def get(self, request, *args, **kwargs):
qs = list(Foo.objects.values('name', 'number').all())
data = {"results": qs}
return JsonResponse(data)
Then map this view to some url. For the sake of simplicity let's just add this to your main urls.py file:
url('api/v1/foo/$', FooList.as_view(), name='foo-list'),
Now you should be able to reach it from the browser. The example below uses jQuery:
$.getJSON('http://yourdomain.com/api/v1/foo/',
function(data, textStatus, jqXHR) {
console.log(data);
}
)
That is it. I did this from memory so you probably will find a few errors or missing imports - but this should put you on the right track.