We help IT Professionals succeed at work.

How can I incorporate an "eye" icon to let me user see the password they're attempting to set?

Bruce Gust
Bruce Gust asked
on
I'm working on a Nodejs application and I want to give the user the opportunity to view the password they're attempting to set.

I've seen this option before where you can click on an "eye" icon and you can see the characters that would otherwise be represented by asterisks.

How do you pull that off?
Comment
Watch Question

SILVER EXPERT
Most Valuable Expert 2017
Distinguished Expert 2019
Commented:
That is not a Node function - node is server side.

To do this you would basically run some javascript to toggle the type of the input to text and back
Here is a very simple implementation
<form name="myform" class="w-50">
  <label>Enter password</label>
  <input class="form-control" type="password" id="pwd" value="password">
  <input type="checkbox" onclick="this.checked ? document.forms.myform.pwd.type = 'text' : document.forms.myform.pwd.type = 'password'"> Toggle Password visibility
</form>

Open in new window

Working sample here

The toggling is done with an onclick handler as it is a very simple piece of code but you can put that in as a normal javascript function or jQuery
Bruce GustPHP Developer

Author

Commented:
Julian!

I've tested your code on a generic page and it works!

Very pumped!

But when I attempt to implement it into my project, I'm getting an error that says:"Invalid left-hand side in assignment."

I'm assuming that has to do with the way I'm attempting to identify the password field, but I don't know how to fix it.

Here's the twig file with my attempts in bold:

