flask admin datepicker localization - flask

1. Problem
This is the datepicker in my flask admin form, all the month and week names are in English, but I want customize the names also the start week number. like this question: How do I localize the jQuery UI Datepicker?. I searched a lot, but all I got is about how to customize date format in flask.
2. My code
class Receipt(db.Model):
delivery_time = db.Column(db.Date,index=True)
It's a date column can view and edit in admin form.
Is there any way to config the month、week names ? And how to make the start week number to Monday not Saturday, thanks a lot.

You could change locale globally in your templates, by adding:
<script>moment.locale(#YOURLOCALESTRING);</script>
This would guarantee that any other script loaded after this one that uses moment would use the global locale setting. You can find more details about setting locale here.

That code is not a good solution, but it can be helpful:
{% block tail_js %}
{{ super() }}
<script>
$(document).ready(function () {
var el = $('#your_element_id'); // change this selector
el.daterangepicker({
timePicker: true,
showDropdowns: true,
timePickerIncrement: 1,
timePicker12Hour: false,
separator: ' to ',
format: el.attr('data-date-format'),
locale: {
format: "MM/DD/YYYY",
separator: " - ",
applyLabel: "Выбрать",
cancelLabel: "Закрыть",
fromLabel: "От",
toLabel: "До",
customRangeLabel: "Custom",
weekLabel: "W",
daysOfWeek: ["Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"],
monthNames: [ "Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Октябрь", "Сентябрь", "Ноябрь", "Декабрь"],
firstDay: 1
},
});
});
</script>
{% endblock %}
P.S.
Need to add this code into your master.html

I find a quick way to fix this issue, but I know there are better ways to do this. just modify the code in path:lib/python2.7/site-packages/flask_admin/static/vendor/daterangepicker.js to below:
this.locale = {
applyLabel: 'Apply',
cancelLabel: 'Cancel',
fromLabel: 'From',
toLabel: 'To',
weekLabel: 'W',
customRangeLabel: 'Custom Range',
// daysOfWeek: moment.weekdaysMin(),
daysOfWeek: ["日","一","二","三","四","五","六"],
// monthNames: moment.monthsShort(),
monthNames: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",],
// firstDay: moment.localeData()._week.dow
firstDay: 1
};

Related

Trying to render a django form field as a variable in a script tag in an html template, but the javascript isn't working

My issue is simple enough--I am trying to render a form field from a django form into a javascript variable, defined within a <script> tag, within a django template.
When I output a CharField, there's no problem. But when I try to render a ChoiceField, the resulting output breaks the html, and prevents the script tag from correctly parsing my variable.
To demonstrate my setup, I have a form defined in forms.py, exactly like this example form:
from django import forms
form = TestForm(forms.Form):
testfield = forms.ChoiceField(initial="increase_rate",
choices=[
("a", "option a"),
("b", "option b"),
("c", "option c"),
("d", "option d")
])
I am instantiating the form in views.py, and passing it into a django template to be rendered.
from django.shortcuts import render
from .forms import TestForm
[...]
#require_http_methods(["GET"])
def webpage(request):
form = TestForm()
return render(request, 'index.html', {"form":form})
Then, finally, in my template, I have something like the following:
[...]
<script>
window.testfield = '{{ form.testfield }}'
</script>
[...]
Up until this point, everything works perfectly. No trouble at all. But when I render the field into the template, and inspect it in my browser, I get the following:
<script>
window.testfield = '<select name="trigger" id="id_trigger">
<option value="a" selected>option a</option>
<option value="b">option b</option>
<option value="c">option c</option>
<option value="d">option d</option>
</select>'
</script>
This output breaks the html, and prevents the script tag from being interpreted as a variable like I want. This is a major problem, because I want to reuse these programmatically elsewhere on the page.
I tried the following:
<script>
window.testfield = '{{ form.testfield|escape }}'
</script>
But was still unsuccessful. Any help anyone can give would be greatly appreciated!
I am actively researching a solution. My current guess is that the output needs to be escaped somehow that I don't understand. I figure the template tags and filters have my answer, I just have to find it. Will post an update once a solution is found.
Use <script type="text/template"></script>.
This way the browser knows it's just text and will ignore it.
So, I figured it out. Turns out that the issue was that the presence of white space, line breaks, and unescaped double quotes (") were breaking the tag when it was parsed at HTML.
So I ended up using the following:
{% spaceless %}
<script>
window.testfield = '{{ form.testfield|addslashes }}'
</script>
{% endspaceless %}
And it worked, allowing me to store the string representation of the django form field in a javascript variable. As per the documentation, the {% spaceless %} "Removes whitespace between HTML tags. This includes tab characters and newlines." [1]. As for the filter |addslashes, it "Adds slashes before quotes. Useful for escaping strings in CSV" [2]. In my case, both solutions were needed, as without either of them, the script tag broke.
As for why the |escape filter didn't work on it's own, I'm not sure. Reading the documentation, it seems like it probably should have. The following is what the |escape filter actually does [3]:
Escapes a string’s HTML. Specifically, it makes these replacements:
< is converted to <
> is converted to >
' (single quote) is converted to '
" (double quote) is converted to "
& is converted to &
I can only guess why this didn't work. I figure it's because it didn't do anything about the white space. But I shouldn't speculate. I welcome any explanations you might have. As ever, understanding the way the machine thinks is better than any single, specific solution. Thanks.
[1] - https://docs.djangoproject.com/en/dev/ref/templates/builtins/#spaceless
[2] - https://docs.djangoproject.com/en/dev/ref/templates/builtins/#addslashes
[3] - https://docs.djangoproject.com/en/dev/ref/templates/builtins/#escape

get values from multiple inputs with same key django

I'm fighting against the django forms. When I've solved one problem a new one appears, well I got a "dynamic" html with 3 types of forms.
class NameForm(forms.Form):
text = forms.CharField(widget=forms.TextInput(attrs={'id': 'field1'}))
select = forms.ChoiceField(widget = forms.Select(attrs={'id': 'field1'}), choices = ([('default','Select option')]), initial='default')
date = forms.DateField(widget=DateTypeInput(attrs={'id': 'field1'}))
And via JavaScript I create one type or other:
var createElement={
'text': '{{ form.text }}',
'select':'{{ form.select }}',
'date': '{{ form.date }}',
}
Then I want to get all type of elements created but the problem is there are multiple inputs with name "text" or select or date.
I parse this data with method GET and this one uses a dictionary. This dict only can have one key "text".
How can I solve this problem? Thanks a lot.
You can use request.GET.getlist('text') to get multiple values as a list.
But you are probably better off using formsets for something like this.

Separate Kendo Scheduler Editor Templates

Am I able to load a custom template based on a condition?
eg..
If I was making a booking for a mechanic then the editor form would show textboxes for carmodel, yearmake etc.
If I was making a booking for a carpet cleaner the editor form would show textboxes for howmanyrooms, room sizes etc..
Am I able to pass an ID of a service and show the particular editor form for the correct service?
we can currently display this functionality if we create different scheduler Views but that would then create a duplication of many pages.
I had the exact same problem and after searching a long time and combining what I found, I came to this :
1) above my scheduler I have a kendodropdownlist
<input id="reservationPicker" />
<script>
$("#reservationPicker").kendoDropDownList({
dataTextField: "name",
dataValueField: "reservationDefTypeId",
dataSource: reservationPickerDataSource
});
</script>
2) my event has an extra field reservationDef which will hold the information of the dropdownlist.
3) I can use this information in my template
<script id="editorScheduler" type="text/x-kendo-template">
<center>
<div id="main">
#if(reservationDef=="mechanic"){#
<h3>Mechanic stuff</h3>
#}else if(reservationDef=="carpetCleaner"){#
<h3>Carpet Cleaner stuff</h3>
#}else{#
<h3>unknown type of reservation !</h3>
#: reservationDef #
#}#
</div>
</center>
</script>
4) I use this template in my scheduler
editable: {
template: $("#editorScheduler").html()
},
5) but what with a new appointment ! I use the add event of the scheduler and I fill in this information in the event
add: function (e) {
var reservationTypes = $("#reservationPicker").data("kendoDropDownList");
var selectedReservationType = reservationTypes.dataItem();
e.event.reservationDef = selectedReservationType.appointmentTitle;
},
This does the trick for me. Good luck !
No I didn't but I did find a work around by dynamically adding textboxes on the following page. To b able to choose a view model at runtime for the scheduler didn't seem possible
if anyone knows how to load a particular viewmodel at runtime using mvc would be very intresting for future ideas and development.

