input type="Password" does not work by default

1,637 views
Skip to first unread message

Alex Brown

unread,
May 26, 2013, 2:25:43 AM5/26/13
to shiny-...@googlegroups.com
I'm crafting html manually.  This doesn't work:

tags$input(id="password",type="password",placeholder="Password")

But does work as

tags$input(id="password",type="text",placeholder="Password")

Any guidance?

-Alex

Ramnath Vaidyanathan

unread,
May 26, 2013, 7:34:20 AM5/26/13
to shiny-...@googlegroups.com
I think the issue is that text inputs are identified by their type. Here is the relevant code from textInputBinding.

$.extend(textInputBinding, {
    find: function(scope) {
      return $(scope).find('input[type="text"]');
    }
...

Either, this can be patched to allow "password" as a type, or you could write a passwordInputBinding, that extends textInputBinding

var passwordInputBinding = new InputBinding();
$.extend(textInputBinding, {
    find: function(scope) {
      return $(scope).find('input[type="password"]');
    }
}


Best,
Ramnath

tmedz...@gmail.com

unread,
Jul 20, 2013, 11:05:04 PM7/20/13
to shiny-...@googlegroups.com
Hi Alex,

Did you find a solution to this problem? I am also stuck with this and I am not sure the JS
code provided by Ramnath can be used directly in ui.R. 

Kindly let us know if you happened to find the answer.
Thanks.

Timur


On Sunday, May 26, 2013 2:25:43 AM UTC-4, Alex Brown wrote:

Ramnath Vaidyanathan

unread,
Jul 21, 2013, 5:18:50 AM7/21/13
to shiny-...@googlegroups.com
You can save the JS as custombindings.js in a folder named www (it is important that the folder be named www), and then in ui.R, call it using

tags$script(src = 'custombindings.js')

Let me know if this works.

Timur Medjitov

unread,
Jul 21, 2013, 1:32:43 PM7/21/13
to shiny-...@googlegroups.com
Hi Ramnath:

1 I saved the below JS code in a file custombindings.js in www folder.


var passwordInputBinding = new InputBinding();
$.extend(textInputBinding, {
    find: function(scope) {
      return $(scope).find('input[type="password"]');
    }
}

2 In ui.R I am calling tags$script(src = 'custombindings.js') and also I have
modified my existing code from:
tags$input(id="password",type="password",placeholder="")
to:
tags$input(id="passwordInputBinding",type="password",placeholder="")

3 In server.R I changed input$password to input$passwordInputBinding
And I still got the same error: argument is of length zero
(it works of course if I go back to type="text" without JS file etc.)

The sad part is that I have not worked with JavaScript much and I most likely doing something wrong...
Conceptually, I feel like your approach should work, but I am not quite sure how to make it work.

Thanks a lot for help.

Timur Medjitov

unread,
Jul 22, 2013, 6:31:58 PM7/22/13
to shiny-...@googlegroups.com
Okay, I finally made it work.
The solution is basically based on what Ramnath originally suggested.
I have patched my local copy of the shiny.js with input binding for type = password.

 Steps are:

1. Make a local copy of shiny.js --> shiny_copy.js
On my machine it is located in the installation folder of the shiny package: C:\Users\mtimur\R\win-library\3.0\shiny\www\shared

2. Open shiny.js in a text editor

3. Find the section for "// Text input" and insert this snippet of code (the key point here is: 'input[type="password" )

// Password input

var passwordInputBinding = new InputBinding();
$.extend(passwordInputBinding, {
  find: function(scope) {
    return $(scope).find('input[type="password"]');
  },
  getId: function(el) {
    return InputBinding.prototype.getId.call(this, el) || el.name;
  },
  getValue: function(el) {
    return el.value;
  },
  setValue: function(el, value) {
    el.value = value;
  },
  subscribe: function(el, callback) {
    $(el).on('keyup.passwordInputBinding input.passwordInputBinding', function(event) {
      callback(true);
    });
    $(el).on('change.passwordInputBinding', function(event) {
      callback(false);
    });
  },
  unsubscribe: function(el) {
    $(el).off('.passwordInputBinding');
  },
  receiveMessage: function(el, data) {
    if (data.hasOwnProperty('value'))
      this.setValue(el, data.value);

    if (data.hasOwnProperty('label'))
      $(el).parent().find('label[for=' + el.id + ']').text(data.label);

    $(el).trigger('change');
  },
  getState: function(el) {
    return {
      label: $(el).parent().find('label[for=' + el.id + ']').text(),
      value: el.value
    };
  },
  getRatePolicy: function() {
    return {
      policy: 'debounce',
      delay: 250
    };
  }
});
inputBindings.register(passwordInputBinding, 'shiny.textInput');

// end of block

4. Save the file.

Another option is to save this code in a file xxx.js in your projects' www directory and call it from ui.R or server.R by using
tags$script(src = 'xxx.js'), but it will give you 'file not found' error. (you can see the error in the browser's debugger:
ctrl+shift+I in Chrome)
I even tried to save it in www/js directory as it was suggested in one of the threads here  - same error.
So, patching the shiny.js as outlined above works fine.

Thanks.

Joe Cheng

unread,
Jul 22, 2013, 7:13:17 PM7/22/13
to shiny-...@googlegroups.com
Just curious, what are you doing with the password? Implementing your own auth, or connecting to a database, or what?


--
You received this message because you are subscribed to the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shiny-discus...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Timur Medjitov

unread,
Jul 22, 2013, 8:14:40 PM7/22/13
to shiny-...@googlegroups.com
Hi Joe,

yes, that is correct, I've been working on implementing an authentication for shiny app.
and so I needed this password type for the input.

Thanks.

Joe Cheng

unread,
Jul 23, 2013, 4:52:08 PM7/23/13
to shiny-...@googlegroups.com
That's a little scary, but alright :)

I hope that when we release the commercial version of Shiny Server with authentication, that it's a viable option for you.

Michael Gao

unread,
Aug 29, 2013, 2:40:24 AM8/29/13
to shiny-...@googlegroups.com
Timur and Ramnath,Thank you so much for posting such clear steps for others like me to follow. I really appreciate it!

Timur, if I may ask, what were general steps that you took in creating your own authentication? I saw some users attempting to do the same and I am interested in giving it a shot myself -- however my Javascript experience right now is next to none.

Thanks again,

ijly...@yahoo.com

unread,
Aug 31, 2013, 12:29:26 PM8/31/13
to shiny-...@googlegroups.com
Hi Joe,

Just to add my two-cents worth: my use-case is that I want the user to be able enter authentication to connect to a database (for example), is there an easy way today to obscure the entry?

Is the solution suggested in this thread the way to go?

Could a native password input-control be part of a future release?

Thanks for clarification.

Ian

Timur Medjitov

unread,
Sep 1, 2013, 11:18:08 PM9/1/13
to shiny-...@googlegroups.com

Hi Michael,

General steps I believe can be found in many online resources (I am sure you can find some good videos on youtube); the only exposure to this topic that I had is back when I worked with ASP.NET 2.0... and many things came out of the box. I think one of the approaches you can consider is to start with designing the GUI for your Shiny page(s). It will help you to have a list of functionality (or functions) that you would need to code. It may be something simple, just a log in page for a couple of users,

or it can be more complex that includes sign in/registration form, password reset/recovery etc. In latter case you'd probably need a number of separate pages and as far

as I understand that would mean running several Shiny sites (Shiny server). After GUI part is done, you can move on to the database side, if you need to.

Again, in some complex scenario, you'd probably need some repository to keep users names/passwords/temp user's session tokens etc. Then it is easier to write up your functions related to authenticating a user and keeping the track of some sort of session token. You can assign a token to the user's session and then pass it over from one page to another by using a URL parameter and then read it by using intrinsic Shiny's session object: shinyServer(function(input, output, session) {}).

I don't think you need JavaScript to implement this functionality. R + Shiny framework should be enough for that. If you need all this for some sort of enterprise/commercial application, you might check on the current offers from RStudio folks. I have not been following them for a month or so, unfortunately, but they were planning to release some commercial server that supposedly includes authentication capabilities as well. Hope this helps.

Reply all
Reply to author
Forward
0 new messages