Django application that allows creation, preview and usage of custom multivariant restrictions applied on the forms.
Project description
Demo application
You can check it online http://offermaker.kjw.pt
Or checkout and install locally:
git clone git@bitbucket.org:kkujawinski/offer-maker-demo-site.git
Quick start
Install django-offermaker
pip install django-offermaker
Site configuration in settings.py
INSTALLED_APPS = ( ... 'offermaker', )
Create Django form:
from django import forms class MyForm(forms.Form): product = forms.ChoiceField( label=u'Product', choices=( ('', '---'), ('PROD1', 'Product X'), ('PROD2', 'Product Y'), ('PROD3', 'Product Z'), ), required=False) crediting_period = forms.ChoiceField( label=u'Crediting period', choices=(('', '---'), ('12', '12'), ('24', '24'), ('36', '36'), ('48', '48'))) interest_rate = forms.FloatField(label=u'Interest rate', min_value=1, max_value=5) contribution = forms.FloatField(label=u'Contribution', min_value=0)
Define your offer (in case you do not store it in database):
offer = { 'variants': [ [{ 'params': {'product': 'PROD1', 'crediting_period': ['24']}, }, { 'params': {'product': 'PROD2'}, 'variants': [ {'params': {'crediting_period': ['12']}}, {'params': {'crediting_period': ['36']}}, {'params': {'crediting_period': ['48']}}] }, { 'params': {'product': 'PROD3'}, }], [{ 'params': {'product': 'PROD1'}, 'variants': [ {'params': {'contribution': (10, 20), 'interest_rate': (2, 2)}}, {'params': {'contribution': (30, 40), 'interest_rate': (4, 4)}}] }, { 'params': {'product': ['PROD2', 'PROD3']}, 'variants': [{ 'params': {'contribution': (30, 70), 'interest_rate': (5, 5)} }] }] ] }
Offer form:
Use dispatcher code in Django view
import offermaker def my_form_view(request): core_object = offermaker.OfferMakerCore(DemoOfferMakerForm, offer) def handler_get(form): return render(request, 'my_form.html', ({'form': form}) def handler_post(form): if form.is_valid(): return HttpResponseRedirect('success') return handler_get(form) dispatcher = offermaker.OfferMakerDispatcher.from_core_object(handler_get, handler_post, core_object=core_object) return dispatcher.handle_request(request)
Initialize offerform in template
<head> {% load offermaker %} <script type="text/javascript" src="http://code.jquery.com/jquery-1.10.2.min.js"></script> {% offermaker_javascript %} </head> <body> <form action="?" method="post" id="offer_form"> <div class="alert-placeholder" style="height: 30px;"></div> {% csrf_token %} {{ form.as_p }} <button type="submit">Submit</button> </form> <script type="text/javascript"> (function() { $('#offer_form').offer_form(); })(); </script>
Offer preview:
Pass offerform object from view to template:
def my_form_view(request): core_object = offermaker.OfferMakerCore(DemoOfferMakerForm, offer)
Use proper template tag in template to print table:
{% load offermaker %} {% offermaker_preview offer %}
Offer editor:
Use OfferJSONField field in your model. Remember to pass your django form created in 3.:
import offermaker class MyOffer(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=30) offer = offermaker.OfferJSONField(form_object=MyForm())
Create your own Admin Site for model:
import models class OfferAdmin(admin.ModelAdmin): list_display = ('name',) search_fields = ('name', 'user') fields = ('name', 'offer') admin.site.register(models.Offer, OfferAdmin)
Basic customization
Using offers stored in database:
you need to pass proper offer object to Offermaker in form/preview view:
offer = MyOffer.objects.filter(id=request.GET['id']).first() core_object = offermaker.OfferMakerCore(DemoOfferMakerForm, offer.offer)
and configure proper params to be used ajax requests:
$('#offer_form').offer_form({ ajax_extra_params: function(params) { return { id: {{ request.GET.id }} }; }, });
Substituting builtin formatters for infotip and error alerts:
$('#offer_form').offer_form({ error_alert_factory: function (msg) { var $error = $('<p class="error"><span>' + msg + '</span></p>'); $('.alert-placeholder', $form).append($error); return $error; }, tooltip_factory: function ($field, msg) { var $tooltip = $('<p class="infotip">' + msg + '</p>'); $field.parent().append($tooltip); return $tooltip; } });
Use builtin formatters for Twitter Bootstap3:
(function() { $('#offer_form').offer_form({ bootstrap3: true, }); })();
Customizing messages:
(function() { $('#offer_form').offer_form({ msgs: { 'NO_VARIANTS': 'No matching variants', 'INFO_ITEMS': 'Available values are: %s.', 'INFO_FIXED': 'Only available value is %s.', 'RANGE_left': 'to %2$s', 'RANGE_right': 'from %1$s', 'RANGE_both': 'from %1$s to %2$s', 'AND': ' and ' }, iteration_str: function (items) { return items.slice(0, -2).concat(items.slice(-2).join(msgs.AND)).join(', '); } }); })();
Creating preview table for certain fields:
{% offermaker_preview offer fields='product, crediting_period' %}
Add html attributes to generated preview table:
{% offermaker_preview offer class='table table-bordered' %}
Troubleshooting
I run Django 1.5 and I have jQuery older than 1.9.
You need to add new jQuery library dependency in you django admin site:
class OfferAdmin(admin.ModelAdmin): ... class Media: js = ('//code.jquery.com/jquery-1.11.0.min.js',)
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.