Partial view updated via ajax does not persist the data - c#

in a MVC 5 project, the Index page contains 2 partial views. One to enter the search arguments and the other to show the rates (via ajax call). Everything works as expected and the rates view does show the returned data. What happens is that if the user goes to another page, in the same project, then returns, the rates partial view is empty, although the search arguments in the other partial view are still present. Is there a way to persist the rates data?
// This script is in the index page with the 2 partial views
<script>
$(function () {
$('#viewSearch').submit(function () {
if ($(this).valid()) {
$.ajax({
url: '/Home/GetRates',
type: "POST",
cache: true,
dataType: 'html',
data: $("#viewSearch").serialize(),
success: function (data) {
$('#viewRates').html(data);
},
});
}
return false;
});
});
</script>
// This is the viewRates
#model Models.Rate
<table class="table table-bordered input-sm">
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Notes)
</td>
<td>
#Html.DisplayFor(modelItem => item.Daily)
</td>
<td>
#Html.ActionLink("BOOK NOW", "Edit", new { id=item.Id })
</td>
</tr>
}
</table>
// and this is the controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult GetRates()
{
if (ModelState.IsValid)
{
// code
...
return PartialView("~/Views/Shared/Rates.cshtml", rates);
}
return PartialView("~/Home/Contact.cshtml");
}

if the search results are persisted just reload the partial on document.ready

Related

Bind All data in Jquery Datatables from View To Controller

