If statement in razor results on 2 columns merging into one - c#

Below I have a grid layout in Razor.
The last 2 col should be between two separate cols... but it appears that the IF statement's are resulting in combining both the bottoms cols into one.
Am I doing this wrong?
It worked with just the second col to last col, but when I added the latest (at the bottom) - it is merging them now.
Here below, you'll see the code, and I attached a screen shot of what it looks like.
<div class="list-group container" id="JobRequestMonitorTable">
<div class="row list-group-item list-group-item-heading container divTableHeading">
<div class="col-md-4"> Job Code </div>
<div class="col-md-5"> Description </div>
<div class="col-md-2"> Schedule </div>
<div class="col-md-1"> Running </div>
<div class="col-md-1"></div>
</div>
#if (!string.IsNullOrEmpty(ViewBag.ErrorMessage))
{
<div class="row list-group-item-danger">
<div class="col-md-1 text-center">#ViewBag.ErrorMessage</div>
</div>
}
#foreach (var item in Model.JobRequests)
{
<div class="row list-group-item container">
<div class="col-md-4">#item.JobCode</div>
<div class="col-md-5">#item.Description</div>
<div class="col-md-2">#item.Schedule</div>
#if (#item.IsRunning == true)
{
<span class="glyphicon glyphicon-ok"></span>
}
<div class="col-md-1 text-break"></div>
#if (!item.IsRunning)
{
<span class="glyphicon glyphicon-list-alt"></span>
}
<div class="col-md-1"></div>
</div>
}
To clarify: I want these two cols to be SEPERATE cols:
#if (#item.IsRunning == true)
{
<span class="glyphicon glyphicon-ok"></span>
}
<div class="col-md-1 text-break"></div>
#if (!item.IsRunning)
{
<span class="glyphicon glyphicon-list-alt"></span>
}
<div class="col-md-1"></div>

You could add an empty icon if the item isn't running:
#if (#item.IsRunning == true)
{
<span class="glyphicon glyphicon-ok"></span>
}
#else
{
<span class="glyphicon"></span>
}

You need to put the <span> tags inside the <div> tags, which is what is defining your columns. You'll also need to probably change the item.Description column to col-md-4, as Bootstrap has a maximum of 12 columns across (each col being width: 8.3333%).
<div class="col-md-1 text-break">
#if (#item.IsRunning == true)
{
<span class="glyphicon glyphicon-ok"></span>
}
</div>
<div class="col-md-1">
#if (!item.IsRunning)
{
<span class="glyphicon glyphicon-list-alt"></span>
}
</div>

Related

Model List returning as null from view to controller ASP.NET Core MVC

