Issue passing value from textbox to jquery function and onto controller function - c#

I came across an issue with passing values to jQuery where I want to pass the value from a textbox.
Here is the .cshtml:
#Html.TextBoxFor(m => m.OrderNumber, new { #class = "form-control", id = "orderNumber" })
My script:
function maintenance_tapped(e) {
var data = $('#orderNumber').val();
$("#SapPopUp")
.dialog({
width: 600,
height: 420,
model: true,
buttons: {
"OK": function() {
$.ajax({
url: '#Url.Action("RetrieveOrder", "Home")',
data: data,
type: "POST"
}).done(function() {
$(this).dialog("close");
});
},
"Cancel": function() {
$(this).dialog("close");
}
}
});
}
Code in my controller:
[HttpPost]
public async Task<ActionResult> RetrieveOrder(string number)
{
if (_sapHelper == null)
{
_sapHelper = new Helper();
}
return View();
}
My issue is that if I put a breakpoint in the RetrieveOrder function and I check the value of number i get null.
Then if go into Chrome->inspect element->Console and type $('#orderNumber').val(), I get the value I entered into the textbox.
It also seems like its not passing the value into the function.

Try this
dataType :'json',
data: {number: data},

Fixed this thanks to Aleksander Matic and Rob Lang.
Soloution
function maintenance_tapped(e) {
//var data = $('#orderNumber').val(); <------- Remove from here
$("#SapPopUp")
.dialog({
width: 600,
height: 420,
model: true,
buttons: {
"OK": function() {
var data = $('#orderNumber').val(); //<--------- Place here
$.ajax({
url: '#Url.Action("RetrieveOrder", "Home")',
data: data,
type: "POST",
dataType :'json', //<-------- Added
data: {number: data}, //<-------- Added
}).done(function() {
$(this).dialog("close");
});
},
"Cancel": function() {
$(this).dialog("close");
}
}
});
}

You can have the value in a javascript object and match the key to your action's parameter name.
This should work.
$.ajax({
url: '#Url.Action("RetrieveOrder", "Home")',
data: {
number: $('#orderNumber').val()
},
type: "POST"
}).done(function() {
$(this).dialog("close");
});
Also, I see you are returning a viewresult from the action method, but not using that in your ajax method call's done/success event handler. What is the point of doing that?

Related

The result from autocomplete are not displayed in partial view

I am using an ASP.NET MVC web site written in C#. I have code for an autocomplete that works fine in a regular view but not in a partial view. In the partial view,the results are sent back from the controller and the data is there but it is not displayed for the text box in the partial view.
The following is the Javascript code:
$(document).ready(function () {
$("#SearchBox1").autocomplete({
source: function (request, response) {
//alert(request.term);
$.ajax({
url: "/MArrangement/EventDetailAutoView",
type: "POST",
dataType: "json",
async: false,
data: { Prefix: request.term },
success: function (data) {
response($.map(data, function (item) {
//alert(item.CityName);
return { label: item.CityName, value: item.CityId };
}))
}
})
},
error: function (response) {
alert('1a');
alert(response.responseText);
},
failure: function (response) {
alert('2b');
alert(response.responseText);
},
messages: {
noResults: "", results: ""
}
});
});
This is the partial view:
<div>
<label>Search by Item or Inventory Type</label><br />
#Html.EditorFor(m => m.City.CityName, new { htmlAttributes = new { id = "SearchBox1", style = "position:absolute; z-index:11" } })
</div>
This is the controller code:
[HttpPost]
public JsonResult EventDetailAutoView(string Prefix)
{
List<Models.City> ObjList = new List<City>();
Models.Mod.InventoryMain.getInventory(ref ObjList, Guid.Parse(Session["UserID"].ToString()));
var CityList = (from N in ObjList
where N.CityName.ToLower().Contains(Prefix.ToLower())
select new { N.CityName, N.CityId }).ToList();
return Json(CityList, JsonRequestBehavior.AllowGet);
}
The method EventDetailAutoView is being called and is returning the correct data. In the success portion of the Javascript code, the data is shown (I put in a alert statement to see the data) but the results are not displayed underneath the SearchBox1 text box. The following code works fine in a regular view but not in a partial view.
You should add same code in regular view once partial view loads successfully.
var strUrDomainNamel = + '/Controller/Method';
$.ajax({
url: strUrl,
cache: false,
data: {},
type: 'POST',
success: function (data) {
$(".partialLoadview").html(data);
$("#SearchBox1").autocomplete({
//Your code for autocomplete must be here.
});
},
error: function (req, status, error) {
alert('error message');
}
});

asp.net mvc why ajax response after refreshing the page