Im binding my Data in View to Controller, so later I could do what I want with the data. In my View, im using dataTable and #Html.EditorForModel() to render my View.
View
<form action="xx" method="POST">
<table id="myTable" class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th></th>
<th>
#Html.DisplayNameFor(model => model.Field1)
</th>
<th>
#Html.DisplayNameFor(model => model.Field2)
</th>
<th>
#Html.DisplayNameFor(model => model.Field3)
</th>
</tr>
</thead>
<tbody>
#if (Model != null)
{
#Html.EditorForModel()
}
</tbody>
<tfoot></tfoot>
</table>
<input type="submit" value="submit" />
</form>
Script
$("#myTable").dataTable({
searching: false,
ordering: false,
responsive: true,
"bLengthChange" : false,
"pageLength": 20,
"bStateSave": true
});
Controller
[HttpPost]
public ActionResult MyAction(List<MyModel> MyListModel)
This method works great if the data is no more than 1 page in dataTables. if its more than 1 page, then My Controller either only can receive the List Data of the first page or receive nothing(null)
How should I bind all of my data in DataTables from View to Controller? This binding should include all pages, not only the first one
I'm unsure how you're triggering the update of data, so assuming it's a button the following should work:
$('#your-button').on('click', function(e){
var data = ('#myTable').DataTable().$('input,select,textarea').serialize();
$.ajax({
url: '/MyController/MyAction/',
data: data,
success: function(){
alert('success');
},
error: function(){
alert('failure');
}
});
});
Edit 1:
As per this answer to How to post data for the whole table using jQuery DataTables, if you're set on using a form use the following:
var table = $('#myTable').DataTable();
$('#myForm').on('submit', function(e){
var form = this;
var params = table.$('input,select,textarea').serializeArray();
$.each(params, function(){
if(!$.contains(document, form[this.name])){
$(form).append(
$('<input>')
.attr('type', 'hidden')
.attr('name', this.name)
.val(this.value)
);
}
});
});
since you don't want any ajax
Use Javascript Source Data, Pass your model to the view, serialize it, and use it as your source
var myData = #Html.Raw(Json.Encode(Model.ListOfData));
//then pass it to the datatable
$('#example').DataTable( {
data: myData,
columns: [
{ title: "col1" },
{ title: "col2" },
etc ...
]
} );
With DataTables, only the current page data exist in the DOM. If you submit the form, only the current page data are being submitted back in the server. One solution to this is submit the data via ajax:
var myTable = $('#myTable').DataTable();
$('#your-form').on('submit', function(e){
e.preventDefault();
//serialize your data
var data = myTable.$('input,select,textarea').serialize();
$.ajax({
url: '#Url.Action('MyAction', 'MyController')',
data: data,
success: function(responseData){
//do whatever you want with the responseData
}
});
});
You need to use the data() method to get the data for the whole table:
$('#your-form').on('submit', function(e){
e.preventDefault();
var table = $('#myTable').DataTable();
var data = table.data();
$.ajax({
url: '/MyController/MyAction/',
type: 'POST',
dataType: 'json',
contentType: "application/json;",
data: JSON.stringify(data),
success: function(){
alert('success');
},
error: function(){
alert('failure');
}
});
Please go through following link
https://www.codeproject.com/Articles/155422/jQuery-DataTables-and-ASP-NET-MVC-Integration-Part

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 !

Binding in Razor for loop on ajax reload refusing to rebind

I'm trying to display a table in razor that has delete buttons on each row and there is an add button in the toolbar. When I delete an item it calls an ajax POST that will remove the item from the list(model).
//Ajax
//The add function is basically the same
function DeleteFromGrid(index) {
var formData = $("#GridForm").serialize();
$.ajax({
type: "POST",
cache: false,
url: "People/DeleteFromGrid?index=" + index,
data: formData,
success: function (data) {
$("#Container").html(data);
}
});
}
//Controller
//The add function is very similar is just adds an item
Public Function DeleteFromGrid(viewModel As PeopleViewModel, index As Integer) As ActionResult
viewModel.People.RemoveAt(index)
Return PartialView("PeopleView", viewModel)
End Function
//Html-Razor
<table id="MultiRateGrid" class="DataGrid" style="width: 100%">
<tbody>
<tr>
<th>#Html.LabelFor(Function(model) model.People(0).Name)</th>
</tr>
#For i = 0 To Model.People.Count - 1
Dim j As Integer = i
#<tr>
<td>
#Html.TextBoxFor(Function(m) m.People(j).Name)
#Model.People(j).Name
</td>
<td>
<input type="button" onclick="#String.Format("DeleteFromGrid(({0})", j)" value="Delete"/>
</td>
</tr>
Next
</tbody>
</table>
My issue is if I delete the first item from the list, the viewModel is updated correctly by me checking with #Model.People(j).Name (and in the controller) but actually displays the old value in the TextboxFor. I think it might be something with binding due to it retaining the previous object bound to People(j) because it is a lambda.

How to get the value from a button click and use it in the same view MVC 5

I have a table with rss feeds and a button after each feed. When the user clicks the button I want to read the feed on the same page. I have everything working, except one thing. How do I send the url of the newsfeed back to the controller and then use it to show the news feeds, when the user clicks the button.
Here I show the urls of the newsfeeds in a table
<table class="table">
#{if (ViewBag.Rsslist != null)
{
foreach (var item in ViewBag.Rsslist)
{
<tr class="something">
<td class="col-md-2">
#item.sTidning
</td>
<td class="col-md-2">
#item.SUrl
#{string rssurl = item.SUrl; }
</td>
<td class="col-md-2">
Open
</td>
</tr>
}
}
else
{
<tr class="something">
<td class="col-md-2">No data to dsiplay</td>
</tr>
}}
</table>
Here i want to display the newsfeeds
<div class="col-md-4">
<table class="table">
<tr>
<td>
#{var inlast = reader.Las(ViewBag.Feed); }
#inlast.Title.Text
<br />
#inlast.Links[0].Uri<br />
#{foreach (var item in inlast.Items)
{
#item.Title.Text
<br />
}}
</td>
</tr>
</table>
Here is the line of code I tried above to accomplish my goal.
Open
What should I write instead? Here is my controller:
public class HomeController : Controller
{
private Rss_DevEntities _db = new Rss_DevEntities();
public ActionResult Index()
{
List<RSS_Head> rss_head = new List<RSS_Head>();
rss_head = _db.RSS_Head.ToList();
ViewBag.Rsslist = rss_head;
return View();
}
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
public ActionResult Flasare()
{
return View();
}
}
}
Edit: Solution
I couldn't get the Ajax to work. I will have to look into Ajax more :) But I finally found a solution that works.
In my controller I created a method GettheFeed like this:
public ActionResult GettheFeed(string rssfeed)
{
List<RSS_Head> rss_head = new List<RSS_Head>();
rss_head = _db.RSS_Head.ToList();
ViewBag.Rsslist = rss_head;
ViewBag.Feed = rssfeed;
return View("~/Views/Home/Index.cshtml");
}
}
In my indexview I added this line of code
#Html.ActionLink("Open", "GettheFeed", new { rssfeed = rssurl })
Instead of
Open
And I finally got it to work after making sure that I checked if a variable is null instead of checking if a ViewBag is null in the code that displays the newsfeed.
You need to use Ajax
For example, fire this ajax when the user click on the button :
$.ajax({
url: '#Url.Action("getRssFeed", "Home")',
data: {rssurl = feedInfo}, //store the feed info in an attribute of your button for example
type: 'POST',
success: function(data) {
alert(data);
}
});
and with an getRssFeed function in your index controller :
[HttpPost]
public ActionResult getRssFeed(string rssurl)
{
ViewBag.Feed = rssurl ;
return View();
}
The alerted data will be the data you need to display. ( for example affect the data to your 'inlast' variable.
EDIT :
Your buttons in the loop will look like this, (based on ur code)
<a class="loadRss" id="#item.SUrl" class="btn btn-success btn-sm">Open</a>
And your js :
$(".loadRss").click(function() {
$.ajax({
url: '#Url.Action("getRssFeed", "Home")',
data: {rssurl : $(this).attr('id')},
type: 'POST',
success: function(data) {
}
});
});
And put the getRssFeed function above in your controler. I think what I wrote works, but it's ugly because your return your view (all the html, js ... etc) though you only need the modification of your model.
So I advise you to use partial views
Yes i agree with #kypaz , Use ajax which works fine without postback. You will get value of button.
You controller will be
public ActionResult Index(string rssurl)
{
List<RSS_Head> rss_head = new List<RSS_Head>();
rss_head = _db.RSS_Head.ToList();
ViewBag.Rsslist = rss_head;
return View();
}

How can I update a Table without refresh the entire site razor

Hi I'm working on a table
I cannot atm update the table without the site refreshing.
I need a way to easily
Add a row ,Delete a row, Modify a row in a table's content.
my table is build like this.
{....}
#using (Html.BeginForm())
{
<fieldset>
<legend>ShiftTypes</legend>
<table class="EditableTable" id="EditableTableShiftTypes">
<thead>
<tr>
<th>
#:
</th>
<th>
ShiftName:
</th>
<th>
ShiftCode:
</th>
<th>
Suplement:
</th>
<th>
ExtraSuplement:
</th>
<th>
</th>
</tr>
</thead>
<tbody>
#foreach (BPOPortal.Domain.Models.ShiftTypeView type in Model.ShiftTypeList)
{
<tr>
<td>
#type.ID
</td>
<td>
#type.ShiftName
</td>
<td>
#type.Name
</td>
<td>
#type.Supplement
</td>
<td>
#type.OneTimePayment
</td>
<td>
<button>
Delete</button>
</td>
</tr>
}
<tr>
<td>
<label>
</label>
</td>
<td>
#Html.Editor("ShiftName")
</td>
<td>
#Html.Editor("ShiftCode")
</td>
<td>
#Html.Editor("Suplement")
</td>
<td>
#Html.DropDownList("ExtraSuplement", new SelectListItem[] { new SelectListItem() { Text = "yes", Value = "true", Selected = false }, new SelectListItem() { Text = "No", Value = "false", Selected = false } }, "--Choose--")
</td>
<td>
<button id="AddButton">
Add</button>
</td>
</tr>
</tbody>
</table>
<button type="submit" id="Gem">
Save</button>
</fieldset>
{....}
I've Tried to use Ajax in the following way but it refreshes the entire page.
{....}
var ID= 2;
$("#AddButton").click(function(){
var ShiftName= $('#ShiftName').attr('value');
var ShiftCode= $('#ShiftCode').attr('value');
var Suplement= $('#Suplement').attr('value');
var ExtraSuplement= $('#ExtraSuplement').attr('value');
$.ajax({
url: '#Url.Action("AddData", "ShiftTypesConfiguration")',
data: { ID: ID.toString(), ShiftName: $('#ShiftName').attr('value'), ShiftCode: $('#ShiftCode').attr('value'), Suplement: $('#Suplement').attr('value'), ExtraSuplement: $('#ExtraSuplement').attr('value') },
type: 'POST',
// contentType: 'application/json; charset=utf-8;',
dataType: 'json',
success: function (response)
{
function fnClickAddRow() {
$('#EditableTableShiftTypes').dataTable().fnAddData([
response.ID,
response.ShiftName,
response.ShiftCode,
response.Suplement,
response.ExtraSuplement,
"<button>Delete</button>"]); }
}
});
ID++;
});
{....}
</script>
My Method in the Controller that should handle the request.
public JsonResult AddData(string ID, string ShiftName, string ShiftCode, string Suplement, string ExtraSuplement)
{
TableViewModel tableViewModel = new TableViewModel();
tableViewModel.ID = ID;
tableViewModel.ShiftName= ShiftName;
tableViewModel.ShiftCode= ShiftCode;
tableViewModel.Suplement= Suplement;
tableViewModel.ExtraSuplement= ExtraSuplement;
return Json(tableViewModel);
}
However it doesn't seem to work Now I'm asking For Ideas and ways to make this better/easier/Working
Edit:saw a copy past Error
EDIT2: I've now changed it slightly I found that I had a error in how my script was running this is the latest. there are still problems but at least now I can see and describe the error.
this is what I changed the script is now
$("#AddButton").click(function (event) {
event.preventDefault();
var ShiftName = $('#ShiftName').attr('value');
var ShiftCode = $('#ShiftCode').attr('value');
var Suplement = $('#Suplement').attr('value');
var ExtraSuplement = $('#ExtraSuplement').attr('value');
$.ajax({
url: '#Url.Action("AddData", "ShiftTypesConfiguration")',
data: { ID: ID.toString(), ShiftName: ShiftName, ShiftCode: ShiftCode, Suplement: Suplement, ExtraSuplement: ExtraSuplement },
type: 'POST',
// contentType: 'application/json; charset=utf-8;',
dataType: 'json',
success: function (response) {
function fnClickAddRow() {
$('#EditableTableShiftTypes').dataTable().fnAddData([
response.ID,
response.ShiftName,
response.ShiftCode,
response.Suplement,
response.ExtraSuplement,
"<button>Delete</button>"]);
}
}
});
ID++;
});
now with the help of firebug I've seen that the values are back on the page but before I can see them the page is refreshed.
I am not writing in code here, but here is how you should do it.
On Add/Edit/Delete make an ajax call to your action. In your Action implement your operation (Add/Edit/Delete) and depending on operation completed successfully or failed due to some error, return a true/false flag as json.
Then in the success function success: function (response){} of the ajax call, check wether the value returned is a true/false which means success or error.
And then using some jquery you can add a row or delete a row from the table.
Check out these links : http://viralpatel.net/blogs/dynamically-add-remove-rows-in-html-table-using-javascript/

Categories

Resources