<form id="user-form" class="needs-validation" method="post" action="{% if profile == true %}/profile{% else %}/users/save{% endif %}" novalidate>

  <div class="user-messages"></div>
    
  <div class="row formfields-list ">
      <div class="col-lg-3 animated fadeInUp">
          <div class="row">
              <div class="col text-center">  
                  <p style="border-bottom: 1px dashed #ced4da; padding-bottom: 10px;">Logo/ Avatar</p>
                  <input type="hidden" name="user[avatar]" id="user-avatar" value="{{ user.avatar }}" />
                  <a class="avatar-picker" data-toggle="modal" data-target="#profilePictureModal">
                     {% if user.avatar is empty %}
                      <img class="img-thumbnail" src="https://ui-avatars.com/api/?name={{ user.firstName|e('html_attr') }}%20{{ user.lastName|e('html_attr') }}&amp;background=33b5e5&amp;size=200&amp;color=000000" alt="Click to edit Avatr" title="Click to change Avatr" data-toggle="tooltip"/>
                      {% else %}
                      <img src="{{user.avatar}}" alt="Click to edit Avatr" title="Click to change Avatr" data-toggle="tooltip" class="img-thumbnail"/>
                      {% endif %}
                      <i class="fa fa-edit fa-lg " style="position: absolute;right: 10px;top: 55px;color: #41ad49;  "></i>
                  </a>
             
            
              </div>
          </div>
          <div class="mb-3"></div>
          <div class="row">
              <div class="col text-center signature-col">
                  <input type="hidden" name="user[signature]" id="user-signature" value="{{ user.signature }}" />
                  <label for="signature"  data-toggle="modal" data-target="#signaturePadModal">Click to draw your Signature</label>
              <a href="javascript:void(0);" class="signature-link" data-toggle="modal" data-target="#signaturePadModal">
                  {% if user.signature is empty %}
                  <span>____________</span>
                  {% else %}
                  <img src="{{user.signature}}" style="width:100%;" alt="Signature"/>
                  {% endif %}
              </a> 
              </div>
          </div>
      </div>
    <div class="col-lg-5 password-col fadeInUp animated">
      <div class="row">
        <div class="col-lg-6">
          <div class="md-form">
            
            <input type="text" id="user-first-name" name="user[firstName]" class="form-control" value="{{ user.firstName|e('html_attr') }}" required />
            <label for="user-first-name">First Name*</label>
          </div>
        </div>
        <div class="col-lg-6">
          <div class="md-form">
            
            <input type="text" id="user-last-name" name="user[lastName]" class="form-control" value="{{ user.lastName|e('html_attr') }}" required />
            <label for="user-last-name">Last Name*</label>
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-lg-6">
          <div class="md-form">
           
            <input type="email" id="user-email" name="user[email]" class="form-control" value="{{ user.email|e('html_attr') }}" required />
             <label for="user-email">Email*</label>
          </div>
        </div>
        <div class="col-lg-6">
          <div class="md-form">
            
            <input type="text" id="user-mobile" name="user[mobile]" class="form-control field-phone" value="{{ user.mobile|e('html_attr') }}" />
            <label for="user-mobile">Mobile Number</label>
          </div>
        </div>
      </div>
      <div class="row">          
        <div class="col-lg-6">
          <div class="md-form">
           
            <select id="user-timezone" name="user[settings][timezone]" class="form-control mdb-select md-form">
              <option value="America/New_York"{% if user.settings.timezone == 'America/New_York' %} selected="selected"{% endif %}>Eastern</option>
              <option value="America/Chicago"{% if user.settings.timezone == 'America/Chicago' %} selected="selected"{% endif %}>Central</option>
              <option value="America/Denver"{% if user.settings.timezone == 'America/Denver' %} selected="selected"{% endif %}>Mountain</option>
              <option value="America/Phoenix"{% if user.settings.timezone == 'America/Phoenix' %} selected="selected"{% endif %}>Mountain - No DST</option>
              <option value="America/Los_Angeles"{% if user.settings.timezone == 'America/Los_Angeles' %} selected="selected"{% endif %}>Pacific</option>
              <option value="America/Anchorage"{% if user.settings.timezone == 'America/Anchorage' %} selected="selected"{% endif %}>Alaska</option>
              <option value="America/Adak"{% if user.settings.timezone == 'America/Adak' %} selected="selected"{% endif %}>Hawaii</option>
              <option value="Pacific/Honolulu"{% if user.settings.timezone == 'America/Honolulu' %} selected="selected"{% endif %}>Hawaii - No DST</option>
              <option value="Asia/Kolkata"{% if user.settings.timezone == 'Asia/Kolkata' %} selected="selected"{% endif %}>Kolkata - No DST</option>
            </select>
             <label for="user-settings-timezone" class="active">Timezone*</label>
          </div>
        </div>
          <div class="col-lg-6">
              <div class="md-form">
                  <input type="hidden" name="user[active]" id="user-active" value="{{user.active}}" />
                <label for="chk-user-active" class="check-box-design"><input type="checkbox" id="chk-user-active" /> Active</label>
              </div>                
            </div>
      </div>
        <div class="row">
           <div class="col-lg-6">
          <div class="md-form">           
            <select id="user-role" name="user[role]" class="form-control mdb-select md-form" required>
               {% if roles is not empty %}
                {% for role in roles %}                
                    <option value="{{role}}" {{role=='Sales Representative'?'selected="selected"':''}} >{{role}}</option>
                {% endfor %}
                {% endif %}
            </select>
             <label for="user-role" class="active">Role*</label>
          </div>
        </div> 
        </div>
        <input type="hidden" name="user[team]" id="user-team" />
        <div class="row team-dragula">
            <div class="col-6 col-sm-12 ">
                <h3 class="drag-title">Reports to</h3><hr />
                <div class="dragula" id="drag-team" style="height: 100px; border: 2px dashed #eef0f3; overflow: auto; min-height: 100px; cursor:grab;"></div>                
                <div class="text-muted"><small>Drag available user's avatar and Drop into above to ADD. Drag avatar & Drop on available members to REMOVE. </small></div>
            </div>
            <div class="col-2 col-sm-12 "></div>
            <div class="col-4 col-sm-12 ">
                <h3>Available <span class="available-title">Managers</span></h3><hr />
                
                  <div class="dragula" id="drag-members" style="height: 100px; border: 2px dashed #eef0f3; overflow: auto; min-height: 100px; cursor:grab;"></div>
                
                
            </div>   
            
            

        </div>
        <div class="row" style="display:none;">
            <div class="col"> 
                 
                <div class="md-form">
                     <h3 class="active">Permissions</h3>
                <hr />
                <div class="permission-section" style="height:150px; overflow-y:auto; overflow-x: hidden;">
                {% if permissions is not empty %}
                {% for key, value in permissions.permissions %}
                    <div class="row"><div class="col" style="text-transform:capitalize">{{key}}</div></div>                    
                        <div class="row pl-5 permission-labels-check">
                        {% for k, v in value %}
                            <div class="label-col">
                                <div class="custom-control custom-checkbox">
                                    <input type="checkbox" name="user[permissions][{{key}}][{{k}}]" id="user-permissions-{{key}}-{{k}}" {{v==true?'value="true"':'value="false"'}} {{v==true?'checked="checked"':''}}  class="custom-control-input"/>
                                    <label for="user-permissions-{{key}}-{{k}}" class="custom-control-label" style="text-transform:capitalize;font-size: small;">{{k}}</label>                                    
                                    
                                </div>
                            </div>
                        {% endfor %}
                        </div>
                  <hr />
                {% endfor %}
                {% endif %}
                </div>
                </div>               
            </div>
        </div>
    </div>
    <div class="col-lg-4 password-col fadeInDown animated">
      <h3>Password</h3>
      <hr />

      <div class="password-wrapper">
        <button type="button" class="btn btn-primary btn-change-password"><i class="fas fa-fw fa-key"></i> Change Password</button>
			<div class="password-template d-none">
				<div class="row">
					<div class="col-lg-6">
						<div class="md-form">
							<input type="password" id="user-password" name="user[password]" class="form-control" required />
							<label for="user-password">Password*</label>
						</div>
					</div>
					<div class="col-lg-6">
						<div class="md-form">
							<input type="password" id="user-confirm" class="form-control" required />
							<label for="user-password">Confirm*</label>
						</div>
					</div>
				</div>
				[b]<div class="row">
					<div class="col-lg-12" style="margin-top:-10px;">
						<div style="width:95%; height:auto; background-color:#4d4e53; border-radius:5pt; margin:auto; color:#fff; padding:5px; font-size:9pt; text-align:center;">
							Check box to view your password. 
							<div style="float:right; margin-right:5px; width:auto; height:auto;">
								<input type="checkbox" onclick="this.checked ? document.forms.user-form.user-password.type = 'text' : document.forms.user-form.user-password.type = 'password'">
							<div>
						</div>
					</div>
				</div>[/b]
				<div class="row">
					<div class="col-lg-12" style="text-align:center; margin-top:10px;">
						<div class="form-group">
							<!--<label>&nbsp;</label><br />-->
							<button type="submit" class="btn btn-primary save" style="width:55%; margin:auto; padding:5px; border-radius:5pt;"><i class="fas fa-fw fa-key"></i> Change Passwords</button>
							<button type="button" class="btn btn-danger btn-cancel-password" style="width:35%; margin:auto; padding:5px; border-radius:5pt;">Cancel</button>
						</div>
					</div>
				</div>
          <p>Please ensure that your password meets the following requirements:</p>
          <ul class="password-requirements">
            <li data-reg="upper">At least 1 uppercase letter.</li>
            <li data-reg="lower">At least 1 lowercase letter.</li>
            <li data-reg="number">At least 1 number.</li>
            <li data-reg="special">At least 1 of the following special characters: !@#$%^&*</li>
            <li data-reg="total">At least 8 total characters.</li>
          </ul>
        </div>
      </div>
    </div>
  </div>

  <hr />

  <div class="footer-btns-form">
    <button type="submit" id="btn-save" class="btn btn-success"><i class="fas fa-fw fa-check"></i> Save</button>   
  </div>