this method I'm writing database and folder operations. no problem at all
the response is coming but the page refreshes. The problem disappears when I cancel folder operations.I don't want the page refreshed
$(".btnSave").on("click", function (e) {
var model = {
"ProductName": productName, "BrandCategoryId": BrandCategoryId, "TaxRate": taxRate, "WareHouseId": WareHouseId, "ProductId": ProductId, "PurchasePrice": purchasePrice, "Count": count, "Discount": discount
};
e.preventDefault();
e.stopPropagation();
swal({
title: "Lütfen Bekleyin", text: "Stok kayıt yapılıyor..", showConfirmButton: false, allowOutsideClick: false
});
$.ajax({
method: "POST",
url: "/Warehouseworker/JavaScript/NewStock",
data: model,
dataType: "json",
success: function (response) {
if (response.ModelErrors) {
var errors = response.ModelErrors;
swal.close();
showErrors(errors);
}
if (response.errorMsg) {
swal({ title: "Uyarı", text: "hata var", type: "warning" });
}
if (response.success) {
swal({ title: "Stok kaydı gerçekleştirilmiştir", text: "", type: "success" });
}
}
});
});
Are you using a button and it is in a form?
If so, make the button type="button" and it won't refresh the page. The default behavior is to post the form that it is in.
It it's a link then add the href=javascript:;.

Create chart with serverside object data using JSON

What I'm trying to do:
Create a chart and have it display data from the server (held in a C# object) every x mminutes. From googling using JSON (which I've never used before) would be best practice.
What I have so far:
I have the backend C# (using MVC 5) getting the correct data, lots of objects with lots of properties, some I want to display in the chart, others I don't.
I'v also started on a JSON function in my Index.cshtml which is where my graph is (currently set with static data, it's a simple jQuery plug-in).
The problem:
Unsure how to get specific object properties, to the JSON data and then to the chart data.
What would be the best way of achieving this?
Code:
Controller:
// GET: Graphs
public ActionResult Index()
{
return View();
}
public static List<server> GetServer()
{
Api api = new Api();
List<server> sList = api.GetServerStats();
return sList;
}
Script in INdex:
<script src="~/Scripts/canvasjs.min.js"></script>
<script type="text/javascript">
window.onload = function () {
var chart = new CanvasJS.Chart("someChart", {
title: {
text: "Space left on Server vs Total"
},
data: [
{
type: "column",
name: "Totals",
showInLegend: true,
dataPoints: [
{ label: "Space", y: 20 }
]
},
{
type: "column",
name: "Used",
showInLegend: true,
dataPoints: [
{ label: "Space", y: 10 }
]
}
],
axisY: {
prefix: "",
suffix: "GB"
}
});
chart.render();
}
$(document).ready(function () {
window.onload(function () {
$.ajax({
type: "POST",
url: "GraphController/GetServer",
data: { someParameter: "some value" },// array of values from object or just object
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
// need to push into jQuery function
}
});
});
});
</script>
Returning a serialised list of objects couldn't be easier with MVC, it takes a lot of the heavy lifting out of it for you if you just return a JsonResult:
public ActionResult GetServer() {
var api = new Api();
var = api.GetServerStats();
return Json(sList);
}
Debug the success of your ajax call to find out if result is what you want and expect, and then pass it to your chart script.
NOTE: From your use of wording (i.e. 'lots'), I'd recommend cutting down your list of server properties you return to your view. This is a perfect candidate for creating what's called a view model. This view model would be a kind of 'lite' version of your full server object. It would improve efficiency of serialisation for starters and, semantically, makes more sense.
I was doing same thing with highcharts and here is an approximate solution for you:
public ActionResult GetServer()
{
Dictionnary<server> sList = new Dictionnary<string,object>();
sList.Add("Totals",new{
type= "column",
name= "Totals",
showInLegend= true,
dataPoints= new List<dynamic>(){
new{ label= "Space", y= 20}/*,
new{ label= "label2", y= 30},*/
}
});
sList.Add("Totals",new{
type= "column",
name= "Used",
showInLegend= true,
dataPoints= new List<dynamic>(){
new{ label= "Space", y= 10}/*,
new{ label= "label2", y= 40},*/
}
});
return Json(sList, "text/json", JsonRequestBehavior.AllowGet);
}
Change window.onload=function(){} in
function drawChart(serverData){
var chart = new CanvasJS.Chart("someChart", {
title: {
text: "Space left on Server vs Total"
},
data: serverData,
axisY: {
prefix: "",
suffix: "GB"
}
});
chart.render();
}
$(document).ready(function () {
$.ajax({
type: "POST",
url: "GraphController/GetStuff",
data: { someParameter: "some value" },
// array of values from object or just object
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (serverData) {
// need to push into jQuery function
drawChart(serverData);
}
});
});

