forgive me I am just learning mvc. I have an application that manages projects and utilities. For each project, there can be multiple utilities. There is a "Projects" page that lists all of the projects, and if you click on a Project, it lists all of the utilities associated with it. There is also a button on the project screen to allow you to add Utilities to that project. So, when you click on the project and then click the "Add Utility" button, it pulls up a form to allow you to add a utility to that project. The form has the project ID, utility ID and owner pre-filled, taken from the project controller information. What I am trying to do is set a default on one of the fields in the Utility (relocation expense) to 0.00. So, that, if it is not changed by the user, it shows as 0.00 in the database. Seems simple, right?
Here is my code in the controller currently for the Get method of the Utility (advice from a previous thread) and what I changed it to.
Before:
// GET: /Utility/Create
public ActionResult Create(int? ProjectID)
{
CreateDropDownListForCreateOrEdit(ProjectID);
return View();
}
After:
public ActionResult Create(int? ProjectID)
{
CreateDropDownListForCreateOrEdit(ProjectID);
// initialize the model and set its properties
UtilityDTO model = new UtilityDTO
{
Est_Relocation_Expense = 0M
};
// return the model
return View(model);
}
My view looks like this:
#Html.TextBoxFor(model => model.Est_Relocation_Expense, "{0:0.00}")
This works great...it adds the default value to the field...however, it loses the pre-filled project id, utility id, and owner information (does not pre-fill) that it retrieved from the project controller.
Does anyone know what might be wrong here? I can provide other code from the controller as well, if needed, but it is very long so not sure what else to post.
Added view for project id:
<div class="form-group">
#Html.LabelFor(model => model.Project_ID, new { #class = "control-label col-md-2 CreateEditFieldNamesSpan" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Project_ID, (SelectList)ViewBag.VBProjectIDAndName, "---Select Project---")
#Html.ValidationMessageFor(model => model.Project_ID)
</div>
</div>
You need to set the value of the properties in the model before you pass the model to the view. Your currently only setting at value for Est_Relocation_Expense. If you want the dropdownlist to display the option associated with the ProjectID parameter in your method, then modify your method to
public ActionResult Create(int? ProjectID)
{
CreateDropDownListForCreateOrEdit(ProjectID);
UtilityDTO model = new UtilityDTO
{
Project_ID = ProjectID, // add this
Est_Relocation_Expense = 0M
};
return View(model);
}
Side note: It is not necessary to send the value of ProjectID to the CreateDropDownListForCreateOrEdit() method. From your now deleted code, that was being used only to set the selectedValue property of SelectList which is ignored when binding a dropdownlist to a property. You need only use the constructor which is public SelectList(IEnumerable items, string dataValueField, string dataTextField)
Related
Desc:
I have a web tab and I need to give access to visibility
to a group of people from the database
I tried:
I am downloading a list of people for whom the bookmark must be covered
for. exp. single login: AD/ABCD
I try to send them to a partial view
and load this partial view into the layout by #Html.Action
Controller:
using ActionExecutingContext = Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext;
using ActionResult = Microsoft.AspNetCore.Mvc.ActionResult;
using Controller = Microsoft.AspNetCore.Mvc.Controller;
public class PrivilegeController : Controller
{
private readonly MembersDbContext _membersContext;
public PrivilegeController(MemebersDbContext membersDbContext)
{
_membersContext= membersContext;
}
[ChildActionOnly]
public ActionResult Header(string section)
{
var listOfManagers = _membersContext. Members.Select(x => x.Adlogin).Distinct().ToList();
ViewData["listManager"] = listOfManagers;
return PartialView("_toDevLayout");
}
}
PartialView: _toDevLayout
Layout: _TrueLayout
#Html.Action("Header", "Privilege")
what is wrong?
I got an error in my project that html.action does not exist (version mvc / core 3.1 too high)
I need to find a different solution
Cannot resolve symbol 'Action'
Hi use this in your layout page directly and use list of managers as required.
enter code here-> #{var listOfManagers = _membersContext. Members.Select(x => x.Adlogin).Distinct().ToList();}
In my main INV_Assets controller of my MVC5 app, I have an method for Edit() which passes several populated SelectLists() via the ViewBag to allow users to select from all available entities for the relevant list in the other tables of my Database -- Note, if there is a better practice than passing this through the ViewBag, please feel free to guide me to a better way.
// GET: INV_Assets/Edit/5
public async Task<ActionResult> Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
INV_Assets iNV_Assets = await db.INV_Assets.FindAsync(id);
if (iNV_Assets == null)
{
return HttpNotFound();
}
ViewBag.Location_Id = new SelectList(db.INV_Locations, "Id", "location_dept", iNV_Assets.Location_Id);
ViewBag.Manufacturer_Id = new SelectList(db.INV_Manufacturers, "Id", "manufacturer_description", iNV_Assets.Manufacturer_Id);
ViewBag.Model_Id = new SelectList(db.INV_Models, "Id", "model_description", iNV_Assets.Model_Id);
ViewBag.Status_Id = new SelectList(db.INV_Statuses, "Id", "status_description", iNV_Assets.Status_Id);
ViewBag.Type_Id = new SelectList(db.INV_Types, "Id", "type_description", iNV_Assets.Type_Id);
ViewBag.Vendor_Id = new SelectList(db.INV_Vendors, "Id", "vendor_name", iNV_Assets.Vendor_Id);
return View(iNV_Assets);
}
My lists currently populate fine, but for ease of use I want to insert a value of "Add New" into each list, that when clicked will open pop-up (partial view?) of my relevant Create() View for the relevant entity. For example, if the Locations SelectList() has "Add New" clicked, I want to open my Create view for Locations.
Can anyone offer an example of how to do this?
I've been looking for how to insert a new value into the SelectList() but most of what I seem to be coming across is using the example of forgoing the SelectList() instead for an Html.DropDownList(), though I'm not sure why?
The SelectList class inherits IEnumerable<SelectListItem>, which are used to populate drop down lists.
Given a ViewModel object that has the following property:
public SelectList Options
{
get
{
var items = Enumerable.Range(0, 100).Select((value, index) => new { value, index });
SelectList s = new SelectList(items, "index", "value");
return s;
}
}
public int SelectedOption { get; set; }
The view:
#Html.DropDownListFor(m => m.SelectedOption, Model.Options, "Add New", new { #class = "form-control" })
In order to do what you want regarding the popup, you probably need some javascript to deal with this.
If you don't want the "Add New" in the DropDownListFor() you would need to add it manually to your collection before returning it to the view.
Hope this helps.
I want to do the menu page in a MVC project, there I need to populate some GridViews with different data from some models. First I created some datasets which contain the datatables; in the controller i call the index view which shows the main page.
public ActionResult Index()
{
..........
return View();
}
Index view
#{ Layout = "~/Views/Shared/_mainLayout.cshtml"; }
#{Html.RenderPartial("TicketsPartial");}
#Html.DevExpress().PageControl(s =>
{
s.Name = "tabcontrol";
s.TabPages.Add(tabPage =>
{
tabPage.Text = "Inbox";
tabPage.SetContent(() =>
{
Html.RenderPartial("InboxPartial");
});
});
s.TabPages.Add(tabPage =>
{
tabPage.Text = "Sent";
tabPage.SetContent(() =>
{
Html.RenderPartial("SentPartial");
});
});
}).GetHtml()
So I'm trying to use the Html.RenderPartial to call some partial views... here's the code in InboxPartial
#model DataModels.Email.DS_EmailMessages.DT_com_mail_messagesDataTable
#Html.DevExpress().GridView(s =>
{
s.Name = "Inbox";
s.KeyFieldName = "idticket";
s.Width = System.Web.UI.WebControls.Unit.Percentage(100);
}).Bind(Model).GetHtml()
So first I give the model to the view... the datatable from which the data should be loaded and I bind it to the gridview...
The thing is that this isn't displaying any data and also any column...and I really can't understand why... for example if I give the datatabel as a parameter in the controller like this:
public ActionResult Index()
{
..........
return View(dS_Tickets.DT_com_consultant_tickets);
}
And i erase the model from the views so there will not be any conflict, each partialview will show the columns and data taken from the datatabel, but only from that one table that I gave as a parameter.. I need to take the data from different tables... how can I do this?
Note: I'm using an extension called DevExpress v.12
What is the best approach to take when converting a basic ActionResult to JSON objects and rendering them in a PartialView? My objective is to modify the application so that instead of the page rendering only the comments in the db at the time of the page request to a type of data service that updates thePartialView to add any incoming comments that may have been posted since the last page request. I think the solution I am looking for will use OData in json format and then bind that data using knockout.js, but not sure.
Here is the Controller ActionResult which returns an IEnumerable list of objects from the repository to a PartialView:
[ChildActionOnly]
public ActionResult GetCommentsById(int AId = 0)
{
if (AId == 0)
return HttpNotFound();
return PartialView("_CommentsPartial",
_unitOfWork.ArticleRepository.GetCommentsByArticleId(AId));
}
Here is a snippet of the PartialView to keep things short:
#model IEnumerable<BlogSite.Models.Comment>
#using BlogSite.Helpers;
<ul id="comments-list">
#{
foreach (var comment in Model)
{
<!--Grabs Parent Comment and then all replies w/ParentCommentId b4 grabs new Parent Comment -->
if (comment.isRoot && comment.ParentCommentId == null)
{
<!-- Comment -->
int counter = 0; foreach (var c in Model) { if (c.ParentCommentId == comment.CommentId) { counter += 1; } }
<li id="#comment.CommentId" itemscope itemtype="http://schema.org/UserComments" class="comment-container" tabindex="#comment.CommentId">
Then I call it from the Details view:
<div id="comments-panel" class="panel-box">
<div class="show-comments"><div id="upNdown"></div><span id="showNhide">Show Comments</span></div><br /> <br />
<div id="comments-partial" style="display:none;">
#Html.Action("AddComment", "Comment", new { AId = Model.ArticleId })
#Html.Action("GetCommentsById", "Article", new { AId = Model.ArticleId })
</div>
</div>
How can I make this conversion as painless as possible? Thanks in advance!
I think I gather from your question that the controller already did its work and that you simply want to "consume" the data output from it as if it were an AJAX request using the same js code. You can do this fairly easily by just serializing the data in the model using the Newtonsoft Json.NET api and extensions provided by Forloop.HtmlHelpers. These can be installed as nuget packages if you haven't already.
First, you would place this in your partial view
Note: If you don't want to install the Newtonsoft package you can replace JsonConvert.SerializeObject with the System.Web.Helpers method Json.Encode
#{
using (var context = Html.BeginScriptContext())
{
Html.AddScriptBlock("var jsonData=" + JsonConvert.SerializeObject(Model) + ";");
}
}
Then in your layout page, to ensure that your script block is rendered at the appropriate time, add this call to Html.RenderScripts
#Scripts.Render("~/bundles/jquery")
#*Add any other dependency scripts*#
#Html.RenderScripts()
#RenderSection("scripts", required: false)
This is why you need the Forloop.HtmlHelpers package, these extension methods help mitigate out-of-order script code getting rendered in the partial view before jQuery or anything else has started up.
Hope that helps
My form looks like this
{
using (Ajax.BeginForm("Log",
new AjaxOptions {
UpdateTargetId = "lessonTable"
}))
//removed dropdown list ect... for readability
input type="submit" name = "submitButton" value = "Filter"
input type="submit" name = "submitButton" value = "Print Report"
and my controller does this
[HttpPost]
public ActionResult Log(lesson lesson,string submitButton)
{
/*Retreive all lessons*/
List<lesson> lessonList = (from l in storeDB.lessons
where l.statusID != DELETED
select l).ToList();
/*Filter retreived Lesson*/
lessonList = filterLesson(lesson,lessonList);
switch (submitButton)
{
case "Filter":
return PartialView(lessonList);
default:
{
return DetailsReport();
}
}
}
the DetailsReport() method returns a File
return File(renderedBytes, mimeType);
when click the Print Report button it is updating the div with the file header not requesting that the user opens the file. I have tried removing updatetarget ID but it doesn't prompt for a file download. Also when I make an ajax.actionlink call to the details report method it is working fine.
Thanks
If I understand what you are doing, it is working as intended; because you are making the request from an Ajax.BeginForm(), it is trying to display what ever is returned in the page. Removing the target would not be expected to change that.
You should simply make the "Print Report" button be part of a separate form or not a form at all, and have it pull the info it needs from the existing form before submitting (since it wouldn't do it automatically once it is removed from that form)