I have a project. There is a Portfolio page, which contains project information, project-related categories, project-related technologies and project-related images. I want the pictures of the project to be added one by one and deleted if desired. Finally, when I press the Save button, I want all the information to be saved to the database and the pictures to be saved in a folder.
This is my Portfolio model
public Portfolio()
{
this.Categories = new HashSet<Category>();
this.Technologies = new HashSet<Technology>();
this.Images = new HashSet<Image>();
}
public int Id { get; set; }
[Display(Name ="Project Name"),Required(ErrorMessage ="*")]
public string ProjectName { get; set; }
[Display(Name = "Date")]
public DateTime Date { get; set; }
[Display(Name = "Url")]
public string URL { get; set; }
[Display(Name = "Description")]
public string Description { get; set; }
public virtual ICollection<Technology> Technologies { get; set; }
public virtual ICollection<Category> Categories { get; set; }
public virtual ICollection<Image> Images { get; set; }
This is my Image model
public Image()
{
this.Portfolios = new HashSet<Portfolio>();
}
public int Id { get; set; }
public string URL { get; set; }
[NotMapped]
public HttpPostedFileBase[] files { get; set; }
public int PortfolioId { get; set; }
public virtual ICollection<Portfolio> Portfolios { get; set; }
This is my Create Action
public ActionResult Create(Portfolio portfolio, string[] Cat, string[] Tech, HttpPostedFileBase img)
{
//TODO:Image add
if (ModelState.IsValid)
{
if (Cat != null)
{
portfolio.Categories = new List<Category>();
foreach (var item in Cat)
{
var categoryToAdd = context.Category.Find(int.Parse(item));
portfolio.Categories.Add(categoryToAdd);
}
}
if (Tech != null)
{
portfolio.Technologies = new List<Technology>();
foreach (var item in Tech)
{
var technologyToAdd = context.Technology.Find(int.Parse(item));
portfolio.Technologies.Add(technologyToAdd);
}
}
context.Portfolio.Add(portfolio);
context.SaveChanges();
return RedirectToAction("Index");
}
else
{
return View();
}
}
This is my Create View
<div class="card-body">
@using (Html.BeginForm("Create", "Portfolio", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.AntiForgeryToken()
<div class="form-group">
@Html.LabelFor(m => m.ProjectName, new { @class = "control-label" })
@Html.ValidationMessageFor(m => m.ProjectName, "", new { @class = "text-danger" })
@Html.EditorFor(s => s.ProjectName, new { htmlAttributes = new { @class = "form-control" } })
</div>
<div class="form-group">
@Html.LabelFor(m => m.Date, new { @class = "control-label" })
@Html.ValidationMessageFor(m => m.Date, "", new { @class = "text-danger" })
@Html.EditorFor(s => s.Date, new { htmlAttributes = new { @class = "form-control" } })
</div>
<div class="form-group">
@Html.LabelFor(m => m.URL, new { @class = "control-label" })
@Html.ValidationMessageFor(m => m.URL, "", new { @class = "text-danger" })
@Html.EditorFor(s => s.URL, new { htmlAttributes = new { @class = "form-control" } })
</div>
<div class="form-group">
@Html.LabelFor(m => m.Description, new { @class = "control-label" })
@Html.ValidationMessageFor(m => m.Description, "", new { @class = "text-danger" })
@Html.EditorFor(s => s.Description, new { htmlAttributes = new { @class = "form-control" } })
</div>
<div class="form-group">
@Html.LabelFor(m => m.Categories, new { @class = "control-label" })
@* @Html.ListBoxFor(m=>m.Categories,(IEnumerable<SelectListItem>)ViewBag.Cat)*@
@Html.ListBox("Cat", null, new { @class = "form-control" })
</div>
<div class="form-group">
@Html.LabelFor(m => m.Technologies, new { @class = "control-label" })
@* @Html.ListBoxFor(m=>m.Categories,(IEnumerable<SelectListItem>)ViewBag.Cat)*@
@Html.ListBox("Tech", null, new { @class = "form-control" })
</div>
<div class="form-group">
<script src="~/Scripts/jquery-2.1.3.min.js"></script>
<script>
//$(document).ready(function () {
// $("#fileButton").click(function () {
// var files = $("#fileInput").get(0).files;
// var fileData = new FormData();
// for (var i = 0; i < files.length; i++) {
// fileData.append("fileInput", files[i]);
// }
// $('#files').val(fileData);
// });
//});
$(document).ready(function () {
var i = 1;
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
var img = '<div id="imageItem' + i + '" style="position:relative;width:100px;">' +
'<i onclick="remove(\'imageItem' + i + '\')"' + 'style="position:absolute;right:5px;cursor:pointer;">X</i>' +
' <img src="' + e.target.result + '" width="100" /><input type="hidden" name="img" value="' + e.target.result + '" />' +
'</div>';
$('#imageList').append(img);
}
reader.readAsDataURL(input.files[0]);
i = i + 1;
}
}
$("#fu").change(function () {
readURL(this);
});
});
function remove(id) {
$('#' + id).remove();
}
</script>
<div class="form-group">
<div class="row">
<div class="col-6">
@Html.LabelFor(m => m.Images, new { @class = "control-label" })
<input type="file" id="fu" class="form-control" />
</div>
<div class="col-6">
<div id="imageList">
@*<div id="imageItem1" style="position:relative;width:100px;">
<i onclick="remove('imageItem1')" style="position:absolute;right:5px;cursor:pointer;">X</i>
<img src="~/images/portfolio/1.jpg" width="100" />
</div>*@
</div>
</div>
</div>
</div>
</div>
<div class="form-group row">
<div class="col-6">
<button class="btn btn-outline-success">Save</button>
</div>
<div class="col-6 text-right">
<a href="@Url.Action("Index","Portfolio")" class="text-primary text-decoration-none"><i class="fa fa-arrow-left text-primary"></i> Back To List</a>
</div>
</div>
}
</div>
As in the picture, I want to select the pictures first and then click the save button to save the information. enter image description here
View
script and CSS
Image upload controller
Preview of image
Controller