Passing and handling of varibles to a function with AJAX in MVC - c#

I'm having trouble passing a variable into a function in my view. I'm fairly new to MVC and not sure how I save and pass information.
#model Models.Schedule.SheduleModel
#{
Layout = null;
}
<div>
<div class="tableRow">
<p>Make a schedule reminder.</p>
</div>
<div class="tableRow tableRowHeading">
<div class="row" style="width: 210px">Name</div>
<div class="row" style="width: 210px">Number</div>
</div>
#foreach (var shedule in Model.ScheduleList)
{
<div class="tableRow">
#using (Html.BeginForm("UpdateSchedule", "Schedule", FormMethod.Post))
{
<div class="cell" style="width: 210px">
#Html.HiddenFor(model => schedule.Id)
#Html.TextBoxFor(model => schedule.Name, new { #class = "inputFieldText" })
#Html.ValidationMessageFor(model => schedule.Name)
</div>
<div class="cell" style="width: 210px">
#Html.TextBoxFor(model => agent.ContactNumber, new { #class = "inputFieldText" })
#Html.ValidationMessageFor(model => agent.ContactNumber)
</div>
<div class="cell">
<button name="Update" type="submit" value="Update" class="button" title="Update details">
<span class="text">Update</span>
</button>
</div>
<div class="cell">
<button class="button" type="button" onclick="deleteFromSchedule();" value="Delete">
<span class="text">Delete</span>
</button>
</div>
}
</div>
}
</div>
#Scripts.Render("~/bundles/jqueryval")
<script>
function deleteFromSchedule() {
$.ajax(
{
type: 'POST',
url: urlBase + 'Schedule/UpdateSchedule/' + Id,
data:
{
Id: Id
},
success: function (data) {
console.log(data);
},
error: function () {
var errorMessage = 'Error occurred while sending message';
console.log(errorMessage);
}
});
}
}
</script>
I'm trying to pass the schedule Id in HiddenFor into the delete function but everything I try doesn't work, i'm also curious on how to handle the information gotten from the text box in a later unwritten div, I'd like to produce text on the screen saying
User #Model.Name and number #Model.Number will be notified of schedule change but I keep displaying blank spaces. an I use the form I'm creating for this information, what would the syntax be?. My method in the schedule controller is very straight forward.
[HttpPost]
public void UpdateSchedule(int Id)
{
////do stuff here
}

The simplest way is to add your id from the schedule into the inline function call (using razor), and add an id param into your javascript delete function:
<div class="cell">
<button class="button" type="button" onclick="deleteFromSchedule(#schedule.Id);" value="Delete">
<span class="text">Delete</span>
</button>
</div>
<script>
function deleteFromSchedule(id) {
$.ajax(
{
type: 'POST',
url: urlBase + 'Schedule/UpdateSchedule/' + id,
data:
{
Id: id
},
success: function (data) {
console.log(data);
},
error: function () {
var errorMessage = 'Error occurred while sending message';
console.log(errorMessage);
}
});
}
}
</script>

Related

There's some problem in "mixing ways" to do posts requests?

For example, in my project I'm using #using(Html.BeginForm(some stuff))to create an instance of my model and finally appending it to my database. But, when I'm editing (updating) some object of model, I'm usingn ajax get to retrieve data and finally using #Html.BeginForm() to post the update. Well, this is breaking some pattern of coding in MVC or whatever good principle?
Retrieving data and filling in the input fields
$.ajax({
url: "../../Obra/" + id,
type: "POST",
success: function(data) {
var obj = JSON.parse(JSON.stringify(data));
tit.value = obj.titulo;
ed.value = obj.editora;
obj.autores.forEach(x => {
var newn = divAutor.appendChild(aut.cloneNode());
newn.value = x;
});
img.value = obj.imagem;
divAutor.removeChild(aut);
},
error: function() {
alert('Error.');
}
});
All modal:
<div class="modal" id="modalOverlay">
<div class="modal-content" id="modalContent">
<header class="modal-header">
<h1 id="updateObraModalTitulo"></h1>
</header>
#using(#Html.BeginForm("Update", "Obra", FormMethod.Post, new { id="form-update" })) {
<div class="updateObraDivProp">
#Html.LabelFor(m => m.Titulo, "Título:")
#Html.TextBoxFor(m => m.Titulo, new { #class="editInputValue", #id="editTituloInput" })
</div>
<div class="updateObraDivProp">
#Html.LabelFor(m => m.Editora, "Editora:")
#Html.TextBoxFor(m => m.Editora, new { #class="editInputValue", #id="editEditoraInput"})
</div>
<div class="updateObraDivProp">
#Html.LabelFor(m => m.Autores, "Autores:")
<div id="divInputAutores">
#Html.TextBoxFor(m => m.Autores, new { #class="inputPostValue", id="addAutoresInput"})
</div>
<div class="btnNewAutorOp">
<button type="button" id="btnAddAutor" onclick="addNewAutor()">+</button>
<button type="button" id="btnDeleteAutor" onclick="deleteNewAutor()">×</button>
</div>
</div>
<div class="updateObraDivProp">
#Html.LabelFor(m => m.Imagem, "Imagem:")
#Html.TextBoxFor(m => m.Imagem, new { #class="inputPostValue", #id="editImagemInput" })
</div>
<input type="submit">
}
</div>
</div>
Because I can't retrieve the Id property when I click in the modal with mvc (or maybe I can using partial views?), I'm using javascript to create a function with the param id and getting data with ajax and finally updating with form