</form>
 <!-- Modal -->
<div class="modal fade" id="signaturePadModal" tabindex="-1" role="dialog" aria-labelledby="signaturePadLabel"  aria-hidden="true">
  <div class="modal-dialog modal-lg modal-dialog-scrollable" role="document">
    <div class="modal-content" style="height:600px !important; width:670px !important;">
      <div class="modal-header">
        <h5 class="modal-title" id="signaturePadLabel"><i class="fas fa-signature"></i> Signature Pad</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">                   
          <div id="signature-pad" class="signature-pad">
                      <div class="signature-pad--body">
                          <canvas width="664" height="373" style="touch-action: none;"></canvas>
                      </div>
                      <div class="signature-pad--footer">
      <div class="description">Sign above</div>

      <div class="signature-pad--actions">
        <div>
          <button type="button" class="btn btn-default btn-sm button clear" data-action="clear">Clear</button>
          <button type="button" class="btn btn-default btn-sm button" data-action="change-color">Change color</button>
          <button type="button" class="btn btn-default btn-sm button" data-action="undo">Undo</button>

        </div>
        <div>
          <button type="button" class="btn btn-default btn-sm button save" data-action="save-png">Done</button>
          <!--<button type="button" class="button save" data-action="save-jpg">Save as JPG</button>
          <button type="button" class="button save" data-action="save-svg">Save as SVG</button>-->
        </div>
      </div>
    </div>
                  </div>
      </div>  
    </div>
  </div>
