﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
27055	Model form with geometry widgets has invalid html	Antonis Christofides		"== Synopsis ==

I have a model with a `MultiPolygonField`. I have Django automatically create a form for it (using a `CreateView`). I show the form on a template with `{{ form.as_p}}`. The result is invalid HTML; it has `<style>` inside a `<p>`.

The reason for this is that the MultiPolygonField is rendered with a `django.contrib.gis.forms.widgets.OpenLayersWidget`, which uses `django/contrib/gis/templates/gis/openlayers.html`. This template contains a `<style>` element followed by a `<div>` element. Apparently whenever some other code elsewhere decides to show the widget, it wraps it in a `<p>` or in a `<td>` (I've also seen it wrapped in a `<div>`).

== How to reproduce ==

1) Create or clone the minimal project.

If you prefer to clone it, it's at https://github.com/aptiko/testgishtml. It's only three commits, of which the first two commits only contain the empty django project and app created by `django-admin startproject` and `./manage.py startapp`, so if you merely `git show` when you are at master it will show you all the custom code.

If you prefer to do it manually, first `django-admin startproject testgishtml`, then do the following:

* `./manage.py startapp gishtml`.

* Replace file `gishtml/models.py` with this:

{{{#!python
from django.contrib.gis.db import models


class Polygon(models.Model):
    mpoly = models.MultiPolygonField()
}}}

* Replace `gishtml/views.py` with this:

{{{#!python
from django.views.generic import CreateView

from .models import Polygon


class CreatePolygonView(CreateView):

    model = Polygon
    template_name = 'create_polygon.html'
    fields = ('mpoly',)
}}}

* Add file `gishtml/templates/create_polygon.html`:

{{{
<!DOCTYPE html>
<title>Create polygon</title>
{{ form.as_p }}
}}}

* Add `django.contrib.gis` and `gishtml` to `INSTALLED_APPS`.

* Add `url(r'^', gishtml.views.CreatePolygonView.as_view())` to `urlpatterns`.

2) Run `./manage.py migrate` and `./manage.py runserver`.

3) Visit http://localhost:8000/

== Results ==

{{{
<!DOCTYPE html>
<title>Create polygon</title>
<p><label for=""id_mpoly"">Mpoly:</label> 
<style type=""text/css"">
    #id_mpoly_map { width: 600px; height: 400px; }
    #id_mpoly_map .aligned label { float: inherit; }
    #id_mpoly_div_map { position: relative; vertical-align: top; float: left; }
    #id_mpoly { display: none; }
    .olControlEditingToolbar .olControlModifyFeatureItemActive {
        background-image: url(""/static/admin/img/gis/move_vertex_on.svg"");
        background-repeat: no-repeat;
    }
    .olControlEditingToolbar .olControlModifyFeatureItemInactive {
        background-image: url(""/static/admin/img/gis/move_vertex_off.svg"");
        background-repeat: no-repeat;
    }
</style>

<div id=""id_mpoly_div_map"">
    <div id=""id_mpoly_map""></div>
    <span class=""clear_features""><a href=""javascript:geodjango_mpoly.clearFeatures()"">Delete all Features</a></span>
    
    <textarea id=""id_mpoly"" class=""vSerializedField required"" cols=""150"" rows=""10"" name=""mpoly""></textarea>
    <script type=""text/javascript"">
        var map_options = {};
        var options = {
            geom_name: 'MultiPolygon',
            id: 'id_mpoly',
            map_id: 'id_mpoly_map',
            map_options: map_options,
            map_srid: 4326,
            name: 'mpoly'
        };
        
        var geodjango_mpoly = new MapWidget(options);
    </script>
</div>
</p>
}}}

If you feed this to http://validator.w3.org/, it says ""Element `style` not allowed as child of element `p` in this context""."	Bug	closed	GIS	dev	Normal	fixed			Accepted	0	0	0	0	0	0
