Can't implement Jquery Ui slider for a DecimalField for a model in Django - django

Just started to fuse JQuery UI with my app. Apparently the slider only works on div elements. I have a form based on a model(ModelForm). One of the fields is a Decimal Field like so:
class mymodel(models.Model):
rating = models.DecimalField(max_digits = 5, decimal_places = 2)
...
being created like so:
class modelCreate(generic.CreateView):
template_name = 'form.html'
model = mymodel
form.html:
{% extends "base.html" %}
{% block content %}
{% load staticfiles %}
<!--<script src='http://jqueryjs.googlecode.com/files/jquery-1.2.6.min.js'></script>-->
<link rel="stylesheet" href="{% static 'Content/css/startTheme/jquery-ui-1.10.4.custom.css' %}" />
<script src={% static 'Scripts/js/jquery-1.10.2.js' %} ></script>
<script src={% static 'Scripts/js/jquery-ui-1.10.4.custom.js' %} ></script>
<div class="form_container">
<form action="" id="myform" method="post">{% csrf_token %}
{{ form.non_field_errors }}
<table>
<tr class="fieldWrapper">
<td class="label">
<label for="id_rating">Your number:</label>
</td>
<td class="field">
{{ form.rating }}
<div class="error">
{{ form.rating.errors }}
</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="btnContainer">
<input type="submit" class='btn' value="Create" />
</div>
</td>
</tr>
</table>
</form>
</div>
{% endblock %}
Using the slider on a normal div that I created works correctly.
But in the form if used on an input element it just changes the color of the border of the input box. It becomes a glorified input box.
Another approach I've thought of is to remove the decimal field on the page, replace with a div, and save that value to the model before commit (throught Form_valid()).
But I'm keeping that solution as a last resort.
A customizable slider is very important for this app. Any help would be appreciated.

The easiest way would be to hide the rating input field and add a <div> for the slider that updates the rating value. I've created a simple demo (below) to demonstrate this idea.
Note: The demo has a max value of 5. However, declaring your field, DecimalField(max_digits=5, decimal_places=2) allows you to store numbers up to 999. This would obviously make it difficult to get the exact number you wanted using a slider.
DEMO
More specifically for your form.html:
...
<td class="field">
{{ form.rating.as_hidden }}
<div id="rating_slide"></div>
<div class="error">
{{ form.rating.errors }}
</div>
</td>
...
If you want a more integrated method you could create a mixin class for your view or inclusion-tag for your template.

Related

How to customise task context (process_data cards) in django-viewflow