</div>
 <!-- Modal -->
<div class="modal fade" id="profilePictureModal" tabindex="-1" role="dialog" aria-labelledby="profilePictureLabel"  aria-hidden="true">
  <div class="modal-dialog modal-lg modal-dialog-scrollable" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="profilePictureLabel">Change Avatar</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
          <div class="">
              <div class="imageBox">
                    <div class="img-thumbnail thumbBox"></div>
                    <div class="spinner" style="display: none">Loading...</div>
                </div>
              <div class="action">
                    <input type="file" id="file" style="float:left; width: 250px" accept="image/*">
                    <input type="button" id="btnCrop" value="Done" style="float: right">
                    <input type="button" id="btnZoomIn" value="+" style="float: right">
                    <input type="button" id="btnZoomOut" value="-" style="float: right">
                </div>
          </div>
      </div>  
    </div>
  </div>
</div>

Open in new window


And here's a screen shot:

screenshot of page
What do you think?
SILVER EXPERT
Most Valuable Expert 2017
Distinguished Expert 2019

Commented:
@Bruce
Take a look at this line
document.forms.user-form.user-password.type = 'text'

Open in new window

Specifically at this
user-form

Open in new window

What are you seeing? Put your code glasses on
Break it up - and how does the compiler see this
user - form

Open in new window

As an expression - the '-' is interpreted as a minus as you are in code space.

What you need to do is use the alternative indexing method
document.forms.user-form['user-password'].type = 'text'

Open in new window

By using the [] with quoted string we bypass the interpretation of the string as a mathematical expression
Bruce GustPHP Developer

Author

Commented:
Well, kick me in the pants!

Alright! I'll try that as soon as I get back behind my desk.

Thank you!
SILVER EXPERT
Most Valuable Expert 2017
Distinguished Expert 2019

Commented:
Oops
document.forms.['user-form']['user-password'].type = 'text'

Open in new window

Missed that there were two of them

The other option is to change the names so they don't have hyphens in the name
Bruce GustPHP Developer

Author

Commented:
Julian!

I got it done!

One thing I hadn't communicated, simply because I wasn't aware of it, is that because this whole thing is a pop up, the way in which you target your id's has to include $form.

Hopefully that resonates with you, but the bottom line is that "document" didn't work because the popup wasn't included in the DOM initially. So, here's what finally worked:

 
	$form.on('mouseover', '#exposure', function(e){
		e.preventDefault();
		$form.find('#user-password').attr('type', 'text');
		$form.find('#user-confirm').attr('type', 'text');
	  });
	  $form.on('mouseout', '#exposure', function(e){
		e.preventDefault();
		$form.find('#user-password').attr('type', 'password');
		$form.find('#user-confirm').attr('type', 'password');
	  });

Open in new window


Do you smell that? That's the aroma of victory!

Thanks, friend!
SILVER EXPERT
Most Valuable Expert 2017
Distinguished Expert 2019

Commented:
You are welcome.