I have an appointments application with multiple users who can multiple appointments. I display this on FullCalendar.
However, I'm having a problem. I want the User logged in to see their events and not others. This works when I close the application completely but if I log out and want to login as another user, I see the other users appointments.
I tried using re fetch events with FullCalendar then I looked at the Configuration.ProxyCreationEnabled = false; within my DAL class.
Here's my controller method:
public JsonResult GetEvents()
{
string username = Membership.GetUser().UserName;
var getAdmin = (from a in db.Admins
where username == a.AdminUsername
select a.AdministrationId).SingleOrDefault();
var events = (from a in db.Appointments
where getAdmin == a.AdministrationId
select a).ToList();
return new JsonResult { Data = events, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
And FullCalendar:
<script>
$(document).ready(function () {
var events = [];
$.ajax({
type: "GET",
url: "/Appointments/GetEvents",
success: function (data) {
$.each(data, function (i, v) {
events.push({
details: v.DetailsOfAppointment,
date: moment(v.DateOfAppointment),
room: v.RoomType,
confirmed: v.Confirmed,
colour: v.ThemeColour,
church: v.Church.Name,
parishAdminName: v.Admins.AdministratorName,
parishAdminUser: v.Admins.AdminUsername,
parishAdminId: v.Admins.AdministratorId,
fee: v.Fee,
id: v.AppointmentId
});
})
GenerateCalender(events);
},
error: function (error) {
alert("failed");
console.log(error);
}
})
function GenerateCalender(events) {
$('#calender').fullCalendar('destroy');
$('#calender').fullCalendar('refetchEvents');
$('#calender').fullCalendar({
contentHeight: 500,
defaultDate: new Date(),
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay'
},
timeFormat: 'HH:mm',
eventLimit: true,
eventColor: events.ThemeColour,
events: events,
eventRender: function (event, element) {
if (event.fee == null) {
if (event.confirmed == false) {
element.css('background-color', '#FF0000');
element.css('border-color', '#FF0000');
}
else {
element.css('background-color', '#008000');
element.css('border-color', '#008000');
}
}
else
{
element.css('background-color', '#0000FF');
element.css('border-color', '#0000FF');
}
},
eventClick: function (calEvent, jsEvent, view) {
$('#myModal #details').text(calEvent.details);
var $details = $('<div/>');
if (calEvent.fee != null) {
$details.append($('<p/>').html('<b>Date of Ceremony : </b>' + calEvent.date.format("DD-MMM-YYYY HH:mm a")));
}
else {
$details.append($('<p/>').html('<b>Date of Appointment : </b>' + calEvent.date.format("DD-MMM-YYYY HH:mm a")));
}
if (calEvent.end != null) {
$details.append($('<p/>').html('<b>End:</b>' + calEvent.end.format("DD-MMM-YYYY HH:mm a")));
}
$details.append($('<p/>').html('<b>Details : </b>' + calEvent.details));
$details.append($('<p/>').html('<b>Church Name : </b>' + calEvent.church));
if (calEvent.fee == null) {
if (calEvent.room != null) {
$details.append($('<p/>').html('<b>Room : </b>' + calEvent.room));
}
else {
$details.append($('<p/>').html('<b>Room Not Confirmed'));
}
}
$details.append($('<p/>').html('<b>Parish Admin : </b>' + calEvent.parishAdminName));
if (calEvent.confirmed == true)
{
$details.append($('<p/>').html('<b>Status : Confirmed </b>'));
}
else
{
$details.append($('<p/>').html('<b>Status : Not Confirmed </b>'));
}
$('#myModal #pDetails').empty().html($details);
$('#myModal').modal();
}
})
}
})
</script>
}
Your JSON payload is likely being cached by the browser.
To stop this, add this attribute above GetEvents:
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*", Location = OutputCacheLocation.None)]
to disable caching.
Related
I got an project in dotnet and i'm trying to use GoogleCharts, but it's not working.
The project is on .net mvc
Here is my code:
Views->Sensor->Chart.cshtml
#{
ViewData["Title"] = "Chart";
}
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div" style="width: 900px; height: 500px;"></div>
<script type="text/javascript">
google.charts.load('current', {packages: ['corechart', 'bar']});
google.charts.setOnLoadCallback(LoadData);
function LoadData() {
$.ajax({
url: '#Url.Action("ChartJson","Sensor")',
dataType: "json",
type: "GET",
error: function(xhr, status, error) {
var err = eval("(" + xhr.responseText + ")");
toastr.error(err.message);
},
success: function(data) {
CreateChart(data);
return false;
}
});
return false;
}
function CreateChart(data) {
var dataArray = [
['Tag', 'Average value']
];
$.each(data, function(i, item) {
dataArray.push([item.tag, item.value]);
});
var data = google.visualization.arrayToDataTable(dataArray);
var options = {
title: 'Sensor data per coutry and region',
chartArea: {
width: '50%'
},
colors: ['#b0120a', '#ffab91'],
hAxis: {
title: 'Arithmetic average',
minValue: 0
},
vAxis: {
title: 'Tag'
}
};
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
return false;
}
</script>
This view is loaded on the url, but there is no graph on it.
I thied to debug the controller class, but the ChartJson() method is never called.
This is the two methods on the controller for the charts draw routine:
Controllers->SensorController.cs
public IActionResult Chart()
{
return View();
}
public JsonResult ChartJson()
{
var sensors = from s in _context.Sensor select s;
var sensorsList = sensors.ToList();
Console.WriteLine("Entrou");
List<ChartData> listChart = new List<ChartData>();
foreach (Sensor s in sensorsList)
{
int value;
bool isNumeric = int.TryParse(s.value, out value);
if (!isNumeric)
continue;
string tag = s.country + "." + s.region;
for (int i = 0; i < listChart.Count; i++)
{
if (listChart[i].tag.Equals(tag))
{
listChart[i].AddValue(value);
break;
}
if (i == listChart.Count - 1)
{
listChart.Add(new ChartData(tag));
break;
}
}
}
return Json(listChart);
}
Can anyone help me? Thanks.
This is a last attempt for me to get some insight on this issue before I scratch JqGrid all together. I have a col in my colModel to upload an Image. I am using ajaxfileupload. Although there are several of the same examples out there they seem to work for others but mine is not. When I select an Image from the enctype: "multipart/form-data" for some reason it is not putting anything in the record for the object. I have a few breakpoints and when I view the data everything is visible but the product Image. So all fields are there and ProductImage is null. It is like JqGrid is not holding the object and passing it. Since it is null, nothing gets uploaded either. Maybe I am missing something but I have looked through my code over and over again and it appears to be just like what I have read in examples that supposedly work.
Any help with would be fantastic as I am ready to scratch this and use something else.
Below is my code for the process. sections only. if you need to see other code let me know.
JqGrid:
{
name: "ProductImage",
index: "ProductImage",
mtype: "Post",
editable: true,
editrules: { required: true },
edittype: "file",
search: true,
resizable: false,
width: 210,
align: "left",
editoptions: {
enctype: "multipart/form-data"
}
},
.....
{
// edit option
zIndex: 100,
url: "/Admin/EditProducts",
closeOnEscape: true,
closeAfterEdit: true,
recreateForm: true,
afterSubmit: uploadImage,
afterComplete: function (response) {
if (response.responseText) {
alert(response.responseText);
}
}
},
....
function uploadImage(response, postdata) {
//debugger;
//var json = $.parseJSON(response.responseText);
//if (json) return [json.success, json.message, json.id];
//return [false, "Failed to get result from server.", null];
var data = $.parseJSON(response.responseText);
if (data.success == true) {
if ($("#ProductImage").val() != "") {
ajaxFileUpload(data.id);
}
}
return [data.success, data.message, data.id];
}
function ajaxFileUpload(id) {
$.ajaxFileUpload(
{
url: "/Admin/UploadImage",
secureuri: false,
fileElementId: "ProductImage",
dataType: "json",
data: { id: id },
success: function (data, status) {
if (typeof (data.isUploaded) != "undefined") {
if (data.isUploaded == true) {
return;
} else {
alert(data.message);
}
}
else {
return alert("Failed to upload image!");
}
},
error: function (data, status, e) {
return alert("Failed to upload image!");
}
}
)
return false;
}
Controller:
public string EditProducts(Product product)
{
string msg;
try
{
if (ModelState.IsValid)
{
using (StoreEntities db = new StoreEntities())
{
db.Entry(product).State = EntityState.Modified;
db.SaveChanges();
msg = "Saved Successfully";
}
}
else
{
msg = "Did not save! ";
}
}
catch (DbEntityValidationException ex)
//catch (Exception ex)
{
msg = "Error occured:" + ex.Message;
foreach (var validationErrors in ex.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
System.Diagnostics.Debug.WriteLine("Property: {0} Error: {1}",
validationError.PropertyName, validationError.ErrorMessage);
}
}
}
return msg;
}
....
#region Upload Images
[HttpPost]
public JsonResult UploadImage(HttpPostedFileBase ProductImage)
{
string directory = "~/Images/";
if (ProductImage != null && ProductImage.ContentLength > 0)
{
var fileName = Path.GetFileName(ProductImage.FileName);
ProductImage.SaveAs(Server.MapPath(Path.Combine(directory, fileName)));
//ProductImage.SaveAs(Path.Combine(directory, fileName));
}
return Json(new { isUploaded = true, message = "Uploaded Successfully" }, "text/html");
}
#endregion
I have a stored procedure that equates and gets the occupancy rate of a room. I want to fetch the data from the back-end using JSon and display the output data of the stored procedure in the front-end code. But the output data only sticks at the Business Layer. How can i call it from my Controller using Json?
Here is my code
In my Controller
public JsonResult GetoccupancyRate()
{
string _connectionString = rAppSetting.ConnectionString;
try
{
IList<Hotel> _currentOccupancyRateList = rHotelFacade.GetOccupancyRate(HotelIDCookie, DateTime.Now, _connectionString);
IList<Hotel> _yesterdayOccupancyRateList = rHotelFacade.GetOccupancyRate(HotelIDCookie, DateTime.Now.AddDays(-1), _connectionString);
return Json(new
{
success = true,
message = "Success",
yesterdayOccupancyRate = _yesterdayOccupancyRateList,
currentOccupancyRate = _currentOccupancyRateList
},JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Json(new
{
success = false,
message = ex.Message,
currentOccupancyRate = "",
yesterdayOccuoancyRate = ""
}, JsonRequestBehavior.AllowGet);
}
}
Javascript
myapp.factory("occupancyRateService", ['$http', function ($http) {
this.LoadOccupancyRate = function () {
return $http.get("/Dashboard/GetOccupancyRate", {});
};
return this;}]);
myapp.controller('MainController', ['$scope', 'dashboardService', 'occupancyRateService', function ($scope, dashboardService, occupancyRateService) {
$scope.myChart = {
type: 'google.charts.Bar',
options: {},
data: {}
};
$scope.loadOccupancyRateDetails = function () {
occupancyRateService.LoadOccupancyRate().success(function (result) {
if (result.success)
{
var currentOccupancyRateData = result.currentOccupancyRate;
var yesterdayOccupancyRateData = result.yesterdayOccupancyRate;
console.log(result.currentOccupancyRate);
console.log(result.yesterdayOccupancyRate);
//console.log(yesterdayResultData)
if (currentOccupancyRateData || yesterdayOccupancyRateData === null)
{
google.charts.load('current', { 'packages': ['line', 'bar'] });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Day', 'Rate'],
['Yesterday', 0],
['Today', 0]
]);
var options = {
chart: {
//title:'Occupancy Rate',
},
bars: 'vertical',
hAxis: { format: 'none', gridlines: { count: 5 } },
vAxis: { format: '.######%' },
height: 180,
//width: 100%,
colors: ['#1b9e77']
};
var chart = new google.charts.Bar(document.getElementById('chart_div'));
chart.draw(data, google.charts.Bar.convertOptions(options));
};
$(window).resize(function () {
drawChart();
});
}
else
{
google.charts.load('current', { 'packages': ['line', 'bar'] });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Day', 'Rate'],
['Yesterday', currentOccupancyRateData],
['Today', yesterdayOccupancyRateData]
]);
//function drawChart() {
// var data = google.visualization.arrayToDataTable([ORData]);
var options = {
chart: {
//title:'Occupancy Rate',
},
bars: 'vertical',
hAxis: { format: 'none', gridlines: { count: 5 } },
vAxis: { format: '.################%' },
height: 180,
//width: 100%,
colors: ['#1b9e77']
};
var chart = new google.charts.Bar(document.getElementById('chart_div'));
chart.draw(data, google.charts.Bar.convertOptions(options));
};
$(window).resize(function () {
drawChart();
});
}
}
})
.error(function (error) {
alert(error);
})
};
$scope.loadOccupancyRateDetails();
//<--------------------------------------->
}]);
On my View I have a button I use to submit a [description] value to my Controller via JSON, which is then used to create a new Table record. For example:
[HttpPost]
public JsonResult createNewStatus(string description)
{
INV_Statuses status = new INV_Statuses()
{
// ID auto-set during save
status_description = description,
created_date = DateTime.Now,
created_by = System.Environment.UserName
};
//var allErrors = ModelState.Values.SelectMany(x => x.Errors);
try
{
if (ModelState.IsValid)
{
db.INV_Statuses.Add(status);
db.SaveChanges();
}
}
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
return Json(new { ID = status.Id, Text = status.status_description }, JsonRequestBehavior.AllowGet);
}
What I'd like to do now (before saving the Status to the DB) is run a check to see if any other records in the INV_Statuses table have a [description] value matching the one submitted to the function for new creation. If there is a match, I want to return an error/validation? message and alert the user the submitted value already exists and to choose it from the DropDownList on the View.
Can anyone provide an example of how to go about this with LINQ in my MVC Controller?
EDIT: Added my View JS code for submitting the new Status:
$('#createNewStatus').click(function () {
$('#createStatusFormContainer').show();
})
$('#cancelNewStatus').click(function () {
$('#createStatusFormContainer').hide();
})
$('#submitNewStatus').click(function () {
var form = $(this).closest('form');
var data = { description: document.getElementById('textNewStatus').value };
$.ajax({
type: "POST",
dataType: "JSON",
url: '#Url.Action("createNewStatus", "INV_Assets")',
data: data,
success: function (resp) {
$('#selectStatus').append($('<option></option>').val(resp.ID).text(resp.Text));
form[0].reset();
$('#createStatusFormContainer').hide();
var count = $('#selectStatus option').size();
$("#selectStatus").prop('selectedIndex', count - 1);
},
error: function () {
alert("ERROR!");
}
});
});
EDIT2:
Adricadar's suggestion:
INV_Statuses status = new INV_Statuses()
{
// ID auto-set during save
status_description = description,
created_date = DateTime.Now,
created_by = System.Environment.UserName
};
try
{
var existingStatus = db.INV_Statuses.FirstOrDefault(x => x.status_description.ToUpper() == status.status_description.ToUpper());
var isDuplicateDescription = existingStatus != null;
if (isDuplicateDescription)
{
ModelState.AddModelError("Error", "[" + status.status_description + "] already exists in the database. Please select from the DropDownList.");
}
else if (ModelState.IsValid)
{
db.INV_Statuses.Add(status);
db.SaveChanges();
}
}
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
return Json(new { ID = status.Id, Text = status.status_description }, JsonRequestBehavior.AllowGet);
I added a .ToUpper() in my comparison in Controller, but even though the match with .ToUpper() gets identified, the ModelState.AddModelError() code fires, then the code returns and no error message is issued?
The value (though duplicate) still gets added to the dropdownlist (visually, not in DB) via my current JS code:
$('#createNewStatus').click(function () {
$('#createStatusFormContainer').show();
})
$('#cancelNewStatus').click(function () {
$('#createStatusFormContainer').hide();
})
$('#submitNewStatus').click(function () {
var form = $(this).closest('form');
var data = { description: document.getElementById('textNewStatus').value };
$.ajax({
type: "POST",
dataType: "JSON",
url: '#Url.Action("createNewStatus", "INV_Assets")',
data: data,
success: function (resp) {
$('#selectStatus').append($('<option></option>').val(resp.ID).text(resp.Text));
form[0].reset();
$('#createStatusFormContainer').hide();
var count = $('#selectStatus option').size();
$("#selectStatus").prop('selectedIndex', count - 1);
},
error: function () {
alert("ERROR!");
}
});
});
Check for existing status and set status back as follows:
var existingStatus = db.INV_Statuses.FirstOrDefault(s => s.status_description == description);
if (existingStatus ==null)
{
db.INV_Statuses.Add(status);
db.SaveChanges();
}
else
{
// set the status back to existing
status = existingStatus;
}
Set an existing flag in your response:
return Json(new { ID = status.Id, Text = status.status_description, AlreadyExists = (existingStatus != null) }, JsonRequestBehavior.AllowGet);
Then in your response JavaScript, simply parse out the returned data:
success: function (resp) {
if (resp.AlreadyExists != true)
{
$('#selectStatus').append($('<option></option>').val(resp.ID).text(resp.Text));
form[0].reset();
$('#createStatusFormContainer').hide();
var count = $('#selectStatus option').size();
$("#selectStatus").prop('selectedIndex', count - 1);
}
else
{
alert(resp.status_description + " already exists");
$("#selectStatus").val(resp.Id);
}
}
You can query the database for a status with an existing description and if exists and an model state error.
Be aware that string comparison is case sensitive.
[HttpPost]
public JsonResult createNewStatus(string description)
{
INV_Statuses status = new INV_Statuses()
{
// ID auto-set during save
status_description = description,
created_date = DateTime.Now,
created_by = System.Environment.UserName
};
//var allErrors = ModelState.Values.SelectMany(x => x.Errors);
try
{
var existingStatus = db.INV_Statuses.FirstOrDefault(x => x.status_description.ToUpper() == status.status_description.ToUpper());
var isDuplicateDescription = existingStatus != null;
string error = String.Empty;
if (isDuplicateDescription)
{
error = "[" + status.status_description + "] already exists in the database. Please select from the DropDownList.";
}
else if (ModelState.IsValid)
{
db.INV_Statuses.Add(status);
db.SaveChanges();
}
}
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
return Json(new { ID = status.Id, Text = status.status_description, Error = error , IsDuplicate = isDuplicateDescription }, JsonRequestBehavior.AllowGet);
}
In javascript verify if response have IsDuplicate = true if is true you skip the part where you need to add an element in dropdown.
$('#createNewStatus').click(function () {
$('#createStatusFormContainer').show();
})
$('#cancelNewStatus').click(function () {
$('#createStatusFormContainer').hide();
})
$('#submitNewStatus').click(function () {
var form = $(this).closest('form');
var data = { description: document.getElementById('textNewStatus').value };
$.ajax({
type: "POST",
dataType: "JSON",
url: '#Url.Action("createNewStatus", "INV_Assets")',
data: data,
success: function (resp) {
if(resp.IsDuplicate)
{
//display error from response
//display resp.Error
} else {
$('#selectStatus').append($('<option></option>').val(resp.ID).text(resp.Text));
form[0].reset();
$('#createStatusFormContainer').hide();
var count = $('#selectStatus option').size();
$("#selectStatus").prop('selectedIndex', count - 1);
}
},
error: function () {
alert("ERROR!");
}
});
});
I reached a point in my code where I need to call a method in the controller from the view.
I need to send some parameters with him from DropDownLists and TextBoxes.
I dont want to make a #using (Html.BeginForm... and an <input>, I just want to keep a <button> with a function call there that gathers that info and runs the method.
Is it possible?
An example of my DDL and Textbox:
#Html.DropDownListFor(cModel => cModel.QueueMonitorConfigTypeName, Enum.GetValues(typeof(BPM.Website.Models.PathType)).Cast<BPM.Website.Models.PathType>().Select(v => new SelectListItem
{
Text = v.ToString(),
Value = v.ToString()
}), new { id = "ddlConfigTypeName" })
#Html.TextBoxFor(cModel => cModel.Location, new { id = "txtbLocation" })
My button:
<button id="btnAddUpdateConfig" name="btnAddUpdateConfig" value="Apply" onclick="ValidateValues()">Apply</button>
JS:
function ValidateValues()
{
$.ajax({
type: "POST",
url: "Storage/AddUpdateConfigs",
data: ({id: #Model.QueueMonitorConfigurationsID, PathType: $('#ddlConfigTypeName').val(), Threshold:$('#ddlThreshold').val(), ValueType:$('#ddlValueTypeName').val(), Location: $('#txtbLocation').val(), Limit: $('#txtbLimit').val(), config: $('#NewOrUpdate').val() }),
dataType: JSON
});
}
But my function AddUpdate Configs is not being triggered:
public ActionResult AddUpdateConfigs(int id, string configType, string location, string threshold, string valueType, int limit)
{
return PartialView();
}
I put a breakpoint in the return and is not reached
Something like this should work:
$.postify = function(value) {
var result = {};
var buildResult = function(object, prefix) {
for (var key in object) {
var postKey = isFinite(key)
? (prefix != "" ? prefix : "") + "[" + key + "]"
: (prefix != "" ? prefix + "." : "") + key;
switch (typeof (object[key])) {
case "number": case "string": case "boolean":
result[postKey] = object[key];
break;
case "object":
if (object[key].toUTCString)
result[postKey] = object[key].toUTCString().replace("UTC", "GMT");
else {
buildResult(object[key], postKey != "" ? postKey : key);
}
}
}
};
buildResult(value, "");
return result;
};
function login() {
var logonmodel = {
UserName: $tbUsername.val(),
Password: $tbPassword.val()
};
$.ajax({
type: "POST",
url: "/account/logon",
data: $.postify(logonmodel),
asynch: true,
dataType: "json",
success: function (msg) {
console.log(msg.state);
if (msg.state == 'good') {
window.location.href = msg.url;
}
else {
var $generalLoginError = $('span#generalLoginError');
var $loginuserNameError = $('span#loginUserNameError');
var $loginPasswordError = $('span#loginPasswordError');
$loginuserNameError.html(msg.errors.username);
$loginPasswordError.html(msg.errors.password);
if (msg.errors.incorrect != '')
$generalLoginError.html(msg.errors.incorrect);
}
}
});
}
Here's the controller action:
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, false);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
return Json(new { url = returnUrl, message = "", state = "good" });
}
else
{
return Json(new { url = "/", message = "", state = "good" });
}
}
}
// If we got this far, something failed, redisplay form
return Json(new
{
url = "/",
errors = new
{
username = (model.UserName == null) ? "required" : "",
password = (model.Password == null) ? "required" : "",
incorrect = (!Membership.ValidateUser(model.UserName, model.Password)) ? "The user name or password provided is incorrect." : "",
//generic = "An error has occurred. If the error persists, please contact the webmaster."
},
state = "error"
});
}
Do an AJAX request when the button is clicked.
$.ajax({
type: "POST",
url: http://site.com/Controller/Action,
data: data,
success: success,
dataType: dataType
});
See:
http://api.jquery.com/jQuery.post/