Refresh the view from JQuery ajax call - c#

I am having a cshml view in which i am calling another view in a div as follows
<div class="family_name" id="DisplayPartilView">
<div class="content_part content_part2">
<h1 class="family_nameStyle">Additional Contacts <button id="AddEmergencyContact" jid="#ViewData["offerId"].ToString()" class="btn highlight" data-dismiss="modal" >
+</button></h1>
<h6> </h6>
<div id="listChildContactAuthorisationsCI" class="table_form">
<table style="width: 640px;" id="CIAuthtable">
<tr>
<td>Contact Name</td>
<td title="This contact is authorised to drop off and collect this child.">Collection</td>
<td title="This contact is an emergency contact for the child.">Emergency</td>
<td title="This contact can authorise the child to participate in centre excursions.">Excursion</td>
<td title="This contact can authorised the administering of medication to the child.">Medical</td>
</tr>
#if (Model.ChildContactAuthorisations != null)
{
#Html.EditorFor(x => x.ChildContactAuthorisations)
}
</table>
</div>
</div>
</div>
This view is shared among other view and so it is in Shared/Editor Template folder.
I am using the ajax from another page (addcontact) as follows
$.ajax({
data: $.parseJSON('{"Id" : "' + EntityId + '"}'),
type: 'POST',
url: '#(Url.Action("GetAdditionalContacts", "QkEnrolment"))',
success: function (result) {
alert(result.outerHTML);
$('div#listChildContactAuthorisationsCI').html(result);
},
error: function () {
alert('Error');
}
});
The control is going to the controller following controller function after adding a contact
public ActionResult GetAdditionalContacts(int Id)
{
Id = Convert.ToInt32(TempData["offerId"]);
User user = DependencyResolver.Current.GetService<ICrud<User>>().Where(x => x.Username == WebSiteContext.Current.UserId).FirstOrDefault();
var offer = _offerRepo.Get(Id);
var child = _childRepo.Get(offer.Child.Id);
var childStubContactAuthorisations = child.GetContactAuthorisations().ToList();
List<Section_ChildContactAuthorisation> ChildContactAuthorisations1 = GetAggregateChildContactAuthorisations(user, childStubContactAuthorisations);
TempData["offerId"] = Id;
return Json(ChildContactAuthorisations1, JsonRequestBehavior.AllowGet);
}
But i want to update the view with the model(which contains newly added contact) return from this above controller function. But the view is not updating.
Can anybody please help me in this
Thanks,
Vidya

Now you are setting json as html in your $('div#listChildContactAuthorisationsCI') you will have to iterate through the returned json and create appropriate html from those values and then add these to your $('div#listChildContactAuthorisationsCI').html(data)
Example:
data = '';
for(i=0;i<result.length;i++) {
data += '<li>' + result.whateverIsInhere + '</li>';
}
If you don't know what's in your json use Console.Log(result) then use the developer tools (F12 in chrome) and see what's inside.

Related

Razor Pages: Page with partialview inside. How can i store my Data for the partialview?