Kendo UI Scheduler: Delete/Edit/Update only specified events

Im working with the Kendo Scheduler and users can create, delete, update, edit events to my local database. But I'm working with different users on this webapp so I only want those users to be able to edit, delete and update events that they personally created. So user 1 can delete events created by user 1 but can't delete events created by user 2 or 3 etc...
I thought I just modify the model/controller to check the userID of the logged in user against the userID in the db of the event.
public virtual JsonResult Meetings_Destroy([DataSourceRequest] DataSourceRequest request, MeetingViewModel meeting)
{
var userid = System.Convert.ToInt32(Session["userID"]);
if (ModelState.IsValid)
{
if (meeting.UserID== userid)
{
meetingService.Delete(meeting, ModelState);
}
else
{
"cant delete"
}
}
return Json(new[] { meeting });
}
But this doesn't seem to work, when click on delete the event dissapears but after reloading you see that it actually isn't really deleted from the db ... That of course isn't a good solution cause the goal is of course that that user just can't delete that event.
Any idea's?
VIEW
$(function () {
$("#scheduler").kendoScheduler({
date: new Date(Date.now()),
startTime: new Date(2013, 5, 13, 9, 0, 0, 0),
height: 800,
timezone: "Etc/UTC",
dataSource: {
transport: {
read: {
url: "#Url.Action("Meetings_Read", "Home")",
dataType: "json",
contentType: "application/json; charset=utf-8",
type: "POST"
},
update: {
url: "#Url.Action("Meetings_Update", "Home")",
dataType: "json",
contentType: "application/json; charset=utf-8",
type: "POST"
},
create: {
url: "#Url.Action("Meetings_Create", "Home")",
dataType: "json",
contentType: "application/json; charset=utf-8",
type: "POST"
},
destroy: {
url: "#Url.Action("Meetings_Destroy", "Home")",
dataType: "json",
contentType: "application/json; charset=utf-8",
type: "POST"
},
parameterMap: function (options, operation) {
if (operation === "read") {
var scheduler = $("#scheduler").data("kendoScheduler");
var result = {
start: scheduler.view().startDate(),
end: scheduler.view().endDate()
}
return kendo.stringify(result);
}
return kendo.stringify(options);
}
},
error: error_handler,
schema: {
model: {
id: "MeetingID",
fields: {
MeetingID: { type: "number" },
title: { from: "Title", type: "string", defaultValue: "No title", validation: { required: true } },
description: { from: "Description", type: "string" },
start: { from: "Start", type: "date" },
startTimezone: { from: "StartTimezone", type: "string" },
end: { from: "End", type: "date" },
endTimezone: { from: "EndTimezone", type: "string" },
recurrenceRule: { from: "RecurrenceRule", type: "string" },
recurrenceId: { from: "RecurrenceID", type: "number", defaultValue: null },
recurrenceException: { from: "RecurrenceException", type: "string" },
isAllDay: { from: "IsAllDay", type: "boolean" },
Timezone: { type: "string" },
RoomID: { type: "number", defaultValue: null },
Attendees: { type: "object" }
}
}
}
},
});
});
JAVASCRIPT
<script type="text/javascript">
function error_handler(e) {
if (e.errors) {
var scheduler = $("#scheduler").data("kendoScheduler");
scheduler.one("dataBinding", function (e) {
e.preventDefault();
for (var error in e.errors) {
alert("can't delete")
}
})
var message = "Errors:\n";
$.each(e.errors, function (key, value) {
if ('errors' in value) {
$.each(value.errors, function () {
message += this + "\n";
});
}
});
alert(message);
}
}
CONTROLLER
public virtual JsonResult Meetings_Destroy([DataSourceRequest] DataSourceRequest request, MeetingViewModel meeting)
{
if (ModelState.IsValid)
{
if(meeting.UserID == System.Convert.ToInt32(Session["userID"]))
{
meetingService.Delete(meeting, ModelState);
}
else
{
ModelState.AddModelError("","cant delete");
}
}
return Json(new[] { meeting });
}
I have a similar situation with my project where I have users that have limited access to do things on the calendar. I have found that you have to prevent things like Adds, Edits, and Deletes, that a user should not do, you can do this with the JavaScript events. Then, in the JavaScript functions, if a condiation is met (or not), then call the e.preventDefault(); method. Here's the demo on Client Events.
View (HTML 5 snippet)
remove: RemoveMe,
edit: EditMe,
add: AddMe,
View (MVC version snippet)
.Events(events =>
{
events.Add("AddMe").Edit("EditMe").Remove("RemoveMe");
})
JavaScript
function AddMe (e) {
if (SomeValue != SomeOtherValue)
e.preventDefault();
};
function EditMe (e) {
if (SomeValue != SomeOtherValue)
e.preventDefault();
};
function RemoveMe (e) {
if (SomeValue != SomeOtherValue)
e.preventDefault();
};
So, the good news is that this prevents the Calendar from showing updates (whether a Delete occurs or not), but it doesn't prevent the Delete Prompt (aka. "Are you sure you want to delete this event?"). Preventing the actions on the Client side is the way to go and you could extend it with alerts or notifications to the screen (since you would have the condition in the JavaScript function anyways), all to inform the user they can't do something.
ModelState.AddModelError("cant delete");
return Json(ModelState.ToDataSourceResult());
in the view
.Read("Grouping_Horizontal_Read", "Scheduler")
.Create("Grouping_Horizontal_Create", "Scheduler")
.Destroy("Grouping_Horizontal_Destroy", "Scheduler")
.Update("Grouping_Horizontal_Update", "Scheduler")
.Events(events => events.Error("error"))
.Events(events => events.Error("error")) is the trick and now importent the funktion for the error
function error(args) {
if (args.errors) {
var scheduler = $("#scheduler").data("kendoScheduler");
scheduler.one("dataBinding", function (e) {
e.preventDefault(); // cancel scheduler rebind if error occurs
for (var error in args.errors) {
alert(error + " args: " + args.errors[error].errors[0])
}
});
args.sender.cancelChanges();
}
}
It depends on how you are creating the meeting too.
Because to remove a task you just need a unique ID.
Right now it's just being deleted in JSON but not in the backend database, as I guess that meeting.id is not matching to the taskID generated when create event was fired.
I recommend to save taskID in ViewBag, SQL Table or somewhere, when task is created in the scheduler. Then pass this id as the parameter in your Meetings_Destroy method, when remove event is fired.
And [as mentioned in previous answer] use JavaScript remove event to validate logged in user, as e.preventDefault() can be used to restrict Meetings_Destroy method being fired if condition is not met. If debug is reached at Controller Method [Meetings_Destroy] it would remove event from scheduler [Either successfully removed in database or not], i-e from front end, but would bring it back on page refresh.
I have a same situation. I took a different approach to resolve it. In the edit function I compare task id and current userId and than I simply hide those button save, cancel and delete. These button will so only a user who created that.
function(e)
{
var customHide13= $(".k-scheduler-update, .k-scheduler-delete, .k-scheduler-cancel");
if (taskId == userId)
customHide13.show();
else
customHide13.hide();
},

