django-component - passing string instead of context variable - django

Having trouble passing context variable to a django-component
View:
labels = "'January','February','March','April','May','June'"
data = "69, 10, 5, 2, 20, 30"
colors = "'#3e95cd', '#8e5ea2','#3cba9f','#e8c3b9','#c45850','#a45350'"
context = { 'title': title, 'language': langCode, 'clabels':labels, 'cdata':data, 'ccolors':colors}
return render(request, "reports/dashboard.html", context)
In Template:
<div class="col-lg-6">{% component "simplechart" width="980" height="300" chartid="chart1" title="We are testing" clabels='{{ clabels }}' cdata="{{ cdata }}" ccolors="{{ ccolors }}" type="bar" %}</div>
Components.py
#component.register("simplechart")
class SimpleChart(component.Component):
# Note that Django will look for templates inside `[your app]/components` dir
# To customize which template to use based on context override get_template_name instead
template_name = "simplechart/simplechart.html"
# This component takes three parameters
def get_context_data(self, width, height, chartid, title, clabels,cdata,ccolors, type):
print("CHART GET CONTEXT")
print(cdata)
print(clabels)
return {
"width": width,
"height": height,
"chartid": chartid,
"title": title,
"clabels": clabels,
"cdata": cdata,
"ccolors": ccolors,
"type": type
}
class Media:
css = {
'all': ('css/simplecard.css')
}
js = 'js/cmx_chart.js'
The debug print statements output:
CHART GET CONTEXT
{{cdata}}
{{clabels}}
It is passing in the litereal string, not replacing with context variable passed in from the view. Any ideas what I'm doing wrong?

The problem is that you are passing a string: "{{ clabels }}". Delete the quotes and the "{{" inside the tag. So:
{% component "simplechart" width="980" height="300" chartid="chart1" title="We are testing" clabels=clabels cdata=cdata ccolors=ccolors type="bar" %}

Related

Rendering a v2 form from Preside formbuilder

I'm stuck in rendering a v2 form that I created using Preside formbuilder.
so far I have:
args.newsletter = formbuilderService.getForm("[id]");
args.rendered = formbuilderService.renderForm(
formId = args.newsletter.id,
layout = "default",
validationResult = "");
but all I get from args.rendered is:
<div class="formbuilder-form form form-horizontal"> <div class="alert alert-success"></div> </div>
But I want to render the whole form, like if I would add it by using a widget.
FormbuilderService.renderForm expects the configuration argument to contain data from the form builder widget in order to render the form correctly.
You can use the renderWidget helper to render the form
args.newsletter = formbuilderService.getForm( "[id]" );
args.rendered = renderWidget(
widgetId = "formbuilderForm"
, config = {
form = args.newsletter
, layout = "default"
, instanceid = ""
}
);

how to send just one part of an object to template in django

I want to send just one part of an object to template.
I Have 2 models like below:
class Person(models.Model):
name = models.CharField(max_legth=50)
sure_name = models.CharFiled(max_length=50)
class Office(models.Model):
location = models.CharField(max_legth=50)
and I also created a model like below:
class PersonOffice(models.Model):
person = models.ForeignKey(Person)
office = models.ForeignKey(Office)
now, when I take data from database, by PersonOffice.objects.all(),the data is like below:
{
{
"pk": 0,
"person": {
"pk":0,
"name":"Harry",
"sure_name":"Potter"
},
"office":{
"pk":5,
"location":"Toronto"
}
},
{
"pk": 1,
"person": {
"pk":6,
"name":"John",
"sure_name":"Kelly"
},
"office":{
"pk":6,
"location":"NewYork"
}
}
}
I want to send just offices to the template by render function. How can I do it?
thanks
Updated
I want to use it in template with {% for %} loop. for example:
{% for office in Offices %}
<p>Office location: {{ office.location }}</p>
{% endfor %}
I used below code:
offices = PersonOffice.objects.all().values('office')
print(offices)
and below is the result in terminal:
<QuerySet [{'office': 1}, {'office': 2}, {'office': 11}]>
You can use values
PersonOffice.objects.values('office')
This will output a queryset with office for each object.
EDIT:
PersonOffice.objects.values('office__location')

How to update a specific value inside a dictionary using JQuery and Flask?

