Student Data Grid that display the student id and a description in the grid. It also has a select button when the user click on it that would route to a javascript function. This function will set some flags on the server side, close the window, past the studentID on a search box and do an automatic search on the studentID. The click appears to be doing exactly what I want it to do.
However, if the user were to double click on a row in the grid, it is supposed to do the exact same thing. it should also do a post. The double click is doing the post twice. What is causing it to do the post twice? I have not been able to figure it out. I've been putting alert all over the place and no success as to why.
In case you may be wondering why I have the dataroute and a client side script. This grid is in a pop up page that is also being called from other pages. When the user calls the grid from another page, the user will have the ability to select multiple records vs. only being able to select one records when they are calling it from the Course Page.
Here is the Grid:
#(Html
.Telerik()
.Grid((IEnumerable<OverrideStudent>)SessionWrapper.Student.OtherStudentSelected)
.Name("StudentData")
.DataKeys(Keys =>
{
Keys.Add(c => c.StudentID);
})
.DataBinding(databinding => databinding.Server())
.Columns(columns =>
{
columns.Bound(p => p.StudentId)
.Title("Student ID")
.Width(15)
.Sortable(true)
.Filterable(false);
columns.Bound(p => p.StudentDescription)
.Title("Description")
.Width(65)
.Sortable(true)
.Filterable(false);
columns.Command(command =>
{
command.Custom("AddStudent")
.Text("Select")
.DataRouteValues(routes =>
{
routes.Add(o => o.StudentID).RouteKey("StudentID");
routes.Add(o => o.StudentDescription).RouteKey("StudentDescription");
})
.Action("Student", "StudentInfo");
.HtmlAttributes(new { onclick = "PostData(this);StudentSelectClick(this)" });
}).Width(20);
}).ClientEvents(clients => clients
.OnComplete("OnComplete")
//.OnDataBinding("DataBinding")
//.OnDataBound("onRowDataBound")
.OnRowSelected("StudentDoubleClick")
)
.Sortable()
.Selectable()
.Filterable(filtering => filtering
.Enabled(true)
.Footer(true)
.HtmlAttributes(new { style = "padding-right: 0.0em;" }))
Here are the JavaScripts that are doing the post:
function StudentDoubleClick(e) {
var fromCourse = "#SessionWrapper.Student.FromCoursePage";
var fromList = "#SessionWrapper.Student.FromListingPage";
if (fromCourse == "True") {
$('tr', this).live('dblclick', function () {
alert("Inside TR count = " + count);
count = count + 1;
DoSearchStudent(e);
});
}
if (fromList == "True") {
$('tr', this).live('dblclick', function () {
DoSearchStudent(e);
});
}
}
function DoSearchStudent(e) {
var row = e.row;
var StudentID = row.cells[0].innerHTML;
var StudentDescription = row.cells[1].innerHTML;
// alert(procCodeDesc);
var data = { "StudentID": StudentID, "StudentDescription": StudentDescription, "action": "Double Click" };
var url = '#Url.Action("Student", "StudentInfo")';
$.ajax({
url: url,
type: 'post',
dataType: 'text',
cache: false,
async: false,
data: data,
success: function (data) {
window.top.location.href = window.top.location.href;
},
error: function (error) {
alert("An error has occured and the window will not be closed.");
}
});
}
//Single Click on BUtton
function StudentSelectClick(e) {
var windows = this.parent.$('#Window').data('tWindow');
var fromCourse = "#SessionWrapper.Student.FromCoursePage";
var fromList = "#SessionWrapper.Student.FromListingPage";
if (fromCourse == "True") {
var studentInformation = e.toString();
var data = { "myModel": "null", "studentInformation": studentInformation };
var url = '#Url.Action("UpdatedFromSelect", "StudentProcedure")';
$.ajax({
url: url,
type: 'post',
dataType: 'text',
cache: false,
async: false,
data: data,
success: function (data) {
// window.top.location.href = window.top.location.href;
windows.close();
// setTimeout(this.window.top.location.href = this.window.top.location.href, 1000);
window.top.location.href = window.top.location.href;
},
error: function (error) {
alert("An error has occured and the window will not be closed.");
}
});
}
}
This is the method where the double is being posted to. It simply redirect to a different method of return type ActionResult that also does a redirect to the index page of return ActionResult:
public string Student(string StudentID, string StudentDescription, string action)
{
if (StudentDescription != null)
{
StudentDescription = HttpUtility.HtmlDecode(StudentDescription);
}
try
{
AddStudent(StudentID, StudentDescription, action);
}
catch (Exception e)
{
return "Error " + e.ToString();
}
return "Success";
}
Your help would be greatly appreciated, thanks.
Have you checked the number of times jQuery and the Unobtrusive scripts are added in your html? I had an issue in a previous project where one of these was duplicated and caused a double post.
Related
Hello wenn i want to send a post request to my Controller there is no data.
I tried to log my Json file and there is something. But when I send the post request my controller shows it is empty.
Here is my call:
var item = {};
var jsonObj = [];
item["ProductCategoryId"] = i;
item["Name"] = txtName;
item["Description"] = txtDescription;
item["Price"] = txtPrice;
item["Stock"] = txtStock;
item["ProductCategory"] = txtProductCategory;
item["Image"] = await getAsByteArray(txtImage);
jsonObj.push(item);
var jsonString = JSON.stringify(jsonObj);
console.log("jsonString : " + jsonString);
$.ajax({
url: "/Admin/SaveProductToDB",
type: "POST",
data: { dataToSend: jsonString},
success: function (data) {
if (data.status == "Success") {
BootstrapDialog.show({
title: 'Success!',
message: "Data Updated Successfully!",
buttons: [{
label: 'OK',
action: function (dialog) {
window.location.href = "/Admin/Product";
removeProdData(i);
$("#btnAddProd").attr("disabled",false);
dialog.close();
}
}]
});
}
}
});
//Here I make a breakpoint but my string is empty
public JsonResult SaveProductToDB(string dataToSend)
{
List<Product> _List = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Product>>(dataToSend);
}
the getAsByteArray
async function getAsByteArray(file) {
return new Uint8Array(await readFile(file))
}
function readFile(file) {
return new Promise((resolve, reject) => {
// Create file reader
let reader = new FileReader()
// Register event listeners
reader.addEventListener("loadend", e => resolve(e.target.result))
reader.addEventListener("error", reject)
// Read file
reader.readAsArrayBuffer(file)
})
}
I found out if I remove the Image. that the controller is then able to resize it. Thanks for the help so far. So I need to look at this place where the problem is.
You are checking against data.status as if it's a given that it exists. Just console.log(data) instead and you will see whether or not status is being returned.
Also, if you open the Network tab in Chrome you can click on the post request & see if your headers are going through accurately and also click on 'Preview' to see an unfiltered result from the controller.
You might want to modify your code to catch errors for debugging, ie:
$.ajax({
url: "/Admin/SaveProductToDB",
type: "POST",
data: { dataToSend: jsonString},
success: function (data) {
if (data.status == "Success") {
BootstrapDialog.show({
title: 'Success!',
message: "Data Updated Successfully!",
buttons: [{
label: 'OK',
action: function (dialog) {
window.location.href = "/Admin/Product";
removeProdData(i);
$("#btnAddProd").attr("disabled",false);
dialog.close();
}
}]
});
}
},
error:function (xhr, ajaxOptions, thrownError) {
// Set up whatever error reaction you want, here. ie:
console.log('An error was encountered.');
alert(xhr.status);
alert(thrownError);
}
});
Another tip is to validate empty data being submitted prior to the Ajax call, so you only touch the backend server when your data is valid - to avoid an error.
I'm new to Ajax but I want to delete a row from the grid with ajax.
The code below doesn't work. Could you give me some insights?
Whenever the checkbox is checked then it must delete the row.
#Html.Grid(Model.RequestList.OrderByDescending(x => x.CreateDate)).Columns(c => {
c.Add().Titled("View").Encoded(false).Sanitized(false).SetWidth(30).RenderValueAs(p => Html.CheckBox("checkedz",(int)p.Status==1?true:false,new {#class="aaa",onclick="aaa('"+p.Id+"')" }));
})
.WithPaging(20).Selectable(false)
function aaa(id) {
var idyus = id;
var chbox = $(this);
$.ajax({
type: "POST",
url: '#Url.Action("Remove", "Request", new { Area = "Options" })',
success: function () {
chbox.parent().parent().remove();
console.log("success");
}
});
}
public ActionResult Remove(Guid? Id)
{
if (!Id.HasValue)
{
return NotFound();
}
_requestService.Remove(Id.Value);
_requestService.Save();
return RedirectToAction("Index");
}
I am trying to use a ShieldUI Data Grid with filtering and editing together. I am using in an ASP.Net core application.
The funny thing is - I added the Edit and Delete Button to the rows and it initially seems to work. But when I am trying to change the filter value via javascript function, the correct filtered values are appearing in the rows, but the Edit and Delete Buttons are disappeared and no longer available. I can still use the Insert Button on the Top, but even there I cannot save new values as the Edit/Update Button is no longer visible.
Does anyone else having this problem and probably knows a way around this?
This is the gridview-code:
#(Html.ShieldGrid()
.Name("actionsGrid")
.DataSource(ds => ds
.Events(eb => eb
.Error(#<text>
function (event) {
if (event.errorType == "transport") {
// transport error is an ajax error; event holds the xhr object
alert("transport error: " + event.error.statusText);
// reload the data source if the operation that failed was save
if (event.operation == "save") {
this.read();
}
}
else {
// other data source error - validation, etc
alert(event.errorType + " error: " + event.error);
}
}
</text>))
.Remote(rb => rb
.ReadConfiguration(r => r
.Add("type", "GET")
.Add("url", "/api/admin/tree/params")
.Add("dataType", "json"))
.ModifyObject(m => m
.Modify(ShieldUI.AspNetCore.Mvc.DataSource.ModifyOptions.Create, #<text>
function (items, success, error) {
var newItem = items[0];
newItem.data.actionid = $("#actionReference").html();
$.ajax({
type: "POST",
url: "/api/admin/tree/params",
dataType: "json",
contentType : "application/json; charset=utf-8",
data: JSON.stringify(newItem.data),
complete: function (xhr) {
if (xhr.readyState == 4) {
if (xhr.status == 201) {
var location = xhr.getResponseHeader("Location");
success();
return;
}
}
error(xhr);
}
});
}
</text>)
.Modify(ShieldUI.AspNetCore.Mvc.DataSource.ModifyOptions.Update, #<text>
function (items, success, error) {
$.ajax({
type: "PUT",
url: "/api/admin/BaseScenarioApi/tree/#Model.ScenarioId/params",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(items[0].data)
}).then(success, error);
}
</text>)
.Modify(ShieldUI.AspNetCore.Mvc.DataSource.ModifyOptions.Remove, #<text>
function (items, success, error) {
var actionid = items[0].data.actionId;
var paramname = items[0].data.paramName;
$.ajax({
type: "DELETE",
url: "/api/admin/BaseScenarioApi/tree"?paramName=" + paramname
}).then(success, error);
}
</text> )))
.FilterGroup(
ShieldUI.AspNetCore.Mvc.DataSource.FilterCondition.Or,
new object[]{
new Dictionary<string, string>(){
{"path", "actionId"},
{"filter", "eq"},
{"value", "dummy"}
},
new Dictionary<string, string>(){
{"path", "actionId"},
{"filter", "isnull"}
},
})
.Schema(sb => sb
.Fields("actionId", fb => fb.Path("actionId").Type(ShieldUI.AspNetCore.Mvc.DataSource.FieldType.String))
.Fields("orderNumber", fb => fb.Path("orderNumber").Type(ShieldUI.AspNetCore.Mvc.DataSource.FieldType.Number))
.Fields("isActive", fb => fb.Path("isActive").Type(ShieldUI.AspNetCore.Mvc.DataSource.FieldType.Boolean))
.Fields("paramType", fb => fb.Path("paramType").Type(ShieldUI.AspNetCore.Mvc.DataSource.FieldType.String))
.Fields("paramName", fb => fb.Path("paramName").Type(ShieldUI.AspNetCore.Mvc.DataSource.FieldType.String))))
.Sorting(true)
.RowHover(false)
.Columns(cb => cb.Field("orderNumber").Title(Html.DisplayNameFor(t => _actionParView.OrderNumber)).Width(120))
.Columns(cb => cb.Field("isActive").Title(Html.DisplayNameFor(t => _actionParView.isActive)).Width(120))
.Columns(cb => cb.Field("paramType").Title(Html.DisplayNameFor(t => _actionParView.ParamType)).Editor(#<text>ParamTypeSelection</text>).Width(120))
.Columns(cb => cb.Width(140).Title(" ")
.Buttons(b => b.CommandName("edit").Caption("Edit"))
.Buttons(b => b.CommandName("delete").Caption("Delete")))
.Events(ev => ev
.GetCustomEditorValue(#<text>CustomEditorValue</text> )
)
.ToolBar(tb => tb.Buttons(b => b.CommandName("insert").Caption("Add Parameter"))
.Position(ShieldUI.AspNetCore.Mvc.Grid.PositionOptions.Top)
.Buttons(b => b.CommandName("edit").Caption("Edit"))
.Position(ShieldUI.AspNetCore.Mvc.Grid.PositionOptions.Top))
.PagingConfiguration(pb => pb.PageSize(5))
.Editing(eb => eb.Enabled(true)
.Type(ShieldUI.AspNetCore.Mvc.Grid.EditingTypeOptions.Row)))
I added a function, which should update my GridView Filter after I selected a different option in a Treeview (also ShieldUI..).
function selectTree(e) {
var actionsGrid = $("#actionsGrid").swidget();
actionsGrid.dataSource.filter.or[0].value = e.item.actionId;
actionsGrid.refresh();
}
As said previously, the function is working and is filtering the correct values which are also shown in the Grid - but the "Edit" and "Delete" - Buttons have disappeared.
Any help is greatly appreciated!
I have the following Javascript code contained on the click event of an upload button where I want to record an xAPI statement. I have put a breakpoint on my Admin/NewStatement method and although it is hitting it the page is always displaying the error message even before I have stepped through the breakpoint. Why is this failing all the time?
var postData = {
'userID': 1,
'verbID': 26,
'objectID':1
};
$.ajax({
type: "GET",
cache: false,
dataType: "json",
url: "/Admin/NewStatement",
data: postData,
success: function (data) {
var json = data;
alert("THIS IS MY JSON" + json);
//tincan.sendStatement(json);
},
error: function (error) {
alert("An Error has occurred during the Creation of this xAPI Statement");
alert(error);
}
});
I have the following method at Admin/NewStatement
public string NewStatement(int userID, int verbID, int objectID)
{
string result;
result = avm.AddStatement(userID, verbID, objectID);
return result;
}
avm.AddStatement refers to my ViewModel code:
public string AddStatement(int userID, int verbID, int objectID)
{
Actor actor = actorRepository.Get(a => a.UserID == userID).FirstOrDefault();
Verb verb = verbRepository.Get(v => v.VerbID == verbID).FirstOrDefault();
StatementObject statementObject = statementObjectRepository.Get(o => o.StatementObjectID == objectID).FirstOrDefault();
Statement newStatement = new Statement();
newStatement.id = System.Guid.NewGuid();
newStatement.ActorID = actor.ActorID;
newStatement.VerbID = verb.VerbID;
newStatement.StatementObjectID = statementObject.StatementObjectID;
this.statementRepository.Add(newStatement);
this.statementRepository.SaveChanges();
JsonSerializerSettings jss = new JsonSerializerSettings();
jss.ObjectCreationHandling = ObjectCreationHandling.Auto;
var json = JsonConvert.SerializeObject(newStatement);
return json.ToString();
}
I have an MVC4 application, and on the layout (master page for the oldies), I have some javascript:
<script type="text/javascript">
$(document).ready(function () {
$('.btnSubmit').on('click', function () {
var data = { username: $('.txtUsername').val(), password: $('.txtPassword').val(), rememberMe: $('.cbRemember').val() };
$.ajax({
url: '#Url.Action("LoginUser", "User")',
type: "POST",
contentType: "application/json",
data: JSON.stringify(data),
cache: false,
async: true,
success: function (result) {
console.log(result.toString());
if (result.Success == 'true') {
window.location = '#Url.Action("Index", "Home")';
} else {
alert(result.Message);
}
},
error: function () {
alert("Error in input");
}
});
});
});
</script>
This simply logs in a user.
This is working fine.
However, on another screen I now have some new javascript, which does similar function, by taking data from a form, and passing it to a controller to handle.
<script type="text/javascript">
$(document).ready(function () {
$('.btnSubmitNewCard').on('click', function () {
var data = { cardNumber: $('.txtNewCardNumber').val(), cardHolder: $('.txtNewCardHolder').val(), expiryMonth: $('.txtNewExpiryMonth').val(), expiryYear: $('.txtNewExpiryYear').val(), active: $('.txtNewActive').val(), accountId: $('.Id').val() };
$.ajax({
url: '#Url.Action("SaveBankCard", "BankAccount")',
type: "POST",
contentType: "application/json",
data: JSON.stringify(data),
cache: false,
async: true,
success: function (result) {
console.log(result.toString());
if (result.Success == 'true') {
// window.location = '#Url.Action("Index", "Home")';
} else {
alert(result.Message);
}
},
error: function () {
alert("Oh no");
}
});
});
});
</script>
When I click the save button that this code is linked to, the code fires, the controller method goes well, the data is stored, but then, when I refresh the screen, I get an 'Undefinied' error coming from the LOGIN script above. It seems to fire when the page is reloaded. I am unsure why it's firing. It should just load, ready to fire, but it seems to be called, and fails.
The controller that it calls is this:
public ActionResult SaveBankCard(string cardNumber, string cardHolder, int expiryMonth, int expiryYear, string active, int accountId)
{
var card = new AccountCardDto
{
Id = 0,
AccountId = accountId,
Active = active == "on",
CardHolderName = cardHolder,
CardNumber = cardNumber,
ExpiryDate = new DateTime(expiryYear, expiryMonth, 1)
};
int id = new BankAccountService().SaveCard(card);
return RedirectToAction("EditBankAccount", new { bankAccountId = accountId });
}
The problem happens on the RedirectToAction... when that view reloads, which includes the Layout, the Layout javascript fires.
EDIT: I now see that it's the btnSubmitNewCard javascript that is fired twice. Once when the click event happens (expected), and then again when the postback happens. Why is the second event happening?
Check with this: -
$('.btnSubmitNewCard').click(function () {...});
You are getting Undefined in the line that checks status:
if (result.Success == 'true') {
Because result contains string with html response of the view for the EditBankAccount action and does not have "Success" property.
You can put breakepoint in debugger and see. You can use debugger; statement as breakpoint