Call the same function

I would like whichever button been clicked I want to call the same function.
for now I have six card on View but work only one first. Other dosent work
My view
<h2>Our workouts</h2>
<div class="container">
<div class="row">
#foreach (var item in Model)
{
<div class="col-md-4">
<div class="card" style="width: 18rem;">
<img src="~/Content/not-found-image.jpg" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">#item.Name</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
<div id="textButton">
#*Go to anywhere*#
<a id="btnNewSave" class="btn btn-primary">Go to anywhere</a>
<input type="text" id="getValue" value="#item.Id" hidden />
</div>
</div>
</div>
</div>
}
</div>
</div>
My controller:
[HttpGet]
public ActionResult ListCoach(int? Id)
{
var ChoachList = _TraningService.Coach(Id);
return View(ChoachList);
}
script
I call My script from View use helper section
#section scripts {
<script>
$(document).ready(function () {
$("#btnNewSave").click(function () {
var data = $("#getValue").val();
$.ajax({
type: "GET",
url: '/TrainingType/ListCoach',
data: { id: data },
success: function (data) {
console.log(data);
window.location.href = '/TrainingType/ListCoach';
return data;
},
error: function () {
$("#loader").fadeOut("slow");
console.log("error1");
}
});
});
});
</script>
}
You should try this way, because your type of buttons are diffrent as per current scenario <a> and button so below way you could try.
Script:
#section scripts {
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"></script>
<script>
function PassToContoller(data) {
//alert(data);
$.ajax({
type: "GET",
url: '/UserLog/AnotherListCoach',
data: { id: data },
success: function (data) {
console.log(data);
window.location.href = '/appUser/ManageAccount';
return data;
},
error: function () {
$("#loader").fadeOut("slow");
console.log("error1");
}
});
}
$(document).ready(function () {
$("a[name=link]").on("click", function () {
var valueOfClickedTag = $(this).data("index");
alert("Clicked On Anchor: " + valueOfClickedTag);
var callFunc = PassToContoller(valueOfClickedTag)
});
$(":button[id=GoToAnywhere3]").on("click", function () {
var valueOfClickedBtn = $(this).data("index");
var callFunc = PassToContoller(valueOfClickedBtn )
});
});
</script>
}
Razor HTML:
<div class="container">
<div class="row">
#foreach (var item in Model)
{
<div class="col-md-4">
<div class="card" style="width: 18rem;">
#*<img src="~/Content/no_foto.png" class="card-img-top" alt="...">*#
<div class="card-body">
<h5 class="card-title">#item.StudentID</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
<div id="textButton">
Go to anywhere
<a class="btn btn-primary" data-index="#item.Name" name="link">Go to anywhere</a>
<input class="btn btn-primary" type="button" id="GoToAnywhere3" data-index="#item.StudentID" value="Save" />
<input type="text" class="inputVal" id="getValue" value="#item.Name" hidden />
</div>
</div>
</div>
</div>
}
</div>
</div>
Output:
Note: <input type="text" class="inputVal" id="getValue" value="#item.StudentID" hidden /> is not needed anymore.
Hope it would completely resolve your problem.
Firstly make use of button type rather than an a. With that change, you can use the onclick event in two ways:
First opt:
<button class="btn btn-primary list-coaches" onclick="listCoaches()">List Coaches</button>
function listCoaches() { ... }
Second opt:
<button class="btn btn-primary list-coaches">List Coaches</button>
$('.list-coaches').click(function() { ... });