What I want
I'm building an approval workflow using django-viewflow and django-material.
The individual tasks are rendered as a main form with context on a very narrow column on the right-hand side.
I want to change the layout so that the task context (the detail views of all involved model instances) is better readable to the user, and also customise which fields are shown (eg. exclude a user's password hash).
Where I'm stuck
Is there a way to override which data is available as process_data short of overriding viewflow's get_model_display_data and include_process_data? E.g. I'd like to have the related instance's __str__() as title.
Does viewflow have any canonical way to provide individual detail card templates? My alternative would be to completely re-work the contents of the process_data sidebar using context['process'] as the central instance, but that would tie the templates to the data model.
Are django-material formsets with read-only fields and a custom layout the answer I'm after? (I will try this out as soon as I have a viewflow pro license.)
I'd be grateful on any pointers here.
What I've tried
I'm overriding/extending the viewflow templates. As per templatetag include_process_data, the template process_data.html supplies the column of model instance detail cards, fed by data from
get_model_display_data.
It's e.g. easy to override process_data.html to change the cards into a MaterializeCSS collapsible list:
{% load i18n viewflow material_frontend viewflow_frontend %}
<!--
This is template "APP_NAME/PROCESS_NAME/process_data.html" overriding "viewflow/flow/process_data.html".
We override instead of extending as "viewflow/flow/process_data.html" has no content block.super
Changes:
* Collapsible list of process context instead of cards.
-->
<script type="text/javascript">
$(document).ready(function () { $('.collapsible').collapsible(); });
</script>
<ul class="collapsible">
{% for root, fields, root_url in process_data %}
<li>
<div class="collapsible-header">
<span class="card-title">{{ root }} #{{ process.pk }}</span>
{% if root_url and request.user.is_staff %}
<a href="{{ root_url }}" class="card-edit" target="_blank" data-turbolinks="false" style="float:right">
{% trans 'edit' %}
</a>
{% endif %}
</div>
<div class="collapsible-body process_data_content">
<dl class="dl-horizontal">
{% for name, value in fields %}
<dt>{{ name }}:</dt>
<dd>
{% if value is True %}{% trans 'Yes' %}{% else %}
{% if value is False %}{% trans 'No' %}{% else %}
{% if value and value.url %}{{ value.name }}{% else %}
{{ value }}{% endif %}{% endif %}{% endif %}
</dd>
{% endfor %}
</dl>
</div>
{% if not hide_active_tasks and forloop.counter == 1 and process.active_tasks %}
<li>
<div class="collapsible-header">
<span class="card-title">{% trans 'Active tasks' %}</span>
</div>
<div class="collapsible-body process_data_content">
<table>
<thead>
<tr>
<th>{% trans 'Task' %}</th>
<th>{% trans 'Owner' %}</th>
</tr>
</thead>
<tbody>
{% for task in process.active_tasks %}
{% if task.flow_task.task_type == 'HUMAN' or task.flow_task.task_type == 'JOB' %}
<tr>
<td>
{{ task.flow_task}}/#{{ task.pk}}
</td>
<td>{{ task.owner|default:"" }}</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
</li>
{% endif %}
</li>
{% endfor %}
</ul>
Overriding the template viewflow/flow/task.html with my own APP_NAME/PROCESS_NAME/TASK_NAME.html template at the cost of including model-specific information can show e.g. customised cards of related instances over the main form. I would refactor the individual cards into their own templates.
{% extends "viewflow/flow/task.html" %}
{% block left-panel__top %}
<!--
This is template "APP_NAME/PROCESS_NAME/TASK_NAME.html" extending "viewflow/flow/task.html".
-->
<!-- Help specific to this step goes here. -->
{% with activation.process as p %}
<div class="row">
<h3>Nested formsets</h3>
<p>These cards are placeholders for formsets nested within the main application form.</p>
<p>Nested formsets and the main application form can be updated at the same time and have exactly one submission button.</p>
</div>
<div class="row">
<!-- Organisation Questions: Answers -->
<!-- TODO refactor to template include -->
{% for x in p.organisationanswer_set.all %}
<div class="col s12 m6 xl4">
<div class="card blue-grey darken-1">
<div class="card-content white-text">
<span class="card-title">
{{ x.question.question }}
</span>
<p><strong>Your answer:</strong> {{ oa.answer }}</p>
</div>
<div class="card-action">
Provide an answer
</div>
</div>
</div>
{% endfor %}
<!-- Dataset Questions: Answers -->
{% for x in p.datasetanswer_set.all %}
<div class="col s12 m6 xl4">
<div class="card blue-grey darken-1">
<div class="card-content white-text">
<span class="card-title">
{{ x.question.question }}
</span>
<p><strong>Your answer:</strong> {{ x.answer }}</p>
</div>
<div class="card-action">
Provide an answer
</div>
</div>
</div>
{% endfor %}
<!-- Approvals: Receipts - TODO show this in task after custodian approval -->
{% for x in p.approvalreceipt_set.all %}
<div class="col s12 m6 xl4">
<div class="card blue-grey darken-1">
<div class="card-content white-text">
<span class="card-title">
{{ x.approval }}
</span>
<p><strong>Your approval receipt:</strong> {{ x.receipt }}</p>
</div>
<div class="card-action">
Provide an answer
</div>
</div>
</div>
{% endfor %}
</div>
{% endwith %}
<div class="row">
<h3>Main application form</h3>
<p>These main application form would include the forms above as nested formsets.</p>
<p>This note will disappear once this has been implemented.</p>
</div>
{% endblock %}
For the basic cases create a template named as [app_label]/[flow_label]/process_data.html For example check the shipment demo
Viewflow is the thin workflow layer on top of the standard Django model-view-template pattern. Any customization practices for Django are valid for Viewflow
For the complex cases it's better to not to tune some universal implementation, but create your own set of templates for Viewflow, ex cookbook/custom_ui

Loop over Django objects and Bootstrap cards

I would like to use Bootstrap cards in order to create one card by object and add some sub_objects in each one.
For example :
I have an object Publication which could contain one or many sub_objects Document.
Publication object has some attributes : category, title, picture, description and Document object has some attributes like title, format, language, ...
I would like to get something like this :
For a same category, I create a card by publication and I list all documents for each publication.
This is what I get with my code :
As you can see, I should have document nĀ°1 and documentĀ°2 in the same card and not two different cards.
This is my code :
{% for category in research_categories|dictsort:'name' %}
<div class="row">
<fieldset>
<legend id="category_{{ category.id }}"><span class="name">{{ category }}</span></legend>
</fieldset>
</div>
<div class="row">
<div class="col-sm-4">
{% for element in test_research %}
{% if element.publication.category|stringformat:"s" == category|stringformat:"s" %}
{% ifchanged %}
<div class="card" style="width:250px">
<img class="card-img-top" src="{{ element.publication.cover.url }}" alt="Card image">
<div class="card-body">
<h4 class="card-title">{{ element.publication }}</h4>
<table class="table table-condensed">
<tbody>
<tr>
<td> {{ element.title }}</td>
</tr>
</tbody>
</table>
</div>
</div>
{% endifchanged %}
{% endif %}
{% endfor %}
</div>
</div>
{% endfor %}
And my view according to this part is :
# By default, display documents
test_research = Document.objects.all().order_by('publication__title', 'title', 'language', 'format')
research_categories = defaultdict(list)
for element in test_research:
research_categories[element.publication.category].append(element)
research_publications = defaultdict(list)
for element in test_research:
research_publications[element.publication].append(element)
kwargs['test_research'] = test_research
kwargs['research_categories'] = research_categories
kwargs['research_publications'] = research_publications

request POST not working with <TABLE>

With Django 1.8 template, tried to POST table data. I set <TABLE> id = 'tasktable'. But in request information, there's no data of 'tasktable'
Also, how can I access dynamic table POST data in Django views?
Is only ways to make id each row?
(like <td><input id='1_data'></td><td><input id='2_data'></td>
POST request info
Below Code is template.
{% extends "base.html" %}
{% load staticfiles %}
{% block scripts %}
<script src="//code.jquery.com/jquery.min.js"></script>
<script>
$(function () {
$('#btn-add-row').click( function() {
$('#tasktable > tbody:last').append('<tr><td><input type="text"></td><td><select name="format"><option value="INT">INT</option><option value="TEXT">TEXT</option></select></td></tr>');
});
$('#btn-delete-row').click( function() {
$('#tasktable > tbody:last > tr:last').remove();
});
});
</script>
{% endblock %}
{% block title %}
Angel Feeder - Manager
{% endblock %}
{% block body %}
<div class="container">
<form class="" method="post" action="">
{% csrf_token %}
{{ taskform }}
<br>
<button id="btn-add-row" type="button">+</button><button id="btn-delete-row" type="button">-</button>
<table name='tasktable' id='tasktable' class="table">
<thead>
<tr>
<th>Data name</th>
<th>Format</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text"></td>
<td><select name="format"><option value="INT">INT</option><option value="TEXT">TEXT</option></select></td>
</tr>
</tbody>
</table>
<button class="btn btn-lg btn-primary" type="submit">set task</button>
</form>
</div>
{% endblock %}
Only form elements with a name attribute will have their values passed when submitting a form.
name is not an allowed attribute of <table> in HTML5
https://stackoverflow.com/a/13677670/3033586
Obviously you have to set unique names for each form element inside table>tr>td so you can reference it after post
If you want simple styled [model]forms (for example with bootstrap) - look at http://django-crispy-forms.readthedocs.org/en/latest/

Create template for forms django

I currently have a login.html, which has inside it a form for login. All my forms need to look similar, however will have different content. At the moment my code for it looks like this:
<form enctype="multipart/form-data" method="POST" action="">
<fieldset>
<legend>{{ legend }}</legend>
<div style="line-height:18px">{% block top %}{% endblock %}<br></div>
<table class="form">
{% for text,name,inputtype in formcontent %}
<tr>
<td class="right">
<label>{{ text }}:</label><br/>
</td><td style="float:left">
<input name="{{ name }}" type="{{inputtype}}">
</td>
</tr>
{% endfor %}
</table>
<input value="{{ button }}" type="submit">
<div style="line-height:18px">
<div class="err">
{{ err }}
</div>
{{ bottom }}
</div>
</fieldset></form>
I was wondering if there was a better way to do it than to put variables into my urls.py (given that there may be multiple forms on hte page, I don't believe that this would work under all circumstances). A nice solution would be to create a class, but I don't know how to call this class from a page. I know it would involve making a tag, but I don't see how you can provide a 2d array as an argument from a template.
Django Crispy Forms were made for this exact reason. I think they are exactly what you need.

Django admintemplates

I have a form which is like:
class Address_info_updateForm(forms.Form):
street = forms.CharField(label=_("Street"), required=True)
street2 = forms.CharField(label=_("Additional Address"), required=False, max_length=50)
zip = forms.CharField(label=_("Postcode"), required=True, max_length=50)
city = forms.CharField(label=_("City"), required=True, max_length=50)
state = forms.CharField(label=_("State"), required=False, max_length=50)
country = forms.ChoiceField(label=_("Country"), choices=countries, widget=forms.Select, required=True)
Now I have rendered to template which is like:
{% extends "base/base_page.html" %}
{% load i18n %}
{% load static %}
{% block html_title %}
{% trans "Update Profile" %}
{% endblock %}
{% block html_page_left_content %}
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="stepcarousel.js">
stepcarousel.setup({
galleryid: 'mygallery2', //id of carousel DIV
beltclass: 'belt2', //class of inner "belt" DIV containing all the panel DIVs
panelclass: 'panel2', //class of panel DIVs each holding content
autostep: {enable:true, moveby:1, pause:3000},
panelbehavior: {speed:500, wraparound:false, wrapbehavior:'slide', persist:true},
defaultbuttons: {enable: true, moveby: 1, leftnav: ['{{ STATIC_PREFIX }}images/home/bigarrowleft.png', 5, 168], rightnav: ['{{ STATIC_PREFIX }}images/home/bigarrowright.png', -47, 163]},
statusvars: ['statusA', 'statusB', 'statusC'], //register 3 variables that contain current panel (start), current panel (last), and total panels
contenttype: ['inline'] //content setting ['inline'] or ['ajax', 'path_to_external_file']
})
</script>
<div style="height: 400px">
<div>
<p class="title">{% trans "BILLING ADDRESS" %}</p>
</div>
<form action="" method="POST" class="custom_form">{% csrf_token %}
<table style="color:black;text-align:left; margin-left: 20px;">
{% if form.errors %}
<span style="color:red;">{% trans "You have not filled in the form correctly. Please correct the errors"%}:</span>
{% endif %}
{% for field in form %}
{% if not field.is_hidden %}
<tr>
<td>
{{field.label}}
{% if field.field.required %}
<span style="color:red;">*</span>
{%endif%}
</td>
</tr>
{%else%}
{{field}}{{field.errors}}
{%endif%}
{% endfor %}
<tr>
<td colspan="2">
<input type="submit" value="{% trans "UPDATE" %}">
<input type="button" value="{% trans "CANCEL" %}" onclick="document.location.href='{{base_url}}MyProfile/'" class="custom_button">
</td>
</tr>
</table>
</form>
<script>
jQuery('select#id_country').wrap('<div class="select_div" />');
</script>
</div>
{% endblock %}
{% block html_page_right_sidebar_login %}
{% endblock %}
the problem is when i use {{form.as_table}} i see my textboxes along with my form fields in very descent manner.
But when i am using the stepcruousel to display the errors and * marked fields it is NOT SHOWING ME THE TEXTBOXES and it is only showing me the fields with aestrics * like this
Street * and so on
I want the fields to be aestrix along with the texboxes also.
Thanks in advance
To show the field label & textbox you are using:
{{field.label}}
{% if field.field.required %}
<span style="color:red;">*</span>
{%endif%}
but this will show only label {{field.label}} but not textbox because there is no {{ field }} which is the widget translated to html of the field (in your case its the text box). Add it:
{{field.label}}
{% if field.field.required %}
<span style="color:red;">*</span>
{%endif%}
{{ field }}