Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
185 views
in Technique[技术] by (71.8m points)

c# - add multiple tags to form in net core 3.1 mvc

In my project users can add a entry in the database of a video they want to store. The video is supposed to have multiple tags (optional) go with it. What is a good way to let users enter dynamically multiple tags?

I have created three models, Video, Tag and VideoTags, which holds the m2m relationship of the tags for each video.

Video

public class Video: BaseModel
{
    public string Name { get; set; }
    public string OriginUrl { get; set; }
    public string Description { get; set; }
    public string FileLocationIcon { get; set; }
    public ICollection<VideoTags> VideoTags { get; set; }
}

Tag

public class Tag: BaseModel
{        
    public string TagName { get; set; }
    public ICollection<VideoTags> VideoTags { get; set; }
}

VideoTags

public class VideoTags
{
    public string VideoId { get; set; }
    public Video Video { get; set; }

    public string TagId { get; set; }
    public Tag Tag { get; set; }

}

My html (Create.cshtml)

<div class="col-md-4">
    <form asp-action="Create" enctype="multipart/form-data" method="post">
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <div class="form-group">
            <label asp-for="Name" class="control-label"></label>
            <input asp-for="Name" class="form-control" />
            <span asp-validation-for="Name" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="OriginalUrl" class="control-label"></label>
            <input asp-for="OriginalUrl" class="form-control" />
            <span asp-validation-for="OriginalUrl" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Description" class="control-label"></label>
            <textarea asp-for="Description" class="form-control"> </textarea>
            <span asp-validation-for="Description" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Icon" class="control-label"></label>
            <input type="file" asp-for="Icon" class="form-control" accept="image/x-png,image/gif,image/jpeg" />
            <span asp-validation-for="Icon" class="text-danger"></span>
        </div>

        <div class="form-group">
            <input type="submit" value="Create" class="btn btn-primary" />
        </div>
    </form>
</div>

Now, my question is how can I properly implement this on my html form where the user provides the other details of the Video entry? I think it will involve JQuery, but I don't really know how to proceed. Users are supposed to add these tags, so I want them to be able to add input fields if needed, and then on Submit to the backend, my Controller will take that input and turn it into a IEnumerable or List.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This is part of the code I used in my online store project.


Solution:

We should have two inputs.

  1. The first input is only a display and is what the user is working on.
  2. The second input is exactly what holds the entered tags and ultimately allows us to send them all to the server.

Operation:

The user enters a value in the first input. You can then enter your keyword by hitting the + key or the Enter key. According to the rules of Google or Bing or any other search engine, keywords must be separated by ,. So what we do is paste a comma into the end of a keyword after entering it. Also, this process continues until the end.

Emphasis:

Of course, this is not the only way we can get keywords from the user. But I think it's one of the best methods that is still popular. Unlike the ICollection definition method, this method does not need to create a for loop to print the tags, and all the tags are printed together and search engines can follow them. So this method works much faster than the ICollection method. Also, your user will be much more comfortable with this method and will have a more enjoyable user experience.

Footnote:

Finally, if you have more questions about this method or my code, ask me. I will try to answer them as soon as possible. I hope this answer meets all your needs. I invite you to accept this answer if this is the case.


//call addKey() by pressing Enter (  This block is optional!  )
$(window).keydown(function(event) {
  if (event.keyCode == 13) {
    event.preventDefault();
    addKey();
    return false;
  }
});

//call addKey() by pressing button
$('#addKey').click(function(e) {
  addKey();
});


//Add key function
function addKey() {
  let key = $('#keysInput').val()
  if (key != '') {
    let tag = document.createElement('span')
    $(tag).append(key)
    $(tag).attr('onclick', `$(this).remove();removeKey("${key}");`)
    $('.addedKeysHolder').append(tag)
    $('#keysInput').val('')
    resetKey()
  }
}

//According to my goals, this function was equal to the resetKey(). But here I put it in a separate block, so you can easily customize it if you want
function removeKey() {
  resetKey()
}

//Reset all keys
function resetKey() {
  $('#lkey').val('')
  for (let i = 1; i <= $('.addedKeysHolder span').length; i++) {
    let theKey = $(`.addedKeysHolder span:nth-child(${i})`).text()
    let prevVal = $('#lkey').val() + ','
    $('#lkey').val(prevVal + theKey)
  }
  $('#lkey').val($('#lkey').val());
  $('#keysInput').focus();
}
/*  Just add some styles to make it beautiful  */
*,
::after,
::before {
  box-sizing: border-box;
}

.keyHandler {
  float: left;
  width: 250px;
  height: 40px;
}

.keyHandler>button {
  float: left;
  height: 100%;
  width: 40px;
  border: none;
  outline: none !important;
  background: #673AB7;
  border-radius: 7px;
  color: white;
  cursor: pointer;
  font-size: 26pt;
}

.keyHandler>input {
  float: left;
  width: calc(100% - 45px);
  margin: 0 0 0 5px;
  height: 38px;
  padding: 0 14px;
  background: #ffffff;
  border: none;
  outline: none !important;
  font-family: monospace;
  border-bottom: 2px solid #673AB7;
}

.addedKeysHolder {
  float: left;
  width: 100%;
  height: auto;
  margin: 8px 0 0 0;
}

.addedKeysHolder>span {
  background: #2196F3;
  padding: 8px 10px 8px 30px;
  float: left;
  margin: 2px;
  border-radius: 100px;
  color: white;
  font-family: monospace;
  font-size: 12pt;
  position: relative;
  cursor: pointer;
}

.addedKeysHolder>span:after {
  content: "d7";
  position: absolute;
  left: 12px;
  top: 0;
  bottom: 0;
  width: 14px;
  height: 14px;
  line-height: .5;
  margin: auto;
  font-size: 17pt;
}
<div class="keyHandler">
  <button type="button" id="addKey">+</button>
  <input type="text" placeholder="Keyword + Enter" id="keysInput">
</div>
<div class="addedKeysHolder"></div>


<!-- Just give this input the name="etc" attribute -->
<input type="hidden" id="lkey" name="tags">


<!--------------------------------------------------->
<script src="https://code.jquery.com/jquery-3.5.1.js" integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous"></script>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...