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
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.
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.
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)
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.
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 %}