I'm trying to load a partial view and change it through a POST Ajax, but model doesn't update on view.
This is how I'm loading my partial:
#{
Html.RenderAction("UltimeNovità", "User");
}
and my action in UserController is:
public ActionResult UltimeNovità()
{
_UltimeNovitàViewModel model = new _UltimeNovitàViewModel();
model.NumeroPagina = 1;
return PartialView("~/Views/User/Partial/_UltimeNovità.cshtml",model);
}
and here the partial:
#model Mine.Models._UltimeNovitàViewModel
<script>
$(document).ready(function () {
});
function nextPage() {
$.ajax({
url: '#Url.Action("UltimeNovitàPaginaSuccessiva")',
type: 'POST',
data: { pagina: #Model.NumeroPagina },
success: function (data) {
$('#x').text('#Model.NumeroPagina');
},
error: function (xhr) {
alert('error');
}
});
}
</script>
<p id="x">1</p>
finally, the POST action in the same controller:
[HttpPost]
public ActionResult UltimeNovitàPaginaSuccessiva(int pagina)
{
_UltimeNovitàViewModel model = new _UltimeNovitàViewModel();
ModelState.Clear();
model.NumeroPagina = pagina + 1;
model.UltimeNovità = UserControllerMethods.GetUltimeNovità(model.NumeroPagina);
return PartialView("~/Views/User/Partial/_UltimeNovità.cshtml", model);
}
My problem is: why after the POST action #Model.NumeroPagina is always 1? I expect that each time I press the button which calls the function with ajax the #Model.NumeroPagina increases by 1 and it's shown in my paragraph.
The button is in the main page that contains the partial, actions are always hit and during debugging I can see that model.NumeroPagina is 2, but in view is always 1.
There are some issues in your code. I don't see where you're updating the HTML content, also you're generating the nextPage function eachTime, and others.
Check this sample, it should be easy to use.
Controller/ViewModel
public class NovitàController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult UltimeNovità(int? page)
{
var model = new UltimeNovitàViewModel
{
NumeroPagina = 1
};
return PartialView("_UltimeNovità", model);
}
[HttpPost]
public ActionResult UltimeNovitàPaginaSuccessiva(int pagina)
{
var model = new UltimeNovitàViewModel
{
NumeroPagina = pagina + 1,
UltimeNovità = GetUltimeNovità(pagina + 1)
};
return PartialView("_UltimeNovità", model);
}
public string GetUltimeNovità(int page)
{
return $"Ultime Novità: {page}"; //FOR DEMO
}
public class UltimeNovitàViewModel
{
public int NumeroPagina { get; set; }
public string UltimeNovità { get; set; }
}
}
_UltimeNovità partial view:
#model NovitàController.UltimeNovitàViewModel
#if (Model.UltimeNovità != null)
{
<div>
UltimeNovità: #Model.UltimeNovità
</div>
}
<div>
Pagina: #Model.NumeroPagina
</div>
<div>
<a class="next-page-link" href="#Url.Action("UltimeNovitàPaginaSuccessiva", "Novità", new {pagina = Model.NumeroPagina})">
Pagina Successiva
</a>
</div>
And the Index page:
#{
ViewBag.Title = "Novità";
}
<div id="RootDiv">
#{ Html.RenderAction("UltimeNovità", "Novità");}
</div>
#section scripts{
<script>
$(function() {
function bindNextPageLink() {
$("#RootDiv a.next-page-link").click(function(event) {
event.preventDefault();
$.post($(this).attr("href"),
function(data) {
$("#RootDiv").html(data);
bindNextPageLink();
}
);
});
}
bindNextPageLink();
});
</script>
}
I tried to write the example very similar to your code.
Related
I am attempting to use partial views for the first time and I need some help. I am posting a string from Javascript to my ASP controller so that I can query my database using that string. Like so:
JavaScript
function findEmployees(userCounty) {
$.ajax({
type: "POST",
url: '#Url.Action("Index", "Contact")',
data: JSON.stringify(userCounty),
contentType: "application/json",
error: function (e) {
console.log(e)
console.log("error")
}
});
}
Controller
[HttpPost]
public ActionResult Index([FromBody]string userCounty)
{
string county = userCounty.Substring(0, userCounty.IndexOf(" "));
var query = from SOP in _context.SalesOffice_Plant
where SOP.County == county
select new SalesOffice_Plant
{
Employee = SOP.Employee
};
return PartialView(query.ToList());
}
[HttpGet]
public ActionResult Index()
{
ViewData["Title"] = "Contact Us";
ViewBag.Current = "Contact";
return View();
}
When I set break points - I can see that the string is passed correctly and my LINQ query works just fine. My problem occurs when I want to render a table of the employees in my Index page. The JavaScript returns a value to the controller after the page loads. This means I needed a way to "refresh the page". I was told to use a partial view to solve this problem and this is what I came up with.
Index.cshtml
#model IEnumerable<Project.Models.SalesOffice_Plant>
//A bunch of Html
#await Html.PartialAsync("_IndexPartial")
//More Html
_IndexPartial.cshtml
#model IEnumerable<Project.Models.SalesOffice_Plant>
<table class="table">
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Employee)
</td>
</tr>
}
</tbody>
Ideally, I would like a table of Employees to be generated and displayed in the Index.cshtml. However, when I load the page I get and error telling me that my #await Html.PartialAsync("_IndexPartial") 'is not set to an instance of an object.
Any pointers in the right direction would be very helpful.
When you use ajax,it would not reload your page after backend code finishing,so you need to use .html() method to render the backend result to html.
Here is a whole working demo:
Model:
public class SalesOffice_Plant
{
public int Id { get; set; }
public string County { get; set; }
public string Employee { get; set; }
}
View(Index.cshtml):
<button type="button" onclick="findEmployees('a ')">Find</button>
<div id="employee">
</div>
#section Scripts
{
<script>
function findEmployees(userCounty) {
$.ajax({
type: "POST",
url: '#Url.Action("Index", "Contact")',
data: JSON.stringify(userCounty),
contentType: "application/json",
error: function (e) {
console.log(e)
console.log("error")
},
success: function (res) {
$("#employee").html(res); //add this...
}
});
}
</script>
}
Partial View(_IndexPartial.cshtml):
#model IEnumerable<SalesOffice_Plant>
<table class="table">
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Employee)
</td>
</tr>
}
</tbody>
</table>
Controller:
[HttpPost]
public ActionResult Index([FromBody] string userCounty)
{
string county = userCounty.Substring(0, userCounty.IndexOf(" "));
var query = from SOP in _context.SalesOffice_Plant
where SOP.County == county
select new SalesOffice_Plant
{
Employee = SOP.Employee
};
return PartialView("_IndexPartial", query.ToList()); //must specify the partial view name
//otherwise it will match the action name as partial view name
}
[HttpGet]
public ActionResult Index()
{
ViewData["Title"] = "Contact Us";
ViewBag.Current = "Contact";
return View();
}
Result:
I have a view inside which i am saving records to the database and showing that records with Viewbag variable on same page i have a delete button in front of each record to delete records, i want after deleting the record the view should get updated how to achieve that
My controller method
public ActionResult Delete(int id)
{
db.Delete<Logs>(id);
return RedirectToAction("Index", new { id });
}
My html and query
<button type="button" id="delete" data-id="#item.LogId" class="delete btn btn-default" style="background-color:transparent"><i class="fas fa-times h3" style="color:red;"></i></button>
$('.delete').click(function () {
var selectedid = $(this).data("id");
$.post("#Url.Action("Delete", "Log")", { id: selectedid });
});
First thing you should know is RedirectToAction won't work in AJAX call, you should pass URL to redirect with location.href as follows:
Controller Action
[HttpPost]
public ActionResult Delete(int id)
{
db.Delete<Logs>(id);
// other stuff
string url = this.Url.Action("Index", "Log", new { id = id });
return Json(url);
}
jQuery
$.post("#Url.Action("Delete", "Log")", { id: selectedid }, function (result) {
window.location.href = result;
});
Or better to create a partial view that contains all elements to be updated via AJAX and pass it into success part afterwards:
Controller Action
[HttpPost]
public ActionResult Delete(int id)
{
db.Delete<Logs>(id);
// other stuff
return PartialView("PartialViewName");
}
jQuery
$.post("#Url.Action("Delete", "Log")", { id: selectedid }, function (result) {
$('#targetElement').html(result);
});
This is our Home Index:
#model ELearning.Data.ELearningEgitimDTO
#{
ViewBag.Title = "Home Page";
}
<div class="jumbotron">
#if (TempData["message"] != null)
{
<div class="alert alert-info" role="alert">#TempData["message"]</div>
}
<div>
<div>
#if (Model.EgitimTuru == 5)
{
<h1>Yangın Eğitimi</h1>
}
<table class="table table-responsive">
<tr>
<td width="20%">Şirket Adı:</td>
<td width="80%">#Model.Name</td>
</tr>
<tr>
<td>Eğitimi Veren:</td>
<td>#Model.PersonelAdi</td>
</tr>
<tr>
<td>Eğitim Tarihi:</td>
<td>#Model.Tarih</td>
</tr>
</table>
</div>
<div>
<table class="table table-responsive">
<tr>
<td>Eğitim Konuları:</td>
</tr>
#foreach (var konu in Model.Adi)
{
<tr>
<td><ul><li>#konu</li></ul></td>
</tr>
}
</table>
</div>
</div>
<p class="text-right"><button onclick="getStartDate()" class="btn btn-primary btn-lg ">Eğitime Başla »</button></p>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script type="text/javascript">
function getStartDate() {
$.post("/Video/GetStartDate",
{
PerNr: #Model.PerNr,
StartDate: "",
EndDate: "",
EgitimFilesId: #Model.FileId
});
}
</script>
</div>
This is Video Index:
#model WebApplication3.Models.VideoLogsModel
#{
ViewBag.Title = "Video Page";
}
<div class="jumbotron">
<div>Eğitime başlanan zaman:</div>
<div id="startdate"></div>
<div class="col-md-12 text-center">
<video controls controlslist="nodownload" id="videoPlayer" width: 100% height: auto>
<source src="~/Video/GetVideo" type="video/mp4">
</video>
</div>
<br />
<div class="text-right">
<p id="button" onclick="egitimiBitir()" class="btn btn-danger btn-lg ">Eğitimi Bitir</p>
</div>
<script type="text/javascript">
var vid = document.getElementById("videoPlayer");
var button = document.getElementById("button");
if (vid.played) {
setInterval(function () { vid.pause(); }, 30000);
}
vid.addEventListener("ended", function() {
button.className = "btn btn-success btn-lg "
});
function egitimiBitir() {
if (vid.ended) {
$.post("/Video/GetEndDate",
{
PerNr: #Model.PerNr,
StartDate= "",
EndDate: "",
EgitimFile sId: #Model.EgitimFilesId
});
}
else {
document.getElementById("message").innerHTML = "Video tamamlanmadan eğitimi bitiremezsiniz.."
}
}
</script>
</div>
This is our main model:
public class ELearningEgitimDTO
{
public ELearningEgitimDTO() { }
public ELearningEgitimDTO(string PerNr, int ID)
{
this.ID = ID;
this.PerNr = PerNr;
}
public int ID { get; set; }
public string PerNr { get; set; }//katılımcıID
public string Name { get; set; }//şirket adı
public int EgitimTuru { get; set; }
public DateTime Tarih { get; set; }//egitim tarihi
public string PersonelAdi { get; set; } // eğitimi veren
public int FileId { get; set; }
public string FileName { get; set; }
public string[] Adi { get; set; }
}
This is our model:
public class VideoLogsModel
{
public int EgitimFilesId { get; set; }
public int PerNr { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
}
This is our Home Controller:
public class HomeController : Controller
{
public ActionResult Index(int EgitimId=4, string PerNr="2")
{
ELearningService service = new ELearningService();
ELearningEgitimDTO egitim = new ELearningEgitimDTO(PerNr, EgitimId);
return View(service.getInfo(egitim)); //eğitim bilgileri istenirken egitimId ve egitim kullanıcıdaki eğitmenin perNr si verilmeli!!
}
}
This is our Video Controller:
public class VideoController : Controller
{
public ActionResult Index(VideoLogsModel model)
{
return View(model);
}
public ActionResult GetVideo()
{
var memoryStream = new MemoryStream(System.IO.File.ReadAllBytes(#"C:\Users\cyare\Desktop\videoplayback.mp4"));
//byte[] bytes = System.IO.File.ReadAllBytes(#"C:\Users\melik.DESKTOP-LQQAB68\Desktop\videoplayback.mp4");
//System.IO.File.WriteAllBytes(#"C:\Users\melik.DESKTOP-LQQAB68\Desktop\videoplayback.mp4", bytes);
return new FileStreamResult(memoryStream, "video/mp4");
}
/* [HttpPost]
public ActionResult GetStartEndDate(VideoLogsModel logs)
{
DateTime startDate = logs.StartDate; //database de uygun tabloya yazılır
return RedirectToAction("Index", "Video");
}*/
[HttpPost]
public ActionResult GetStartDate(VideoLogsModel model)
{
model.StartDate = System.DateTime.Now;
ELearningDosyaKullaniciDTO user = new ELearningDosyaKullaniciDTO();
user.egitimFileID = model.EgitimFilesId;
user.egitimKullanıcı = model.PerNr;
user.startDate = model.StartDate;
ELearningService service = new ELearningService();
//service.CreateLogs(user);
//return RedirectToAction("Index","Video",model);*/
return RedirectToAction("Index", model);
}
[HttpPost]
public ActionResult GetEndDate(VideoLogsModel model)
{
model.EndDate = System.DateTime.Now;
ELearningDosyaKullaniciDTO user = new ELearningDosyaKullaniciDTO();
user.egitimFileID = model.EgitimFilesId;
user.egitimKullanıcı = model.PerNr;
user.endDate = model.EndDate;
ELearningService service = new ELearningService();
service.UpdateLogs(user);
TempData.Add("message", String.Format("Eğitiminiz Tamamlanmıştır!"));
return RedirectToAction("Index", "Home");
}
}
My question is how can i pass the model from home index to video controller and then to video index?
Video Index doesn't run. It goes to video index but then it runs home index again.
Also it runs egitimibitir() function before button's onclick function.
You send an ajax request to your service. (endpoint => GetEndDate) I think you can change your code like that,
$.ajax({
type: "POST",
url: "/Video/GetEndDate", //your reqeust url
contentType: "application/json; charset=utf-8",
data: JSON.stringify({
// your data here
}),
success: function (data) {
// check state of data
// after check window.location = // redirect url
},
error: function (data) {
// handle exception
}
});
You can change your controller method to a data controller. (not an ActionResult. create a custom result object which include your data and your success state. you can use this custom result object every ajax requests for return state and data). If an exception occurs while executing "GetEndDate" method, you need to handle exception and you need to show it to client. You send exception or your success complete response to to client(view). (you can handle your exception data in ajax error: function)
I am trying to filter datatable by select.
I can see the data in select but don't know how to filter it.
Here's my code.
Thanks
function getSearchList() {
$.post('#(Url.Action("GetSearchList", "ESR"))')
.success(function (data) {
if (data.length > 0) {
$.each(data, function () {
$('#Search_Id').append($('<option>', {
value: this.ID,
text: this.S_ID
}));
});
}
$(window).unblock();
})
}
and
$(document).ready(function () {
$('#Search_Id').select2({
placeholder: "Search",
allowClear: true,
});
});
and
<div class="col-sm-2">
<select class="select" id="Search_Id"></select>
</div>
following are whole backend side of codes
following are whole backend side of codes
following are whole backend side of codes
following are whole backend side of codes
following are whole backend side of codes
following are whole backend side of codes
public List<SearchId> GetSearchIdData()
{
string strSQL = string.Format(#"SELECT ID, S_ID FROM TBR");
using (var conn = SqlUtility.GetDBConnection())
{
conn.Open();
return conn.Query<SearchId>(strSQL).ToList();
}
}
and
public ActionResult GetSearchIdList()
{
JsonResult result;
List<SearchId> List = service.GetSearchIdList();
result = Json(List);
result.MaxJsonLength = int.MaxValue;
return result;
}
and
public class SearchId
{
public int ID { get; set; }
public string S_ID{ get; set; }
}
and
public List<SearchId> GetSearchIdList()
{
return repo.GetSearchIdData();
}
I am new to both asp.net MVC and JQuery so be gentle.
I am trying to use a HTTP Post to update my contact form, used to send an email, using AJAX. I have seen lots of posts but what I want seems specific and I cant seem to find anything relevant.
The down low: I have a layout page which has the header, renders the body and has my footer in. My footer contains the form I want to submit. I want to submit this form without refreshing the whole page. The layout page:
<div id="footer">
#{Html.RenderAction("Footer", "Basic");}
</div>
<p id="p"></p>
I have a model for this form to send an email.
namespace SimpleMemberShip.Models
{
public class EmailModel
{
[Required, Display(Name = "Your name")]
public string FromName { get; set; }
[Required, Display(Name = "Your email"), EmailAddress]
[StringLength(100, ErrorMessage = "The email address entered is not valid")]
public string FromEmail { get; set; }
[Required]
public string Message { get; set; }
}
The footer:
<h2> footer yo !</h2>
#Html.ValidationSummary()
<fieldset>
<legend>Contact Me!</legend>
<ol>
<li>
#Html.LabelFor(m => m.FromEmail)
#Html.TextBoxFor(m => m.FromEmail)
</li>
<li>
#Html.LabelFor(m => m.FromName)
#Html.TextBoxFor(m => m.FromName)
</li>
<li>
#Html.LabelFor(m => m.Message)
#Html.TextBoxFor(m => m.Message)
</li>
</ol>
<button id="submit"> Submit </button>
</fieldset>
controller:
[ChildActionOnly]
public ActionResult Footer()
{
return PartialView("~/Views/Shared/_Footer.cshtml");
}
[HttpPost]
public ActionResult Footer(EmailModel model)
{
return PartialView("~/Views/Shared/_Footer.cshtml");
}
I want to use the model validation and everything to be the same or similar as if the form was posted normally through the server.
Edit:
My new code, which works great! but it only works once, when the button is clicked again nothing happens. Anyone know why?
<script type="text/javascript">
$("#submit").click(function () {
$("#footer").html();
var url = '#Url.Action("Footer", "Basic")';
$.post(url, { FromName: $("[name=FromName]").val(), FromEmail: $(" [name=FromEmail]").val(), Message: $("[name=Message]").val() }, function (data) {
$("#footer").html(data);
});
var name = $("[name=FromName]").val();
$("#p").text(name);
});
</script>
new Edit:
did some research and using
$("#submit").live("click",function () {
instead of
$("#submit").click(function () {
seemed to do the trick.
<script type="text/javascript">
$("#submit").live("click",function () {
$('.validation-summary-errors').remove();
var url = '#Url.Action("Footer", "Basic")';
$.post(url, { FromName: $("[name=FromName]").val(), FromEmail: $("[name=FromEmail]").val(), Message: $("[name=Message]").val() }, function (data) {
$("#footer").html(data);
});
});
</script>
ended up with this but will try the "serialize()" option next time.
controller was changed to this without the [ChildActionOnly] and works perfect now
[HttpPost]
public ActionResult Footer(EmailModel model)
{
return PartialView("~/Views/Shared/_Footer.cshtml");
}
Thank you everyone that helped!
Change the [ChildActionOnly] to [HttpGet] in the controller
You can pass model data to controller by doing the following steps
1. Get the input values on click of submit and sent to the Footer action in controller
$("#submit").click(function () {
var FromEmailValue = $('#FromEmail').val();
var FromNameValue = $('#FromName').val();
var MessageValue = $('#Message').val();
var url = '#Url.Action("Footer", "Basic")';
$.ajax({
url: urlmodel,
data: { FromName: FromNameValue, FromEmail: FromEmailValue, Message: MessageValue},
cache: false,
type: "POST",
success: function (data) {
do something here
}
error: function (reponse) {
do something here
}
});
});
In the controller
``
[HttpGet]
public ActionResult Footer()
{
return PartialView("~/Views/Shared/_Footer.cshtml");
}
[HttpPost]
public ActionResult Footer(string FromName = "", string FromEmail = "", string Message = "")
{
//for ajax request
if (Request.IsAjaxRequest())
{
do your stuff
}
}