Silverstripe 3 show date picker on template - templates

Is there a certain way to get the datepicker to show on the template?
I have used the following code:
TextField::create('DateFrom','Date From')
->setAttribute('data-datepicker', true)
->setAttribute('data-date-format', 'DD-MM-YYYY'),
I added this to my config yaml file:
DateField:
default_config:
showcalendar: true
The text box shows but no date picker shows when the textbox is clicked on.

There are two ways. Either you use the SilverStripe DateField like so:
DateField::create('DateFrom','Date From')->setConfig('showcalendar', true);
The SilverStripe DateField will render a date-picker using JavaScript.
Or you use an HTML5 date field that relies on the browser implementation for the date-picker. For that to work, you need to also set the type of the field to date (it defaults to text):
DateField::create('DateFrom','Date From')
->setAttribute('type', 'date')
->setConfig('datavalueformat', 'dd-MM-yyyy') // Server side validation
->setAttribute('data-datepicker', true)
->setAttribute('data-date-format', 'DD-MM-YYYY');

You should be using a DateField instead of a TextField.
TextField::create('DateFrom','Date From')
->setAttribute('data-datepicker', true)
->setAttribute('data-date-format', 'DD-MM-YYYY'),
should be
DateField::create('DateFrom','Date From')
->setAttribute('data-datepicker', true)
->setAttribute('data-date-format', 'DD-MM-YYYY'),

Related

TimeInput Format Validation

I have a template with an input field. The input field uses a timepicker plugin which uses a format like "1:00 AM" or "4:30 PM".
In forms.py, ive tried:
timepicker = forms.TimeField(label='Time', widget=forms.TimeInput(format='%H:%M %p'))
timepicker = forms.TimeField(label='Time', widget=forms.TimeInput(format='%I:%M %p'))
But with both these snippets, i continue to get a input validation error that says it does not match the format.
Have you tried the following?
forms.TimeField(label='time',
input_formats=['%I:%M %p'],
widget=forms.TimeInput(format='%I:%M %p'))

django one widget for two m2m fields

I have two manytomany fields for my model ModelFrom, that both go to the same Model, call it ModelTo.
ModelFrom(models.Model):
field_one = ManyToManyField(ModelTo)
checked = ManyToManyField(ModelTo)
checked is a subset of field one. I have properly validated this in model clean() and adminform clean() methods, and updated model::save() to call self.full_clean().
Ideally, I would have one widget, much like the django.forms.SelectMultiple, but with a checkbox inside each <option>.
what it currently looks like, I have one of these widgets for each field:
:
I want to combine them and have a checkbox or something, here is my unicode representation of what it would look like
{ [ blah: 2 ☐] , [blah: 1 ☑] }
Value in the list -> field one is set. Checked box -> checked is set as it is a subset of field_one.
I have seen jQuery UI MultiSelect Widget but there doesn't seem to be a way to be able to select an option, but not check the box.
I couldn't directly answer my own question, but like most questions, if the answer is not possible then there may be an underlying problem.
Instead of having two many2many fields, I should just have one, setting the through property, for an intermediate field.
Like so:
class IntermediateField(models.Model):
checked = BooleanField()
from = ForeignKey(ModelFrom)
to = ForeignKey(ModelTo)
ModelFrom(models.Model):
field_one = ManyToManyField(ModelTo, through=IntermediateField)
Then, we can just use an inline for IntermediateField in ModelFrom admin, easily checking the boxes etc

Django admin pagination... how to add a custom button to show all rows

In my code I've something like this (I'm using Django 1.6):
class CategoryAdmin(CategoryBaseAdmin):
[...]
list_per_page = 50
[...]
But I want to give users the possibility to switch the table for displaying all rows...
Something like a button (or a link) in the pagination bar... Is it possible?
Django 1.6 has an inbuilt thing called ModelAdmin.list_max_show_all set this value greater than the value that you're expecting would be the total number of resultset returned and the 'Show All' (appears in the form link) at bottom of page(area where you can switch pages).
Here's the link to django where you can find the explanation. Go ahead and add it to your class in admin.py.
Example :
class foo(admin.ModelAdmin):
list_display = ['feild1', 'feild2']
ordering = ['feild1']
list_max_show_all = n
actions = ('action1', 'action2')
where n is your value (should be greater than the expaected number of resultset). And it should work. Hope that you're fine with the 'Show all' appearing as link.

TimeField format in Django template

