Usually I do very little work on html side of the application because for the most part I just let that get generated for me.
I am working on an app for a blog with Posts Tags and Comments. What I want to do is when creating a new post, I should be able to add existing tags to the new post. I am trying to use Select2 but I can't figure out how to make the selected values passed to my Create method in the post controller so that they can be stored in the database.
Here is what I am working with:
namespace Blog.Data.Entities
{
public class Post
{
public virtual long PostId { get; set; }
-------------------
public virtual ICollection<Tag> Tags { get; set; }
}
public class Tag
{
public virtual long TagId { get; set; }
public virtual string Name { get; set; }
public virtual string Description { get; set; }
}
}
Post Controller
// POST: /Post/Create
[HttpPost]
public ActionResult Create(PostsCreateViewModel postModel)
{
if (ModelState.IsValid)
{
Post post = new Post
{
Title = postModel.Title,
Body = postModel.Body,
PostDate = _dateTime.UtcNow
};
foreach (var tag in postModel.Tags)
{
post.Tags.Add(_tagRepository.GetTag(tag.TagId));
}
_postRepository.SavePost(post);
return RedirectToAction("Detail");
}
return View(postModel);
}
I am successfully able to load data from remote with: Json code left out
<script type="text/javascript">
$(document).ready(function () {
$("#tags").select2(
{
placeholder: "Select a Tag",
minimumInputLength: 1,
multiple: true,
maximumSelectionSize: 5,
ajax: {
url: '@Url.Action("SearchTag", "Post")',
dataType: 'json',
data: function (term, page) {
return {
searchTerm: term,
page_limit: 10,
page: page,
};
},
results: function (data, page) {
var more = (page * 10) < data.total;
return { results: data, more: more };
}
}
});
});
</script>
View: usually I would have something like
<div class="form-group">
@Html.LabelFor(model => model.Title, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Title)
@Html.ValidationMessageFor(model => model.Title)
</div>
</div>
How can I write similar html for my tag textbox, so that when I click save everything is saved to appropriate tables?
Currently I just have this for select2:
<div class="form-group">
@Html.LabelFor(model => model.Tags, new { @class = "control-label col-md-2" })
<div class="col-md-10">
<input id="tags" style="width: 300px" />
@Html.ValidationMessageFor(model => model.Tags)
</div>
</div>
Which produces;
I'm also using select2 and this works for me:
The View
@Html.ListBoxFor(M => M.TagsId, new MultiSelectList(Model.Tags, "Id", "Description"), new { @class = "form-control select-multiple", multiple = "multiple" })
The ViewModel
public List<Tag> Tags { get; set; } = new List<Tag>();
public int[] TagsId { get; set; }
You can use the Tags collection to fill the options in the multiple select and the TagsId array will be populated with the id of the selected tags. If you're populating the select options via ajax I guess you could ommit the Tags property.
Note I'm using a multiple input select and not a textbox.
If the list and the selected items comes form different sources:
Example:
-Model.CategoryList >> the actual selectList items
-Model.SubCategories (m => m.SubCategories) >> the selected items only (Ids int[])
@Html.DropDownListFor(m => m.SubCategories, Model.CategoryList, Html.DescriptionFor(m => m.SubCategories), new { @class = "form-control m-select2 select2", multiple = "multiple" })
I did it like this with little js code:
@using Newtonsoft.Json;
<script>
//Edit mode
//set "selected" prop for the <select> manaually
$(function () {
var SubCategories_selected = @JsonConvert.SerializeObject(Model.SubCategories);
SubCategories_selected.forEach(function (value, index) {
$('[name="SubCategories"]').find(`[value="${value}"]`).prop("selected", true);
});
//recall the select2 init
$('#SubCategories').select2();
});
</script>
i think it just same as a <select multiple>
for example
<select name="abc" multiple>
<option value=1>a</option>
<option value=2>b</option>
<option value=3>c</option>
<option value=4>d</option>
</select>
you choose option a and option b then submit the form with post method
the post data will be
abc 1
abc 2
and you can get the data in mvc action with a param like IEnumeralbe<int> abc
the action will like
public ActionResult ActionName(IEnumerable<int> abc)
the select2 plugin only change the view,post data also use a http post
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With