I've created a session list that contains my products, i need to update the quantity of any product by increasing it amount, for that am using an HTML type="number" , i also created a function which take the changed amount and multiplying it value with the current quantity, so lets say the amount of the first product by default is 2 by increasing the number lets say 2 the product amount will become 4 and so on, also the price will be multiplied .
Here are the codes:
<th style="text-align: center;" class="amount-izd">{{value["amount"]}}</th>
<th style="text-align: center; width: 14%;">
<div class="block">
<input type="number" id="myNumber" value="1" min=1 data-amount='{{value["amount"]}}' data-pros='{{value["id"]}}' data-price='
{% if g.currency == "euro" %}
{{format_price(value["price"] * config.SITE_CURRENCIES["euro"]).rsplit(".",1)[0]}}
{% elif g.currency == "dollar" %}
{{format_price(value["price"] * config.SITE_CURRENCIES["dollar"]).rsplit(".",1)[0]}}
{% else %}
{{format_price(value["price"] * config.SITE_CURRENCIES["ruble"]).rsplit(".",1)[0]}}
{% endif %}
'>
<label for="myNumber">qty</label>
</div>
</th>
JQuery codes:
$("input[type='number']").bind('keyup change click', function (e) {
if (! $(this).data("previousValue") ||
$(this).data("previousValue") != $(this).val()
)
{
var currentAmount = $(this).attr('data-amount');
var currentPrice = $(this).attr('data-price');
$(this).closest('tr').find('.amount-izd').text(parseInt(currentAmount) * $(this).val());
$(this).closest('tr').find('.price-izd').text(parseInt(currentPrice) * $(this).val());
$.ajax({
type: 'post',
url: '/standard-{{g.currency}}/profile/'+$(this).attr("data-pros")+'/update/price/' + parseInt(currentPrice) * $(this).val(),
cache: false
}).done(function(data){
if(data.error){
toastr.error(data.error)
}
});
$(this).data("previousValue", $(this).val());
} else {
}
});
And finally views.py :
#profile_route.route("/standard-<set_curr>/profile/cart/", methods=['GET','POST'])
#authorize
def cart_products():
if "cart" not in session:
return render_template("my-cart.html", display_cart = {}, total = 0)
else:
items = session["cart"]
dict_of_products = {}
total_price = 0
for item in items:
product = Goods.query.get(item)
total_price += product.price
if product.id in dict_of_products:
pass
else:
dict_of_products[product.id] = {"qty":1, "name":product.product_name, 'category':product.Category.name, "sizes": product.sizes, "hex_color":product.hex_color, "text_color":product.text_color, "material":product.material, "article":product.article, "price":product.price, "sort": product.sort, "amount": product.amount, 'slug':product.slug, 'public_id' : product.public_id, "id":product.id}
return render_template("my-cart.html", display_cart=dict_of_products, total = total_price)
#profile_route.route("/standard-<set_curr>/profile/<int:id>/update/price/<price>", methods=['GET','POST'])
#login_required
def update_price(id, price):
items = session["cart"]
dict_of_products = {}
for item in items:
product = Goods.query.get(item)
if product.id in dict_of_products:
dict_of_products[id]['price'] = price
return jsonify(success=dict_of_products[id]['price'])
return jsonify(error='No product found.')
If i changed the amount , in console i got a 500 error that says:
return jsonify(success=dict_of_products[id]['price'])
KeyError: 47
Please how to overcome this problem ?
Update:
I was wondering , is it possible to update any value of the dictionary by accessing it directly from JQuery ??

Add Calendar Widget to Django Form

