django dynamic add form fields - django

Based on this i want to write a dynamic template, where i can dynamicly add forms with choosen width.
Models:
class TodoList(models.Model):
SEC = 'section'
DIV = 'div'
SECCHOICES = (
(SEC, "Section"),
(DIV, "Div"),
)
tag = models.CharField(max_length=20, choices=SECCHOICES, default=SEC)
def __unicode__(self):
return self.name
class TodoItem(models.Model):
COL16 = '16'
COL25 = '25'
COL33 = '33'
COL50 = '50'
COL66 = '66'
COL75 = '75'
COL100 = '100'
CHOICES = (
(COL16, "16%"),
(COL25, "25%"),
(COL33, "33%"),
(COL50, "50%"),
(COL66, "66%"),
(COL75, "75%"),
(COL100, "100%"),
)
width = models.CharField(max_length=3, choices=CHOICES, default=COL100)
list = models.ForeignKey(TodoList)
def __unicode__(self):
return self.name + " (" + str(self.list) + ")"
View:
def post_list(request):
posts = TodoItem.objects.order_by('id')
return render(request, 'blog/post_list.html', {'posts': posts})
Template:
{% for post in posts %}
<{{ post.list.tag }}>
<div class="column{{ post.width }}" >
</div>
</{{ post.list.tag }}>
{% endfor %}
Output is:
Section: col, Section: col, Section: col, Section: col
And i wish:
Section: col, col, col, col
Happy about any Ideas, Sorry if something is too stupid – im very new to django/python

You can do that by doing this only?
<{{ post.list.tag }}>
{% for post in posts %}
<div class="column{{ post.width }}" >
</div>
{% endfor %}
</{{ post.list.tag }}>

Related

Django upload csv to DB via template with function

I made a function with "runscript" on Django. I wanna know how can I upload a CSV file via a template with my function.
this is my function:
def run():
df = pd.read_csv("scripts/Combination.csv", dtype=str)
df = df[pd.isnull(df["id"])]
def sub_budget_owner_found(v_BO, v_SBO):
try:
Employee.objects.get_or_create(name=v_BO)
v_BO_obj = Employee.objects.get(name=v_BO)
except:
v_BO_obj = Employee.objects.get(name="99999 No Budget Owner")
try:
Employee.objects.get_or_create(name=v_SBO)
v_SBO_obj = Employee.objects.get(name=v_SBO)
except:
v_SBO_obj = Employee.objects.get(name="99998 No Sub Budget Owner")
return SubBudgetOwner.objects.get_or_create(
budget_owner=v_BO_obj, sub_budget_owner=v_SBO_obj
)
for i, row in df.iterrows():
v_subsidiary = row["Subsidiary"]
v_department = row["Department"]
v_account = row["Account"]
v_sub_budget = row["Sub Budget"]
v_budget_owner = row["Budget Owner"]
v_sub_budget_owner = row["Sub Budget Owner"]
Combination.objects.get_or_create(
subsidiary=Subsidiary.objects.get_or_create(name=str(v_subsidiary))[0],
department=Department.objects.get_or_create(name=str(v_department))[0],
account=Account.objects.get_or_create(name=str(v_account))[0],
sub_budget=SubBudget.objects.get_or_create(name=str(v_sub_budget))[0],
budget_owner=sub_budget_owner_found(v_budget_owner, v_sub_budget_owner)[0],
)
print(i, row)
I use Django view classes. The purpose is to upload new data via CSV file in the GUI.
Thanks a lot
So I found a solution for this.
my urls.py
path("combinationimport/", views.import_combination, name="combination_import"),
in my views.py
def import_combination(request):
if "GET" == request.method:
return render(request, "budget/combination_import.html", {})
else:
excel_file = request.FILES["excel_file"]
wookbook = openpyxl.load_workbook(excel_file)
worksheet = wookbook.active
print(worksheet)
data = worksheet.values
# Get the first line in file as a header line
columns = next(data)[0:]
df = pd.DataFrame(data, columns=columns)
def sub_budget_owner_found(v_BO, v_SBO):
try:
Employee.objects.get_or_create(name=v_BO)
v_BO_obj = Employee.objects.get(name=v_BO)
except:
v_BO_obj = Employee.objects.get(name="99999 No Budget Owner")
try:
Employee.objects.get_or_create(name=v_SBO)
v_SBO_obj = Employee.objects.get(name=v_SBO)
except:
v_SBO_obj = Employee.objects.get(name="99998 No Sub Budget Owner")
return SubBudgetOwner.objects.get_or_create(
budget_owner=v_BO_obj, sub_budget_owner=v_SBO_obj
)
new_data_entry = []
excel_data = list()
# iterating over the rows and
# getting value from each cell in row
for row in worksheet.iter_rows():
row_data = list()
for cell in row:
row_data.append(str(cell.value))
excel_data.append(row_data)
for i, row in df.iterrows():
v_subsidiary = row["Subsidiary"]
v_department = row["Department"]
v_account = row["Account"]
v_sub_budget = row["Sub Budget"]
v_budget_owner = row["Budget Owner"]
v_sub_budget_owner = row["Sub Budget Owner"]
combo = Combination.objects.get_or_create(
subsidiary=Subsidiary.objects.get_or_create(name=str(v_subsidiary))[0],
department=Department.objects.get_or_create(name=str(v_department))[0],
account=Account.objects.get_or_create(name=str(v_account))[0],
sub_budget=SubBudget.objects.get_or_create(name=str(v_sub_budget))[0],
budget_owner=sub_budget_owner_found(v_budget_owner, v_sub_budget_owner)[
0
],
)
if combo[1] == True:
new_data_entry.append(f"Row #{i+2}: {combo[0]}")
return render(
request,
"budget/combination_import.html",
{"excel_data": excel_data, "new_data_entry": new_data_entry},
)
combination_import.html
XLSX FILE
<form action="{% url "budget:combination_import" %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file"
title="Upload excel file"
name="excel_file"
style="border: 1px solid black; padding: 5px;"
required="required">
<p>
<br>
<input type="submit" value="Upload" style="padding:5px 15px;
background:#3CBC8D;
border:0 none;
cursor:pointer;
-webkit-border-radius: 5px;
border-radius: 5px;">
</form>
<hr>
<p>New Records:</p>
{% for q in new_data_entry %}
<p style="background-color:green; color:white">{{ q }}</p>
{% endfor %}
<hr>
<p>All Records:</p>
{% for row in excel_data %}
{% for cell in row %}
{{ cell }}
{% endfor %}
<br>
{% endfor %}
I hope it will help.

