Objetive: I'm trying to construct a view where the records from a table (machines) can be updated in a grid, and that each atribute of each record has the option to be chosen from a dropdownlist.
This is my Get method:
public async Task<IActionResult> Test()
{
return View(await _context.Machines.Include(t => t.MachineTypes).Include(p => p.Suppliers).Include(s=>s.Stores).AsNoTracking().ToListAsync());
}
And this is the definition for the dropdown list:
private void PopulateMachineTypeDropDownListStore(object selectedStore = null)
{
var typequery = from k in _context.Stores
orderby k.StoreName
select k;
ViewBag.StoreID = new SelectList(typequery.AsNoTracking(), "StoreID", "StoreName", selectedStore);
}
Now, to the View:
Model:
#model IEnumerable<Application.Models.Machine>
Since I need all the registers. Then the table.
Header:
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.MchName)
</th>
<th>
#Html.DisplayNameFor(model => model.StoreID)
</th>
</tr>
</thead>
Body:
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.MchName)
</td>
<td>
<div class="form-group">
<label asp-for="StoreID" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select asp-for="StoreID" class="form-control" asp-items="ViewBag.StoreID">
<option value="">-- Seleccione Tienda --
</option>
</select>
<span asp-validation-for="StoreID" class="text-danger"></span>
</div>
</div>
</td>
</tr>
}
</tbody>
</table>
}
Question: I've read that is not best to use a div inside a td but it may work, altough there may be better options. Which would be the best practice?
Question: Well, this is a Test but I'm getting this error:
"'IEnumerable' does not contain a definition for 'StoreID' and no extension method 'StoreID' accepting a first argument of type 'IEnumerable' could be found (are you missing a using directive or an assembly reference?)"
I can't track the error. For me it looks fine and I don't know why it can't read the StoreID. I wonder if it's for the "asp-for" inside the div. I don't know.
Any help is appreciated.
Thanks
I have a problem to display the ImageNotFound when my database doesn't have an image set for an article in my webstore. I got the error Value cannot be null or empty.
The imageArticle is null when I debug it. I don't know but is seems the ImageArticle from the DB is causing this error. Any way I can't bypass it ?
I added an #if condition to check the null but it doesn't see to like it.
The database is containing a description, price and quantity but the image path has not been store. It is set to null. (this is because I want to allow the user to create new article in the webstore but maybe he doesn't have any picture yet for this new added item.
Here is the Browse.html
#model IEnumerable<MyWebStore.Models.Product>
#{
ViewBag.Title = "Browse";
}
<h2>Make your Selection</h2>
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.ImageArticle)
</th>
<th>
#Html.DisplayNameFor(model => model.Description)
</th>
<th>
#Html.DisplayNameFor(model => model.Price)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#if (item.ImageArticle == null)
{
<img class="img_set_size" src="~/Images/ImageNotFound.jpg" />
} <==== the error occurs here
Else
{
<img class="img_set_size" alt="Image" src="#Url.Content(item.ImageArticle)"
/>
}
</td>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
#Html.DisplayFor(modelItem => item.Price)
</td>
<td>
#Html.ActionLink("Add to Cart", "AddToCart", "Cart", new { id =
item.ProductId }, null)
</td>
</tr>
}
</table>
try like this:
#if (item.ImageArticle == null)
{
<img class="img_set_size" src="#Url.Content("~/Images/ImageNotFound.jpg")" />
}
else
{
<img class="img_set_size" alt="Image" src="#Url.Content(item.ImageArticle)"/>
}
I am creating a rails 3 app using batman.js for the front end. I am able to submit a successful delete request when I'm in the show.html view of an individual record. But when I am in the index.html view, the same pattern is not triggering the delete method. I am guessing there's a little magic occurring when Batman.js triggers a delete request which I do not understand. Probably something to do with the scope of the venue variable in the index.html view. I'll show my code for the controller and the two views in question. If you need something else, please ask.
/app/assets/javascripts/controllers/venues_controller.js.coffee
class Plansandpictures.VenuesController extends Batman.Controller
routingKey: 'venues'
index: (params) ->
#set 'newVenue', new Plansandpictures.Venue
Plansandpictures.Venue.load (err, venues) =>
#set 'venues', Plansandpictures.Venue.get('loaded')
show: (params) ->
Plansandpictures.Venue.find parseInt(params.id, 10), (err,result) =>
throw err if err
#set 'venue', result
#render source: 'venues/show'
create: (params) ->
#newVenue.save (err, venue) =>
if !err
#set 'newVenue', new Plansandpictures.Venue
Plansandpictures.Venue.get('loaded').add(venue)
update: (params) ->
destroy: (params) ->
#get('venue').destroy (err) =>
if err
throw err unless err instanceof Batman.ErrorsSet
else
Plansandpictures.flashSuccess "Removed successfully!"
#redirect '/venues'
/app/assets/javascripts/views/venues/show.html
<h4 data-bind="venue.name"></h4>
<h6>Description</h6>
<p data-bind="venue.description"></p>
<h6>Address</h6>
<p data-bind="venue.address"></p>
<h6>City</h6>
<p data-bind="venue.city"></p>
<h6>State</h6>
<p data-bind="venue.state"></p>
<a data-event-click="controllers.venues.destroy | withArguments venue">delete</a>
/app/assets/javascripts/views/venues/index.html
<h2>Venues</h2>
<table>
<thead>
<th>Name</th>
<th>Description</th>
<th>Address</th>
<th>City</th>
<th>State</th>
</thead>
<tbody>
<tr data-foreach-venue="venues">
<td data-bind="venue.name"></td>
<td data-bind="venue.description"></td>
<td data-bind="venue.address"></td>
<td data-bind="venue.city"></td>
<td data-bind="venue.state"></td>
<td><a data-route="routes.venues[venue]">show</a></td>
<td><a data-event-click="controllers.venues.destroy | withArguments venue">delete</a></td>
</tr>
</tbody>
</table>
<h3>Add a Venue</h3>
<form data-formfor-venue="controllers.venues.newVenue" data-event-submit="controllers.venues.create">
<input class="new-item" placeholder="Name" data-bind="venue.name" />
<input class="new-item" placeholder="Description" data-bind="venue.description" />
<input class="new-item" placeholder="Address" data-bind="venue.address" />
<input class="new-item" placeholder="City" data-bind="venue.city" />
<input class="new-item" placeholder="State" data-bind="venue.state" />
<input class="new-item" type="number" placeholder="1" data-bind="venue.user_id" />
<input type="submit" value="Add Venue" />
</form>
Your controller assumes it can fetch the venue via #get('venue'), but that's not necessarily set on the index view. So change:
destroy: (params) ->
#get('venue').destroy (err) =>
to:
destroy: (venue) ->
venue.destroy (err) =>
And this ought to work from both contexts.
i try to make a simple project, that check the list of checkbox. my database is like this... !
i want to check my checkbox when hotel have the facilities...
i have code like this...
my controller
public ActionResult Facility()
{
var model = db.Facilities
.Where (htl => htl.FacilityID == hotelFacility.FacilityID)
.Select(htl => new CheckFacilityVM
{
FacilityID = htl.FacilityID,
facilityName = htl.FacilityName,
facilityAvailable = htl.IsActive == true,
})
.ToList();
return View(model);
}
my constuctor class
public Facility ShowRoomFacility(int HotelID)
{
var x = (from d in db.Facilities
where d.FacilityID == HotelID
select d).FirstOrDefault();
return x;
}
my view
#model List<XNet.WebUI.Hotel.ViewModel.CheckFacilityVM>
#{
ViewBag.Title = "Facility";
}
<h2>Facility</h2>
#using (Html.BeginForm())
{
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th> is available</th>
</tr>
</thead>
<tbody>
#for (int i = 0; i < Model.Count; i++)
{
<tr>
<td>
#Html.DisplayFor(x => x[i].FacilityID)
#Html.HiddenFor(x => x[i].FacilityID)
</td>
<td>
#Html.DisplayFor(x => x[i].facilityName)
#Html.HiddenFor(x => x[i].facilityName)
</td>
<td>
#Html.CheckBoxFor(x => x[i].facilityAvailable)
</td>
</tr>
}
</tbody>
</table>
}
<br />
<input style="width:100px;" type="button" title="Save" value="Save" onclick="location.href='#Url.Action("Index","Hotel")'" />
<input style="width:100px;" type="button" title="Reset" value="Reset" onclick="location.href='#Url.Action("Facility","Hotel")'" />
<input style="width:100px;" type="button" title="Cancel" value="Cancel" onclick="location.href='#Url.Action("Room","Hotel")'" />
how can i make checkbox is checked ??
help me please
You want to store the true/false in your database as a bit. 0 is false and 1 is true.
Then when you have a boolean property in your view model, populated by your database
public bool FacilityXAvailable { get; set; }
On your view you can then just do this
#Html.DisplayFor(model=>model.FacilityXAvailable)
That will display a checkbox checked on unchecked depending on Db value.
I have a MVC4 page that has a form with a collection of checkboxes, radio buttons and textboxes used as the search fields. Upon post the selections are parsed and the lower results grid is updated with new results. Right now all the form values are wiped out upon return and the new results are displayed in the grid - only the grid is part of the model.
I want all the form selections to retain their values after post so the user can see (and change) the selections for next post/search. The form is popuplated with viewbags.
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "searchform" }))
{
#Html.ValidationSummary("Please correct the following errors")
<div style="float:left;">
<div style="float:left;">
<label>Name:</label>
#Html.TextBox("name")
</div>
<div style="float:left; margin-left:15px">
<label>Company:</label>
#Html.TextBox("company")
</div>
<div style="float:left; margin-left:65px">
<label>Date Range:</label>
#Html.TextBox("dateStart", "", new { #class = "datefield", type = "date" })
to
#Html.TextBox("dateEnd", "", new { #class = "datefield", type = "date" })
</div>
</div>
<div style="clear: both;">
Match Any Categories? <input type="radio" name="categoryMatchAll" value="false" checked="checked" />
Match All Categories? <input type="radio" name="categoryMatchAll" value="true" />
</div>
<div style="float:left;">
<div id="searchform-categories" style="float:left;">
<div class="scroll_checkboxes">
<label>Categories</label>
<ul>
#foreach (var x in ViewBag.Categories)
{
<li>
<input type="checkbox" name="categories" value="#x.Id"/>
#x.Name
</li>
}
</ul>
</div>
</div>
<div id="searchform-diversity" style="float:left; margin-left:30px">
<div class="search-selection" style="float:left;">
<label>Minority Owned</label>
<ul>
#foreach (var x in ViewBag.Minorities)
{
<li>
#Html.RadioButton("minorities", (String)x.Id.ToString())
#x.Name
</li>
}
</ul>
</div>
<div class="search-selection" style="float:left;">
<label>Diversity Class</label>
<ul>
#foreach (var x in ViewBag.Classifications)
{
<li>
#Html.RadioButton("classifications", (String)x.Id.ToString())
#x.Name
</li>
}
</ul>
</div>
</div>
</div>
<div style="clear: both;">
<input type="submit" value="Search Profiles" />
<input type="submit" value="Reset" />
</div>
}
the data grid is bound to the model as
#model IEnumerable<VendorProfileIntranet.Models.VendorProfile>
<table id="VendorTable" width="100%" class="gradeA">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.CompanyName)
</th>
<th>
#Html.DisplayNameFor(model => model.City)
</th>
<th>
#Html.DisplayNameFor(model => model.State)
</th>
<th>
#Html.DisplayNameFor(model => model.DateCreated)
</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td class="list-field">
#Html.DisplayFor(modelItem => item.Name)
</td>
<td class="list-field">
#Html.DisplayFor(modelItem => item.CompanyName)
</td>
<td class="list-field">
#Html.DisplayFor(modelItem => item.City)
</td>
<td>
#Html.DisplayFor(modelItem => item.State)
</td>
<td class="list-field">
#Html.DisplayFor(modelItem => item.DateCreated)
</td>
<td class="list-field">
#Html.ActionLink("Edit", "Edit", new { id = item.ProfileID }) |
#Html.ActionLink("View", "View", new { id = item.ProfileID }) |
#Html.ActionLink("Delete", "Delete", new { id = item.ProfileID }, new { onclick = " return DeleteConfirm()" })
</td>
</tr>
}
</tbody>
<tfoot>
<tr>
<td> </td>
</tr>
</tfoot>
if you are using html in mvc then check solution 2 from here, value="#Request["txtNumber1"]" worked fine for me,
<input type="text" id="txtNumber1" name="txtNumber1" value="#Request["txtNumber1"]"/>
hope helps someone.
So here is how I typically solve this problem. My notes are purely my opinion (religous?) about naming classes in an MVC project to keep clear their purpose.
Couple of interfaces to keep it extensible:
// be specific about what type of results, both in the name of the
// interface and the property needed, you don't want to have overlapping
// properies on your classes, I like suffixing interfaces that are specific
// to a View or Partial View with View
public interface IPersonSearchResultsView
{
IEnumerable<EFPerson> PersonSearchResults { get; }
}
public interface IPersonSearchCriteriaView
{
PersonSearchCriteriaModel PersonSearchModel { get; }
}
Couple of classes
// I like suffixing classes that I only use for MVC with Model
public PersonSearchCriteriaModel
{
public string Name {get; set;}
public string Company {get; set;}
public string DateStart {get; set;}
public string DateEnd {get; set;}
}
// I like suffixing classes that I used passed to a View/Partial View
// with ViewModel
public class PersonSearchViewModel : IPersonSearchResultsView,
IPersonSearchCriteriaView
{
public IEnumerable<EFPerson> PersonSearchResults { get; set; }
public PersonSearchCriteriaModel PersonSearchModel { get; set; }
}
Now for your controllers, I'll set them up in a way that would also allow you to do Ajax in the future.
public PersonController : Controller
{
public ActionResult Search()
{
var model = new PersonSearchViewModel();
// make sure we don't get a null reference exceptions
model.PersonSearchModel = new PersonSearchCriteriaModel ();
model.PersonSearchResults = new List<EFPerson>();
return this.View(model);
}
[HttpPost]
public ActionResult Search(PersonSearchViewModel model)
{
model.PersonSearchResults = this.GetPersonResults(model.PersonSearchModel);
return this.View(model)
}
// You could use this for Ajax
public ActionResult Results(PersonSearchViewModel model)
{
model.PersonSearchResults = this.GetPersonResults(model.PersonSearchModel);
return this.Partial("Partial-SearchResults", model)
}
private GetPersonResults(PersonSearchCriteriaModel criteria)
{
return DbContext.GetPersonResults(criteria)
}
}
Create a couple of partial-views your Views.
/Views/Person/Partial-SearchCriteria.cshtml
#model IPersonSearchCriteriaView
// the new part is for htmlAttributes, used by Ajax later
#using (Html.BeginForm(..., new { id="searchCriteria" }))
{
// Here is were the magic is, if you use the #Html.*For(m=>)
// Methods, they will create names that match the model
// and you can back back to the same model on Get/Post
<label>Name:</label>
#Html.TextBoxFor(m => Model.PersonSearchModel.Name)
// or let mvc create a working label automagically
#Html.EditorFor(m => Model.PersonSearchModel.Name)
// or let mvc create the entire form..
#Html.EditorFor(m => Model.PersonSearchModel)
}
/Views/Person/Partial-SearchResults.cshtml
#model IPersonSearchResultsView
#foreach (var person in Model.PersonSearchResults )
{
<tr>
<td class="list-field">
#Html.DisplayFor(modelItem => person.Name)
</td>
// etc
</tr>
}
And Finally the view:
/Views/Person/Search.cshtml
#model PersonSearchViewModel
#Html.Partial("Partial-SearchCriteria", Model)
// easily change the order of these
<div id="searchResults">
#Html.Partial("Partial-SearchResults", Model);
</div>
Now enabling Ajax is pretty crazy easy (simplified and my not be exactly right):
$.Ajax({
url: '/Person/Results',
data: $('#searchCriteria').serialize(),
success: function(jsonResult)
{
$('#searchResults').innerHtml(jsonResult);
});
What I typically do is pass the posted Model back into the view. This way the values are not cleared out.
Your code would look something like this:
<div style="float:left;">
<div style="float:left;">
<label>Name:</label>
#Html.TextBox("name", Model.Name)
</div>
<div style="float:left; margin-left:15px">
<label>Company:</label>
#Html.TextBox("company", Model.Company)
</div>
<div style="float:left; margin-left:65px">
<label>Date Range:</label>
#Html.TextBox("dateStart", Model.DateStart, new { #class = "datefield", type = "date" })
to
#Html.TextBox("dateEnd", Model.DateEnd, new { #class = "datefield", type = "date" })
</div>
When initially getting the form, you'll have to create a new Model, otherwise the Model will be null and throw an exception when properties are called on it.
Sample Model
public class SearchModel
{
public SearchModel()
{
Results = new List<Result>();
}
public string Name {get; set;}
public string Company {get; set;}
public string DateStart {get; set;}
public string DateEnd {get; set;}
public List<Result> Results {get; set;}
}
#foreach (var item in Model.Results)
{
<tr>
<td class="list-field">
#Html.DisplayFor(modelItem => item.Name)
</td>
<td class="list-field">
#Html.DisplayFor(modelItem => item.CompanyName)
</td>
<td class="list-field">
#Html.DisplayFor(modelItem => item.City)
</td>
<td>
#Html.DisplayFor(modelItem => item.State)
</td>
<td class="list-field">
#Html.DisplayFor(modelItem => item.DateCreated)
</td>
<td class="list-field">
#Html.ActionLink("Edit", "Edit", new { id = item.ProfileID }) |
#Html.ActionLink("View", "View", new { id = item.ProfileID }) |
#Html.ActionLink("Delete", "Delete", new { id = item.ProfileID }, new { onclick = " return DeleteConfirm()" })
</td>
</tr>
}
Here is a link on creating models for a view in MVC.