jazzband / django-widget-tweaks

Tweak the form field rendering in templates, not in python-level form definitions. CSS classes and HTML attributes can be altered.
MIT License
2.09k stars 139 forks source link

'Name' attribute does not override built in 'name' attribute #110

Open ruslaniv opened 3 years ago

ruslaniv commented 3 years ago

I have the following code in the Django template:

{{ form.username|attr:"name:email"|as_crispy_field}}

but when I inspect the element in the Chrome Dev Tools I can see that the element still has the default username attribute.

<input type="text" name="username" autofocus="" autocapitalize="none" autocomplete="username" maxlength="150" class="textinput textInput form-control" required="" id="id_username">

I'm trying to change this attribute so that the label for this field should read Email.

How can I change the name attribute from username to email?

timobrembeck commented 3 years ago

I think this is just a limitation of Django's widget implementation.

The name of a widget is a special attribute which is directly inherited from the field name and cannot be overwritten by other custom attributes. If you have a look at the actual source code (not the code inspection tool), you will see that the name attribute exists twice on your input field and browsers just consider the first name attribute to be the correct one.

There are also a few questions on StackOverflow about this topic, e.g.:

However, just out of curiosity: What is your use case for this? Why not simply changing the name in the form itself? Keep in mind that you won't be able to submit the input field with the new name, since the form expects the original name in response.

ruslaniv commented 3 years ago

@timoludwig Thank you for your answer! That pretty much clears it.

However, just out of curiosity: What is your use case for this? Why not simply changing the name in the form itself? Keep in mind that you won't be able to submit the input field with the new name, since the form expects the original name in response.

I was just watching one tutorial and the guy was overriding the field names and labels left and write using bootstrap4 Django package. So, although this was a username field, he wanted to display email label with this:

{% bootstrap_label "Email" %}
{% bootstrap_field form.username show_label=False placeholder="Email" %}

Which is pretty bad coding practice if you ask me, but the curiosity got the best of me (well, actually in this case - the worst of me) and I wondered if I could do something similar using crispy-forms and widget-tweaks.

timobrembeck commented 3 years ago

Well, but that's a totally different question :sweat_smile: The name attribute is only visible in the source code and used on the server-side to identify the submitted values. What you show to your users in the label and placeholder is up to you - of course you can customize that.

The recommended way of changing the label is in the field definition of the form class rather than in the html code, but of course you can just write:

<label for="{{ form.username.id_for_label }}">Email</label>

and the placeholder can e.g. be customized via the render_field tag:

{% render_field form.username placeholder="Email" %}

as mentioned in the README.

I don't know anything about crispy-forms, but at first sight I think it serves a similar purpose like widget-tweaks, so I don't see a reason to use both at the same time.