How do I add reset button for crispy filter.form in Django to reset current selection in filter fields?

I have django-filters fields above django-table2 and I would like to add reset button which would clear values selected in particular filter fields.
My code:
filters.py
class DiaryFilter(django_filters.FilterSet):
def trade_win_loss(self, queryset, name, value):
if (value == 'Win'):
return queryset.filter(netpnl__gt=0)
if (value == 'Loss'):
return queryset.filter(netpnl__lt=0)
if (value == 'BE'):
return queryset.filter(netpnl=0)
return queryset
class Meta:
model = Diary
fields = ("ticker", "strategy", "position", "entryDate", "netpnl")
WIN_LOSS_CHOICES = (
('Win', 'Win'),
('Loss', 'Loss'),
('BE', 'Break Even'),
)
ticker = django_filters.CharFilter(label="Ticker", lookup_expr='icontains')
entryDate = django_filters.DateFilter(widget=DateInput(attrs={'type': 'date'}))
netpnl = django_filters.ChoiceFilter(empty_label='---------', label="NetP/L", choices=WIN_LOSS_CHOICES, method="trade_win_loss")
class DiaryFilterFormHelper(FormHelper):
form_method = 'GET'
layout = Layout(
Div(
Div("ticker", css_class="col-6 col-sm-4 col-md-2"),
Div("strategy", css_class="col-6 col-sm-4 col-md-2"),
Div("position", css_class="col-6 col-sm-4 col-md-2"),
Div("entryDate", css_class="col-6 col-sm-4 col-md-3 col-lg-2"),
Div("netpnl", css_class="col-6 col-sm-4 col-md-2"),
Div(Submit('submit', 'Filter', css_class='btn btn-dark'), css_class="col-2 col-md-2 col-lg-1 block my-auto align-bottom"),
Div(Submit('reset', 'Clear', css_class='btn btn-dark'), css_class="col-1 block my-auto align-bottom"),
css_class="row"
)
)
views.py
class DiaryView(LoginRequiredMixin, SingleTableMixin, FilterView):
template_name = "diary.html"
model = Diary
table_class = DiaryTable
filterset_class = DiaryFilter
table_pagination = {
"per_page": 10
}
def get_filterset(self, filterset_class):
filterset = super().get_filterset(filterset_class)
filterset.form.helper = DiaryFilterFormHelper()
return filterset
html template
<div class="col-11">
<div class="text-center justify-content-center align-bottom">
{% crispy filter.form %}
</div>
{% render_table table %}
</div>
As I am beginner, I was searching for a similar code, but did not find anything useful. I expect that I should probably write some function and assign it somehow to the Clear button in filters.py, so any help with example of code would be appreciated.

How to display your queries using filter?