How can I get my Popup to close on submit button from AJAX call in ASP.NET MVC?

I have a view that lists a bunch of items. I'm trying to make it so that when a user clicks on the "Action Event" for one of these items (from a table row), a pop-up will appear. The user can then update same information about this item, and either submit the information or close it. Regardless of which option they choose, I'm trying to get the pop-up window to close.
I'm 90% there, I just can't seem to work out one little detail - closing the popup after the submit button is pressed! A lot of the solutions I have seen don't appear to be working, and I just seem to be having some trouble tweaking them to work with my issue. Given the following code, what changes do I need to do to make this work?
Here is what I have:
View
Index.cshtml
<table>
#foreach (var item in Model)
<tr>
<td colspan="5" align="right">
Action Event
</td>
</tr>
}
</table>
<div id="myModal" class="modal">
<div class="modal-dialog">
<div class="modal-content">
<div id="myModalContent"></div>
</div>
</div>
</div>
<script>
var TeamDetailPostBackURL = '/Database/Edit';
$(function () {
$(".anchorDetail").click(function () {
var $buttonClicked = $(this);
var id = $buttonClicked.attr('data-id');
var options = { "backdrop": "static", keyboard: true };
$.ajax({
type: "GET",
url: TeamDetailPostBackURL,
contentType: "application/json; charset=utf-8",
data: { "Id": id },
datatype: "json",
success: function (data) {
$('#myModalContent').html(data);
$('#myModal').modal(options);
$('#myModal').modal('show');
},
error: function () {
alert("Dynamic content load failed.");
}
});
});
});
</script>
Popup View
Edit.cshtml
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.AID)
<table>
<tr>
<td>#Html.LabelFor(model => model.Comment)</td>
<td>#Html.TextAreaFor(model => model.Comment, new { #class = "form-control", rows = "5" })</td>
</tr>
<tr>
<td><input type="submit" value="Save" class="btn btn-primary" id="btnSave"/></td>
<td><button type="button" class="btn btn-primary" data-dismiss="modal">Cancel</button></td>
</tr>
</table>
</div>
}
Controller
DatabaseController.cs
public ActionResult Index()
{
return View(db.ActionableEvents.ToList());
}
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
ActionableEvents actionableEvents = db.ActionableEvents.Find(id);
if (actionableEvents == null)
{
return HttpNotFound();
}
return View(actionableEvents);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "AID,Comment")] ActionableEvents actionableEvents)
{
if (ModelState.IsValid)
{
db.Entry(actionableEvents).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(actionableEvents);
}
I did see this resource here: asp.net submit button close Jquery Ajax, but I'm just not seeing how I would be able to tweak this into what I've got going on right now.
The cancel button I have right now works perfectly. Is there some way to use data-dismiss for my submit button and have it still save the data like I have for the cancel button? I've also seen some solutions use an onClick() parameter in the submit button, but then it would use a window.close() option. I don't want the entire window to close, nor do I want the user to be prompted about it either.
What is a good way I can approach this problem? I want my submit button to work just like my cancel button, only save the data. Thanks in advance for any advice!!!
Can you try the following in your Index.cshtml (make sure you set an id for the form and correct it below):
$("form").submit(function(){
$('#modal').modal('toggle');
});
If you want to make an AJAX request to the server and save the data you can do as follows (just include the code below in a click event on the dismiss button from the modal):
$.ajax({
type: "POST",
url: "SaveData",
content: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(data),
success: function (result) {
// do something
},
error: function (result) {
// do something
}
});
And have a MVC action similiar to:
[HttpPost]
public JsonResult SaveData()
{
// save data
}
Edit:
After a second reading of your question, you need to make Edit.cshtml a partial view, then on Index.cshtml include your partial view in the div for the modal like this:
<div id="myModal" class="modal">
<div class="modal-dialog">
<div class="modal-content">
#Html.Partial("_EditView")
</div>
</div>
</div>
And your JS should look like this:
$("form").submit(function () {
e.preventDefault();
formData = $(this).serialize();
$.ajax({
type: "POST",
url: "SaveData",
content: "application/json; charset=utf-8",
dataType: "json",
data: formData ,
success: function (result) {
// do something
},
error: function (result) {
// do something
}
});
$('#modal').modal('toggle');
});
The JS should be in the Index.cshtml because that's where your partial exists, try it and you'll see.
So, after a lot of playing around, I was able to come up with the following solution:
View
Index.cshtml
<table>
#foreach (var item in Model)
<tr>
<td>
<button class="btn btn-primary" onclick="ActionAway(#item.AID)">Action Event</button>
</td>
</tr>
}
</tbody>
</table>
<div class="modal fade" id="myModal1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
×
<h3 class="modal-title">Action This Event</h3>
</div>
<div class="modal-body" id="myModalBodyDiv1">
</div>
</div>
</div>
</div>
</div>
<script>
var ActionAway = function (theid) {
var url = "/Database/Edit?id=" + theid;
$('#myModalBodyDiv1').load(url, function () {
$('#myModal1').modal("show");
})
}
</script>
Pop-up View
Edit.cshtml
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.AID)
<table>
<tr>
<td>#Html.LabelFor(model => model.Comment)</td>
<td>#Html.TextAreaFor(model => model.Comment, new { #class = "form-control", rows = "5" })</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Save" class="btn btn-primary" id="btnSave"/>
<button type="button" class="btn btn-primary" data-dismiss="modal">Cancel</button>
</td>
</tr>
</table>
</div>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
<script>
$(document).ready(function () {
$("#btnSave").click(function () {
$.ajax({
success: function () {
$("#myModal").modal("hide");
}
})
})
})
</script>
The controller I was able to leave as it was without making any changes. Thanks again for all the help!

