【问题标题】:Blazor autocomplete taggingBlazor 自动完成标记
【发布时间】:2021-04-20 23:38:39
【问题描述】:

类似于this question,我正在寻找一个组件来将标签添加到像 stackoverflow 中的对象,这意味着标签的自动完成文本字段。我正在寻找本机组件或包装 JS 解决方案的方法,以便它可以在 blazor 中使用。

另一个想法是带有复选框的多选组件,如讨论的here, 但我不太喜欢这个主意。

理想情况下,我会提供所有标签的列表,并绑定到正在为其设置标签的项目上的列表。

【问题讨论】:

    标签: javascript c# autocomplete tags blazor


    【解决方案1】:

    通常,共享完整代码是不正确的做法,因为 SO 不是代码共享站点,并且通常会询问 到目前为止您尝试过什么?。然而,由于 Blazor 是一项新技术,因此初学者很难在网络上找到一个好的解决方案或插件来满足他们的要求,因此我认为这是一个例外。

    现在回答您的问题,创建用于添加标签的新组件。您可以使用我在我正在处理的项目之一中创建的以下解决方案。这不需要任何 JS,并且可以使用 C# 处理,仅用于创建标签。您还可以查看我在小提琴上为您准备的Blazor Fiddle 解决方案。希望这是您正在寻找的。​​p>

    @using System;
    @using System.Collections.Generic;
    @using System.Linq;
    @using System.Text.RegularExpressions;
    
    <style>
    
    .suggestion-container {
        position: relative;
    }
    
    .tagsinput, .tagsinput * {
        box-sizing: border-box
    }
    
    .tagsinput {
        display: -webkit-box;
        display: -webkit-flex;
        display: -ms-flexbox;
        display: flex;
        -webkit-flex-wrap: wrap;
        -ms-flex-wrap: wrap;
        flex-wrap: wrap;
        background: #fff;
        font-size: 14px;
        line-height: 20px;
        color: #556270;
        padding: 5px 5px 0;
        border: 1px solid #e6e6e6;
        border-radius: 2px
    }
    
        .tagsinput.focus {
            border-color: #ccc
        }
    
        .tagsinput .tag {
            position: relative;
            background: #556270;
            display: block;
            max-width: 100%;
            word-wrap: break-word;
            color: #fff;
            padding: 5px 30px 5px 5px;
            border-radius: 2px;
            margin: 0 5px 5px 0
        }
    
            .tagsinput .tag .tag-remove {
                position: absolute;
                background: 0 0;
                display: block;
                width: 30px;
                height: 30px;
                top: 0;
                right: 0;
                cursor: pointer;
                text-decoration: none;
                text-align: center;
                color: #ff6b6b;
                line-height: 30px;
                padding: 0;
                border: 0
            }
    
                .tagsinput .tag .tag-remove:after, .tagsinput .tag .tag-remove:before {
                    background: #ff6b6b;
                    position: absolute;
                    display: block;
                    width: 10px;
                    height: 2px;
                    top: 14px;
                    left: 10px;
                    content: ''
                }
    
                .tagsinput .tag .tag-remove:before {
                    -webkit-transform: rotateZ(45deg);
                    transform: rotateZ(45deg)
                }
    
                .tagsinput .tag .tag-remove:after {
                    -webkit-transform: rotateZ(-45deg);
                    transform: rotateZ(-45deg)
                }
    
        .tagsinput div {
            -webkit-box-flex: 1;
            -webkit-flex-grow: 1;
            -ms-flex-positive: 1;
            flex-grow: 1
        }
    
            .tagsinput div input {
                background: 0 0;
                display: block;
                width: 100%;
                font-size: 14px;
                line-height: 20px;
                padding: 5px;
                border: 0;
                margin: 0 5px 5px 0
            }
    
                .tagsinput div input:focus {
                    color: #495057;
                    background-color: #fff;
                    border-color: #80bdff;
                    outline: 0;
                    box-shadow: 0 0 0 0.2rem rgba(0,123,255,.25);
                }
    
                .tagsinput div input.error {
                    color: #ff6b6b
                }
    
                .tagsinput div input::-ms-clear {
                    display: none
                }
    
                .tagsinput div input::-webkit-input-placeholder {
                    color: #ccc;
                    opacity: 1
                }
    
                .tagsinput div input:-moz-placeholder {
                    color: #ccc;
                    opacity: 1
                }
    
                .tagsinput div input::-moz-placeholder {
                    color: #ccc;
                    opacity: 1
                }
    
                .tagsinput div input:-ms-input-placeholder {
                    color: #ccc;
                    opacity: 1
                }
    </style>
    
    <div class="suggestion-container w-75">
        <div id="@($"{Id}_tagsinput")" class="tagsinput">
    
            @if (Tags != null && Tags.Any())
            {
                @foreach (var tag in Tags)
                {
                    <span class="tag">
                        <span class="tag-text">@tag</span>
                        <span class="tag-remove" @onclick="() => DeleteTag(tag)" />
                    </span>
                }
            }
    
            <div id="@($"{Id}_addTag")">
                <div class="@(IsContainSpecialCharacter ? "tag-tooltip" : string.Empty)">
                    <input id="@($"{Id}_tag")"
                           class="tag-input"
                           placeholder="Add tags"
                           autocomplete="off"
                           @bind-value="Value"
                           @bind-value:event="oninput"
                           @onkeyup="AddTags" />
    
                    @if (IsContainSpecialCharacter)
                    {
                        <div class="error-right d-inline-flex p-2">
                            <i class="oi oi-warning text-warning p-1"></i>
                            <p class="text-left m-0 p-1">Special characters not allowed.</p>
                            <i></i>
                        </div>
                    }
                </div>
            </div>
        </div>
    </div>
    
    @code{
    
        private Guid Id => Guid.NewGuid();
        protected string Value { get; set; }
        protected bool MenuVisibility { get; set; }
        protected bool IsContainSpecialCharacter { get; set; }
        protected List<string> Tags { get; set; } = new List<string>();
    
            protected void AddTags(KeyboardEventArgs eventArgs)
            {
                IsContainSpecialCharacter = false;
    
                if (!String.IsNullOrEmpty(Value))
                {
                    if (eventArgs.Key.Equals("Enter"))
                    {
                        var regex = new Regex(@"[^a-zA-Z0-9\s]");
                        if (!regex.IsMatch(Value))
                        {
                            if (!Tags.Exists(t => t.Equals(Value, StringComparison.CurrentCultureIgnoreCase)))
                            {
                                Tags.Add(Value);
                            }
    
                            Value = string.Empty;
                        }
                        else
                        {
                            IsContainSpecialCharacter = true;
                        }
                    }
                }       
            }
        
            protected void DeleteTag(string value)
            {
                if (String.IsNullOrEmpty(value)) return;
    
                var tag = Tags.FirstOrDefault(t => t == value);
                if (tag == null) return;
    
                Tags.Remove(tag);
            }
    }
    

    PS 我在这里分享的只是一个构建标签的代码sn-p,它不包含带有自动完成选项的标签,因为它需要时间来在小提琴上创建一个完整的解决方案用假数据。因此,由于时间限制,我避免这样做。

    【讨论】:

    • 谢谢,这很好。我正在考虑将其与 blazorise 自动完成功能结合使用来获得所需的一切
    • 你能解释一下为什么在随附的css中没有声明输入类tag-input吗?
    • 这非常好 - 感谢您的示例。
    猜你喜欢
    • 1970-01-01
    • 2011-02-09
    • 1970-01-01
    • 2020-09-11
    • 1970-01-01
    • 2014-09-14
    • 2021-10-20
    • 2012-05-08
    • 1970-01-01
    相关资源
    最近更新 更多