How can you style/modify django file fields? - html

In my django (1.6) project, I have a form with a FileField for uploading images (It is a FileField and not an ImageField for legacy reasons).
Currently I render the form field in a template by doing {{ form.image }} which renders it with the label, link to the image, clearing checkbox and upload button. This is all good, but I need to style those separate modules.
For the url, I'd like to make it render as:
<a href="url" class="fancybox" rel="group">
<img src="url" alt="product image" class="img-responsive">
</a>
And for the other parts (buttons, checkbox), I want to add CSS classes to them.
I looked at the ClearableFileInput widged which is responsible for rendering the FileField and I am thinking maybe I can achieve this by overriding some methods, but I am not sure what to override to change as little as possible.
How can I achieve this the right way?

The widget accepts an attrs parameter. It's a dictionary that is passed along to be the attributes on the rendered HTML widget. Here are the docs.
Here's the example from the docs with the class specified:
name = forms.TextInput(attrs={'size': 10, 'title': 'Your name', 'class': 'img-responsive'})

If you want build custom widget - you can inherit it from ClearableFileInput override render method and specify custom template_with_initial, it is quite simple

Related

how to display in models img to html in django

I tried to display to html changeable profile image with admin. can someone explain please
models in Portfolio app :
class ProfileImage(models.Model):
profile = models.ImageField(("Profile image"), upload_to=None, height_field=None, width_field=None, max_length=None)
this is base html in template folder (i tried this one) :
<img src="{{ portfolio.models.ProfileImage.progile.url }}" alt="profile"><br />
You should first configure your model to store profile pictures. Your ProfileImage model looks correct, but you need to specify where the images should be uploaded using the upload_to argument of ImageField.
Include the model in your admin form by using a ModelForm or manually adding it to the admin's fields list.
In your HTML template, you can display the image using the url attribute of your template's ImageField object.
You have an error in your HTML above, it should be profile.url and not portfolio.models.ProfileImage.profile.url:
<img src="{{ profile.image.url }}" alt="profile">

How to add button role to a custom element in angular to make it accessible by screen reader?

I have a custom component in angular that handles images. I have alt text as an input to the element and the screen reader picks it up to utter it out. But whenever I tab to the image, it says 'Trash' group. I want the screen reader to read it out as 'Trash' button. How can I achieve this? The following is my current implementation:
Icn component:
<img [ngClass]="class" [file]="file" [alt]="alt">
Usage:
<icn class="del-icon" [file]="'trash'" [alt]="Trash"></icn>
I tried role="button" but that didn't work.
I don't know Angular so you may need to do some digging on how to structure this but your approach is making things difficult.
Instead make the button a <button>. This way you get all the native accessibility built in (e.g. accessible via tab by default, accepts focus, has hover and focus states etc.)and you will also get the correct announcements in screen readers.
Then place the icon inside the <button> and just style it appropriately.
<button> <!--add whatever directives angular requires here-->
<img [ngClass]="class" [file]="file" [alt]="alt">
</button>
Also you may consider using inline SVGs for your icons as they offer styling options and can change colour according to user preferences. It is also one less resource to download so will help with performance.
I figured out the solution to this problem by experimenting more with the roles.
The image tag doesn't take the role="button" as an attribute. Instead, the role needs to be assigned to the parent element of the image tag i.e., in my case the component icn like follows:
<icn class="del-icon" role="button" [file]="'trash'" [alt]="Trash"></icn>
Now, the screen reader software reads out as the 'Trash button' and gives further more instructions on how to interact with the button. And also if the above doesn't work, just by encapsulating the custom component in a span tag and assigning the role="button" to the span tag works like a charm.
<span class="del-btn-container" role="button">
<icn class="del-icon" [file]="'trash'" [alt]="Trash"></icn>
</span>
Note: Button role examples

How to make Symfony/Bootstrap checkbox errors display outside of the form_widget?