How to correctly use Partial views with Ajax Begin form

I have the following code, in my index.cshtml
#using Kendo.Mvc.UI;
#using xx.Relacionamiento.Modelo.Bussiness.Entities;
#using xx.Relacionamiento.Modelo.Bussiness.Entities.Custom;
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
#model PresupuestosGenerale
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="">
<div id="ContenedorPresupuestoGeneral">
#Html.Partial("CreateOrEditPresupuestoGeneralxx", Model)
</div>
<br />
<br />
Then I have the following PartialView
#using xx.Relacionamiento.Modelo.Bussiness.Entities.Enumeraciones;
#using xx.Relacionamiento.Modelo.Bussiness.Entities;
#using Kendo.Mvc.UI;
#model PresupuestosGenerale
<div class="panel panel-default">
<div class="panel-heading">
#using (Ajax.BeginForm("CreateOrEditPresupuestoGeneralxx", new AjaxOptions() { HttpMethod = "Post", UpdateTargetId = "ContenedorPresupuestoGeneral", InsertionMode = InsertionMode.Replace }))
{
#Html.HiddenFor(h => h.PresupuestoGeneralId)
#Html.Hidden("Categoria",CategoriaEvento.xx.ToString())
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-6">
<label>Presupuesto Global xx</label>
<br />
#(Html.Kendo().NumericTextBoxFor(e => e.PresupuestoGlobal)
.Decimals(0)
.DecreaseButtonTitle("Decrementar")
.IncreaseButtonTitle("Incrementar")
.Format("c0")
.HtmlAttributes(new { style = "width:99%;" })
.Max(1000000000000000000)
.Min(1)
.Step(100000)
.Placeholder("Presupuesto General xx"))
#Html.ValidationMessageFor(v => v.Valor, "", new { #style = "color: rgba(247, 20, 10, 0.97);" })
</div>
<div class="col-md-3">
<br />
<input type="submit" class="form-control btn btn-primary" value="Guardar Presupuesto" onclick="SetMostrarVentana();" />
</div>
</div>
}
</div>
</div>
<script type="text/javascript">
$(function () {
MostrarVentanaLoading = false;
#if (!string.IsNullOrEmpty(ViewBag.MensajeError))
{
#:mostrarMensajeAlertGlobal("#ViewBag.MensajeError",15000)
}
else if (!string.IsNullOrEmpty(ViewBag.MensajeSuccess))
{
#:mostrarMensajeAlertSuccessGlobal("#ViewBag.MensajeSuccess", 15000);
}
});
</script>
Then on my controller I have business logic that returns something different depending on conditions
public ActionResult CreateOrEditPresupuestoGeneralxx(PresupuestosGenerale presupuestoGeneralxx)
{
try
{
ModelState.Remove("PresupuestoGlobal");
if (presupuestoGeneralxx == null)
{
return PartialView();
}
if (!ModelState.IsValid)
{
return PartialView(presupuestoGeneraxx);
}
if (presupuestoGeneralxx.Valor < 1)
{
ModelState.AddModelError("Valor", "Por favor ingrese un presupuesto total");
return PartialView(presupuestoGeneralxx);
}
So, when the user submits the form, the container from the index view is replaced with the new html.
The code works perfectly fine, however I feel that the code is ugly, not maintainable and difficult to read.
My questions, is, with asp.net mvc and ajax is there a better and more organized way to achieve the same thing with more readable code?
I would refactor the views moving the ajax form outside the partial. That way the full partial which is rendered inside the form is refreshed on ajax posts, keeps unaware and decoupled of container structure and every view has their own responsibility:
Index.cshtml
<div class="panel panel-default">
<div class="panel-heading">
#using (Ajax.BeginForm("CreateOrEditPresupuestoGeneralxx", new AjaxOptions() { HttpMethod = "Post", UpdateTargetId = "form-content", InsertionMode = InsertionMode.Replace }))
{
<div id="form-content">
#Html.Partial("CreateOrEditPresupuestoGeneralxx", Model)
</div>
}
</div>
</div>
CreateOrEditPresupuestoGeneralxx.cshtml
#using xx.Relacionamiento.Modelo.Bussiness.Entities.Enumeraciones;
#using xx.Relacionamiento.Modelo.Bussiness.Entities;
#using Kendo.Mvc.UI;
#model PresupuestosGenerale
#Html.HiddenFor(h => h.PresupuestoGeneralId)
#Html.Hidden("Categoria",CategoriaEvento.xx.ToString())
<div class="row">
...
Here is one of the example that I used in some of my projects. In this example not only PartialView is rendered, also a DropdownList value is passed to the PartialView and displayed on it.
View :
<div id="divPartialView">
#Html.Partial("~/Views/MyPartialView.cshtml", Model)
</div>
$(document).ready(function () {
$(".SelectedCustomer").change(function (event) {
$.ajax({
url: '#Url.Action("GetPartialDiv", "Home")',
data: { id: $(this).val() /*add other additional parameters */ },
cache: false,
type: "POST",
dataType: "html",
success: function (data, textStatus, XMLHttpRequest) {
SetData(data);
},
error: function (data) { onError(data); }
});
});
function SetData(data) {
$("#divPartialView").html(data); //HTML DOM replace
}
});
Controller :
[HttpPost]
public PartialViewResult GetPartialDiv(int id /* ddl's selectedvalue */)
{
Models.GuestResponse guestResponse = new Models.GuestResponse();
guestResponse.Name = "this was generated from this ddl id:";
return PartialView("MyPartialView", guestResponse);
}

Validate Model data before ajax method call

I have a partial view on my application I am creating user registration functionality on partial view(not using any form tag) , I am calling Controller's action method using ajax-jquery & passing user details(model) to action method , before calling ajax method i need to validate user detail at client side. how can i do this?
need to validate model before ajax call(not using any form tag).
#model MVC4Demo.Models.Student
<script src="~/Scripts/jquery-1.7.1.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<script type="text/javascript">
function onClientClick() {
var obj = { FirstName: "name", City: "abc" };
$.ajax({
url: "/Home/AjaxDemo",
data: JSON.stringify(obj),
type: "POST",
datatype: "json",
contentType: "application/json; charset=utf-8",
success: function (result) {
alert('success');
},
error: function () {
alert("error");
}
});
}
</script>
<div id="Main">
<label>Student</label>
<div class="editor-label">
#Html.LabelFor(model => model.FirstName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.FirstName)
#Html.ValidationMessageFor(model => model.FirstName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.LastName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.LastName)
#Html.ValidationMessageFor(model => model.LastName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.City)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.City)
#Html.ValidationMessageFor(model => model.City)
</div>
<p>
<input type="submit" onclick="onClientClick()" value="Create" />
</p>
</div>
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Put your model into form. After:
<script>
$(function () {
$('#myForm').unbind('submit');
$('#myForm')
.bind('submit', function () {
var form = this;
if ($("#myForm").valid()) {
$.post('/Home/AjaxDemo', $(form).serialize(), function (data) {
if (data.success) {
alert('success');
} else {
alert("error");
}
});
}
return false;
});
});
I'm afraid a form tag is required. And something else, you can prepend
#Html.EnableClientValidation();
#Html.ValidationSummary(true);
to the form.

Categories