Skip to content

Commit

Permalink
Add full example of front-office usage
Browse files Browse the repository at this point in the history
  • Loading branch information
SebCorbin committed Jul 26, 2020
1 parent bea517d commit ea24947
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 39 deletions.
103 changes: 65 additions & 38 deletions README.rst
Expand Up @@ -22,17 +22,15 @@ It provides:
.. image:: https://github.com/fle/django-jsignature/blob/master/screen.png

==================
INSTALL
Installation
==================

For now:

::

pip install django-jsignature

==================
USAGE
Usage
==================

* Add ``jsignature`` to your ``INSTALLED_APPS``:
Expand All @@ -45,48 +43,37 @@ USAGE
'jsignature',
)

* Use provided form field and widget:
* Use provided model field (for easy storage):

::

# forms.py
from django import forms
from jsignature.forms import JSignatureField
# models.py
from django.db import models
from jsignature.fields import JSignatureField

class SignatureForm(forms.Form):
class SignatureModel(models.Model):
signature = JSignatureField()

* In your template
* In your form template

::

{{ form.media }}
<form action="." method="POST">
{% for field in form %}
{{ field.label_tag }}
{{ field }}
{% endfor %}
<input type="submit" value="Save"/>
<form action="" method="post">
{{ form }}
<input type="submit" value="Save" />
{% csrf_token %}
</form>

* Render image after form validation:
* Render image from db value in your display template:

::

# views.py
from jsignature.utils import draw_signature
from myapp.forms import SignatureForm
{# yourtemplate.html #}
{% load jsignature_filters %}

<img src="{{ obj.signature|signature_base64 }}" alt="{{ obj }}" />

def my_view(request):
form = SignatureForm(request.POST or None)
if form.is_valid():
signature = form.cleaned_data.get('signature')
if signature:
# as an image
signature_picture = draw_signature(signature)
# or as a file
signature_file_path = draw_signature(signature, as_file=True)

* By default, jSignature is made to work outside of admin, requiring that
you include the jQuery library in your ``<head>``.
Expand All @@ -95,8 +82,11 @@ USAGE
``JSIGNATURE_JQUERY`` setting to ``admin``. Otherwise if set to any url
pointing to jQuery, it will be automatically included.

It is strongly suggested to take example from ``example_project``, which is
`located in this repo <https://github.com/fle/django-jsignature/tree/master/example_project>`_

==================
CUSTOMIZATION
Customization
==================

JSignature plugin options are available in python:
Expand Down Expand Up @@ -131,10 +121,11 @@ Available settings are:
* ``JSIGNATURE_RESET_BUTTON`` (ResetButton)

==================
IN YOUR MODELS
In your models
==================

If you want to store signatures, provided mixin gives a ``signature`` and a ``signature_date`` that update themselves:
If you want to store signatures easily, a provided mixin gives a ``signature``
and a ``signature_date`` that update themselves:

::

Expand All @@ -145,6 +136,41 @@ If you want to store signatures, provided mixin gives a ``signature`` and a ``si
name = models.CharField()


==================
In your forms
==================

* If you need more precise handling of the form field, you can use it directly:

::

# forms.py
from django import forms
from jsignature.forms import JSignatureField

class SignatureForm(forms.Form):
signature = JSignatureField()


* And upon saving, have direct access to the image with ``draw_signature()``

::

# views.py
from jsignature.utils import draw_signature
from myapp.forms import SignatureForm

def my_view(request):
form = SignatureForm(request.POST or None)
if form.is_valid():
signature = form.cleaned_data.get('signature')
if signature:
# as an image
signature_picture = draw_signature(signature)
# or as a file
signature_file_path = draw_signature(signature, as_file=True)


==================
Example project
==================
Expand All @@ -163,16 +189,17 @@ If you want to have a demo of this package, just use the example project:
./manage.py migrate
./manage.py createsuperuser

Fill the user info, launch django with ``./manage.py runserver`` and head over to
`http://127.0.0.1:8000/ <http://127.0.0.1:8000/>`_ and login with the
credentials your provided.
Fill the user info, launch django with ``./manage.py runserver`` and head over
to `http://127.0.0.1:8000/ <http://127.0.0.1:8000/>`_, you can also
`login to the admin <http://127.0.0.1:8000/admin>`_ with the credentials your
provided.

==================
AUTHORS
Authors
==================

* Florent Lebreton <florent.lebreton@makina-corpus.com>
* Sébastien Corbin <sebastien.corbin@makina-corpus.com>
* Florent Lebreton <florent.lebreton@makina-corpus.com> (original author)
* Sébastien Corbin <sebastien.corbin@makina-corpus.com> (maintainer)

|makinacom|_

Expand Down
39 changes: 39 additions & 0 deletions example_project/templates/base.html
@@ -0,0 +1,39 @@
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

<title>Example project</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="{% url 'admin:index' %}">Admnistration</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'list' %}">List</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'create' %}">Create</a>
</li>
</ul>
</div>
</nav>

<div class="container">
{% block content %}{% endblock %}
</div>

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
{% block extra_media %}{% endblock %}
</body>
</html>
14 changes: 14 additions & 0 deletions example_project/templates/example_project/examplemodel_form.html
@@ -0,0 +1,14 @@
{% extends "base.html" %}

{% block extra_media %}
{{ form.media }}
{% endblock %}

{% block content %}
<form action="" method="post">
{{ form }}
<input type="submit" value="Save" class="btn btn-success" />
<a href="{% url 'list' %}" class="btn btn-danger">Cancel</a>
{% csrf_token %}
</form>
{% endblock %}
24 changes: 24 additions & 0 deletions example_project/templates/example_project/examplemodel_list.html
@@ -0,0 +1,24 @@
{% extends "base.html" %}{% load jsignature_filters %}

{% block content %}
<h1>List</h1>

<ul>
{% for obj in object_list %}
<li>
<dl>
<dt>Raw data (from db)</dt>
<dd>{{ obj.signature }}</dd>
<dt>As image</dt>
<dd>
<img src="{{ obj.signature|signature_base64 }}" alt="{{ obj }}" />
<a href="{% url 'update' obj.pk %}" class="btn btn-primary">
Update
</a>
</dd>
</dl>
</li>
{% endfor %}
</ul>
<a href="{% url 'create' %}" class="btn btn-primary">Create</a>
{% endblock %}
7 changes: 6 additions & 1 deletion example_project/urls.py
Expand Up @@ -3,6 +3,11 @@
from django.contrib import admin
from django.urls import path

from example_project import views

urlpatterns = [
path('', admin.site.urls),
path('', views.ExampleListView.as_view(), name='list'),
path('create', views.ExampleCreateView.as_view(), name='create'),
path('update/<int:pk>', views.ExampleUpdateView.as_view(), name='update'),
path('admin', admin.site.urls),
]
20 changes: 20 additions & 0 deletions example_project/views.py
@@ -0,0 +1,20 @@
from django.urls import reverse_lazy
from django.views import generic

from example_project.models import ExampleModel


class ExampleCreateView(generic.CreateView):
model = ExampleModel
fields = '__all__'
success_url = reverse_lazy('list')


class ExampleUpdateView(generic.UpdateView):
model = ExampleModel
fields = '__all__'
success_url = reverse_lazy('list')


class ExampleListView(generic.ListView):
model = ExampleModel

0 comments on commit ea24947

Please sign in to comment.