I'm having trouble with a list within my model returning as null even tho in the view it clearly has some value.
I had trouble trying to add objects to my model's list, someone helped me and my problem was half solved. This is the code I came up with after the help
My view:
#model ActivityForm
#{
ViewData["Title"] = "Activity Details";
}
<section class="my-sm-5">
<div class="container">
<div class="section-header d-flex mb-5">
<h1 class="h-02 flex-grow-1">Activity Details</h1>
</div>
<div class="row">
<div class="col-md-7">
<div class="section-header d-flex mb-5">
<h1 class="h-04 flex-grow-1">Form</h1>
</div>
<form id="form" class="row g-3 w-90" asp-action="Create">
<div class="col-md-12">
<label asp-for="Name" class="form-label">#Html.DisplayNameFor(model => model.Name)</label>
<input asp-for="Name" type="text" class="form-control" id="inputEmail4"
placeholder="#Html.DisplayNameFor(model => model.Name)">
<span asp-validation-for="Name" class="invalid-feedback"></span>
</div>
<div class="col-12">
<label asp-for="Description" class="form-label">#Html.DisplayNameFor(model =>
model.Description)</label>
<textarea asp-for="Description" class="form-control" id="exampleFormControlTextarea1" rows="5"
placeholder="#Html.DisplayNameFor(model => model.Description)"></textarea>
<span asp-validation-for="Description" class="invalid-feedback"></span>
</div>
<div class="col-md-4">
<label asp-for="StartDate" class="form-label">#Html.DisplayNameFor(model =>
model.StartDate)</label>
<input asp-for="StartDate" type="date" class="form-control"
placeholder="#Html.DisplayNameFor(model => model.StartDate)">
<span asp-validation-for="StartDate" class="invalid-feedback"></span>
</div>
<div class="col-md-4">
<label asp-for="EndDate" class="form-label">#Html.DisplayNameFor(model => model.EndDate)</label>
<input asp-for="EndDate" type="date" class="form-control"
placeholder="#Html.DisplayNameFor(model => model.EndDate)">
<span asp-validation-for="EndDate" class="invalid-feedback"></span>
</div>
<div class="col-md-4 mb-6">
<label asp-for="Points" class="form-label">#Html.DisplayNameFor(model => model.Points)</label>
<input asp-for="Points" type="number" class="form-control"
placeholder="#Html.DisplayNameFor(model => model.Points)">
<span asp-validation-for="Points" class="invalid-feedback"></span>
</div>
<div class="col-8 d-grid gap-2">
<a class="btn btn-primary mb-2" data-bs-toggle="modal" data-bs-target="#add-award">Add award</a>
<div class="row">
<div class="col-md-6">
<a class="btn btn-outline-primary w-100" data-bs-toggle="modal"
data-bs-target="#cancel-activity">Cancel</a>
</div>
<div class="col-md-6">
<a class="btn btn-outline-primary w-100" data-bs-toggle="modal"
data-bs-target="#post-activity">Post Activity</a>
</div>
</div>
</div>
<div class="modal" id="add-award" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content br-20 pd-20">
<div class="modal-header justify-content-center">
<h5 class="modal-title h-04 text-prim-color">Award details</h5>
</div>
<div class="row g-3">
<div class="modal-body">
<div class="row g-3">
<div class="col-md-12">
<label asp-for="Award.Name" class="form-label">Name</label>
<input asp-for="Award.Name" type="text" class="form-control"
id="award-name">
</div>
<div class="col-12">
<label asp-for="Award.Description" for="inputAddress"
class="form-label">Description</label>
<textarea asp-for="Award.Description" class="form-control"
id="award-description" rows="5"></textarea>
</div>
</div>
</div>
<div class="modal-footer justify-content-center">
<button type="button" class="btn btn-outline-primary w-100"
data-bs-dismiss="modal">Close</button>
<input class="btn btn-primary w-100" type="submit" value="Confirm"></input>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
<div class="col-md-5">
<div class="section-header d-flex mb-5">
<h1 class="h-04 flex-grow-1">Awards</h1>
</div>
<table class="table">
<thead>
<tr>
<th scope="col">Award name</th>
<th scope="col">Description</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
#if (Model.Awards != null)
{
foreach (var item in Model.Awards)
{
<tr>
<td>#item.Name</td>
<td>#item.Description</td>
<td>
<a class="btn btn-outline-primary btn-sm">Edit</a>
<a class="btn btn-outline-primary btn-sm">Remove</a>
</td>
</tr>
}
}
</tbody>
</table>
</div>
</div>
</div>
</section>
Method in controller:
[HttpPost]
public async Task<IActionResult> Create(ActivityForm data)
{
var award = data.Award;
if (award.Name != null && award.Description != null)
{
if (data.Awards == null) data.Awards = new List<AwardForm>();
data.Awards.Add(new AwardForm { Name = award.Name, Description = award.Description });
data.Award.Name = "";
data.Award.Description = "";
return View(data);
}
if (!ModelState.IsValid)
{
return View(data);
}
string userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
await service.NewActivityAsync(data, userId);
return RedirectToAction(nameof(Index));
}
Model
public class ActivityForm
{
public string Name { get; set; }
public string Description { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public int Points { get; set; }
public AwardForm Award { get; set; }
public List<AwardForm> Awards { get; set; }
}
Everything was now working as intended but I had one more issue left. When I try to add another Award to the list, the list is returned to the controller method as null.
I'm not really sure if the issue is related to binding, I have noticed that every other value is bound and is returning the expected value except the list which is not bound.
Change the foreach loop to:
<tbody>
#if (Model.Awards != null)
{
#for (var i = 0; i < Model.Awards.Count; i++)
{
<input type="hidden" asp-for="#Model.Awards[i].Name" />
<input type="hidden" asp-for="#Model.Awards[i].Description" />
<tr>
<td>#Model.Awards[i].Name</td>
<td>#Model.Awards[i].Description</td>
<td>
<a class="btn btn-outline-primary btn-sm">Edit</a>
<a class="btn btn-outline-primary btn-sm">Remove</a>
</td>
</tr>
}
}
</tbody>
This has same effect to what #Victor suggested but using input tag helper instead of html helper.
Documentation for binding model to a collection: https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-6.0#collections-1
Also your form should wrap around both Form and Awards sections:
<form id="form" class="row g-3 w-90" asp-action="Create">
<div class="col-md-7">
<div class="section-header d-flex mb-5">
<h1 class="h-04 flex-grow-1">Form</h1>
</div>
...
</div>
<div class="col-md-5">
<div class="section-header d-flex mb-5">
<h1 class="h-04 flex-grow-1">Awards</h1>
</div>
...
</div>
</form>
The list binding context should include indexes to work properly.
Add to following code located below right after declaration of the <form> tag:
<form id="form" class="row g-3 w-90" asp-action="Create">
#if (Model.Awards != null)
{
for (int i=0; i < Model.Awards.Count; i++)
{
#Html.Hidden("Awards[" + i + "].Name", Model.Awards[i].Name)
#Html.Hidden("Awards[" + i + "].Description", Model.Awards[i].Description)
}
}
... your markup and control that performs the submit are located here
</form>
To be a part of the binding context these hidden fields should be declared inside the <form> from that the submit is performing.

ASP.NET Core Old image isn't deleted after update

I'm beginner. When updating an entity object, namely a picture, the old picture is not deleted, although everything is written in the method. I don't understand why ImageUrl is null.
When I get the object ImageUrl is there, and when I try to update ImageUrl is empty.
Backend:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Upsert(Department item)
{
if (ModelState.IsValid)
{
string webRootPath = _webHost.WebRootPath;
var files = HttpContext.Request.Form.Files;
if (files.Count > 0)
{
string fileName = Guid.NewGuid().ToString();
var uploads = Path.Combine(webRootPath, #"images\department");
var extenstion = Path.GetExtension(files[0].FileName);
if (item.ImageUrl != null) // ImageUrl is null (0_0)
{
// Update data with image
var imagePath = Path.Combine(webRootPath, item.ImageUrl.TrimStart('\\'));
if (System.IO.File.Exists(imagePath))
{
System.IO.File.Delete(imagePath);
}
}
using (var fileStreams = new FileStream(Path.Combine(uploads, fileName + extenstion), FileMode.Create))
{
await files[0].CopyToAsync(fileStreams);
}
item.ImageUrl = #"\images\department\" + fileName + extenstion;
}
else
{
// Update data without update image
if (item.Id != 0)
{
var model = await _db.Departments.FindAsync(item.Id);
item.ImageUrl = model.ImageUrl;
}
}
if (item.Id == 0)
{
await _db.Departments.AddAsync(item);
}
else
{
_db.Departments.Update(item);
}
await _db.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
else
{
if (item.Id != 0)
{
item = await _db.Departments.FindAsync(item.Id);
}
}
return View(item);
}
Frontend
#model Department
#{
var title = "Add";
}
<div class="container">
<form method="post" enctype="multipart/form-data">
<div class="row p-2 border" style="margin-top:10%;">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
#if (Model.Id != 0)
{
// Edit
title = "Edit";
<input type="hidden" asp-for="Id" />
}
<div class="col-12 border-bottom">
<h3>#title</h3>
</div>
<div class="col-12 pt-4">
#if (Model.Id != 0)
{
<div class="form-group row p-2">
<img src="#Model.ImageUrl" />
</div>
}
<div class="form-group row">
<div class="col-4">
<label asp-for="Name"></label>
</div>
<div class="col-8">
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<div class="col-4">
Image
</div>
<div class="col-8">
<input type="file" name="files" id="uploadBox" multiple class="form-control" />
</div>
</div>
<div class="form-group row">
<div class="col-4">
<label asp-for="Address"></label>
</div>
<div class="col-8">
<input asp-for="Address" class="form-control" />
<span asp-validation-for="Address" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<div class="col-4">
<label asp-for="Phone"></label>
</div>
<div class="col-8">
<input asp-for="Phone" class="form-control" />
<span asp-validation-for="Phone" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<div class="col-4">
<label asp-for="Description"></label>
</div>
<div class="col-8">
<textarea asp-for="Description" class="form-control" rows="15"></textarea>
</div>
</div>
<div class="form-group row">
<div class="col-8 offset-4">
#if (Model.Id != 0)
{
<partial name="_EditAndBackToListButton" model="Model.Id" />
}
else
{
<div class="row">
<div class="col">
<button type="submit" onclick="return validateInput()" class="btn btn-sm btn-outline-success form-control">Add</button>
</div>
<div class="col">
<a asp-action="Index" class="btn btn-sm btn-outline-primary form-control text-center">Back</a>
</div>
</div>
}
</div>
</div>
</div>
</div>
</form>
</div>
My GitHub https://github.com/ValencyJacob/DepartmentManagment/blob/master/DepartmentManagment/Controllers/DepartmentController.cs
If you mean item.ImageUrl(old ImgUrl) in Upsert(Department item) when you update the object,you need to add hidden input to bind ImageUrl in view.Here is a demo-:
View:
...
#if (Model.Id != 0)
{
<div class="form-group row p-2">
<img src="#Model.ImageUrl" />
<input hidden asp-for="ImageUrl" />
</div>
}
...
result:

How can i use Bootstrap Carousel As a list for db records?

i was searching a bit and i really need to know how to use the bootstrap 4 class Carousel As a list of some model data ?
i tried to manage in my own and i made something like this in the view :
#model IEnumerable<ElMatrodySite.Models.NewsData>
<link href="~/Content/Home.css" rel="stylesheet" />
#{
ViewBag.Title = "Home Page";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<style>
/* Make the image fully responsive */
.carousel-inner img {
width: 100%;
height: 100%;
}
</style>
<div class="container">
<div style="width:100%;height:150px;padding-top:0px; direction:rtl;">
<div class="row">
<div class="col-xl-4">
<img src="~/photos/Logo.png" class="mx-auto d-block" style="height:250px;"/>
</div>
<div class="col-xl-8" style="text-shadow:0px 4px 10px #808080; color:#352c5e;">
<br />
#if (Request.IsAuthenticated)
{
ElMatrodySite.Models.ApplicationUser Apps = new ElMatrodySite.Models.ApplicationUser();
<h2 class="mx-auto d-block text-center" id="ccword">مرحبًا بك #Apps.Firstname في موقع أسرة المطرودي !</h2>
}
else
{
<h2 class="mx-auto d-block text-center" id="ccword">مرحبًا بكم في الموقع الرسمي الجديد لأسرة المطرودي !</h2>
}
</div>
</div>
</div>
</div>
<div class="row" style="direction:rtl;">
<div class="container">
<div class="col-xl-6" style="padding-top:150px;" id="xcard">
<div id="myCarousel" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
#{
int i = 0;
}
#foreach (var item in Model)
{
<li data-target="#myCarousel" data-slide-to="#i" class="#(i == 0 ? "active" : "")"></li>
i++;
}
</ol>
<div class="carousel-inner">
#{
i = 0;
}
#foreach (var item in Model)
{
<div class="item #(i == 0 ? "active" : "")">
<img src="~/NewsPhotos/#item.file" class="image img-responsive">
<div class="carousel-caption">
<h3>#item.ArticleTitle</h3>
</div>
</div>
i++;
}
</div>
<a class="left carousel-control" href="#myCarousel" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#myCarousel" data-slide="next">
<span class="glyphicon glyphicon-chevron-right"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
</div>
</div>
that's wrong because every item in the list needs an id in the data-slide-to
and also one of them have to be active but it's possible while working with foreach to get the list of data.
this is the code in the controller :
[HttpGet]
public ActionResult Index()
{
List<NewsData> slideList = new List<NewsData>();
using (MatrodyEntities db = new MatrodyEntities())
{
var type = new NewsData();
slideList = db.NewsData.Where(xx => xx.ArticleID == type.ArticleID).Take(5).ToList();
return View(from NewsData in db.NewsData.ToList() select NewsData);
}
}
As i'm taking the latest 5 items added to the database.
so i need a small tutorial to make a Carousel list with asp.net mvc without destroying the whole design.
As I understand, you want to get list of data from the database and want to use bootstrap Carousel. As i noticed in your action method, you are getting latest 5 records and not passing same to view, instead of this you are using
return View(from NewsData in db.NewsData.ToList() select NewsData);
You can use directly
return View(slideList);
And in your view you can use model list as below
<div id="myCarousel" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
#{
int i = 1;
}
#foreach (var item in Model)
{
<li data-target="#myCarousel" data-slide-to="#i" class="#(i == 1 ? "active" : "")"></li>
i++;
}
</ol>
<div class="carousel-inner">
#{
i = 1;
}
#foreach (var item in Model)
{
<div class="item #(i == 1 ? "active" : "")">
<img src="#item.ImagePath" class="image img-responsive">
<div class="carousel-caption">
<h3>#item.Title</h3>
</div>
</div>
i++;
}
</div>
<a class="left carousel-control" href="#myCarousel" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#myCarousel" data-slide="next">
<span class="glyphicon glyphicon-chevron-right"></span>
<span class="sr-only">Next</span>
</a>
</div>