Hello guys i am working on a projekt where i can add articles to a cart. My cart is a partialview.When i add a Article to my cart the old data isnt stored and only one (the new article) article is added to my cart.
This is the code for the Post in my codebehind Im adding a Postition with RandomNumbers for testing
[BindProperty]
public List<Position> ArticlePositions { get; set; } = new List<Position>();
public PartialViewResult OnPostAddPosition(List<Position> articlePositions)
{
Random myObject = new Random();
Random myObject1 = new Random();
articlePositions.Add(new Position
{
ArticleAmount = myObject1.Next(10, 100),
ArticleId = myObject.Next(10, 100)
});
var partialViewResult = new PartialViewResult()
{
ViewName = "_ArticlePositonsPartial",
ViewData = new ViewDataDictionary<List<Position>>(ViewData, articlePositions),
};
return partialViewResult;
}
This is my Partialview with the Model:
#model List<Rechnungen.Models.Position>
<div class="tableFixHead">
<table class="table table-striped text-center table-sm ">
<thead class="table-dark ">
<tr>
<th style="width:72.5px" class="">Anzahl</th>
<th style="width:72.5px" class="">ID</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr id="">
<td style="width:72.5px" class="pt-2 ">
<span class="TBarticleAmount">#item.ArticleAmount</span>
</td>
<td style="width:72.5px" class="pt-2 ">
<span class="TBarticleType">#item.ArticleId</span>
</td>
</tr>
}
</tbody>
</table>
</div>
Where i render the Partial:
<div id="MyPartialView">
#{
await Html.RenderPartialAsync("_ArticlePositonsPartial", Model.ArticlePositions, ViewData);
}
</div>
How i add A Position to cart:
#Html.AntiForgeryToken()
<button class="btn btn-outline-secondary" onclick="GetPartialView()"><i class="fa-solid fa-plus"></i>Hinzufügen</button>
And this is my Javascript for it:
function GetPartialView() {
$.ajax({
type: "POST",
url: '?handler=AddPosition',
dataType: "html",
headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
success: function(data) {
$("#MyPartialView").html(data);
},
error: function(result) {
alert("fail");
}
});
}
My code is working so far, when i add something to my cart my site is looking like this=>
When i click a second time on the add button my site looks like this=>
So my problem is that the Data in ArticlePositions isnt stored. When i Debugg my Code the ArticlePositions are NULL when the Post Method is called.
HTTP is stateless, so any state created in your OnPostAddPosition method is destroyed at the end of the request. You have to implement strategies to persist state across requests. There are a number of options available in Razor Pages. You should research them to identify the most suitable one for your application:
https://www.learnrazorpages.com/razor-pages/state-management

Dynamic "Favorite" button - ASP.NET MVC

I have created a table which dynamically generates records using the "Infinite Loading" process, I have a button in my HTML Code which i need to use to allow users to add the item in their favourite - so this is my HTML code
#model List<PagesAuth.Models.Links.MLink>
#foreach (var I in Model)
{
<tr>
<td class="v-align-top" id="itemcard">
<h4 class="card-title">
#I._title
<small><cite>#I._tp_created.ToString("dd MMM yyyy")</cite> /small>
</h4>
<div class="pull-right" id="options">
<ul class="list-inline text-right" >
#if (I._tp_favourite == 0)
{
<li><button class="btn-link glyphicon glyphicon-heart-empty" onclick="location.href='#Url.RequestContext .Action("_Fav", "Home", "#I._id")'"></button></li>
}
else
{
<li><button class="btn-link glyphicon glyphicon-heart-empty" onclick="location.href='#Url.RequestContext .Action("_UnFav", "Home", "#I._id")'"></button></li>
}
</ul>
</div>
</div>
</td>
</tr>
}
I am trying to use "Favourite" button to allow user to add that website to their favourite list (I am ok with the DB updates etc)
<ul class="list-inline text-right" >
#if (I._tp_favourite == 0)
{
<li><button class="btn-link glyphicon glyphicon-heart-empty" onclick="location.href='#Url.RequestContext .Action("_Fav", "Home", "#I._id")'"></button></li>
}
else
{
<li><button class="btn-link glyphicon glyphicon-heart-empty" onclick="location.href='#Url.RequestContext .Action("_UnFav", "Home", "#I._id")'"></button></li>
}
</ul>
What I want to know is how to achieve this on user front-end - Like I thought I should just create a PartialView and make it child action only in my controller, send it ID and do DB Processing
[ChildActionOnly]
public ActionResult _Fav(int ID)
{//Do DB Processing
return PartialView(ID);
}
First of all the following does not work
onclick="location.href='#Url.RequestContext .Action("_UnFav", "Home", "#I._id")'"
Second, if I end up making this work, it will still refresh the page and I don't want that.
Is there a better way to achieve this
Cheers
I don't know why you want to use partial views but you can do it this way.
Use ajax to send request to controller action.
Handle action result using JavaScript.
View:
#model List<PagesAuth.Models.Links.MLink>
#foreach (var I in Model)
{
<tr>
<td class="v-align-top" id="itemcard">
<h4 class="card-title">
#I._title
<small><cite>#I._tp_created.ToString("dd MMM yyyy")</cite> /small>
</h4>
<div class="pull-right" id="options">
<ul class="list-inline text-right" >
#if (I._tp_favourite == 0)
{
<li><button class="btn-link glyphicon glyphicon-heart-empty" onclick="Fav(#I._id)"></button></li>
}
else
{
<li><button class="btn-link glyphicon glyphicon-heart-empty" onclick="UnFav(#I._id)"></button></li>
}
</ul>
</div>
</div>
</td>
</tr>
}
JS:
Here I am just alerting that the favorite action succeeded, else you have an array of string errors to work with. You could redirect or do some stuff, whichever you prefer.
<script type="text/javascript">
function Fav(id) {
var url = '#Url.Action("_Fav", "Home")';
$.ajax({
url: url,
type: 'POST',
data: {
id: id
},
success: function (data) {
if(data.length == 0) // No errors
alert("Fave success!");
},
error: function (jqXHR) { // Http Status is not 200
},
complete: function (jqXHR, status) { // Whether success or error it enters here
}
});
};
function UnFav(id) {
var url = '#Url.Action("_UnFav", "Home")';
$.ajax({
url: url,
type: 'POST',
data: {
id: id
},
success: function (data) {
if(data.length == 0) // No errors
alert("Unfave success!");
},
error: function (jqXHR) { // Http Status is not 200
},
complete: function (jqXHR, status) { // Whether success or error it enters here
}
});
};
</script>
Controller:
[HttpPost]
public ActionResult _Fav(int ID)
{
List<string> errors = new List<string>(); // You might want to return an error if something wrong happened
//Do DB Processing
return Json(errors, JsonRequestBehavior.AllowGet);
}
[HttpPost]
public ActionResult _UnFav(int ID)
{
List<string> errors = new List<string>(); // You might want to return an error if something wrong happened
//Do DB Processing
return Json(errors, JsonRequestBehavior.AllowGet);
}

