I have created Audit trail and it works fine. you can see all the changes and even the name of the table edited. Now i want to display changes on the popup. Once the user edit some fields, i want to display fieldname,oldvalue,newvalue,username and date.Only once you click on the balloon.
I have no idea on how i can do that. I have implemented the balloon which you can click and view the changes but it doesn't work.
How can i display all the changes on the balloon
Ballon i have created: i have customize it the way i want it if there's an edit
<div class="small-chat-box fadeInRight animated">
<div class="left">
<div class="author-name">
Claim Edit <small class="chat-date">
<br>09-06-2016 12:00 pm
</small>
</div>
<div class="chat-message active">
Username: JJ
<br>fieldname: Surname
<br>oldvalue: small
<br>newvalue big
<br>date: #DateTime.Now
</div>
</div>
</div>
my audit method which works fine
public static List<ClaimAudit> GetClaimLog(SidDbContext db, int claimId)
{
--------------------
foreach (var entry in changeTrack)
{
if (entry.Entity != null)
{
string entityName = string.Empty;
string state = string.Empty;
switch (entry.State)
{
case EntityState.Modified:
entityName = ObjectContext.GetObjectType(entry.Entity.GetType()).Name;
state = entry.State.ToString();
foreach (string prop in entry.OriginalValues.PropertyNames)
{
object currentValue = entry.CurrentValues[prop];
object originalValue = entry.OriginalValues[prop];
if (!currentValue.Equals(originalValue))
{
ClaimLogs.Add(new ClaimAudit
{
tableName = entityName,
state = state,
fieldName = prop,
oldValue = Convert.ToString(originalValue),
newValue = Convert.ToString(currentValue),
userId = "JJ",
UpdateDate = DateTime.Now,
CommentsId = 1,
ClaimId = claimId
});
}
}
break;
}
}
}
calling my update function on save
public async Task<bool> UpdateClaimVehicle(ClaimVehicle vehicleModel)
{
List<ClaimAudit> ClaimLogs = new List<ClaimAudit>();
using (IBaseDataRepository<ClaimVehicle> bs = new BaseRepository<ClaimVehicle>())
{
using (SidDbContext db = new SidDbContext())
{
if (vehicleModel != null)
{
var oldClaim = db.ClaimVehicles.FirstOrDefault(x => x.ClaimId == vehicleModel.ClaimId);
oldClaim.VehicleMakeModelId = vehicleModel.VehicleMakeModelId;
oldClaim.VehicleRegistrationNumber = vehicleModel.VehicleRegistrationNumber;
oldClaim.VehicleYearModel = vehicleModel.VehicleYearModel;
oldClaim.VinNumber = vehicleModel.VinNumber;
ClaimLogs = GetClaimLog(db, oldClaim.ClaimId);
db.claimAuditLog.AddRange(ClaimLogs);
db.SaveChanges();
}
return true;
}
}
}
Here i was trying to display it on the view first,but it says model does not exist
#model Business.Models.ClaimDetailsModel
#foreach (var item in Model) //error here
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.ClaimId)
</td>
</tr>
}
Related
How can I make a blank default to be displayed like " " in this #Html.DropDownListFor.
I have tried the over-rides and they don't work for this.
HTML:
<td>#Html.DropDownListFor(o => o.TerminalsDDL, Model.TerminalsDDL, new { id = "ddlTerminalID", #class = "form-control align-middle" })</td>
Controller:
public ActionResult Index()
{
var model = TCBL.GetTerminalData();
return View(model);
}
//POST: TerminalCommand/Index
/*This function will insert a user selecter terminal command into the TerminalCommand table*/
public ActionResult AddTerminalCommand(AddTerminalCommandVM input)
{
TerminalCommand terminalCommand = new TerminalCommand();
terminalCommand.TerminalID = input.TerminalID;
terminalCommand.Command = input.CommandID;
terminalCommand.CommandValue = input.CommandValue;
TCBL.AddTerminalCommand(terminalCommand);
var redirectUrl = new UrlHelper(Request.RequestContext).Action("Index", "TerminalCommand");
return Json(new { Url = redirectUrl });
}
Data Layer:
/*Gets All termianls for the terminalsDDL and all terminal Cmds for Model.TerminalCommands*/
public TerminalCommandVM GetTerminalData()
{
TerminalCommandVM terminals = new TerminalCommandVM();
//For Terminal drop downs
terminals.TerminalsDDL = TCDA.GetTerminalsDropDown();
//For terminal cmd lists
terminals.TerminalCommands = TCDA.GetAll();
//For helpdescription
terminals.HelpDescriptions = TCDA.GetAllHelpDescriptionValues();
terminals.HelpDescriptionID = TCDA.GetAllHelpDescriptionIDs();
//For TerminalCommandLookupsDDL
List<SelectListItem> terminalCommandLookups = new List<SelectListItem>();
var terminalCommandLookupsResults = TCDA.GetAllTerminalCommandLookups().OrderBy(o => o.Name); //.Where(x => x.Name.Contains("S3"));
if (terminalCommandLookupsResults != null)
{
foreach (var item in terminalCommandLookupsResults)
{
SelectListItem newItem = new SelectListItem();
newItem.Text = item.Name;
newItem.Value = item.ID.ToString();
terminalCommandLookups.Add(newItem);
}
}
var terminalCommandValues = TCDA.GetAllTerminalCommandValues();
terminals.TerminalCommandValues = terminalCommandValues;
terminals.TerminalCommandLookupsDDL = terminalCommandLookups;
return terminals;
}
Bottom is data access layer, where the CA gets the data for display. I believe HTML should have some sort of default blank selection though..
You can add a blank default before the for loop in your Data Layer
SelectListItem newItem = new SelectListItem();
newItem.Text = "";
newItem.Value = "";
terminalCommandLookups.Add(newItem);
you can use this overload of Dropdownlistfor -
Html.DropDownListFor(Expression<Func<dynamic,TProperty>> expression, IEnumerable<SelectLestItem> selectList, string optionLabel, object htmlAttributes)
like this
<td>#Html.DropDownListFor(o => o.TerminalsDDL, Model.TerminalsDDL,"", new { id = "ddlTerminalID", #class = "form-control align-middle" })</td>
So im a bit stuck. I'm still learning all this stuff., but I had to add a csv parser to my application, which should display the results on the my alerts page. If I do
return PartialView(model, pin, tDate, stat);
It will tell me pin, tDate and stat does not exist in the current context. If I take them out, the app will run, but doesn't display the intended result.
I declared pin, tDate and stat in the UserADInfoModel.cs
here is the controller:
public ActionResult _Alerts(UserADInfoModel model, List<string> groups)
{
DataRowCollection drColl = Core.GetAlerts(model);
ViewBag.Alerts = drColl;
var path = #"Exchange Migration data 10-25-17.csv";
using (TextFieldParser csvParser = new TextFieldParser(path))
{
csvParser.CommentTokens = new string[] { "#" };
csvParser.SetDelimiters(new string[] { "," });
csvParser.HasFieldsEnclosedInQuotes = true;
// Skip the row with the column names
csvParser.ReadLine();
// Read the lines
while (!csvParser.EndOfData)
{
string[] fields = csvParser.ReadFields();
string pin = fields[0];
string tDate = fields[2];
string stat = fields[6];
}
}
return PartialView(model, pin, tDate, stat);
}
and here is the view
#if (#ViewBag.pin == Model.SAM)
{
<tr style="background-color : #ff3333; color: #ffffff">
<td style="padding-left :10px; padding-right: 10px;padding-top:2px; padding-bottom: 2px">
<p>Critical</p>
</td>
<td style="padding-left :10px; padding-right: 10px;padding-top:2px; padding-bottom: 2px">
<p>Exchange Migration</p>
</td>
<td style="padding-left :10px; padding-right: 10px;padding-top:2px; padding-bottom: 2px">
<p>Caller was set to migrate on (#ViewBag.tDate). The status of the migration is (#ViewBag.stat). Please contact Hypercare</p>
</td>
</tr>
}
#foreach (var x in ViewBag.Alerts)
{
var uClass = (x["Weight"].Contains("Warning")) ? "#ff8c1a, " : (x["Weight"].Contains("Critical")) ? "#ff3333" : "";
<tr #if (x["Weight"].Contains("Warning")) {
#MvcHtmlString.Create("style=\"background-color: #ff8c1a\"")
}
else if(x["Weight"].Contains("Critical")){
#MvcHtmlString.Create("style=\"background-color: #ff3333; color: #ffffff\"")
}>
what am I doing wrong? TIA
You declared pin, tDate and stat inside the while scope.
Decide if you want to use model (recommended) or ViewBag to pass data:
public ActionResult _Alerts(UserADInfoModel model, List<string> groups)
{
DataRowCollection drColl = Core.GetAlerts(model);
ViewBag.Alerts = drColl;
var path = #"Exchange Migration data 10-25-17.csv";
using (TextFieldParser csvParser = new TextFieldParser(path))
{
// ...
while (!csvParser.EndOfData)
{
string[] fields = csvParser.ReadFields();
model.pin = fields[0];
model.tDate = fields[2];
model.stat = fields[6];
}
}
return PartialView(model);
}
_Alerts.cshtml:
#model UserADInfoModel
#if (#Model.pin == Model.SAM)
// ...
// ... #Model.tDate ... #Model.stat ...
I am using the bootstrap selectpicker for a multiselect dropdown menu to filter items of a table in a mvc5 web app. Everything works fine so far, but i am having trouble to keep the selected filters selected after submitting. So i can read the selected filters in the controller, but after that, there is only the first previously selected filter still shown as selected after the submit. I want all chosen filters to be still selected. How can I reach this?
Here ist my Code, the ViewModel contains:
public MultiSelectList AvailableUser_ID { get; set; }
private List<string> _selectedUserId = new List<string>();
public List<string> SelectedUserId
{
get { return _selectedUserId; }
set { _selectedUserId = value; }
}
The Controller (Post):
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index([Bind(Include = "SelectedUserId,SelectedUserInteractionTypesId")] IndexUserInteractionViewModel indexUserInteractionViewModel)
{
indexUserInteractionViewModel.UserInteractionViewModels = new List<UserInteractionViewModels>();
indexUserInteractionViewModel.AvailableUser_ID = new MultiSelectList(db.AspNetUsers.ToList(), "Id", "Email", indexUserInteractionViewModel.SelectedUserId);
// Filter Function: selectedUserId contains all the Ids of the previously selected filters
foreach (string selectedUserId in indexUserInteractionViewModel.SelectedUserId)
{
if (userInteraction.AspNetUsers_Id.Equals(selectedUserId))
// ...
}
}
And the View:
<script type="text/javascript">
$(document).ready(function () {
$('.selectpicker').selectpicker();
});
</script>
<th>#Html.DropDownListFor(Model => Model.SelectedUserId, Model.AvailableUser_ID as MultiSelectList, new { #id = "userFilter", #class = "selectpicker", #multiple = "mulitple", data_live_search = "true" })</th>
So how can I keep the Selection selected?
Unfortunately I have little js-knowledge and i am assuming that i could solve it in the js-script. I am hoping for some experts here. Thank you!
A colleague of mine found a solution, this is what works:
var selectedList = #Html.Raw(Json.Encode(Model.SelectedUserId));
if(selectedList.length > 0){
var result = '[';
for (i = 0; i < selectedList.length; i++) {
result += '"' + selectedList[i] + '",';
}
result = result.slice(0, -1); //remove last comma
result += ']';
$('.selectpicker').selectpicker('val', JSON.parse(result1));
}else{
$('.selectpicker').selectpicker();
}
I have a controller with two actions. One action is simply a post that updates the database. The other is the view model. However in my action that updates the database I return it back to the original view with the view model.
public ActionResult ManageMxieUsers()
{
var model = from el in aphdb.view_EmployeeList
join p in aphdb.MxieCallRevPermissions on el.Id equals p.AspNetUserUserID into gj
from sub in gj.DefaultIfEmpty()
select new vm_ManageMxieUsers { Id = el.Id, UserName = el.UserName, PermissionLevel = sub.PermissionLevel, MxieCallRevPermCustomList = aphdb.MxieCallRevPermCustomList.Where(w => w.PermissionID == sub.PermissionID ) };
ViewBag.EmployeeList = aphdb.view_EmployeeList.OrderBy(o => o.UserName);
return View(model);
}
This part works perfectly.
Here is my post method:
[HttpPost]
public ActionResult ManageMxieUsers(string userID, Int16 permissionLevel, List<string> customUserList)
{
var UserToEdit = aphdb.MxieCallRevPermissions.Where(w => w.AspNetUserUserID == userID).FirstOrDefault();
if (UserToEdit == null)
{
MxieCallRevPermissions addPerm = new MxieCallRevPermissions();
addPerm.AspNetUserUserID = userID;
addPerm.PermissionLevel = permissionLevel;
aphdb.MxieCallRevPermissions.Add(addPerm);
aphdb.SaveChanges();
if (permissionLevel == 3)
{
foreach (var id in customUserList)
{
MxieCallRevPermCustomList list = new MxieCallRevPermCustomList();
list.PermissionID = addPerm.PermissionID;
list.AspNetUserID = id;
aphdb.MxieCallRevPermCustomList.Add(list);
}
}
aphdb.SaveChanges();
#ViewBag.Success = true;
}
else
{
UserToEdit.PermissionLevel = permissionLevel;
aphdb.SaveChanges();
if (permissionLevel == 3)
{
// Remove old custom list
var customList = aphdb.MxieCallRevPermCustomList.Where(w => w.PermissionID == UserToEdit.PermissionID).ToList();
aphdb.MxieCallRevPermCustomList.RemoveRange(customList);
aphdb.SaveChanges();
foreach (var id in customUserList)
{
MxieCallRevPermCustomList list = new MxieCallRevPermCustomList();
list.PermissionID = UserToEdit.PermissionID;
list.AspNetUserID = id;
aphdb.MxieCallRevPermCustomList.Add(list);
}
aphdb.SaveChanges();
}
else
{
// Remove old custom list
var customList = aphdb.MxieCallRevPermCustomList.Where(w => w.PermissionID == UserToEdit.PermissionID).ToList();
aphdb.MxieCallRevPermCustomList.RemoveRange(customList);
aphdb.SaveChanges();
}
aphdb.SaveChanges();
#ViewBag.Success = true;
}
//aphdb.SaveChangesAsync(); // Testing ot make sure SaveChanges fired before this code.
var model = from el in aphdb.view_EmployeeList
join p in aphdb.MxieCallRevPermissions on el.Id equals p.AspNetUserUserID into gj
from sub in gj.DefaultIfEmpty()
select new vm_ManageMxieUsers { Id = el.Id, UserName = el.UserName, PermissionLevel = sub.PermissionLevel, MxieCallRevPermCustomList = aphdb.MxieCallRevPermCustomList.Where(w => w.PermissionID == sub.PermissionID) };
ViewBag.EmployeeList = aphdb.view_EmployeeList.OrderBy(o => o.UserName);
//return RedirectToAction("ManageMxieUsers"); // WORKS
return View("ManageMxieUsers", model); // ERROR NULL on AspNetUser
}
Now when I simply return View("ManageMxieUsers", model); The error comes back saying AspNetUsers is null. However when I reload this page it works just fine. When I return RedirectToAction("ManageMxieUsers"); I get no error, but of course I lose my ViewBag.
My only guess is that aphdb.SaveChanges() is not reflected instantly? Even tho I can perform a SQL query to the database and see the data has indeed been added/updated. As is referenced by reloading the current page.
So I'm at a loss as to why during this post method my view model portion comes up with null entries, but when I reload it they are populated normally.
I'm fine with leaving it as RedirectToAction, but would like to maybe understand better as to why this behavior is making it work.
Here is the view portion that breaks
<tbody>
#{ int? permissionLevel; }
#foreach (var user in Model)
{
permissionLevel = user.PermissionLevel ?? 4;
<tr>
<td>#user.Id</td>
<td>
#user.UserName
</td>
<td>#permissionLevel</td>
<td>
#foreach (var customUser in user.MxieCallRevPermCustomList)
{
#("[" + customUser.AspNetUsers.FirstName + " " + customUser.AspNetUsers.Lastname + "] ")
}
</td>
</tr>
}
</tbody>
the customUser.AspNetUsers = null when I use return View("ManageMxieUsers", model); in my [HttpPost] method.
I'm currently working on an "Activity Report" application on a first year internship, where employees can select a specific project and assign how many hours they have worked on it per day.
The selection of projects (depending on the employees id) and the display of the page seem to be working. But here's my problem : once I click on the displayed image that is supposed to submit the form - it seems to reload the page as if nothing happened !
The View line of the submission is as following :
<% using (Html.BeginForm("ActivityInputCreate", "Project"))
{ %>
[...]
<td>
<input type="image" style="border: 0; width: 16px;" src="../../Content/Black_16x16/Save.png" onclick="this.form.submit" alt="save" />
<input type="image" style="border: 0; width: 16px;" src="../../Content/Black_16x16/Cancel.png" onclick=" window.location.href = '/Project/ActivityInputIndex'; return false;" alt="cancel" /></td>
<!-- the first line being to save and the second to cancel -->
<td>
}
I don't know how to handle a form submission but here's the controller (the first of the same name being the non [HttpPost] one :
[HttpPost]
public ActionResult ActivityInputCreate(Project objToCreate, FormCollection form)
{
string year = form["Years"];
int iyear = int.Parse(year);
string month = form["Months"];
int imonth = int.Parse(month);
string strUser = Environment.UserName.ToLower();
CalendarController c = new CalendarController();
ViewBag.ListYears = c.ListYears(iyear);
ViewBag.ListMonths = c.ListMonths(imonth);
ViewBag.ListDaysOfMonth = _service.ListDaysOfMonth(iyear.ToString(), imonth.ToString());
//nea11
Session["ActivityInputYear"] = iyear.ToString();
Session["ActivityInputMonth"] = imonth.ToString();
ProjectResourceManagerService pr = new ProjectResourceManagerService(new ModelStateWrapper(this.ModelState));
ViewBag.ProjectList = pr.ListProject();
List<IEnumerable<SelectListItem>> ddlists = new List<IEnumerable<SelectListItem>>();
foreach (string s in ViewBag.ListDaysOfMonth)
ddlists.Add(_service.ListHours(0)); //id de UserActivity à la place de 0
ViewBag.ddlists = ddlists;
//nea12
string strProject = form["Project"];
//nea13
string strSep = ";";
string strDatas = "";
int l = 0;
foreach (var jour in ViewBag.ListDaysOfMonth)
{
string nom = "Hours" + l.ToString();
strDatas += form[nom] + strSep;
l++;
}
//ajout dans la base
UserActivityDb db = new UserActivityDb(#"metadata=res://*/Models.CRA.csdl|res://*/Models.CRA.ssdl|res://*/Models.CRA.msl;provider=Microsoft OLE DB Provider for SQL server;provider connection string="data source=(local)\SQLEXPRESS;initial catalog=CRAV34;persist security info=True;user id=sa;password=as0;multipleactiveresultsets=True;App=EntityFramework"");
if (null != strProject)
db.setFormattedData(iyear, imonth, ViewBag.ListDaysOfMonth, int.Parse(strProject), strUser, strDatas, true);
IEnumerable<Project> lp = _service.List(strUser, iyear.ToString(), imonth.ToString());
lp = lp.Where(p => (true == db.ExistUserActivity(iyear, imonth, ViewBag.ListDaysOfMonth, p.ProjectId, strUser)));
//nea35
List<string[]> lstInts = new List<string[]>();
foreach (Project p in lp)
{
string strInts = db.getFormattedData(iyear, imonth, ViewBag.ListDaysOfMonth, p.ProjectId, strUser, null, 0);
string[] ints = strInts.Split(';');
lstInts.Add(ints);
}
ViewBag.ProjectInts = lstInts;
return View("ActivityInputIndex", lp);
}
I'd love to give you more precision but please keep in mind that most of the code isn't mine and is the last interns'.
TL;DR : Display of the page is fine, I want to submit once the DropDownList are filled, submission button doesn't do anything.
Thank you.
Turns out the issue came with the input of my username (through the SQL INSERT).
string strUser = User.Identity.Name;
Is used with :
command.Parameters.Add("#Login", SqlDbType.VarChar, 50).Value = sLogin;
And works just fine. The issue was not with the sending of a form (which it did receive) but the way the SQL request was built.