I have a view on my website that uses a couple of Django forms to allow the user to specify a date range. I was able to get it so that one Django form creates a start and end field and that when the user clicks on those fields a calendar widget (from here) pops up that allows the user to select a date range. However, when the user selects the date range and hits "apply" the form fields aren't updated.
EDIT
The form I'm using looks like this:
class DateRangeForm(forms.Form):
def __init__(self, *args, **kwargs):
initial_start_date = kwargs.pop('initial_start_date')
initial_end_date = kwargs.pop('initial_end_date')
required_val = kwargs.pop('required')
super(DateRangeForm,self).__init__(*args,**kwargs)
self.fields['start_date'].initial = initial_start_date
self.fields['start_date'].required = required_val
self.fields['end_date'].initial = initial_end_date
self.fields['end_date'].required = required_val
start_date = forms.DateField()
end_date = forms.DateField()
The view they are used in looks like this:
def table_search(request):
initial_start = "2015/2"
initial_end = "2015/222"
message = {'last_url':'table_search'}
if request.method == "POST":
daterange_form = DateRangeForm(request.POST,required=True,initial_start_date=initial_start,initial_end_date=initial_end)
else:
daterange_form = DateRangeForm(required=True,initial_start_date=initial_start,initial_end_date=initial_end)
search_dict.update({'daterange_form':daterange_form})
return render(request, 'InterfaceApp/table_search.html', search_dict)
The Django template here:
<div class="container">
<form action="/InterfaceApp/home/" method="post" class="form">
{% csrf_token %}
<div class="daterangepicker-container mcast-search-filter">
<div class="daterangepicker-label">Date range:</div>
<div id="daterange" class="daterangepicker-content">
{% bootstrap_form daterange_form %}
<i class="icon-calendar icon-large"></i>
</div>
</div>
</form>
</div>
<script>
// the start_date and end_date are the ids that django form fields created
$("#daterange").daterangepicker({
locale: {
format: 'YYYY-MM-DD'
},
startDate: '{{daterange_form.start_date.value}}',
endDate: '{{daterange_form.end_date.value}}'
});
</script>
EDIT 2
And the forms currently look like this (after #ShangWang suggestion) rendered:
Is there a way to display it so the start and end date fields show up? I tried changing the div class so it wasn't hidden, and then they showed up but seemed superfluous.
I use bootstrap-daterangepicker: https://github.com/dangrossman/bootstrap-daterangepicker. It would bind the widget's change to your django form field, so you don't need to manipulate the data once it comes to the views.py.
To get more details you should download and play with it, but here's a rough idea:
Your form.py:
class DateRangeForm(forms.Form):
start_date = forms.DateField()
end_date = forms.DateField()
def __init__(self, *args, **kwargs):
# initialize the start and end with some dates
Your template:
<div class="daterangepicker-container mcast-search-filter">
<div class="daterangepicker-label">Date range:</div>
<div id="daterange" class="daterangepicker-content">
<i class="icon-calendar icon-large"></i>
<span></span> <b class="caret"></b>
</div>
</div>
<!-- This is a hidden div that holds your form fields -->
<div class="hide">From {{ daterange_form.start_date }} to {{ daterange_form.end_date }}</div>
To trigger the widget you need a javascript binding:
// the id_start_date and id_end_date are the ids that django form fields created
$("#daterange").initDateRangePicker("#id_start_date", "#id_end_date");
I created a datepicker wrapper, and defined the initDateRangePicker function. You should put following code in a file called daterangepicker.js and import that in your template as well(or simply copy it into your template):
(function($) {
$.fn.initDateRangePicker = function(start_date_el, end_date_el, future) {
return this.each(function() {
var start = moment($(start_date_el).val());
var end = moment($(end_date_el).val());
var display_date = function(start, end) {
var str = ""
str += start.format('MMMM Do, YYYY');
str += " - ";
str += end.format('MMMM Do, YYYY');
return str;
};
$(this).find("span").html(display_date(start, end));
var self = this;
if(!future) {
$(this).daterangepicker({
format: 'YYYY-MM-DD',
timePicker: false,
ranges: {
'Last 7 days': [moment().subtract('days', 6), moment()],
'Month to date': [
moment().startOf('month'),
moment(),
],
'Last Month': [
moment().subtract('month', 1).startOf('month'),
moment().subtract('month', 1).endOf('month'),
]
},
}, function(start, end) {
$(start_date_el).val(start.format('YYYY-MM-DD'));
$(end_date_el).val(end.format('YYYY-MM-DD'));
$(self).find("span").html(display_date(start, end));
});
}
else {
$(this).daterangepicker({
format: 'YYYY-MM-DD',
timePicker: false,
ranges: {
'Next 7 days': [moment().add('days', 1), moment().add('days', 7)],
'Next month': [
moment().add('month', 1).startOf('month'),
moment().add('month', 1).endOf('month'),
],
},
}, function(start, end) {
$(start_date_el).val(start.format('YYYY-MM-DD'));
$(end_date_el).val(end.format('YYYY-MM-DD'));
$(self).find("span").html(display_date(start, end));
});
}
});
};
}).call(this, jQuery);

Grails findByAll with params doesn't work

I try to display a custom list from my controller, but when I want to use the pagination,
it doesn't work: for example if I want to diplay 10 entries (params.max = Math.min(max ?: 10, 100)), in my gsp list view all entries are displayed in the same page. I also noticed that I have pagination but I when I use it, I still have all entries displayed.
My code
def user = User.findByLogin("John")
List MyList
switch (userView){
case "mylist":
params.sort="date"
params.order="desc"
params.max = Math.min(max ?: 10, 100)
MyList = DS.findAllByCpCreator(user,[params:params])
case ...
...
def DSList = MyList
def DSCount = MyList.size()
[DSInstanceList: DSList, DSInstanceTotal: DSCount,userView:userView]
In gsp view, I modified the pagination like this:
<div class="pagination">
<g:if test="${userView!=null}">
<g:paginate total="${DSInstanceTotal}" params="${[q:userView]}" />
</g:if>
<g:else>
<g:paginate total="${DSInstanceTotal}" />
</g:else>
</div>
In your action, you are passing findAll* a map of maps, it should be:
MyList = DS.findAllByCpCreator(user, params)
EDIT: actually your view tag is ok
For count, you should use: http://grails.org/doc/2.2.x/ref/Domain%20Classes/countBy.html
DSCount = DS.countByCpCreator(user)