ASP.NET MVC: saving multiple values โ€‹โ€‹in autocomplete

I have a mysql database with tables "end results", "tags" and "deliverables_has_tags". I want to associate tags with available ones.

This is what I do in my javascript file:

<script type="text/javascript" language="javascript"> $(function () { var object = {}; $.ajax({ type: "GET", url: "/Deliverable/Tags", dataType: "json", success: function (data) { object.tags = data; } }); function split(val) { return val.split(/,\s*/); } function extractLast(term) { return split(term).pop(); } $("#tags") // don't navigate away from the field on tab when selecting an item .bind("keydown", function (event) { if (event.keyCode === $.ui.keyCode.TAB && $(this).data("ui-autocomplete").menu.active) { event.preventDefault(); } }) .autocomplete({ minLength: 0, source: function (request, response) { // delegate back to autocomplete, but extract the last term response($.ui.autocomplete.filter( object.tags, extractLast(request.term))); }, focus: function () { // prevent value inserted on focus return false; }, select: function (event, ui) { var terms = split(this.value); // remove the current input terms.pop(); // add the selected item terms.push(ui.item.value); // add placeholder to get the comma-and-space at the end terms.push(""); this.value = terms.join(", "); return false; } }); }); </script> 

I can add some tags to the text box.

But now I want to save this in my repository. In my Action method in the controller:

 repository.AddDeliverable(model.Title, model.Description, model.UsernameID, data, datatwo, model.VideoUrl, model.AfstudeerrichtingID, model.ProjectID); 

Tag Action:

 public JsonResult Tags() { var data = (repository.GetTags()).ToArray(); return Json(data, JsonRequestBehavior.AllowGet); } 

In my repository:

 public IQueryable<string> GetTags() { return from tag in entities.tags orderby tag.tag_name select tag.tag_name; } 

I have no clue how to save this in my database.
Can anybody help me?

+4
source share
2 answers

If I understand your question correctly, you implemented tag processing as follows:

  • There is an MVC action method that returns a view using a data-free input placeholder
  • The self-placeholder is probably input type=text with id = tags
  • In "dom ready" mode, you run an ajax request to retrieve your tags from the database, json-serialized as array; when it arrives, you store it in the tags variable (without error handling (!))
  • At the same time, you decorate your input with jqueryui autocomplete, which responds to user input and returns elements from the tag variable
  • Since the input already contains tags (separated by commas), your filter is the first letters of the last tag

So, you have a situation where the user enters several tags separated by commas (maybe some of them may be new) and now wants to save them in the database. For each entry, if it is a known tag, you must save it in deliverables_has_tags. If there is a new tag, you should save it as both "tags" and "deliverables_has_tags".

The most common scenario will have a โ€œSaveโ€ button to start the save process. Let's analyze what you should do in this process.

1) Press the button

When you click the button, you use js to convert the comma-separated string of tags using logic of type split(term) to the array and serialize it. You can serialize using serializeArray and manually create a JSON object or serialize the entire form using $('#yourForm').serialize() . I would choose the first option because this way I get more control over the JSON format and avoid the problem with MVC's default binder.

2) Ajax call

When the JSON object is ready to be submitted, you issue an ajax POST request to the MVC POST action method. When you save state, always avoid GET, because newer versions of browsers can crawl through your page and actively load URLs using GET requests. You do not want this here. Of course, use your data as a data parameter in an ajax call.

3) Method of action

When the request arrives, you must process it in your controller using the new action method. Usually in this case you will have something like public JsonResult SaveTags(SaveTagsModel saveTags) { ... } which saves the tags using your repository and returns a result that says something like โ€œOKโ€ or โ€œERRORโ€ ( sth like response.isSaved = true / false). The hard part may be a view model according to your JSON object - this may help. And with regards to the collection this can be useful.

When saving, use a transaction to ensure that everything will be saved immediately. First check to see if each tag exists in the database and insert those that don't exist. After that, check each tag if there is a corresponding nn in deliverables_has_tags and insert it if this did not happen. I believe that you should use the same storage encapsulation for both operations.

+2
source

In the post action, include the FormCollection collection as an argument and collect tags from this. There is no automatic way. You could implement some custom model bindings, but this is probably not worth the effort.

+1
source

Source: https://habr.com/ru/post/1484468/


All Articles