I'm writing an application in Django and using several TimeFields in a model. I only want to work with the time format hh:mm (not hh:mm:ss or hh p.m./a.m. or other things).
I have set the django setting TIME_FORMAT = 'H:i' and USE_L10N = False according to the documentation,
USE_L10N overrides TIME_FORMAT if set to True
In my template I'm using input boxes automatically created by Django like:
{{formName.timeField}}
The problem is that as long as I introduce something like "10:00" and do a POST, when the POST is done Django (or whatever) turns it into "10:00:00" (so it adds the seconds).
Is there a way to specify the format in which datetime fields display saved dates? If I could just use something like |date:"H:i" in the value of the input box that would do the trick.
On the other side I know I could do the input box manually (not directly using {{formName.timeField}}), but I've had some problems in the past with that so I would like to avoid that (at least for the moment).
There is also this similar question in Django TimeField Model without seconds, but the solution does not work (it gives me 'NoneType' object has no attribute 'strptime')
I had exactly this problem in my app, and solved it by passing a format parameter to Django's TimeInput widget:
from django import forms
class SettingsForm(forms.Form):
delivery_time = forms.TimeField(widget=forms.TimeInput(format='%H:%M'))
Assuming you have a format you want all TimeFields to use, you can add the TIME_INPUT_FORMATS to your settings file. For example, TIME_INPUT_FORMATS = ('%I:%M %p',) will format your times as "5:30 PM".
The docs: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-TIME_INPUT_FORMATS

Django ModelForm Validate custom Autocomplete for M2M, instead of ugly Multi-Select

Given the following models (cut down for understanding):
class Venue(models.Model):
name = models.CharField(unique=True)
class Band(models.Model):
name = models.CharField(unique=True)
class Event(models.Model):
name = models.CharField(max_length=50, unique=True)
bands = models.ManyToManyField(Band)
venue = models.ForeignKey(Venue)
start = models.DateField()
end = models.DateField()
The admin area works great for what I'm doing, but I'd like to open the site up a bit so that certain users can add new Events. For the public portions, I have several "administrative" fields on these models that I don't want the public to see (which is easy enough to fix).
My specific problem, though, is changing the display of the ManyToMany selections when creating a new Event. Because the number of Bands possible to list for an event should not be sent along as a multiselect box, I'd like to use an AutoComplete that handles multiples (like the Tags box, here on StackOverflow!).
I have this part working, and it correctly fills in a hidden input with the Band.id's separated by commas for a value. However, I can't understand how to put together letting Django do the validation using the ModelForms, and somehow also validating the 'Bands' selection.
Ideally, I want to auto-complete like the tags here on StackOverflow, and send along the selected Bands ID's in some kind of Delimited string - all while letting Django validate that the bands passed exist, etc, as if I left the annoying multi-select list in place.
Do I have to create my own Auto-Complete Field type for a form or model, and use that? Is there something else I'm overlooking?
I have seen some existing AutoComplete widgets, but I'd really-really-really like to use my own Autocomplete code, since it's already set up, and some of them look a bit convoluted.
There was a lot more text/explanation here, but I cut back because I'm avoiding Wall Of Text. If I left important stuff out, let me know.
It's a little hard to say without knowing exactly what your autocomplete code is doing, but as long as it is sending the ids of the bands like they would be sent with the <select>, the ModelForm should validate them as usual.
Basically, your POST string should look like:
name=FooBar2009&bands=1&bands=3&bands=4&venue=7&start=...
The easiest way to do this might be to use Javascript to add (and remove) a hidden input field for each band entered with the name band and the id of the band as the value. Then, when the user submits the form, the browser will take care of posting the right stuff, and the ModelForm will validate it.
Using the annointed jquery autocomplete plugin,
On the client-side I have something like this:
jQuery("#id_tags").autocomplete('/tagging_utils/autocomplete/tasks/task/', {
max: 10,
highlight: false,
multiple: true,
multipleSeparator: " ",
scroll: true,
scrollHeight: 300,
matchContains: true,
autoFill: true,
});
So, I have a view that returns when I type in a:
http://skyl.org/tagging_utils/autocomplete/tasks/task/?q=a&limit=10&timestamp=1259652876009
You can see the view that serves that here:
http://github.com/skyl/skyl.org/blob/master/apps/tagging_utils/views.py
Now, it's going to be a little tricky .. you might except the POST, then in the clean method of the field try to .get() based on the strings and raise a form validation error if you can't get it ... right, name = ... unique=True .. so something like (off the top of my head) ... :
def clean_bands(self):
return Band.objects.filter( name__in = self.cleaned_data['bands'].split(' ') )
You could also check each string and raise a form error if there are no bands by that name .. not sure that the clean method should return a qs. Let me know if this helps and you want me to keep going/clarify.