Why does a DOJO tools text area control break my forms

Hi I'm using django comments in one of my apps. I customized the comments framework to fit my needs. Everything works properly until I use dojo to make the textarea for the comments expandable http://dojotoolkit.org/reference-guide/1.7/dijit/form/Textarea.html#dijit-form-textarea. After adding the script the form throws an error after submitting: this field is required. So it seems django doesn't recognize the textarea as part of the form anymore.
in my template I use the standart comment tags:
{% render_comment_form for event %}
{% render_comment_list for event %}
When I'm adding the dojo script, the textarea gets expandable, but the form doesn't pass it's value anymore.
dojo.require("dijit.form.Textarea");
dojo.ready(function(){
var textarea = new dijit.form.Textarea({
name: "id_comment",
style: "width:200px;"
}, "id_comment");
});
dojo adds a bunch of classes to the textarea so that it looks like following. But it still got it's id and it's still a textarea isn't it?
<textarea autocomplete="off" data-dojo-attach-point="focusNode,containerNode,textbox" name="id_comment" class="dijitTextBox dijitTextArea dijitExpandingTextArea" style="overflow-y: hidden; overflow-x: auto; -moz-box-sizing: border-box; width: 200px; height: 36px;" tabindex="0" id="id_comment" widgetid="id_comment" value="" rows="1"></textarea>
After reading the answers for this question: Searching for the Ultimate Resizing Textarea. I thought this might the best way to go but unfortunatly it's not.
I'm wondering if it's just me. Is there a way to get this right or should I use a different method to make the field expandable.
Edit
with dojo the post looks like that:
content_type cylebrations.image
csrfmiddlewaretoken 24827190efbb5b7793aeadaf8276beed
honeypot
id_comment ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
object_pk 4
post Post
security_hash 8a091cfbf1e309627369069d4f71c21b33843a85
timestamp 1335209980
without dojo:
comment eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
content_type cylebrations.image
csrfmiddlewaretoken 24827190efbb5b7793aeadaf8276beed
honeypot
object_pk 4
post Post
security_hash e02d8261f528cfc0f22ee30ced820cfbb80715bc
timestamp 1335210114
Dojo overwrites the name of the textarea. I called it id_comment, instead of just comment. After changing that the post looks just fine and everything works like it should:
dojo.require("dijit.form.Textarea");
dojo.ready(function(){
var textarea = new dijit.form.Textarea({
name: "comment",
style: "width:200px;"
}, "id_comment");
});

