shiny tagsInput by selectizejs

2018/02/06

Categories: shiny Tags: 标签功能 selectize.js

selectize.js是基于jQuery开发的混合了文本输入框与下拉选择框功能的JS库,对应的GITHUB地址

最新版本的shiny已经整合了selectize.js 到 selectInput

> sessionInfo()
R version 3.4.3 (2017-11-30)
...
other attached packages:
[1] shiny_1.0.5

打标签

使用 selectInput/selectizeInput 实现打标签功能

     selectizeInput(inputId='ids1', 
                    label= tags$h5('标签效果'), 
                    choices = NULL, 
                    multiple = TRUE, 
                    options = list( 
                      placeholder = 'Please select/type something', 
                      maxItems = 3, # 最大数量限制
                      onInitialize = I('function() {
                                       this.setValue("hello world"); }'), # 未发现具体作用
                      # class="demo",
                      plugins = list('restore_on_backspace', # backspace 按钮可以起到编辑效果
                                     'remove_button', # 显示移除按钮
                                     'drag_drop'), # 可以拖动编辑顺序
                      create =  TRUE, 
                      delimiter = ',', 
                      persist = FALSE,
                      onDelete = I("function(values) {
                                   return confirm(values.length > 1 ? 'Are you sure you want to remove these ' + values.length + ' items?' : 'Are you sure you want to remove \"' + values[0] + '\"?');
                                   }") # onDelete 触发删除确认的作用
                        ))

默认样式显示的标签效果较差,可以使用自定义css样式的方式修改

下拉选择添加邮箱地址的功能

实现邮箱正则匹配,设置展示规则等。直接将原示例转移到shiny,需要注意:

   selectizeInput(inputId='ids2', 
                  label= tags$h5(em('选择添加邮箱(正则限制)')), 
                  width = "80%",
                  choices = NULL, 
                  multiple = TRUE, 
                  options = list( 
                    persist = FALSE,
                    maxItems = NULL,
                    valueField = 'email',
                    labelField = 'name',
                    searchField = c('name', 'email'), # 搜索字段
                    # 可选项
                    options = I("[
                                {email: 'brian@thirdroute.com', name: 'Brian Reavis'},
                                {email: 'nikola@tesla.com', name: 'Nikola Tesla'},
                                {email: 'someone@gmail.com'}
                                ]"),
                    # 选择后的显示结果
                    render = I("{
                               item: function(item, escape) {
                               return '<div>' +
                               (item.name ? '<span class=\"name\">' + escape(item.name) + '</span>' : '') +
                               (item.email ? '<span class=\"email\">' + escape(item.email) + '</span>' : '') +
                               '</div>';
                               },
                               option: function(item, escape) {
                               var label = item.name || item.email;
                               var caption = item.name ? item.email : null;
                               return '<div>' +
                               '<span class=\"label\">' + escape(label) + '</span>' +
                               (caption ? '<span class=\"caption\">' + escape(caption) + '</span>' : '') +
                               '</div>';
                               }
                               }"),
                          # 生成邮件规则的筛选,正则出现 \ 要替换为 \\
                    createFilter = I("function(input) {
                                     var match, regex;
                                     var REGEX_EMAIL = '([a-z0-9!#$%&\\'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&\\'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)';
                                     
                                     
                                     // email@address.com
                                     regex = new RegExp('^' + REGEX_EMAIL + '$', 'i');
                                     match = input.match(regex);
                                     if (match) return !this.options.hasOwnProperty(match[0]);
                                     
                                     // name <email@address.com>
                                     regex = new RegExp('^([^<]*)\\<' + REGEX_EMAIL + '\\>$', 'i');
                                     match = input.match(regex);
                                     if (match) return !this.options.hasOwnProperty(match[2]);
                                     
                                     return false;
                                     }"),
                          # 创建数据结果
                    create = I("function(input) {
                               var REGEX_EMAIL = '([a-z0-9!#$%&\\'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&\\'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)';
                               
                               if ((new RegExp('^' + REGEX_EMAIL + '$', 'i')).test(input)) {
                               return {email: input};
                               }
                               var match = input.match(new RegExp('^([^<]*)\\<' + REGEX_EMAIL + '\\>$', 'i'));
                               if (match) {
                               return {
                               email : match[2],
                               name  : $.trim(match[1])
                               };
                               }
                               alert('Invalid email address.');
                               return false;
                               }"),
                          delimiter = ','
                        ))

具体效果

具体实例见shinyapps.io

shinyapps.io的部署