How to hook up Google Maps to GeoDjango? - django

GeoDjango docs don't tell anything about hooking up GMap and I don't understand what's going on.
models.py:
from django.contrib.gis.db import models
class Location(models.Model):
name = models.CharField(max_length=100)
coords = models.PointField(srid=4326, blank=True, null=True)
forms.py:
from django.contrib.gis import forms
class LocationForm(forms.ModelForm):
class Meta:
model = Location
fields = ['coords', 'name']
In the add_location.html such code was automatically generated for 'coords':
<div id="div_id_coords" class="form-group">
<div class="controls ">
<div id="id_coords_div_map">
<div id="id_coords_map"></div>
<span class="clear_features">
Delete
</span>
<textarea id="id_coords" class="vSerializedField required" cols="150" rows="10" name="coords"></textarea>
<script type="text/javascript">
var map_options = {};
var options = {
geom_name: 'Point',
id: 'id_coords',
map_id: 'id_coords_map',
map_options: map_options,
map_srid: 4326,
name: 'coords'
};
var geodjango_coords = new MapWidget(options);
</script>
</div>
</div>
</div>
In my js file I am trying to get coordinates of marker into my model:
var mapOptions = {...};
map = new google.maps.Map($('#id_coords_map')[0], mapOptions);
map.addListener('click', function(e){
placeMarker(e.latLng, map);
var position = marker.getPosition();
});
var marker;
function placeMarker(latLng, map) {
marker = new google.maps.Marker({...});
return marker
}
But it doesn't work. It even doesn't come to getting coordinates because I get the error in the chrome console (when I push button Add location at my form):
Uncaught ReferenceError: MapWidget is not defined
related to the line:
var geodjango_coords = new MapWidget(options);
And as validation error at the form field COORDS I can see - "No geometry value provided"
I guessed that something is wrong with connecting GMap and checked what widget was in COORDS field (via self.fields['coords'].widget in the __init__ of ModelForm) and it turned out that it was OpenLayers widget.
What should I do to get GMap as widget and get marker's coords saved in the instance?
P.S. HEAD content at the page (it is about connecting to google maps):
<script type="text/javascript" charset="UTF-8" src="https://maps.googleapis.com/maps-api-v3/api/js/25/5/intl/ru_ALL/common.js"></script>
<script type="text/javascript" charset="UTF-8" src="https://maps.googleapis.com/maps-api-v3/api/js/25/5/intl/ru_ALL/map.js"></script>
<script type="text/javascript" charset="UTF-8" src="https://maps.googleapis.com/maps-api-v3/api/js/25/5/intl/ru_ALL/util.js"></script>
<script type="text/javascript" charset="UTF-8" src="https://maps.googleapis.com/maps-api-v3/api/js/25/5/intl/ru_ALL/onion.js"></script>
<script type="text/javascript" charset="UTF-8" src="https://maps.googleapis.com/maps-api-v3/api/js/25/5/intl/ru_ALL/stats.js"></script>
<script type="text/javascript" charset="UTF-8" src="https://maps.googleapis.com/maps-api-v3/api/js/25/5/intl/ru_ALL/controls.js"></script>
<script type="text/javascript" charset="UTF-8" src="https://maps.googleapis.com/maps-api-v3/api/js/25/5/intl/ru_ALL/marker.js"></script>

adding {{ form.media }} into HEAD has taken away the error 'Uncaught ReferenceError: MapWidget is not defined' from the Chrome console.. but it didn't solve the problem - please, look at -
GeoDjango Google Maps - error - No geometry value provided

Related

Creating a modal popup in django_tables2