MVC 5 WEB API post

I am following this tutorial: https://www.codeproject.com/Articles/424461/Implementing-Consuming-ASP-NET-WEB-API-from-JQuery
to help me implement my web API. But I have something different. This is my index:
#model IEnumerable<dsr_vaja1.Models.Kosarica.Kosarica>
#{
ViewBag.Title = "kosarica";
Layout = "~/Views/Shared/MasterStran.cshtml";
}
<div id="accordion">
<h3>Igre</h3>
<div>
<table class="table table-hover ">
<tr>
<th>
#Html.DisplayNameFor(model => model.ime_igre)
</th>
<th>
#Html.DisplayNameFor(model => model.cena_igre)
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.ime_igre)
</td>
<td>
#Html.DisplayFor(modelItem => item.cena_igre)
</td>
</tr>
}
</table>
<button onclick="AddEmployee();return false;">Add Employee</button>
</div>
</div>
As you can see, here I have a LIST of items named Kosarica. This is my web api:
public void Post(Nakup nakup)
{
nakup.Id = 1;
nc.Nakupi.Add(nakup);
nc.SaveChanges();
}
My web api and everything works completely fine, now I would just like to know how I would use this function:
function AddGame() {
jQuery.support.cors = true;
var game = {
ID: model.id,
ime_igre: model.ime_igre,
};
$.ajax({
url: 'http://localhost:8080/API_SVC/api/EmployeeAPI',
type: 'POST',
data:JSON.stringify(employee),
contentType: "application/json;charset=utf-8",
success: function (data) {
WriteResponse(data);
},
error: function (x, y, z) {
alert(x + '\n' + y + '\n' + z);
}
});
}
FOR ALL of the items in the list after the user clicks a button.
**edit
Isn't there a simpler way to do this? I just realized that the first line of code is a list
#model IEnumerable
model is a list of objects. As you can see below in the foreach loop, I loop through the items in model. So can I just pass the model to the jquery function somehow?
Create a javascript function, eg :
function AddGamesForAllItems(){
// Select the table through JQuery Selector Here
//loop through the elements of the table Here
//Call the AddGame function passing by paremeters the needed elements from the table... You have to declare parameters inside you AddGame function
}
Call the AddGamesForAllItems function when you need it eg: Button click event.
Hope it could help !

Rendering a Partial View on button click in a div C# MVC 5