How to properly add entries for computed values to the django internationalization messages file?

Django documentation states:
The caveat with using variables or computed values, as in the previous
two examples, is that Django's translation-string-detecting utility,
django-admin.py makemessages, won't be able to find these strings.
That is fine with me, I'm ready to provide translations for all possible values of the translated variable by hand. But how to do that?
Let's say I have in my template code like this:
{% trans var %}
The var is extracted from the database, and I know all of the possible values of it - let's say the possible values are "Alice" and "Bob".
I thought all I need to do is provide entries like these:
msgid "Alice"
msgstr "Alicja"
in django.po file. Unfortunately, whenever i run djangoadmin makemessages after that, these entries are being commented out:
#~ msgid "Alice"
#~ msgstr "Alicja"
What am I doing wrong? Have I misunderstood the idea of translating computed values?
We're currently in the process of figuring this out as well. While we haven't done so properly, we do have a rather annoyingly ugly hack to get around it.
We simply define a "dummy" function somewhere in the code (for example your models.py or even settings.py) and fill it up with all the strings that we need to have a translation for.
from django.utils.translation import ugettext_lazy as _, pgettext
def dummy_for_makemessages():
"""
This function allows manage makemessages to find the forecast types for translation.
Removing this code causes makemessages to comment out those PO entries, so don't do that
unless you find a better way to do this
"""
pgettext('forecast type', 'some string')
pgettext('forecast type', 'some other string')
pgettext('forecast type', 'yet another string')
pgettext('forecast type', 'etc')
pgettext('forecast type', 'etc again')
pgettext('forecast type', 'and again and again')
This function is never called but simply defining it prevents the message strings from getting commented out by makemessages.
Not the most elegant solution but it works.
There is one nice way of doing this!
(I know, because I happened to work on the same code).
First of all - this value is computed somewhere. So, in your action, you may have:
context['var'] = 'good' if condition(request) else 'bad'
and later in the template:
{% if var == 'good' %}
{% trans "Congratulations, var equals: "}
{% else %}
{% trans "Oops, var equals: "}
{% endif %}
{% trans var %}
You may have different values, which can become impractical... Unless you use this trick:
_ = lambda x: x
context['var'] = _('good') if condition(request) else _('bad')
You need to make _ something local if you don't want to clash with ugettext_lazy, etc.
This way, you're not:
translating prematurely
using some lame "dummy" redundant function to "list" your translated strings
messing up, and having to give up manage.py makemessages
I ended up solving it with a similar solution suggested in #StFS answer.
When I used pgettext('forecast type', 'some string'), then using {% trans varName %} in my template still returns "some string" instead of "New Text" for the translation.
So I have changed the syntax in the function to gettext('some string').
Now using {% trans varName %} would give "New Text" in my template.