I am trying to add an edit button that brings up a modal in django_tables2. The first entry in the table behaves correctly but the subsequent entries do no result in a modal popup. When I inspect the buttons, the first shows an event while the rest do not. Any ideas why the behavior isn't repeating.
tables.py
import django_tables2 as tables
from .models import expenseModel
from django_tables2 import TemplateColumn
class expenseTable(tables.Table):
class Meta:
model = expenseModel
template_name = "django_tables2/bootstrap.html"
fields = ('vendor', 'date', 'amount', 'category', 'description')
edit = TemplateColumn(template_name = 'edit_button.html')
edit_button.html
<!DOCTYPE html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
</head>
<body>
<button id='editBtn'>Edit</button>
<div id='myModal' class='modal'>
<div class='modal-content'>
<span class='close'>×</span>
<p>Some Text in the modal</p>
<form action="/summary/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="submit">
</form>
</div>
</div>
<script>
let modal = document.getElementById("myModal");
let btn = document.getElementById("editBtn");
let span = document.getElementsByClassName("close")[0];
btn.onclick = function() {
modal.style.display="block";
}
span.onclick = function() {
modal.style.display="none";
}
window.onclick = function() {
if (event.target == modal) {
modal.style.display = "none";
}
}
</script>
</body>
The first button shows this:
The second button shows this:
You should use the same value for ID multiple times. ID should always use unique values where e.g. class can share the same value multiple times.
Check https://stackoverflow.com/a/753183/4151233

How can Javascript or jQuery access my Django Models?

I have a little bit of jQuery on my page which needs to access one of my Django Models. Basically it's a form autocomplete, and it needs to look up values in my database.
I understand how to get values into a Django Template, but getting them into some Javascript code is confusing.
Is this possible? How can it be done?
Thank you.
This link has everything you need. The code is properly written and easy to understand. You can use the values of your model/table to be auto populated in the input field. Check from this link.
def get_Datas(request):
if request.is_ajax():
q = request.GET.get('term', '')
Datas = DataModel.objects.filter(short_name__icontains = q )[:20]
results = []
for Data in Datas:
Data_json = {}
Data_json['value'] = Data.short_name
results.append(Data_json)
data = json.dumps(results)
else:
data = 'fail'
mimetype = 'application/json'
return HttpResponse(data, mimetype)
And use this in template,
<link rel="stylesheet" href="http://code.jquery.com/ui/1.8.18/themes/base/jquery-ui.css" type="text/css" media="all" />
<div class="ui-widget">
<label for="datas">datas: </label>
<input id="datas">
</div>
And the script would be:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript">
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>
<script>
$(function() {
$("#datas").autocomplete({
source: "/get_Datas/",
minLength: 1,
});
});
</script>

How to hook up GMap to GeoDjango?

models.py:
class Location(models.Model):
name = models.CharField(max_length=100)
coords = gis_models.PointField(srid=4326, blank=True, null=True)
forms.py:
class LocationForm(gis_forms.ModelForm):
class Meta:
model = Location
fields = ['coords', 'name']
In the add_location.html such code was automatically generated for 'coords':
<div id="div_id_coords" class="form-group">
<div class="controls ">
<div id="id_coords_div_map">
<div id="id_coords_map"></div>
<span class="clear_features">
Delete
</span>
<textarea id="id_coords" class="vSerializedField required" cols="150" rows="10" name="coords"></textarea>
<script type="text/javascript">
var map_options = {};
var options = {
geom_name: 'Point',
id: 'id_coords',
map_id: 'id_coords_map',
map_options: map_options,
map_srid: 4326,
name: 'coords'
};
var geodjango_coords = new MapWidget(options);
</script>
</div>
</div>
</div>
In my js file earlier I tried such stuff in order to get coords of marker into my model:
$(document).ready(function(){
var mapOptions = {...};
map = new google.maps.Map($('#id_coords_map')[0], mapOptions);
map.addListener('click', function(e){
placeMarker(e.latLng, map);
var position = marker.getPosition();
$('#id_coords').val(position.lng(), position.lat());
});
var marker;
function placeMarker(latLng, map) {
marker = new google.maps.Marker({...});
return marker
}
});
But it didn't work. In the googlechrome console I get the error:
Uncaught ReferenceError: MapWidget is not defined
from line:
var geodjango_coords = new MapWidget(options);
Please, help.. what should I do to get GMap and get marker's coords saved in the instance?
Thanks a lot!!!
P.S. HEAD content:
<script type="text/javascript" charset="UTF-8" src="https://maps.googleapis.com/maps-api-v3/api/js/25/5/intl/ru_ALL/common.js"></script>
<script type="text/javascript" charset="UTF-8" src="https://maps.googleapis.com/maps-api-v3/api/js/25/5/intl/ru_ALL/map.js"></script>
<script type="text/javascript" charset="UTF-8" src="https://maps.googleapis.com/maps-api-v3/api/js/25/5/intl/ru_ALL/util.js"></script>
<script type="text/javascript" charset="UTF-8" src="https://maps.googleapis.com/maps-api-v3/api/js/25/5/intl/ru_ALL/onion.js"></script>
<script type="text/javascript" charset="UTF-8" src="https://maps.googleapis.com/maps-api-v3/api/js/25/5/intl/ru_ALL/stats.js"></script>
<script type="text/javascript" charset="UTF-8" src="https://maps.googleapis.com/maps-api-v3/api/js/25/5/intl/ru_ALL/controls.js"></script>
<script type="text/javascript" charset="UTF-8" src="https://maps.googleapis.com/maps-api-v3/api/js/25/5/intl/ru_ALL/marker.js"></script>
<script async="" src="//kitbit.net/kb.js" type="text/javascript"></script>
<script async="" src="//t.insigit.com/assets/dct.js" type="text/javascript"></script>
<script async="" src="//kitbit.net/s.js?u=http%3A%2F%2F127.0.0.1%3A8000%2Fadd_location%2F" type="text/javascript"></script>

