Load new pages via Ajax without refreshing the whole nav bar Django - python

I'm new to Django and I'm building my own website. I have written a base.html page that contains the main body, CSS, js, fonts, and the navbar that all the pages of my site will have. The navbar is on another HTML file, navbar.html
Now, as soon as the CSS/js/fonts/navbar included in the base.html will be loaded on every page and won't change, is there a way with Ajax to load only the actual content of the page that change seamless without seeing the whole page refresh?
For instance, the part of the page that visually changes everytime is inside a <section class="home"></section> tag

When using JQuery, it is quite simple:
<script>
function load_page(url) {
$.ajax({
url: url,
success: function (data) {
$('#nav_id').html('');
data.nav_items.forEach(item => {
$('#nav_id').append($('<div>').onclick(load_page(item.url)).text(item.title));
}
},
error: function () {
alert('Could not load data');
}
});
}
</script>
And in your url you can define this as /nav/str:slug/ which leads to a view like this:
def nav_ajax(request, slug):
if slug == 'a':
return JsonResponse({
'navitem1': {
'title': 'A',
'url': reverse('your_nav_url_name', kwargs={'slug':'a'}),
},
# other menu items
)
else:
return JsonResponse({}) # default menu items

Related

How do I dynamically change the value of text in html whenever a python variable is changed using ajax?

I'm using ajax, python, Django, HTML, and javascript for my project.
I'd like to know, if there is a p in my HTML file like,
<p class='text_box', id='tbox'>
{{ text_variable_from_python }}
</p>
<input class='input_box', id='ibox', type='text'>
And if I'd input some text into the input box, make a simple ajax request with the "text" variable and get an output from the server, which I would update on the views.py as,
def main(request):
if request.method == 'POST':
new_text = request.POST['text']
context = {'text_variable_from_python': new_text}
else:
context = {'text_variable_from_python': 'You can change me!'}
print(context)
return render(request, 'Main.html', context=context)
My question is, how do I send the data dynamically from the server to appear on client's webpage using ajax and python in between the two?
Using my method, I can only see "You can change me!" on the webpage or nothing at all. No matter how many differing prompts I give, further changes do not show on the webpage.
EDIT:
My ajax code for sending the variable.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
function update_dialogue() {
$.ajax({
type: "json",
url: "update_text",
success: function(data) {
document.getElementById("tbox").value = data['text_variable_from_python'];
}
});
}
My ajax code for recieving the variable.
<script>
function getInputValue() {
let inputVal = document.getElementById("ibox").value;
document.getElementById("ibox").value = '';
$.ajax({
type:'POST',
url: 'main',
data: {csrfmiddlewaretoken: "{{ csrf_token }}",
'text': inputVal,}
});
}
</script>

Running django view/function on button click

I have the following button: <a class="btn btn-success">Accept</a>. Like this previous stack overflow question, I want to call my view after the button is clicked, but I can not seem to get it to work.
What I have tried: Using AJAX, treating button like a form, requesting post data, but this does not seem to work.
How can I make it so when my button is clicked, I call the bellow view?
def acceptdonation(request, pk):
Donation.objects.filter(pk=pk).update(views=F('views')+1)
return HttpResponseRedirect(request.GET.get('next')))
In your template link to the view you want:
Accept
Of course you can also pass a pk or other data to the url if you need to.
If you want to post a form to a view you can use this:
function submitToView() {
var formData = new FormData();
formData.append('some_variable', 'abc');
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
abc = JSON.parse(xhr.responseText);
}
}
xhr.open('POST', '/my_view/', true);
xhr.setRequestHeader("X-CSRFToken", csrftoken);
xhr.send(formData);
}
Please consider adding your javascript with html and your urls.py

How to create button filter in django, without reloading the page?

I am getting a list containing books, I have to make filter button to categorise it, Right now I am passing argument in the link "?filter=2" with each button click. But this requires reloading the page.
In the get function
self.book_type = request.GET.get("book_type")
in the get_queryset
return qs.filter(book_filter=self.book_type)
HTML
Simply redirecting to the page with a query added to the link
containing ?book_type=" anything"
you have to had a view like this:
from django.http import JsonResponse
def get_books(request):
book_type = request.GET.get("book_type")
res = qs.filter(book_filter=self.book_type)
return JsonResponse({"data": res})
Then create url in your template like this(it creates a javascript varibale contains url to get_books):
<script> book_get_url = "{% url 'route_name_to_get_books_from_urls.py' %}";</script>
now you can use the book_get_url variable in your javascript like this:
$.ajax({
url: book_get_url,
type: "GET",
"data": {
book_type: here is your book_type as a number
},
success: function (data) {
//here you have your books in `data.data` in json fromat
}
)};

How to refresh the page when custom plugin is saved?

I have created a website using Django cms. When I save the custom plugin the template is not rendered. But it is rendered when I refresh the page.
So, how to refresh the page while saving the django cms custom plugin or any other way to render the template when the plugin is saved. But the content is saved in the admin side. I am not able to see the content in the template.
You would want to use ajax here. This is a very vague code on how you should go about it. but hope it helps.
<script type="application/javascript">
$(document).ready(function() {
$('.save-plugin-button-id').click(function (e) {
e.preventDefault();
$.ajax({
url: url_which_saves_plugin,
method: 'GET',
data:{},#add data required if any or leave blank
success: function(data){
#You might want to stylize your data here.
$("#update-content-div-id").append(JSON.stringify(data));
}
})
})
})
</script>

Django: AJAX and path params

I am trying to figure out how to communicate variables a particular js file that makes an AJAX request in Django.
Say we have an url with a path param that maps to a particular view:
url(r'^post/(?P<post_id>\d+)/$', TemplateView.as_view('post.html'))
And then the post.html includes a script that performs an AJAX request to fetch the post as JSON:
post.html
<script src="{{ STATIC_URL }}/js/post.js"></script>
<div id="post-container"></div>
This could be the js file. Let's say we do it this way because the post (as JSON) needs to be used in a js plugin to display it in a particular fancy manner.
post.js
$.ajax({
url: '/post/??post_id??',
contentType: 'application/json'
})
.done(function(post_data) {
togglePlugin(post_data);
});
My main concern is how to figure out what post_id is from the js file in order to make the appropriate call.
How are these parts usually connected in Django? The parts I am talking about are urls, path params, views and ajax.
To get urls from your template you should use {% url %} template tag, for that you should add a name to your url:
url(r'^post/(?P<post_id>\d+)/$', TemplateView.as_view('post.html'), name='my_name)
then in your can template call that url in this way {% url 'my_name' object.pk %} see this for more.
when you work with different file for your js, and you want to pass django variables, you should declare a <script> before import the js file, and there declare your variable:
<srcipt>var foo={{django_var}}</script>
<script src="{{ STATIC_URL }}/js/post.js"></script>
and then use the variable foo in the js.
You can pass a post_id variable to django template.
However if you don't want it to "hurt", put your .js code (script) in you html file, rendered by django. So you can use django template tags.
For example:
var url = "/post/{{post_id}}";
$.ajax({
type: 'POST',
url: url,
dataType: 'json',
data: {
some_field: field_data,
some_other_field: field_data
},
success: function(data) {
do_something();
},
error: function(data) {
do_somethin();
}
});

Categories