I'm not sure how I explain this... :)
I am using symfony, twig and bootstrap to make a basic registration form on my website.
I have a checkbox at the end which the user must tick to accept the terms and conditions. the label for this checkbox includes HTML (the tag) which Bootstrap (or Twig) escapes, so I have to use a custom label next to the checkbox:
<div class="row align-items-center"> <!-- this is a workaround, may not be best practise -->
{{ form_errors(form.acceptTerms) }}
{{ form_widget(form.acceptTerms, { 'attr': {'form.acceptTerms.errors': ' '} }) }}
<label class="form-check-label" for="acceptTerms">I have read and accepted the Terms and Conditions</label>
</div>
Bootstrap renders the label as part of the form_widget twig element rather than the form_label , and the form_error is also rendered within the form_widget when there is an error. So, before, my label would just be displayed in plaintext, i.e. the html <a> tags would be visible to the user. But of course, since I am showing a custom label as well as the widget which includes the label, I have to set the widget label to ' ' (empty string) so now only one label is shown.
This work perfectly, UNTIL there is an error (i.e. the user doesn't tick the box and thus cannot register).
Then the error displays within the form_widget which is next to my custom label (they are in a bootstrap row div) and it ends up pushing my label to the right, when I want the error to be above the label. I tried adding {{form_errors(form.acceptTerms) }} above it as you can see, but that just displays the error BOTH above and next to the label. This is what it looks like with the above code in place:
ERROR you must accept the terms and conditions!
[ ] ERROR you must accept the terms and conditions!I Accept the **Terms and Conditions**
then this is what I WANT it to look like:
ERROR you must accept the terms and conditions!
[ ] I accept the **Terms and Conditions**
This seems like it should be a really easy thing to do, I don't know why its this difficult.
I need to somehow stop bootstrap from rendering the form_error and form_label within the form_widget .
Thanks
In Symfony 4.1 the bootstrap form theme was updated to be compliant with the WCAG 2.0 standard. As a result, the error for a field is no longer displayed with form_errors but within your form_label. If you separate your widget and label you will notice.
More information about this change can be found here.
In order to fix your problem just get rid of form_error (you don't need it any more) and only use form_label and form_widget. If that doesn't satisfy your needs or if you do not like the new behaviour for bootstrap 4 forms in symfony 4.1, you can always use an older form theme, or create your own.
If you decide to create your own form theme make sure to update the file twig.yaml file to something like this:
twig:
form_themes:
- form/custom_form_theme.html.twig
In this case, your custom form theme is strored in templates/form/custom_form_theme.html.twig

Thymeleaf - get dom element attributes

I create html components with Thymeleaf. Components are declared in separate file:
Declaration of basic button in buttons.html
<div th:fragment="btn-basic" class="btn btn-basic" th:text="${text}" th:classappend="${class}">
Button
</div>
The idea is to provide some type of tool-set for components. Code for using this component will be:
<div th:replace="~{buttons :: btn-basic (text='Button Text', class='button-class')}"></div>
It's working well, but I think about case when button need to have attributes like: onclick="..." or data-customAttr="..." or any other attribute. And here goes the problem:
How to pass attributes to button?
One way is to pass it as parameter of fragment, but it's too ugly.
Is there any way to get attributes of placeholder in fragment? (see example below)
This how I want to call fragment:
<div th:replace="~{buttons :: btn-basic (text='Button Text', class='button-class')}" onclick="..." data-customAttr="..."></div>
and in btn-basic fragment want to get these attributes and attach to it. Something like this:
<div th:fragment="btn-basic" class="btn btn-basic" th:text="${text}" th:classappend="${class}" onclick="..." data-customAttr="...">
Button
</div>
Any ideas?
I had a similar idea, but the question is, if the customizing of a component is as complex as the result, what is the benefit?
Btw. with the Thymeleaf Layout Dialect you can do something like this: https://ultraq.github.io/thymeleaf-layout-dialect/Examples.html#reusable-templates, I favor that, instead of the everything-as-parameter approach.

Fancybox 3 - Add buttons to custom HTML popup

I'm using fancybox 3, something like this
Click me!
<div id="popup">MY POPUP with custom HTML</div>
However, no buttons get added, and I get a jQuery error "Cannot use 'in' operator to search for 'length' in ['slideShow','fullScreen','thumbs','share']". I've tried passing an object of options through data-options, but that did not work well. What is the correct syntax for what I am trying to do? I want to add some of the standard buttons, like the thumbnails preview, share button (if that's possible with custom HTML), etc
Use correct JSON syntax, e.g., replace ` and ":
<a href="https://source.unsplash.com/xAgvgQpYsf4/1500x1000" data-fancybox="group" data-buttons='["slideShow","fullScreen","thumbs","share"]'>
<img src="https://source.unsplash.com/xAgvgQpYsf4/240x160" />
</a>
Demo - https://codepen.io/anon/pen/oEaoVr?editors=1000