Khalil An
Khalil An

Reputation: 137

Form placeholder in django doesn't show properly

Like stated in title, the placeholder attribute in form widgets doesn't show properly. It's random, sometimes it works fine and sometimes i need to refresh the browser for them to show. I need them as i'm not showing the field labels in the template. Anyway here is the code :

#FORMS.PY
class RegistrationForm(UserCreationForm):
    first_name = forms.CharField(label=_('First name'), max_length=30)
    last_name = forms.CharField(label=_('Last name'), max_length=30)
    email = forms.EmailField(label=_("Email"), required=True)

    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2')

    def __init__(self, *args, **kwargs):
        super(RegistrationForm, self).__init__(*args, **kwargs)
        # Set field Label as Placeholder for every field
        for field in self.base_fields.values(): 
            field.widget.attrs["placeholder"] = field.label
        # Set HTML and CSS attributes to the fields
        self.fields['username'].widget.attrs.update({'class':TEXTINPUT_CSS})
        self.fields['email'].widget.attrs.update({'class':EMAILINPUT_CSS})
        self.fields['password1'].widget.attrs.update({'class':PASSWORDINPUT_CSS})
        ...

By the way i'm using django development server, could the problem come from the fact that the server is slow. Any help would be appreciated

Edit : Views.py and template as requested

#views.py
def register(request):
    if request.method == 'POST':
        form = RegistrationForm(request.POST)
        if form.is_valid():
            form.save()
            if REGISTER_EMAIL_CONFIRMATION == True:
                # Add email confirmation
                username = form.cleaned_data['username']
                email = form.cleaned_data['email']
                salt = hashlib.sha1(str(random.random()).encode('utf-8')).hexdigest()[:5]            
                activation_key = hashlib.sha1((salt+email).encode('utf-8')).hexdigest()            
                key_expires = datetime.datetime.today() + datetime.timedelta(CONFIRMATION_KEY_EXPIRE_DAYS)
                # Create and save User Profile
                user=User.objects.get(username=username)            
                new_profile = UserProfile(user=user, activation_key=activation_key, key_expires=key_expires)
            new_profile.save()
                # Send email with activation key
                subject_file = 'app_authentication/email_signup_confirm_subject.txt'
                body_file = 'app_authentication/email_signup_confirm_body.html'
                context = {'username':username, 'activation_key':activation_key}
                send_email_from_files([email], subject_file, body_file, context)
                return redirect('confirm_email_sent')
            else:
                return redirect('register_success')
    else:
        form = RegistrationForm()
    return render(request, 'registration/register.html', {'form': form, 'title': _('Register')})


#register.html
{% block content2 %}
<form id="register_form" autocomplete="off" method="post" action="{% url 'register' %}">
{% csrf_token %}
    <div class="clearfix">
    {% for field in form %}
        <div class="form-group">
            {{ field }}
            {% if form.errors %}
            {% for error in field.errors %}
                <div class="alert alert-error">
                    <strong>{{ error|escape }}</strong>
                </div>
            {% endfor %}
            {% endif %}
        </div>
    {% endfor %}
        {% if form.errors %}
        {% for error in form.non_field_errors %}
            <div class="alert alert-error">
                <strong>{{ error|escape }}</strong>
            </div>
        {% endfor %}
        {% endif %}
    </div>
    <!-- Send Button -->
    <div class="pt-10">
        <button class="submit_btn btn btn-mod btn-medium btn-round btn-full" id="reg-btn" name="submit">{{ title }}</button>
    </div>
</form>
{% endblock content2 %}

Screenshots :

when i start the development server and try to login : placeholders not working

same login page after i refresh the browser : placeholders working after refresh

@akarilimano :

class LoginForm(AuthenticationForm):
    # username doesn't have label in AuthenticationForm
    username = forms.CharField(label=_("Username"), max_length=254)

    def __init__(self, *args, **kwargs):
        super(LoginForm, self).__init__(*args, **kwargs)
        # Set field Label as Placeholder for every field
        for field in self.base_fields.values():
            print(field.label)
            field.widget.attrs['placeholder'] = field.label

Upvotes: 5

Views: 2715

Answers (3)

ndpu
ndpu

Reputation: 22571

Try to change base_fields here:

    for field in self.base_fields.values(): 

to fields:

    for field in self.fields.values():

base_fields dictionary is the base set of fields defined for the class. You can change it but it is not recommended and in your case not needed.

I guess your version would work if you call super after changing base_fields:

def __init__(self, *args, **kwargs):
    for field in self.base_fields.values(): 
        field.widget.attrs["placeholder"] = field.label
    super(RegistrationForm, self).__init__(*args, **kwargs)

Upvotes: 3

ofnowhere
ofnowhere

Reputation: 1135

Try defining your placeholders directly as widget attributes like :

 class RegistrationForm(UserCreationForm):
        first_name = forms.CharField(label=_('First name'), max_length=30, widget=forms.TextInput(attrs={"placeholder": "First name"}))
        last_name = forms.CharField(label=_('Last name'),max_length=30, widget=forms.TextInput(attrs={"placeholder": "Last Name"}))
        email = forms.EmailField(label=_("Email"), required=True, widget=forms.TextInput(attrs={"placeholder": "Email"}))

Upvotes: 3

akarilimano
akarilimano

Reputation: 1074

Why do you need this code, if you have defined model = User in Meta?

first_name = forms.CharField(label=_('First name'), max_length=30)
last_name = forms.CharField(label=_('Last name'), max_length=30)
email = forms.EmailField(label=_("Email"), required=True)

Maybe they got into conflict with model fields? Can you try removing non-model form fields?

Upvotes: 1

Related Questions