I've been stuck on this issue for a few weeks as I'm not very familiar with how to get the ajax set up. I'm working on a Django app which is basically one page that has a Dropdown menu. I would like to get whatever the user selects from the Dropdown menu and pass that data into my views.py so I can use that information to display a graph. Right now the graph part is working (I can pass in hard coded data into it and it will generate the graph) and my dropdown is working as well. However, I don't know how to get data from the drop down into my views.py. Here is how it looks.
Display.html
{% extends "RecordEvent/nav.html" %}
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
</head>
{% block content %}
<div class="row">
<div class="padded">
<div class="download-header">
<h3>Logs</h3>
<div class="row inline download-header">
<div class="col-lg-6">
<div class="dropdown padding col-lg-6">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<span id="dropdownTitle" class="">Measurable</span>
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
{% include 'RecordEvent/includes/EntryDropdown.html' %}
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div class='padded'>
<div class='col-sm-12' url-endpoint='{% url "api-data" %}'>
<h1>Graph Data</h1>
<canvas id="myChart" width="400" height="400"></canvas>
</div>
</div>
<script>
{% block jquery %}
var endpoint = 'display/api/chart/data/'
var defaultData = []
var defaultLabels = [];
$.ajax({
method: "GET",
url: endpoint,
success: function(data){
defaultLabels = data.labels
defaultData = data.default
console.log(data)
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: defaultLabels,
datasets: [{
label: '# Measurable',
data: defaultData,
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
},
error: function(error_data){
console.log("error")
console.log(error_data)
}
})
{% endblock %}
</script>
{% endblock %}
The first div creates the Dropdown menu. Everything below is to get the graph setup.
views.py
#login_required
def DisplayView(request):
return render(request,'DisplayData/Display.html')
class ChartData(APIView):
authentication_classes = []
permission_classes = []
def get(self, request, format=None):
all_entries = models.Entries.objects.all().filter(parent=2) #change to input from drop down
all_id = models.Entries.objects.all().values_list('id', flat=True)
all_measurables = models.Measurables.objects.all().filter(user_id=1) #change to current user
all_times = [m.timestamp for m in all_entries]
all_data = []
for m in all_entries:
data = m.data
json_data = json.loads(data)
value = json_data['value']
all_data.append(value)
data = {
"labels": all_times,
"default": all_data,
#"default": all_parent,
}
return Response(data)
#login_required
def LogDisplay(request):
measurables=[entry for entry in models.Measurables.objects.all().filter(user_id=request.user.id)]
return render(request, 'DisplayData/Logs.html',{'dropdown':measurables})
I need to get the value from the drop down into the where the comment says get value from drop down.
How can I do it?
to post via form
<form method='post' action = 'api url'>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
{% include 'RecordEvent/includes/EntryDropdown.html' %}
</ul>
</form>
amd in views.py access with
request.post[<name>]
to post via ajax
$('ul li').click(function(){
$.ajax({
url: <api url>,
type:'post',
data:{<name>:$(this).html()},
})
Related
I am trying to get the specific pk of the selected object when the user accepts a delivery. My problem is that I'm getting only the first object's pk in the list every time. I want to get the pk of the selected object.
views:
#login_required(login_url="/signin/?next=/driver/")
def deliveries_available_page(request):
deliveries = Delivery.objects.filter(
status_of_delivery__in=[Delivery.DELIVERY_POSTED]
)
#When driver accept delivery then status of delivery changes to delivering
if request.method == 'POST':
delivery = get_object_or_404(Delivery, pk=request.POST.get('receipt_number'))
if delivery:
delivery.status_of_delivery = Delivery.DELIVERY_DELIVERING
delivery.driver = request.user.driver
messages.success(request, 'Delivery Accepted')
delivery.save()
return redirect(reverse('driver:deliveries_available'))
return render(request, 'driver/deliveries_available.html', {
"GOOGLE_API_MAP": settings.GOOGLE_API_MAP,
"del": deliveries
})
HTML:
<div class="d-flex flex-column h-100" style="padding-bottom: 50px">
<div id="map"></div>
{% if del %}
{% for d in del %}
<div class="card" id="delivery-popup">
<div class="card-body p-2">
<div class="details">
<div class="p-2">
<strong id="address"></strong>
<div>
<strong id="show-info"></strong>
</div>
<div>
<strong id="show-distance"></strong>
<strong id="show-duration"></strong>
</div>
<div>
<strong id="show-price"></strong>
<strong id="show-id"></strong>
</div>
<div>
<form method="POST">
{% csrf_token %}
<button type="submit" class="btn btn-primary" name="accept">Accept</button>
<input type="hidden" value="{{ d.receipt_number }}" name="receipt_number">
</form>
</div>
{% if messages %}
{% for m in messages %}
{% if m.tags %}
<script>alert("{{ m }}")</script>
{% endif %}
{% endfor %}
{% endif %}
</div>
</div>
</div>
</div>
{% endfor %}
{% endif %}
I need the specific pk so when user accept delivery, then the right delivery is accepted and removed from the map. Any help would be appreciated. Thanks.
I can get the specific pk by creating new url and passing it in the url but i want user to accept delivery on the map page.
script added to html
<script>
//Google map and using api to display deliveries on map and click event to show delivery details
function initMap() {
const map = new google.maps.Map(document.getElementById("map"), {
center: { lat: 53.350140, lng: -6.266155 },
zoom: 13,
});
fetch("{% url 'driver:available_deliveries' %}").then(response => response.json()).then(json => {
console.log(json);
for (let d = 0; d < json.deliveries.length; d++) {
const delivery = json.deliveries[d];
const position = { lat: delivery.delivery_address_latitude, lng: delivery.delivery_address_longitude };
const show_on_map = new google.maps.Marker
({
position,
map,
});
new google.maps.InfoWindow({
content: "<small><strong>" + delivery.address + "<medium><br>€" + delivery.price
}).open(map, show_on_map);
show_on_map.addListener("click", () => {
PopUpDelivery(delivery);
})
}
})
}
function PopUpDelivery(delivery) {
$("#delivery-popup").css("display", "block");
$("#address").html(delivery.address);
$("#show-distance").html(delivery.distance + " Km");
$("#show-duration").html(delivery.duration + " Mins");
$("#show-price").html("€ " + delivery.price);
$("#show-info").html("Info : " + delivery.information);
$("#show-id").html("Pk : " + delivery.receipt_number)
}
Keep id unique in html document
The id in an HTML document must be unique within each page source:
The id global attribute defines an identifier (ID) which must be
unique in the whole document. Its purpose is to identify the element
when linking (using a fragment identifier), scripting, or styling
(with CSS).
What I think may have occurred is that since you have many cards in each page, all with the same id's, you were just getting the first one. While your solution works, I think it might be better to give each id a unique value, which you can do simply by appending the receipt_number, or any unique field to the id names. With this, you may not need the function getTag. Here is what I mean:
html
<div class="d-flex flex-column h-100" style="padding-bottom: 50px">
<div id="map"></div>
{% if del %}
{% for d in del %}
<div class="card" id="delivery-popup{{ d.receipt_number }}">
<div class="card-body p-2">
<div class="details">
<div class="p-2">
<strong id="address{{ d.receipt_number }}"></strong>
<div>
<strong id="show-info{{ d.receipt_number }}"></strong>
</div>
<div>
<strong id="show-distance{{ d.receipt_number }}"></strong>
<strong id="show-duration{{ d.receipt_number }}"></strong>
</div>
<div>
<strong id="show-price{{ d.receipt_number }}"></strong>
<strong id="show-id{{ d.receipt_number }}"></strong>
</div>
<div>
<form method="POST">
{% csrf_token %}
<button type="submit" class="btn btn-primary" name="accept">Accept</button>
<input type="hidden" value="{{ d.receipt_number }}" name="receipt_number">
</form>
</div>
{% if messages %}
{% for m in messages %}
{% if m.tags %}
<script>alert("{{ m }}")</script>
{% endif %}
{% endfor %}
{% endif %}
</div>
</div>
</div>
</div>
{% endfor %}
{% endif %}
script
<script>
//Google map and using api to display deliveries on map and click event to show delivery details
function initMap() {
const map = new google.maps.Map(document.getElementById("map"), {
center: { lat: 53.350140, lng: -6.266155 },
zoom: 13,
});
fetch("{% url 'driver:available_deliveries' %}").then(response => response.json()).then(json => {
console.log(json);
for (let d = 0; d < json.deliveries.length; d++) {
const delivery = json.deliveries[d];
const position = { lat: delivery.delivery_address_latitude, lng: delivery.delivery_address_longitude };
const show_on_map = new google.maps.Marker
({
position,
map,
});
new google.maps.InfoWindow({
content: "<small><strong>" + delivery.address + "<medium><br>€" + delivery.price
}).open(map, show_on_map);
show_on_map.addListener("click", () => {
PopUpDelivery(delivery);
})
}
})
}
function PopUpDelivery(delivery) {
let pk = delivery.receipt_number
$("#delivery-popup"+pk).css("display", "block");
$("#address"+pk).html(delivery.address);
$("#show-distance"+pk).html(delivery.distance + " Km");
$("#show-duration"+pk).html(delivery.duration + " Mins");
$("#show-price"+pk).html("€ " + delivery.price);
$("#show-info"+pk).html("Info : " + delivery.information);
$("#show-id"+pk).html("Pk : " + delivery.receipt_number)
}
Solved:
Got the specific pk, when i click on a delivery it gets the right pk, code below if anyone has the same problem:
script
function PopUpDelivery(delivery) {
$("#delivery-popup").css("display", "block");
$("#address").html(delivery.address);
$("#show-distance").html(delivery.distance + " Km");
$("#show-duration").html(delivery.duration + " Mins");
$("#show-price").html("€ " + delivery.price);
$("#show-info").html("Info : " + delivery.information);
$("#show-id").html("Pk : " + delivery.receipt_number);
var input_tag = getTag('getpk');
input_tag.value = delivery.receipt_number;
}
function getTag(id){
return document.getElementById(id);
}
html
<button type="submit" class="btn btn-primary" name="accept">Accept</button>
<input type="hidden" id="getpk" value="" name="receipt_number">
I asked this question previously and didn't get any help/solution. So I'm asking again.
I'm trying to make sure that even if the user refresh the page or goes back and comes back to that page, the radio button is still the same as what the user selects.
N.B: the value of the radio button is saved in sessions
<div class="col-md-1 ps-md-1">
<input class="align-middle h-100" type="radio" name="deliveryOption" id="{{option.id}}"
value="{{option.id}}">
</div>
Ajax
$('input[type=radio][name=deliveryOption]').on('change', function(e) {
e.preventDefault();
$.ajax({
type: "POST",
url: '{% url "checkout:cart_update_delivery" %}',
data: {
deliveryoption: $(this).val(),
csrfmiddlewaretoken: "{{csrf_token}}",
action: "post",
},
success: function (json) {
document.getElementById("total").innerHTML = json.total;
document.getElementById("delivery_price").innerHTML = json.delivery_price;
},
error: function (xhr, errmsg, err) {},
});
});
my view
def cart_update_delivery(request):
cart = Cart(request)
if request.POST.get("action") == "post":
delivery_option = int(request.POST.get("deliveryoption"))
delivery_type = DeliveryOptions.objects.get(id=delivery_option)
updated_total_price = cart.cart_update_delivery(delivery_type.delivery_price)
session = request.session
if "purchase" not in request.session:
session["purchase"] = {
"delivery_id": delivery_type.id,
}
else:
session["purchase"]["delivery_id"] = delivery_type.id
session.modified = True
response = JsonResponse({"total": updated_total_price, "delivery_price": delivery_type.delivery_price})
return response
when I added a django templating if statement, it kinda work but the radio button is always remember on the last radio button when refreshed.
{% for option in deliveryoptions %}
<input class="align-middle h-100" type="radio" {% if deliveryoption == %} checked=1 {% elif delivery_option == 2 %} checked="checked"{% endif %} autocomplete='on' name="deliveryOption" id="{{option.id}}"
value="{{option.id}}">
</div>
</div>
</div>
{% endfor %}
</div>
I am trying to build a dependant dropdown in a django form, but it is not working. I have followed videos and tutorials, but got no luck.
I would like to select a brand of a car (make) and then a model of a car. The model depends on the car's brand, of course.
I have followed this tutorial https://python.plainenglish.io/python-and-django-create-a-dependent-chained-dropdown-select-list-b2c796f5a11
Status: The "Make" dropdown works fine. The "Model" dropdown is never showing anything.
It just does not work, but no error is shown... :S
models.py
from django.db import models
from django import forms
class Vehicle(models.Model):
make = forms.CharField(max_length=30)
model = forms.CharField(max_length=30)
...omitted
forms.py
from django import forms
from .models import Vehicle
import json
def readJson(filename):
with open(filename, 'r') as fp:
return json.load(fp)
def get_make():
""" GET MAKE SELECTION """
filepath = '/Users/alvarolozanoalonso/desktop/project_tfm/tfm/JSON/make_model_A.json'
all_data = readJson(filepath)
all_makes = [('-----', '---Select a Make---')]
for x in all_data:
if (x['make_name'], x['make_name']) in all_makes:
continue
else:
y = (x['make_name'], x['make_name'])
all_makes.append(y)
# here I have also tried "all_makes.append(x['make_name'])
return all_makes
class VehicleForm(forms.ModelForm):
make = forms.ChoiceField(
choices = get_make(),
required = False,
label='Make:',
widget=forms.Select(attrs={'class': 'form-control', 'id': 'id_make'}),
)
...omitted
class Meta:
model = Vehicle
fields = ['make', 'is_new', 'body_type', 'fuel_type', 'exterior_color', 'transmission', 'wheel_system', 'engine_type',
'horsepower', 'engine_displacement', 'mileage', 'transmission_display', 'year', 'fuel_tank_volume',
'city_fuel_economy', 'highway_fuel_economy', 'maximum_seating']
model.HTML
{% block javascript %}
<script>
$("#id_make").change(function () {
var makeId = $(this).val();
$.ajax({
type: "POST",
url: "{% url 'get-model' %}",
data: {
'csrfmiddlewaretoken': '{{ csrf_token }}',
'make': makeId,
},
success: function (data) {
console.log(data.models);
let html_data = '<option value="">-------</option>';
data.models.forEach(function (data) {
html_data += `<option value="${data}">${data}</option>`
});
$("#id_model").html(html_data);
}
});
});
</script>
{% endblock javascript %}
<form class="" action="" method="post">
{% csrf_token %}
{% for error in errors %}
<div class="alert alert-danger mb-4" role="alert">
<strong>{{ error }}</strong>
</div>
{% endfor %}
<div class="form-row">
<div class="form-group col-md-6">
<label>Status:</label>
{{ form.make }}
</div>
<div class="form-group col-lg-6">
<label >Model:</label>
<select id="id_model" class="form-control" name="state">
<option value="-----">Select Model</option>
</select>
</div>
...omitted
<div class="form-group col-md-6">
<button type="submit" class="btn btn-primary">Calculate</button>
</div>
</form>
views.py
def model(request):
context = {}
if request.method == 'GET':
form = VehicleForm()
context['form'] = form
return render(request, 'model.html', context)
if request.method == 'POST':
form = VehicleForm(request.POST)
if form.is_valid():
return render(request, 'model.html', context)
def getModel(request):
make = request.POST.get('make')
models = return_model_by_make(make)
return JsonResponse({'models': models})
Your change handler for id_make is attached before the select is created in the DOM, so your event handler does not fire.
You can use event delegation to set up an event handler before an element is created
$(document).on('change', "#id_make", function () {
var makeId = $(this).val();
$.ajax({
type: "POST",
url: "{% url 'get-model' %}",
data: {
'csrfmiddlewaretoken': '{{ csrf_token }}',
'make': makeId,
},
success: function (data) {
console.log(data.models);
let html_data = '<option value="">-------</option>';
data.models.forEach(function (data) {
html_data += `<option value="${data}">${data}</option>`
});
$("#id_model").html(html_data);
}
});
});
I'm working on a project in which I need to implement private chat for user, so one user can communicate with another user privately, for that purpose I'm using django-private-chat but I'm confused in how to implement this in my application?
Here's what I have done so far:
1): Install websockets
2): Install django-private-chat
3): Add it in INSTALLED_APPS
4): Then add in main urls.py like:
From project.urls.py:
path('', include('jobexpertapp.urls')),
url(r'', include('django_private_chat.urls')),
From myapp.urls.py:
re_path(r'^users/$', views.UserListView.as_view(), name='user_list'),
5): Add a view for that:
class UserListView(LoginRequiredMixin, generic.ListView):
model = get_user_model()
# These next two lines tell the view to index lookups by username
slug_field = 'username'
slug_url_kwarg = 'username'
template_name = 'jobexpertapp/users.html'
login_url = '/login'
6): Then add two templates: (a): users.html (b): dialogs.html
From users.html:
{% extends "base.html" %}
{% block content %}
<h3>Here you can see users avaliable for chat, excluding yourself (chat with yourself is possible thought):</h3>
<div class="container">
{% for user in object_list %}
{% if user != request.user %}
<p>{{ user.get_full_name }}</p>
<a href="{% url 'dialogs_detail' user.username %}" class="btn btn-primary">
Chat with {{ user.username }}
</a>
{% endif %}
{% endfor %}
</div>
{% endblock %}
From dialogs.html:
{# This template is here just to demonstrate how to customize the default one. #}
{# It has none to very few changes #}
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% block css %}
{% endblock css %}
{% block content %}
<input id="owner_username" type="hidden" value="{{ request.user.username }}">
<div class="container">
<div class="col-md-3">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{% trans "Chat list" %}</h3>
</div>
<div class="panel-body">
<div class="user-list-div">
<ul style="list-style-type: none;">
{% for dialog in object_list %}
<li>
{% if dialog.owner == request.user %}
{% with dialog.opponent.username as username %}
<a href="{% url 'dialogs_detail' username %}" id="user-{{ username }}"
class="btn btn-danger">{% trans "Chat with" %} {{ username }}</a>
{% endwith %}
{% else %}
{% with dialog.owner.username as username %}
<a href="{% url 'dialogs_detail' username %}" id="user-{{ username }}"
class="btn btn-danger">{% trans "Chat with" %} {{ username }}</a>
{% endwith %}
{% endif %}
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
</div>
<div class="col-md-9">
<div class="well well-lg">
<div class="row">
<div class="col-md-3 col-md-offset-9">
<span class="pull-right" hidden id="typing-text">
<strong>{{ opponent_username }} {% trans "is typing..." %}</strong>
</span>
</div>
<p>
{{ opponent_username }}
</p>
<p class="text-success" id="online-status" style="display: none">{% trans "Online" %}</p>
<p class="text-danger" id="offline-status" style="display: none">{% trans "Offline" %}</p>
<div class="messages-container">
<div id="messages" class="messages">
{% for msg in active_dialog.messages.all %}
<div class="row {% if msg.read %}msg-read{% else %}msg-unread{% endif %} {% if msg.sender != request.user %}opponent{% endif %}"
data-id="{{ msg.id }}">
<p class="{% if msg.sender == request.user %}pull-left{% else %}pull-right{% endif %}">
<span class="username">{{ msg.sender.username }}:</span>
{{ msg.text }}
<span class="timestamp">– <span
data-livestamp="{{ msg.get_formatted_create_datetime }}">{{ msg.get_formatted_create_datetime }}</span></span>
</p>
</div>
{% endfor %}
</div>
</div>
</div>
<div class="row">
<div class="add-message">
<div class="form-group">
<textarea id="chat-message" class="form-control message"
placeholder="{% trans 'Write a message' %}"></textarea>
</div>
<div class="form-group clearfix">
<input id="btn-send-message" type="submit" class="btn btn-primary pull-right send-message"
style="margin-left: 10px;" value="{% trans 'Send' %}"/>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/scrollmonitor/1.2.0/scrollMonitor.js"
integrity="sha256-BseZlDlA+yL4qu+Voi82iFa5aaifralQEXIjOjaXgeo=" crossorigin="anonymous"></script>
<script>
var base_ws_server_path = "{{ ws_server_path }}";
$(document).ready(function () {
var websocket = null;
var monitor = null;
function initReadMessageHandler(containerMonitor, elem) {
var id = $(elem).data('id');
var elementWatcher = containerMonitor.create(elem);
elementWatcher.enterViewport(function () {
var opponent_username = getOpponnentUsername();
var packet = JSON.stringify({
type: 'read_message',
session_key: '{{ request.session.session_key }}',
username: opponent_username,
message_id: id
});
$(elem).removeClass('msg-unread').addClass('msg-read');
websocket.send(packet);
});
}
function initScrollMonitor() {
var containerElement = $("#messages");
var containerMonitor = scrollMonitor.createContainer(containerElement);
$('.msg-unread').each(function (i, elem) {
if ($(elem).hasClass('opponent')){
initReadMessageHandler(containerMonitor, elem);
}
});
return containerMonitor
}
function getOpponnentUsername() {
return "{{ opponent_username }}";
}
// TODO: Use for adding new dialog
function addNewUser(packet) {
$('#user-list').html('');
packet.value.forEach(function (userInfo) {
if (userInfo.username == getUsername()) return;
var tmpl = Handlebars.compile($('#user-list-item-template').html());
$('#user-list').append(tmpl(userInfo))
});
}
function addNewMessage(packet) {
var msg_class = "";
if (packet['sender_name'] == $("#owner_username").val()) {
msg_class = "pull-left";
} else {
msg_class = "pull-right";
}
var msgElem =
$('<div class="row msg-unread" data-id="' + packet.message_id + '">' +
'<p class="' + msg_class + '">' +
'<span class="username">' + packet['sender_name'] + ': </span>' +
packet['message'] +
' <span class="timestamp">– <span data-livestamp="' + packet['created'] + '"> ' + packet['created'] + '</span></span> ' +
'</p> ' +
'</div>');
$('#messages').append(msgElem);
scrollToLastMessage()
}
function scrollToLastMessage() {
var $msgs = $('#messages');
$msgs.animate({"scrollTop": $msgs.prop('scrollHeight')})
}
function generateMessage(context) {
var tmpl = Handlebars.compile($('#chat-message-template').html());
return tmpl({msg: context})
}
function setUserOnlineOffline(username, online) {
var elem = $("#user-" + username);
if (online) {
elem.attr("class", "btn btn-success");
} else {
elem.attr("class", "btn btn-danger");
}
}
function gone_online() {
$("#offline-status").hide();
$("#online-status").show();
}
function gone_offline() {
$("#online-status").hide();
$("#offline-status").show();
}
function flash_user_button(username) {
var btn = $("#user-" + username);
btn.fadeTo(700, 0.1, function () {
$(this).fadeTo(800, 1.0);
});
}
function setupChatWebSocket() {
var opponent_username = getOpponnentUsername();
websocket = new WebSocket(base_ws_server_path + '{{ request.session.session_key }}/' + opponent_username);
websocket.onopen = function (event) {
var opponent_username = getOpponnentUsername();
var onOnlineCheckPacket = JSON.stringify({
type: "check-online",
session_key: '{{ request.session.session_key }}',
username: opponent_username
{# Sending username because the user needs to know if his opponent is online #}
});
var onConnectPacket = JSON.stringify({
type: "online",
session_key: '{{ request.session.session_key }}'
});
console.log('connected, sending:', onConnectPacket);
websocket.send(onConnectPacket);
console.log('checking online opponents with:', onOnlineCheckPacket);
websocket.send(onOnlineCheckPacket);
monitor = initScrollMonitor();
};
window.onbeforeunload = function () {
var onClosePacket = JSON.stringify({
type: "offline",
session_key: '{{ request.session.session_key }}',
username: opponent_username,
{# Sending username because to let opponnent know that the user went offline #}
});
console.log('unloading, sending:', onClosePacket);
websocket.send(onClosePacket);
websocket.close();
};
websocket.onmessage = function (event) {
var packet;
try {
packet = JSON.parse(event.data);
console.log(packet)
} catch (e) {
console.log(e);
}
switch (packet.type) {
case "new-dialog":
// TODO: add new dialog to dialog_list
break;
case "user-not-found":
// TODO: dispay some kind of an error that the user is not found
break;
case "gone-online":
if (packet.usernames.indexOf(opponent_username) != -1) {
gone_online();
} else {
gone_offline();
}
for (var i = 0; i < packet.usernames.length; ++i) {
setUserOnlineOffline(packet.usernames[i], true);
}
break;
case "gone-offline":
if (packet.username == opponent_username) {
gone_offline();
}
setUserOnlineOffline(packet.username, false);
break;
case "new-message":
var username = packet['sender_name'];
if (username == opponent_username || username == $("#owner_username").val()){
addNewMessage(packet);
if (username == opponent_username) {
initReadMessageHandler(monitor, $("div[data-id='" + packet['message_id'] + "']"));
}
} else {
if ($("#user-"+username).length == 0){
var new_button = $(''+
'<a href="/'+ username + '"' +
'id="user-'+username+'" class="btn btn-danger">{% trans "Chat with" %} '+username+'</a>');
$("#user-list-div").find("ul").append()
}
flash_user_button(username);
}
break;
case "opponent-typing":
var typing_elem = $('#typing-text');
if (!typing_elem.is(":visible")) {
typing_elem.fadeIn(500);
} else {
typing_elem.stop(true);
typing_elem.fadeIn(0);
}
typing_elem.fadeOut(3000);
break;
case "opponent-read-message":
if (packet['username'] == opponent_username) {
$("div[data-id='" + packet['message_id'] + "']").removeClass('msg-unread').addClass('msg-read');
}
break;
default:
console.log('error: ', event)
}
}
}
function sendMessage(message) {
var opponent_username = getOpponnentUsername();
var newMessagePacket = JSON.stringify({
type: 'new-message',
session_key: '{{ request.session.session_key }}',
username: opponent_username,
message: message
});
websocket.send(newMessagePacket)
}
$('#chat-message').keypress(function (e) {
if (e.which == 13 && this.value) {
sendMessage(this.value);
this.value = "";
return false
} else {
var opponent_username = getOpponnentUsername();
var packet = JSON.stringify({
type: 'is-typing',
session_key: '{{ request.session.session_key }}',
username: opponent_username,
typing: true
});
websocket.send(packet);
}
});
$('#btn-send-message').click(function (e) {
var $chatInput = $('#chat-message');
var msg = $chatInput.val();
if (!msg) return;
sendMessage($chatInput.val());
$chatInput.val('')
});
setupChatWebSocket();
scrollToLastMessage();
});
</script>
{% endblock %}
You are making it too complex,you don't need to write any view or anything.After You have installed django-private-chat using pip install django-private-chat and added it to installed apps.
Add following lines to your settings .py file
CHAT_WS_SERVER_HOST = 'localhost'
CHAT_WS_SERVER_PORT = 5002
CHAT_WS_SERVER_PROTOCOL = 'ws'
Next thing you need to do is all its url to your main project's urls.py.
It should look something like this , URLS.py
from django_private_chat import urls as django_private_chat_urls
urlpatterns = [
#other urls of ur project
path('', include('django_private_chat.urls')),
]
Next step is front-end part,hope u have an static directory of your project,if not create an static folder in path same as of your manage.py file of your project.
Now copy contents of static folder of django-private-chat from enviroment.It's path would be your_venv_name/lib/pythonX.X/site-packages/django_private_chat/static.Copy all the contents of this static folder to your project's static folder.It should look somehing like this your_project/static/django_private_chat/static
Next thing is your dailog.html page. If you don't have templates folder in your project already created,create one.Then In that templates folder make an 'base.html' file, contents of your base.html file would be something like this:
base.html
<html><head></head><body>
{% block content %}
{% endblock %}
{%block js%}
{%endblock%}
{% block extra_js %}{% endblock extra_js %}
</body>
Next in your templates folder,create dailogs.html file,an copy whatever you have written in dailogs.html in your question,just copy this inside the {%block css%}
{{ block.super }}
<link href="{% static 'django_private_chat/css/django_private_chat.css' %}" rel="stylesheet" type="text/css" media="all">
Now in One terminal window runserver and in another terminal windows from same directory of where your runserver is running. Execute
python manage.py run_chat_server
go to browser and login into your django project.then go to http://127.0.0.1:8000/dialogs/
you'll find the users to chat with.
Sorry before that i have bad english. So i want to send data from django form with ajax and javascript, but the problem is i have add button to add more field, every time i add field the field id increase
i already tried with single form id, its success, but with multiple dynamic id it fail
My html :
{{ ipform.management_form }}
{% for form in ipform %}
<div class="form-group">
<div class="row form-row spacer">
<div class="col-2">
<label>{{form.ipaddr.label}}</label>
</div>
<div class="col-4">
<div class="input-group">
{{form.ipaddr}}
<div class="input-group-append">
<button class="btn btn-success add-form-row">+</button>
</div>
<div class="col-2">
<p id="cekip"></p>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
Javascript:
function updateElementIndex(el, prefix, ndx) {
var id_regex = new RegExp('(' + prefix + '-\\d+)');
var replacement = prefix + '-' + ndx;
if ($(el).attr("for")) $(el).attr("for",
$(el).attr("for").replace(id_regex, replacement));
if (el.id) el.id = el.id.replace(id_regex, replacement);
if (el.name) el.name = el.name.replace(id_regex, replacement);
}
function cloneMore(selector, prefix) {
var newElement = $(selector).clone(true);
var total = $('#id_' + prefix + '-TOTAL_FORMS').val();
newElement.find(':input').each(function() {
var name = $(this).attr('name')
if(name) {
name = name.replace('-' + (total-1) + '-', '-' + total + '-');
var id = 'id_' + name;
$(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');
}
});
total++;
$('#id_' + prefix + '-TOTAL_FORMS').val(total);
$(selector).after(newElement);
var conditionRow = $('.form-row:not(:last)');
conditionRow.find('.btn.add-form-row')
.removeClass('btn-success').addClass('btn-danger')
.removeClass('add-form-row').addClass('remove-form-row')
.html('-');
return false;
}
function deleteForm(prefix, btn) {
var total = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
if (total > 1){
btn.closest('.form-row').remove();
var forms = $('.form-row');
$('#id_' + prefix + '-TOTAL_FORMS').val(forms.length);
for (var i=0, formCount=forms.length; i<formCount; i++) {
$(forms.get(i)).find(':input').each(function() {
updateElementIndex(this, prefix, i);
});
}
}
return false;
}
$(document).on('click', '.add-form-row', function(e){
e.preventDefault();
cloneMore('.form-row:last', 'form');
return false;
});
$(document).on('click', '.remove-form-row', function(e){
e.preventDefault();
deleteForm('form', $(this));
return false;
});
another js :
$(document).ready(function() {
$('input#id_form-0-ipaddr').keypress(function() {
var _this = $(this);
setTimeout(function() {
//ajax ..
}, 3000);
});
});
the field and field id like this
[ipaddress input field][+] => input id = form-0-ipaddr
[ipaddress input field][+] => input id = form-1-ipaddr
[ipaddress input field][+] => input id = form-2-ipaddr
[+] = add button, every time add form, the input id increase
its just send the first field
As i dont have information on your project, i want to give you an example that you can use.
Create a forms.py if you dont have one
from django.forms import formset_factory
from django import forms
class IPForm(forms.Form):
ipaddr= forms.CharField(
widget=forms.TextInput(attrs={
'class': 'form-control',
})
)
IPFormset = formset_factory(IPForm, extra=1)
Extra could be 100- based on the number of forms you want on your browser(view)
Then in your views.py, import IPFormset
from .forms import IPFormset
from .models import YourModel
So use IPFormset in place of your normal formclass you have here before. and return it as ipform
And in your template(html page)
<form class="form-horizontal" method="POST" action="">
{% csrf_token %}
{% for form in ipform %}
<div class="form-group">
<div class="row form-row spacer">
<div class="col-2">
<label>{{form.ipaddr.label}}</label>
</div>
<div class="col-4">
<div class="input-group">
{{form.ipaddr}}
<div class="input-group-append">
<button class="btn btn-success add-form-row">+</button>
</div>
<div class="col-2">
<p id="cekip"></p>
</div>
</div>
</div>
</div>
</div>
{%endfor%}
And you could look into django formset
https://docs.djangoproject.com/en/2.1/topics/forms/formsets/
for better explanation