pass a list of object to modal popup in ASP.net MVC

I want to pass a list of objects to modal popup which is represented as view in a separate .cshtml file
here what I did :
first, I have the following index.cshtml view:
#model E_Voucher.Models.Contract
#{
ViewBag.Title = "Details";
Layout = "~/Areas/Admin/Views/Shared/_Layout.cshtml";
}
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="portlet box blue">
<div class="portlet-title">
<div class="caption">
Contract #Html.DisplayFor(model => model.ContractId) Details
</div>
</div>
<div class="portlet-body">
<div class="tabbable-line">
<ul class="nav nav-tabs ">
<li class="active">
Info
</li>
<li>
Projects
</li>
<li>
Devices
</li>
<li>
Cards
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab_info">
#1 Tab
</div>
<div class="tab-pane" id="tab_project">
#2 Tab
</div>
<div class="tab-pane" id="tab_devices">
<div class="portlet light bordered">
<div class="portlet-title">
<div class="actions" style="padding-left:5px">
<a class="btn btn-circle btn-outline red" data-target="#AssignDeviceModal" data-toggle="modal">
<i class="fa fa-plus"></i>
<span class="hidden-sm hidden-xs">Assign Device </span>
</a>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="tab_cards">
#4Tab
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="AssignDeviceModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
#Html.Action("AssignDevice")
</div>
</div>
</div>
</div>
</div>
the index.cshtml view contains 4 tabs, in the device_tab there is a button which is responsible to show a modal popup contains all the available device to the user, as you can see in the div with id=AssignDeviceModal I put a #Html.Action("AssignDevice") to call the Action Method AssignDevice which fetch the devices from DB, and render the following AssignDevice.cshtml view:
#model IEnumerable<E_Voucher.Models.Device>
<div class="modal-header">
<h4 class="modal-title">Assign Device</h4>
</div>
<div class="modal-body">
#*for example print the brand of device*#
#foreach (var item in Model)
{
<li>#item.Brand</li>
}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary">Save</button>
<button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
</div>
and here is the Action Method AssignDevice:
public ActionResult AssignDevice()
{
List<Device> _dev = new List<Device>();
Device dev1 = new Device();
dev1.Brand = "Samasung";
_dev.Add(dev1);
Device dev2 = new Device();
dev1.Brand = "SONY";
_dev.Add(dev2);
return View(_dev);
}
the problem is, when I click the button, the popup modal is shown and disappeared immediately !
how to fix this ?

asp.net c# sort right product under right category

I'm trying to render out my projects sorted under the right category. I have it right now so right product will go under right category but it doesn't render out the name. It renders out the object so it looks rather weird.
This is my code:
int i = 0;
var categories = ViewBag.Category as List<Category>;
var products = ViewBag.Products as List<Product>;
foreach (var cateory in categories)
{
i++;
<div class="panel-group accordion" id="accordion1">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion1" href="#collapse_#i">
#cateory.Name
</a>
</h4>
</div>
<div id="collapse_#i" class="panel-collapse collapse">
<div class="panel-body">
<div class="col-md-12">
#cateory.Products
</div>
</div>
</div>
</div>
</div>
}
And this is the output.
System.Collections.Generic.HashSet`1[ProductCatalog.Models.Product]
I have tired this #cateory.Products.Select(n => n.Name).ToString(); but did not do much.

Categories

Resources