I have been following the answers on here but can't seem to get it to work. I think it's firing my function and calling my controller but it isn't rendering my partial view. Any help would be awesome.
Controller
public ActionResult Detail(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
User_Accounts user_accounts = db.User_Accounts.Find(id);
if (user_accounts == null)
{
return HttpNotFound();
}
return PartialView("_Detail", user_accounts);
}
HTML
<h2>Index</h2>
<div class="container left">
<div class="panel-default panelbox" style="position:static">
#*<p>
#Html.ActionLink("Create New", "Create")*#
#using (Html.BeginForm("Index", "Users", FormMethod.Get))
{
<p>
Type: #Html.DropDownList("userType", "All")
</p>
<p>
Last Name: #Html.TextBox("SearchString")
</p>
}
</div>
<div class="panel panel-default left">
<div class="panel-heading">
<label style="text-align:center">
User
</label>
</div>
<div class="table-responsive">
<table id="UserTable" class="table-bordered table leftPanel table-condensed">
#foreach (var item in Model)
{
<tr>
<td>
<button data-url='#Html.Action("Detail", "Users", new { id = item.user_id_IN })' id="js-reload-details">#Html.DisplayFor(modelItem => item.DisplayName)</button>
#*#Html.ActionLink(item.DisplayName, "Detail", new { id = item.user_id_IN }, new { onclick = "renderPartial();" })*#
</td>
</tr>
}
</table>
</div>
</div>
</div>
<div>
<label>Details</label>
<div id="detailsDiv"></div>
</div>
Script
<script>
$('.js-reload-details').click(function (evt) {
var $detailDiv = $('#detailsDiv'),
url = $(this).data('url');
$.get(url, function (data) {
$detailsDiv.replaceWith(data);
});
});
</script>
Let me know if you need anything else.
You cant use data-url='#Html.Action("Detail", "Users", new { id = item.user_id_IN })' in your button to generate a url. #Html.Action() is a method which calls you controller. What would be happening is that for each item in your model you would be hitting the Detail method of UsersController (performance must of been awful if you had a lot of items :) ).
Since you appear to need only the one url (/Users/Detail) I suggest you just store the ID in data to minimize the html generated. As noted in the other answers you also need to use a class name for the button to prevent invalid html, and I also suggest using type="button" because the default (depending on the browser) may be "submit" (you don't have a form so does not matter in this case, but its good practice to get into). There is also no real need to use #Html.DisplayFor() unless your using a custom DisplayTemplate or have a [DisplayFormat] attribute on the property.
Change the html to
<button type="button" data-id="#item.user_id_IN" class="js-reload-details">#item.DisplayName</button>
and the script to
var url = '#Url.Action("Detail", "Users");
$('.js-reload-details').click(function() {
$.get(url, { id: $(this).data('id') }, function (data) {
$('#detailsDiv').html(data);
});
});
Note you do not want to use replaceWith() in your case. .replaceWith() would replace the actual div <div id="detailsDiv"></div> with the html your method returned, so the next time a user clicked on this or any other button, the method would be called, but <div id="detailsDiv"></div> no longer exists and nothing would happen.
$('#detailsDiv').html('Hello world');
renders
<div id="detailsDiv">Hello world</div>
but
$('#detailsDiv').replaceWith('Hello world');
renders
Hello world
The id of your button id="js-reload-details"
Mistake this code is repeated in a foreach loop. which will cause multiple id's of the same name on your HTML page.
Your click event is on : '.js-reload-details'. which is a class:
so make your code like this:
#foreach (var item in Model)
{
<tr>
<td>
<button data-url='#Html.Action("Detail", "Users", new { id = item.user_id_IN })' class="js-reload-details">
#Html.DisplayFor(modelItem => item.DisplayName)
</button>
</td>
</tr>
}
One error I noticed in your jQuery is that you have $detailsDiv.replaceWith(data);
It should be $detailDiv according to your code: var detailDiv = $('#detailsDiv'); instead of $detailsDiv
<script>
$(document).ready(function(){
$('.js-reload-details').click(function (evt) {
evt.stopPropagation();
var detailDiv = $('#detailsDiv');
// TRY using the attr function:
var url = $(this).attr("data-url");
$.get(url, function (data) {
detailDiv.html(data);
});
});
});
</script>
UPDATE:
<script>
$(document).ready(function(){
$('.js-reload-details').click(function (evt) {
evt.stopPropagation();
var detailDiv = $('#detailsDiv');
// TRY using the attr function:
var url = $(this).attr("data-url");
$.get(url).success(function(result) {
detailDiv.html(result);
});
});
</script>
It's a good practice we use unique id's for our HTML elements. Since the following statement is going to be executed mulitple times
<button data-url='#Html.Action("Detail", "Users", new { id = item.user_id_IN })' id="js-reload-details">#Html.DisplayFor(modelItem => item.DisplayName)</button>
You will have multiple buttons with the same id. Instead of doing so, you could use a class.
<button data-url='#Html.Action("Detail", "Users", new { id = item.user_id_IN })' #class="js-reload-details">#Html.DisplayFor(modelItem => item.DisplayName)</button>
Then you have to correct your script:
// Now we bound the click event in all the elements that contain
// the .js-reload-details class
$('.js-reload-details').click(function (evt) {
var $detailDiv = $('#detailsDiv');
// Here was your the error
var url = $(this).attr("data-url");
$.get(url, function (data) {
$detailsDiv.replaceWith(data);
});
});

Close Popup Windows MVC Controller

I have a popup window opened when clicked a link on screen, the view that has the link is _DetailsSurvey. After clicking the link pop up window opens with the content of _EditSurvey view. At the end of _EditSurvey, I have button
<input type="submit" value="Save" />
I am using Ajax option and after button click I insert a row into Survey table if the modelstate is valid.
#using (Ajax.BeginForm("SubmitSurvey", "Blog", null, new AjaxOptions
{
UpdateTargetId = "context",
InsertionMode = System.Web.Mvc.Ajax.InsertionMode.Replace,
HttpMethod = "Post",
Url = "/Home/SubmitSurvey"
},
new { surveyItem = #Model }))
What i want to do is if the modelstate is valid after returning from SubmitSurvey method I want the pop up window to be closed.I use the following method to achieve this but it does not work.
Employee employee;
if (ModelState.IsValid)
{
int employeeId = surveyItem.EmployeeId;
int trainingId = surveyItem.TrainingId;
employee = _work.EmployeeRepository.GetSet().
FirstOrDefault(a => a.Id == employeeId);
var training = _work.TrainingRepository.GetSet().Where(a => a.EmployeeId == employeeId && a.Id == trainingId).ToList().ElementAt(0);
training.Survey = surveyItem.survey;
training.SurveyId = surveyItem.survey.Id;
/* _work.SurveyRepository.Add(surveyItem.survey);
_work.SurveyRepository.Save();*/
_work.TrainingRepository.UpdateAndSave(training);
_work.TrainingRepository.Save();
}
else
{
return PartialView("_EditSurvey", surveyItem);
}
return JavaScript("window.close()");
I create my popup links as follows
<tr>
<td class="view_detail_label">
Eğitim Adı
</td>
<td>
#Html.ActionLink(
training.Name.Name,
"AddSurvey",
new {
employeeId = Model.Id,
trainingId = training.Id
},
new {
#class = "addSurvey"
}
)
<div class="result" style="display:none;"></div>
</td>
</tr>
The called ajax code is as follows:
$(document).ready(function () {
$('.addSurvey').click(function () {
$.ajax({
url: this.href,
type: 'GET',
cache: false,
context: this,
success: function (result) {
$(this).next('.result').html(result).dialog({
autoOpen: true,
title: 'Anket',
width: 500,
height: 'auto',
modal: true
});
}
});
return false;
});
});
In my pop up view I am using previously shown Ajax BeginForm and below that I have the table where user inputs values of the survey. At the end I have the submit button.
<table id="context">
<tr>
<td>
<div class="editor-label">
#Html.LabelFor(model => model.survey.Context)
</div>
</td>
<td>
<div class="editor-field">
#Html.EditorFor(model => model.survey.Context)
#Html.ValidationMessageFor(model => model.survey.Context)
</div>
</td>
</tr>
<tr>
<td>
<input type="submit" value="Kaydet" />
</td>
</tr>
I show validation message next to each field if there is any problem with the provided input. If the model was valid I want to do either close the popup window.
It's a very bad idea to open a popup window for many reasons I won't explain here. I spend a very long time to find a solution I could consider as perfect (for me).
In my case, I prepare the view as a partial one (without html, header and body). Just the necessary items do create my functionality in a div.
Then I request my partial view using an ajax query after what I feed a div with my partial view string and I apply the JQuery dialog method to the div for my view to be displayed as a floating dialog box and I bind the OK button to an ajax post to send data to the server.
If you want to have the unobstrusive validation to works, you must parse the form with the validator.
I invite you to have a look to my framework, everything you need is available.
https://myprettycms.codeplex.com/SourceControl/latest#461106

Categories

Resources