So I am trying to set up a filter for my website and it is not working; It does not give me an error and the url updates like a query is being made but when I click "submit" it still shows all of the content in the page. I can't quite figure out what is wrong.
filters.py
import django_filters
from django_filters import DateFilter
from .models import *
class UserpostFilter(django_filters.FilterSet):
start_date = DateFilter(field_name = "date_published", lookup_expr='gte')
end_date = DateFilter(field_name = "date_published", lookup_expr='lte')
class Meta:
model = Userpost
fields = '__all__'
exclude = ['image', 'user', 'date_published']
models.py
class Userpost(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
Year = models.CharField(max_length = 4)
Mileage = models.CharField(max_length = 8)
Make = models.CharField(max_length = 50)
Model = models.CharField(max_length = 50)
Price = models.DecimalField(max_digits=15, decimal_places=2)
email = models.EmailField()
date_published = models.DateField(default = timezone.now)
image = models.ImageField(null = True, blank = True, upload_to = r"C:\Users\gabri\Desktop\test\ecommerce\static\images")
def __str__(self):
return self.Year + " " + self.Make + " " + self.Model
#property
def imageURL(self):
try:
url = self.image.url
except:
url = ''
return url
views.py
def posts(request):
cars = Userpost.objects.all()
p = Paginator(Userpost.objects.all(), 9)
page = request.GET.get('page')
cars_list = p.get_page(page)
nums = "a" * cars_list.paginator.num_pages
myFilter = UserpostFilter(request.GET, queryset = cars)
cars = myFilter.qs
context = {'cars':cars, 'cars_list':cars_list, "nums":nums, "myFilter":myFilter}
return render(request, 'store/userposts.html', context)
userposts.html
<div class = "row">
<div class="col">
<div class = "card card-body">
<form method="get">
{{myFilter.form}}
<button class="btn btn-primary" type="submit">Search</button>
</form>
</div>
</div>
</div>
<br>
<div class="row">
{% for car in cars_list %}
<div class="col-lg-4">
<img class="thumbnail" src="{{car.imageURL|default:'/images/transparentLogo.png'}}">
<div class="box-element product">
<h6><strong>{{car.Year}} {{car.Make}} {{car.Model}}</strong></h6>
<hr>
<a class="btn btn-outline-success" href="{% url 'post_detail' car.pk %}">View</a>
<h4 style="display: inline-block; float: right"><strong>${{car.Price|floatformat:2}}</strong></h4>
</div>
</div>
{% endfor %}
</div>
I would really appreciate if you guys could help me
EDIT
So I changed the order of the views to first filter and then paginate but it still does the same thing. I get no error, but display all the content from the page rather than the filtered ones.
def posts(request):
cars = Userpost.objects.all()
myFilter = UserpostFilter(request.GET, queryset=cars)
cars = myFilter.qs
p = Paginator(Userpost.objects.all(), 9)
page = request.GET.get('page')
cars_list = p.get_page(page)
nums = "a" * cars_list.paginator.num_pages
context = {'cars':cars, "myFilter":myFilter, 'cars_list':cars_list, "nums":nums}
return render(request, 'store/userposts.html', context)
The paginator should work on the cars not on the orignal queryset, since you are paginate over the filtered results
def posts(request):
cars = Userpost.objects.all()
myFilter = UserpostFilter(request.GET, queryset=cars)
if not myFilter.is_valid():
raise ValidationError('filter is invalid')
cars = myFilter.qs
# This is the change
p = Paginator(cars, 9)
page = request.GET.get('page')
cars_list = p.get_page(page)
nums = "a" * cars_list.paginator.num_pages
context = {'cars':cars, "myFilter":myFilter, 'cars_list':cars_list, "nums":nums}
return render(request, 'store/userposts.html', context)

Django nested forms

I have trouble figuring out how to create nested forms. I have two models: Poll and Question (foreign key for Poll is inside Question model). I want it to be possible to add several questions for the poll dynamically inside one form. I've already tried making it work with inlineform_factory, but found troubles saving the form. Right now I have overcomplicated code that throws MultiValueDictError after saving the poll for the second time. I thought maybe there is some other way. Here's my code
models.py
class Question(models.Model):
type_choices = (
('text', 'Текстовый'),
('integer', 'Числовой'),
)
type = models.CharField(verbose_name=u'Тип вопроса', choices=type_choices, max_length=70)
text = models.CharField(verbose_name=u'Текст вопроса', max_length=255)
poll = models.ForeignKey('Poll', on_delete=models.CASCADE, related_name='questions')
class Poll(BaseFields):
objects = models.Manager()
published = PublishedManager()
title = models.CharField(verbose_name=u'Заголовок', max_length=70)
date_from = models.DateTimeField(u'Дата начала')
date_to = models.DateTimeField(u'Дата окончания')
status = models.IntegerField(choices=Status.choices, default=0)
def status_name(self):
return dict(Status.choices).get(self.status)
def update_url(self):
return reverse('poll_update', args=(self.id, ))
forms.py
QuestionInlineFormSet = inlineformset_factory(Poll, Question, extra=1, can_delete=False,
fields=('type', 'text', 'poll'),
widgets={
'type': w.Select(attrs={'class': 'form-control'}),
'text': w.TextInput(attrs={'class': 'form-control'}),
})
class PollForm(CommonForm):
class Meta(CommonForm.Meta):
model = Poll
views.py
class Create(BaseCreateView):
template_name = 'back/poll/poll.html'
page_title = 'Создание опроса'
model = Poll
form_class = PollForm
def form_valid(self, form):
result = super(Create, self).form_valid(form)
questions_formset = QuestionInlineFormSet(data=form.data, instance=self.object, prefix='questions_formset')
if questions_formset.is_valid():
questions_formset.save()
return result
def get_context_data(self, **kwargs):
context = super(Create, self).get_context_data(**kwargs)
context['questions_formset'] = QuestionInlineFormSet(prefix='questions_formset')
return context
class Update(BaseUpdateView):
template_name = 'back/poll/poll.html'
page_title = 'Редактирование опроса'
model = Poll
form_class = PollForm
def form_valid(self, form):
result = super(Update, self).form_valid(form)
questions_formset = QuestionInlineFormSet(data=form.data, instance=self.object, prefix='questions_formset')
if questions_formset.is_valid():
questions_formset.save()
return result
def get_context_data(self, **kwargs):
context = super(Update, self).get_context_data(**kwargs)
context['questions_formset'] = QuestionInlineFormSet(instance=self.get_object(), prefix='questions_formset')
return context
poll.html
{% extends 'back/base/form/base.html' %}
{% block form %}
{% include "back/includes/status_buttons.html" %}
<div class="row">
<div class="col-md-7">
<div class="row" style="margin-bottom: 15px;">
<div class="col-md-12">
{% include 'back/includes/status_label.html' %}
</div>
</div>
{% include "back/base/form/field.html" with field=form.title %}
{% include "back/base/form/datetime_field.html" with field=form.date_from %}
{% include "back/base/form/datetime_field.html" with field=form.date_to %}
{{ questions_formset.management_form }}
{% for question_form in questions_formset %}
{% include "back/poll/question.html" with form=question_form %}
{% endfor %}
<div style="float: right; margin-right: 45px">
<button class="btn btn-success add-form-row">Добавить вопрос</button>
</div>
</div>
</div>
{% endblock %}
question.html
<div class="questions">
<div class="row form-row">
<div class="form-group col-md-5{% if form.type.errors %} has-error{% endif %}">
<label>{{ form.type.label }}</label>
{{ form.type }}
<p class="help-block">{{ form.type.errors }}</p>
</div>
<div class="form-group col-md-5{% if form.text.errors %} has-error{% endif %}">
<label>{{ form.text.label }}</label>
{{ form.text }}
<p class="help-block">{{ form.text.errors }}</p>
</div>
<div class="col-md-2" style="margin-top: 25px">
<button type="button" class="btn btn-danger remove-form-row">✕</button>
</div>
</div>
</div>
<script>
function updateElementIndex(el, prefix, ndx) {
let id_regex = new RegExp('(' + prefix + '-\\d+)');
let replacement = prefix + '-' + ndx;
if ($(el).attr("for")) $(el).attr("for", $(el).attr("for").replace(id_regex, replacement));
if (el.id) el.id = el.id.replace(id_regex, replacement);
if (el.name) el.name = el.name.replace(id_regex, replacement);
}
function deleteForm(prefix, btn) {
let total = parseInt($('#id_' + prefix + '_formset' + '-TOTAL_FORMS').val());
if (total > 1) {
btn.closest('.form-row').remove();
let forms = $('.form-row');
$('#id_' + prefix + '_formset' + '-TOTAL_FORMS').val(forms.length);
for (let i = 0, formCount = forms.length; i < formCount; i++) {
$(forms.get(i)).find(':input').each(function () {
updateElementIndex(this, prefix, i);
});
}
}
}
function cloneMore(selector, prefix) {
let newElement = $(selector).clone(true);
let total = $('#id_' + prefix + '_formset' + '-TOTAL_FORMS').val();
newElement.find(':input:not([type=button]):not([type=submit]):not([type=reset])').each(function () {
let name = $(this).attr('name').replace('-' + (total - 1) + '-', '-' + total + '-');
let id = 'id_' + name;
$(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');
});
newElement.find('label').each(function () {
let forValue = $(this).attr('for');
if (forValue) {
forValue = forValue.replace('-' + (total - 1) + '-', '-' + total + '-');
$(this).attr({'for': forValue});
}
});
total++;
$('#id_' + prefix + '_formset' + '-TOTAL_FORMS').val(total);
$(selector).after(newElement);
}
$(document).on('click', '.add-form-row', function (event) {
event.preventDefault();
cloneMore('.form-row:last', 'questions');
})
$(document).on('click', '.remove-form-row', function (event) {
event.preventDefault();
deleteForm('questions', $(this));
});
</script>
Here's a photo of what it should look like
Again, I want it to be possible to add questions, remove them, save the form. And after I click on the poll in the list of all polls and go to it's edit page I want already added questions to be there.
UPDATE
Found solution to MultiValueDictKeyError in this post
How to debug a Django MultiValueDictKeyError on Formset POST
Now the only problem I have is removing Questions from Poll. My delete button works, it removes the form from page, but after saving the document it reappears.

Django: How can I combine 2 formsets as one so as to display as one inline table (of course with pagination) in template

Say I have 3 models: Groups, Answers, and Questions (Group as ForeignKey and models are broken for normalization). I have created corresponding formsets for Answers and Questions for these models.
On selection of a group, my goal is to display related Answers and Questions in a inline table on form. Something like this:
I am able to get formsets in a template and display them in separate sections, but not able to display them as one table (I don't want to do this using HTML-JS). Is there any way I can pass the answer and question formsets as one context object so that they can be displayed as one table in the template?
Note: there may be 5 questions but only 3 answers for a group, or vice versa.
Also, it would be nice to add pagination to this inline table (or the formsets).
urls.py:
from django.conf.urls import url
from .views import lists, load_questions
from django.urls import path
urlpatterns = [
url(r'lists', lists, name="lists"),
path('ajax/load_questions/', load_questions, name='load_questions'),
]
I have as of now:
models.py:
from django.db import models
from django.utils.timezone import now
class Groups(models.Model):
class Meta:
verbose_name_plural = "Groups"
group = models.CharField(max_length=30)
group_description = models.CharField(max_length=4000,default=None,null=True)
group_date = models.DateTimeField(blank=True, null=True)
def __str__(self):
return self.group
def save(self,*args,**kwargs):
if(self.group and self.group_date is None):
self.group_date=now()
super(Groups,self).save(*args,**kwargs)
class Questions(models.Model):
class Meta:
verbose_name_plural = "Questions"
question = models.CharField(max_length=30,verbose_name="Input Question")
question_description = models.CharField(max_length=4000 ,default=None)
question_date=models.DateTimeField(blank=True,null=True)
question_group = models.ForeignKey(Groups, on_delete=models.CASCADE)
def __str__(self):
return self.question
def save(self,*args,**kwargs):
if(self.question and self.question_date is None):
self.question_date=now()
super(Questions,self).save(*args,**kwargs)
class Answers(models.Model):
class Meta:
verbose_name_plural = "Answers"
answer = models.CharField(max_length=100,verbose_name="Your Answer")
answers_description = models.CharField(max_length=4000,default=None,help_text="",blank=True,null=True)
answer_date = models.DateTimeField(blank=True, null=True)
answer_group = models.ForeignKey(Groups, on_delete=models.CASCADE,blank=True)
#valid_question = models.ManyToManyField("Questions",related_name="answers")
print("Model Called")
def __str__(self):
return self.answer
def save(self,*args,**kwargs):
if(self.answer and self.answer_date is None):
self.answer_date=now()
super(Answers,self).save(*args,**kwargs)
forms.py:
from django.forms import inlineformset_factory,Textarea,BaseFormSet
from django.forms.models import modelformset_factory
from .models import Groups,Questions,Answers
from django import forms
class groupForm(forms.Form):
group = forms.CharField(label="Group",max_length=100)
def choices(self):
a=[('','Select a Group')]
return a+[ (o.id, str(o)) for o in Groups.objects.all()]
def __init__(self, *args, **kwargs):
super(groupForm, self).__init__(*args, **kwargs)
print([(o.id, str(o)) for o in Groups.objects.all()])
print(type([(o.id, str(o)) for o in Groups.objects.all()]))
self.fields['group'] = forms.ChoiceField(
choices=self.choices(),
required=True,
)
#self.fields['group'].label = "Select Group"
from crispy_forms.helper import FormHelper, Layout
class questionForm(forms.ModelForm):
class Meta:
model = Questions
#fields = ['question', 'question_description',]
exclude = ()
questionFormSet = modelformset_factory(Questions, form=questionForm, extra=1)
class answerForm(forms.ModelForm):
class Meta:
model = Groups
exclude = ()
def add_fields(self, form, index):
"""A hook for adding extra fields on to each form instance."""
super(answerForm, self).add_fields(form, index)
# here call a custom method or perform any other required action
form.set_index(index)
#answerFormSet = modelformset_factory(Answers, form=answerForm, extra=1)
questionFormSet = inlineformset_factory(Groups, Questions,form=answerForm)
answerFormSet = inlineformset_factory(Groups, Answers,form=answerForm)
#myFormset=questionFormSet|answerFormSet
views.py:
from django.shortcuts import render, redirect
from .models import Answers, Questions, Groups
# Create your views here.
from .forms import groupForm,questionFormSet,answerFormSet
from django.http import JsonResponse
def lists(request):
if request.method == 'POST':
questionsform = questionFormSet(request.POST)
answersform = answerFormSet(request.POST)
groupsform = groupForm(request.POST)
print(answersform.is_valid())
print(answersform.errors.as_data())
if answersform.is_valid() and groupsform.is_valid() and questionsform.is_valid():
print("in views")
print(answersform.cleaned_data)
print(type(groupsform.cleaned_data))
a=Answers(answer=answersform.cleaned_data['answer'],
answers_description="",
answer_group=Groups(groupsform.cleaned_data['group']))
a.save()
q = Questions(question=questionsform.cleaned_data['question'],
question_description="",
question_group=Groups(groupsform.cleaned_data['group']))
q.save()
return redirect('lists')
else:
return redirect('chatbot_welcome')
else:
context = {
'groups': groupForm,
'questions': questionFormSet,
'answers': answerFormSet,
}
return render(request, 'lists.html', context)
def load_questions(request):
group_id = request.GET.get ('groupId')
data = {
"Table": {
"TR": [
]
}
}
if group_id is not None:
questions = (Questions.objects.filter(question_group=group_id).values("question", "question_group"))
answers = (Answers.objects.filter(answer_group=group_id).values("answer", "answer_group"))
l_len = len(questions) if len(questions) >= len(answers) else len(answers)#lambda can be used here
for i in range(l_len):
try:
if list(questions)[i]["question"]:
q=list(questions)[i]["question"]
except:
q=''
try:
if list(answers)[i]["answer"]:
a=list(answers)[i]["answer"]
except:
a=''
data["Table"]["TR"].append({
"row": i+1,
"group": group_id,
"question": q,
"Answer": a
})
print(data)
return JsonResponse(data)
else:
return JsonResponse(data)
Template:
{% extends "base.html" %}
{% load staticfiles %}
{% block content %}
{% load crispy_forms_tags %}
<form method="post" id="groupform" data-group-url="{% url 'load_questions' %}">
{% csrf_token %}
<div class="panel-group" id="accordion18" style="display: block;">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion18" href="#accBody20" id="accHeading20" class="">Groups</a>
</h4>
</div>
<div class="panel-collapse collapse in" id="accBody20" style="height: auto;">
<div class="panel-body">
<div class="row"><div class="col-md-12"><div class="form-group">
<div class="form-group">
{{ groups }}
Create a New Group
</div></div></div></div>
</div>
</div>
</div>
</div>
<div class="panel-group" id="accordion21" style="display: block;">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion21" href="#accBody23" id="accHeading23" class="">Questionnaires</a>
</h4>
</div>
<div class="panel-collapse collapse in" id="accBody23" style="height: auto;">
<div class="panel-body">
<div class="row"><div class="col-md-12"></div></div><div class="row"><div class="col-md-12"><div class="form-group">
<div class="panel-body">
<span>{{groups.group.name|title }}</span>:<span id="group">None</span>
{{questions.forms}}
{% for form in questions.forms %}
{% for field in form %}
field={{field}}
{% endfor %}
{% endfor %}
<table>
<thead>
{% for form in questions.forms %}
{% if forloop.first %}
{% for field in form %}
<th>{{ field.label_tag }}</th>
{% endfor %}
{% endif %}
</thead>
<tbody>
<tr>
{% for field in form %}
<td>{{ field }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
<table>
<thead>
{% for form in answers.forms %}
{% if forloop.first %}
{% for field in form %}
<th>{{ field.label_tag }}</th>
{% endfor %}
{% endif %}
</thead>
<tbody>
<tr>
{% for field in form %}
<td>{{ field }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
<!--
<form action="" method="post">
{% csrf_token %}
{% crispy questions %}{% crispy answers %}
</form>
-->
<input type="button" class="add-row" value="Add Row">
<button type="button" class="delete-row">Delete Row</button>
</div>
<div class="panel-body">
<div class="tbl_user_data"></div>
</div>
<button id="button40" type="submit" value="Submit" class="btn btn-primary">Submit</button></div></div></div></div>
</div>
</div>
</div>
</form>
<script>
var groupId=0;
$("#id_group").change(function () {
var url = $("#groupform").attr("data-group-url"); // get the url of the `load_cities` view
groupId = $(this).val(); // get the selected country ID from the HTML input
$('#group').text(groupId);
$.ajax({ // initialize an AJAX request
url: url,
//data: $("#groupform").serialize(),
dataType: 'json',// set the url of the request (= localhost:8000/hr/ajax/load-cities/)
data: {
'groupId': groupId // add the country id to the GET parameters
},
success: function (data) { // `data` is the return of the `load_cities` view function
var data1={
"Table": {
"TR": [
{
"row": 1,
"group": 1,
"question": "heyy",
"Answer": "hey"
},
{
"row": 2,
"group": 1,
"question": "y",
"Answer": "heyy"
},
{
"group": 1,
"row": 3,
"question": "How are you",
"Answer": "Fine"
}
]
}
}
//questions_list=JSON.parse(data.questions)[0].question;
//alert(questions_list)
//answers_list=JSON.parse(data.answers)[0].answer;
//alert(answers_list)
writeintoTable(data)
//alert('done')
}
});
});
function runOnLoad(){
//alert(1)
}
var random_id = function ()
{
var id_num = Math.random().toString(9).substr(2,3);
var id_str = Math.random().toString(36).substr(2);
return id_num + id_str;
}
function writeintoTable(data){
/*
$.each(data.Table.TR, function( index, json ) {
//alert(index +" -- "+ data.Table.TR[index].question)
$("#setupbody").append('<tr><td>'
+data.Table.TR[index].row+
'</td><td>'
+data.Table.TR[index].group+
'</td><td>'
+data.Table.TR[index].question+
'</td><td>'
+data.Table.TR[index].Answer+
'</td></tr>');
});*/
/*
for (i=0;i<=data.Table.TR;i++)
{
$("#setupbody").append('<tr><td></td><td>1</td><td>Hi</td><td>Hello</td></tr>');
}*/
var tbl = '';
tbl +='<table class="table table-hover">'
//--->create table header > start
tbl +='<thead>';
tbl +='<tr>';
tbl +='<th>Select</th>';
tbl +='<th>Row</th>';
tbl +='<th>Group</th>';
tbl +='<th>Question</th>';
tbl +='<th>Answer</th>';
tbl +='<th>Options</th>';
tbl +='</tr>';
tbl +='</thead>';
//--->create table header > end
//--->create table body > start
tbl +='<tbody>';
//--->create table body rows > start
$.each(data.Table.TR, function(index, val)
{
//you can replace with your database row id
var row_id = random_id();
//loop through ajax row data
tbl +='<tr row_id="'+row_id+'">';
tbl +='<td><input type="checkbox" value="" name="record" id="cb'+val['row']+'"></td>'
tbl +='<td ><div class="row_data" edit_type="click" col_name="rnum">'+val['row']+'</div></td>';
tbl +='<td ><div class="row_data" edit_type="click" col_name="fname">'+val['group']+'</div></td>';
tbl +='<td ><div class="row_data" edit_type="click" col_name="lname">'+val['question']+'</div></td>';
tbl +='<td ><div class="row_data" edit_type="click" col_name="email">'+val['Answer']+'</div></td>';
//--->edit options > start
tbl +='<td>';
tbl +='<span class="btn_edit" > <a href="#" class="btn btn-link " row_id="'+row_id+'" > Edit</a> </span>';
//only show this button if edit button is clicked
tbl +='<span class="btn_save"> Save | </span>';
tbl +='<span class="btn_cancel"> Cancel | </span>';
tbl +='</td>';
//--->edit options > end
tbl +='</tr>';
});
//--->create table body rows > end
tbl +='</tbody>';
//--->create table body > end
tbl +='</table>'
//--->create data table > end
//$("#dataTable").append(tbl);
$(document).find('.tbl_user_data').html(tbl);
$(document).find('.btn_save').hide();
$(document).find('.btn_cancel').hide();
}
//--->make div editable > start
$(document).on('click', '.row_data', function(event)
{
event.preventDefault();
if($(this).attr('edit_type') == 'button')
{
return false;
}
//make div editable
$(this).closest('div').attr('contenteditable', 'true');
//add bg css
$(this).addClass('bg-warning').css('padding','5px');
$(this).focus();
})
//--->make div editable > end
//--->save single field data > start
$(document).on('focusout', '.row_data', function(event)
{
event.preventDefault();
if($(this).attr('edit_type') == 'button')
{
return false;
}
var row_id = $(this).closest('tr').attr('row_id');
var row_div = $(this)
.removeClass('bg-warning') //add bg css
.css('padding','')
var col_name = row_div.attr('col_name');
var col_val = row_div.html();
var arr = {};
arr[col_name] = col_val;
//use the "arr" object for your ajax call
$.extend(arr, {row_id:row_id});
//out put to show
$('.post_msg').html( '<pre class="bg-success">'+JSON.stringify(arr, null, 2) +'</pre>');
})
//--->save single field data > end
//--->button > edit > start
$(document).on('click', '.btn_edit', function(event)
{
event.preventDefault();
var tbl_row = $(this).closest('tr');
var row_id = tbl_row.attr('row_id');
tbl_row.find('.btn_save').show();
tbl_row.find('.btn_cancel').show();
//hide edit button
tbl_row.find('.btn_edit').hide();
//make the whole row editable
tbl_row.find('.row_data')
.attr('contenteditable', 'true')
.attr('edit_type', 'button')
.addClass('bg-warning')
.css('padding','3px')
//--->add the original entry > start
tbl_row.find('.row_data').each(function(index, val)
{
//this will help in case user decided to click on cancel button
$(this).attr('original_entry', $(this).html());
});
//--->add the original entry > end
});
//--->button > edit > end
//--->button > cancel > start
$(document).on('click', '.btn_cancel', function(event)
{
event.preventDefault();
var tbl_row = $(this).closest('tr');
var row_id = tbl_row.attr('row_id');
//hide save and cacel buttons
tbl_row.find('.btn_save').hide();
tbl_row.find('.btn_cancel').hide();
//show edit button
tbl_row.find('.btn_edit').show();
//make the whole row editable
tbl_row.find('.row_data')
.attr('edit_type', 'click')
.removeClass('bg-warning')
.css('padding','')
tbl_row.find('.row_data').each(function(index, val)
{
$(this).html( $(this).attr('original_entry') );
});
});
//--->button > cancel > end
//--->save whole row entery > start
$(document).on('click', '.btn_save', function(event)
{
event.preventDefault();
var tbl_row = $(this).closest('tr');
var row_id = tbl_row.attr('row_id');
//hide save and cacel buttons
tbl_row.find('.btn_save').hide();
tbl_row.find('.btn_cancel').hide();
//show edit button
tbl_row.find('.btn_edit').show();
//make the whole row editable
tbl_row.find('.row_data')
.attr('edit_type', 'click')
.removeClass('bg-warning')
.css('padding','')
//--->get row data > start
var arr = {};
tbl_row.find('.row_data').each(function(index, val)
{
var col_name = $(this).attr('col_name');
var col_val = $(this).html();
arr[col_name] = col_val;
});
//--->get row data > end
//use the "arr" object for your ajax call
$.extend(arr, {row_id:row_id});
//out put to show
$('.post_msg').html( '<pre class="bg-success">'+JSON.stringify(arr, null, 2) +'</pre>')
});
//--->save whole row entery > end
$(".add-row").click(function(){
var question = $("#id_question").val();
//var group = $("#group").val();
var answer = $("#id_answer").val();
if (question=='' || question=='undefined'||answer=='' || answer=='undefined' )
{
alert('row not complete to add')
return false;
}
//var markup = "<tr><td><input type='checkbox' name='record'></td><td>" + name + "</td><td>" + email + "</td></tr>";
var tbl = '';
//you can replace with your database row id
var row_id = random_id();
//loop through ajax row data
tbl +='<tr row_id="'+row_id+'">';
tbl +='<td><input type="checkbox" value="" name="record" id="cb'+100+'"></td>'
tbl +='<td ><div class="row_data" edit_type="click" col_name="rnum">'+100+'</div></td>';
tbl +='<td ><div class="row_data" edit_type="click" col_name="fname">'+groupId+'</div></td>';
tbl +='<td ><div class="row_data" edit_type="click" col_name="lname">'+question+'</div></td>';
tbl +='<td ><div class="row_data" edit_type="click" col_name="email">'+answer+'</div></td>';
//--->edit options > start
tbl +='<td>';
tbl +='<span class="btn_edit" > <a href="#" class="btn btn-link " row_id="'+row_id+'" > Edit</a> </span>';
//only show this button if edit button is clicked
tbl +='<span class="btn_save"> Save | </span>';
tbl +='<span class="btn_cancel"> Cancel | </span>';
tbl +='</td>';
//--->edit options > end
tbl +='</tr>';
$("table tbody").append(tbl);
$(document).find('.btn_save').hide();
$(document).find('.btn_cancel').hide();
});
// Find and remove selected table rows
$(".delete-row").click(function(){
var r = confirm("Selected Row will be deleted.");
if (r == true) {
$("table tbody").find('input[name="record"]').each(function(){
if($(this).is(":checked")){
$(this).parents("tr").remove();
}
});
} else {
$("table tbody").find('input[name="record"]').each(function(){
if($(this).is(":checked")){
$(this).prop('checked', false);
}
});
alert("Row(s) not Deleted!");
}
});
</script>
{% endblock %}