fullcalendar: call web service function when next or prev button is pressed

I want to load events of only one month at a time. At first, show the event of one month in one page and when next or prev button is pressed, show the event of that month from database via web service (C#). How can I achieve that?
I also want to get data from one month only and I want to send the selected year, month value to the web service so it can send the data of only specific month.
My current jquery code is:
jQuery(document).ready(function () {
$.ajax({
type: "POST",
contentType: "application/json",
url: "FullcalenderwithWebservice.asmx/GetEvents",
dataType: "json",
success: function (data) {
$("div[id=loading]").hide();
$("div[id=fullcal]").show();
$('div[id*=fullcal]').fullCalendar({
header: {
left: '',
center: 'title',
right: 'today prev,next'
},
editable: false,
events: $.map(data.d, function (item, i) {
var event = new Object();
event.id = item.EventID;
event.start = new Date(item.StartDate);
event.title = item.EventName;
event.className = item.className.toString()
return event;
})
});
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
debugger;
}
});
});
also
$('.fc-button-prev span').click(function(){
alert('prev is clicked, do something');
});
is not working.
You might want to use viewdisplay e.g.
viewDisplay: function(view) { var next = view.title; alert(next); }
Here I am using that event to go and get the next batch of data from a webservice and render it.
$(document).ready(function () {
var calendar = $('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
},
eventSources: [ getCalData() ],
header: {
left: 'prev,next today',
center: 'title',
right: ''
},
viewDisplay: function (view) {
$('#calendar').fullCalendar('removeEvents');
$('#calendar').fullCalendar('addEventSource', getCalData());
$('#calendar').fullCalendar('rerenderEvents');
}
});
});
function getCalData() {
var source = [{}];
$.ajax({
async: false,
url: '/mysite/GetWeekData',
data: { myParam: $('#calendar').fullCalendar('getView').visStart },
success: function (data) {
$(data).each(function () {
source.push({
title: $(this).attr('title'),
start: $(this).attr('start'),
});
});
},
error: function () {
alert('could not get the data');
},
});
return source;
}

Categories