Emberjs store error-Uncaught TypeError: Object [object Object] has no method 'trasitionTo'

I am a beginner to Emberjs and please go through the code and please guide me where am I wrong.
.js file
Sample = Ember.Application.create();
Sample.Router.map(function(){
this.route('view');
this.resource('add');
})
Add = Ember.Object.extend();
View = Ember.Object.extend();
Sample.AddNewRoute = Ember.Route.extend({
model:function(){
return Sample.Add.createRecord();
}
});
Sample.ViewController = Ember.ArrayController.extend();
Sample.AddController = Ember.ObjectController.extend({
content:[],
save:function(){
this.get("model.transaction");
this.get("target").trasitionTo('view');
}
});
Sample.ViewController = Ember.ArrayController.extend();
Sample.Store = DS.Store.extend({
revision:11,
adapter: DS.LSAdapter.create(),
});
Sample.Add = DS.Model.extend({
name: DS.attr("string"),
desig: DS.attr("string"),
age: DS.attr("integer")
});
.html file
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="C:/Users/Guest/Downloads/ember/starter-kit-1.0.0/js/libs/jquery-1.9.1.js"></script>
<script type="text/javascript" src="C:/Users/Guest/Downloads/ember/starter-kit-1.0.0/js/libs/handlebars-1.0.0.js"></script>
<script type="text/javascript" src="C:/Users/Guest/Downloads/ember/starter-kit-1.0.0/js/libs/ember-1.0.0.js"></script>
<script type="text/javascript" src="C:/Users/Guest/Downloads/ember/starter-kit-1.0.0/js/libs/ember-data.js"></script>
<script type="text/javascript" src="C:/Users/Guest/Downloads/ember/starter-kit-1.0.0/js/libs/localstorage_adapter.js"></script>
<script type="text/javascript" src="C:/Users/Guest/Downloads/ember/starter-kit-1.0.0/js/sample.js"></script>
<meta charset=utf-8 />
<title>Demo application</title>
</head>
<body>
<script type="text/x-handlebars">
<h1>Welcome to Demo!</h1>
{{#link-to 'add'}}Add Member{{/link-to}}
{{#link-to 'view'}}View Members{{/link-to}}
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name ='add'>
<h1>Add member!</h1>
<form {{action 'save' on='submit'}}>
<br>{{#view Ember.TextField valueBinding="name" placeholder= "Enter the name"}}{{/view}}</br>
<br>{{#view Ember.TextField valueBinding="desig" placeholder= "Enter the designation"}}{{/view}}</br>
<br>{{#view Ember.TextField valueBinding="age" placeholder= "Enter the age"}}{{/view}}</br>
<br><button {{action "save"}}>Add Member</button></br>
</form>
</script>
<script type="text/x-handlebars" data-template-name ='view'>
<h3><strong>All Registered Members!</strong>
<br></br>
{{#each controller}}
<br>{{name}}</br>
<br>{{desig}}</br>
<br>{{age}}</br>
{{else}}
No members registered yet! :(
{{/each}}
</script>
enter code here
</body>
</html>
After I click the 'Add Member button I am getting the following error:
Uncaught TypeError: Object [object Object] has no method 'trasitionTo'
You have a record Add which it is using for handling the click. Can you rename Add record to something else?
Add = Ember.Object.extend();//use someother name instead of Add
Instead name it something else like MyAddRecord or something else. Once you do that you should will get correct or relevant error message.

typeahead autocomplete for Django

base.html
<html lang=en>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link type="text/css" rel="stylesheet" href="/media/js/autocomplete.css">
<script type="text/javascript" src="/media/js/jquery-1.2.1.js"></script>
<script type="text/javascript" src="/media/js/dimensions.js"></script>
<script type="text/javascript" src="/media/js/autocomplete.js"></script>
{% block extra_css %}{% endblock extra_css %}
<title>{% block title %}books are social{% endblock title %}</title>
</head>
<body>
{% block body %}
{% endblock body %}
</body>
</html>
and the smaller template:
<script type="text/javascript" >
$(function(){
setAutoComplete("bookSearchField", "bookResults", "/lookup/?query=");
});
</script>
<label for="bookSearchField">Book: </label>
<input type="text" id="bookSearchField" name="bookSearchField">
urls.py
from django.conf.urls.defaults import *
urlpatterns = patterns('project.app.views',
(r'^/lookup/$', 'book_lookup'),
)
models.py
class Book(models.Model):
name = models.CharField(max_length=200)
views.py
from django.utils import simplejson
from django.http import HttpResponse
from project.app.models import Book
def book_lookup(request):
# Default return list
results = []
if request.method == "GET":
if request.GET.has_key(u'query'):
value = request.GET[u'query']
# Ignore queries shorter than length 3
if len(value) > 2:
model_results = Book.objects.filter(name__icontains=value)
results = [ {x.id :x.name,} for x in model_results ]
json = simplejson.dumps(results)
return HttpResponse(json, mimetype='application/json')
so is there any tutorial/solution to create bootstrap typeahead for elagent and responsive .
<input id="book_lookup" class="search-query typeahead" data-items="4" type="text"
placeholder="Select here....">
Edited:
<script type="text/javascript">
var typeahead_data = [];
function get_client_names() {
$.ajax({
url: "/lookup/?query=",
success: function (data) {
$.each(data, function (key, value) {
typeahead_data.push(value.toString());
});
// assign the array to my typeahead tag
$('.typeahead').typeahead({
source: typeahead_data,
});
}
});
}
$(function () {
get_client_names();
});
</script>
need something like
$("#book_lookup").tokenInput([{"id": 1, "name": "ddddd"},{"id": 2, "name": "ddffddd"}],{preventDuplicates: true,
hintText: "Type book name here...",
validateInputAjax: true,
validateInputObjectType: "book name",
validateInputNewObjectLink: function (value) {
$('#book_lookup').tokenInput(
'add', {'id': value, 'name': value});
return true;
},
validateInput: function (value) {
$.post("/lookup/", {validate_field_name: value},
function(data){
if (data.valid) {
$("#book_lookup").tokenInput('valid', value);
} else {
$("#book_lookup").tokenInput('invalid', value, 'is not a valid Book name');
};
});
}});
});
how to change data-source to book_lookup json view ?
I have used Bootstrap's typeahead before and what I did was create a method to get the dictionary via Ajax like this:
<script type="text/javascript">
var typeahead_data = [];
function get_client_names() {
$.ajax({
url: "/lookup",
success: function (data) {
$.each(data, function (key, value) {
typeahead_data.push(value.toString());
});
// assign the array to my typeahead tag
$('.typeahead').typeahead({
source: typeahead_data,
});
}
});
}
$(function () {
get_client_names();
});
</script>
The tag element is like this:
<input id="book_lookup" class="search-query typeahead" data-items="4" type="text"
placeholder="Select here....">
And basically the rest of your code is ok.
Note that here you're doing an ajax request (this requeires jquery) to the /lookup/ view which in turn returns a json object, that should look like this: [name1,name2,name3...]. You can test if the view is working ok by just accessing the view through the explorer like this: /lookup/ and if you see the dictionary displaying correctly there, the server side is ok.
Hope this works for you!
In Paulo's answer, he just has a static list of items to search from, that is why he calls the ajax on load, and gets the list and adds it to the source.
In your case, I think, you need to query whatever the user types, and send it to the server. This can be done by adding the function param in data-source, which gets 2 arguments, query and a callback.
Check here