I have Parent View and 2 Partial Views. I have buttons on each partial view that is registered for an on click event on the parent page. They do ajax calls to get their respective partial view.
Controller
[HttpPost]
public ActionResult GetEmployee(int id)
{
HumanResourcesManager man = new HumanResourcesManager();
var emp = man.GetEmployee(id);
EmployeeModel empModel = new EmployeeModel(emp);
return PartialView("_EmployeeDetails", empModel);
}
[HttpPost]
public ActionResult GetEmployeeForEdit(int id)
{
HumanResourcesManager man = new HumanResourcesManager();
var emp = man.GetEmployee(id);
ViewBag.States = man.GetStates();
EmployeeModel empModel = new EmployeeModel(emp);
return PartialView("_EmployeeEdit", empModel);
}
Parent View
#model HumanResources.Web.Models.EmployeeModel
<p>
Selected Employee: #Html.TextBox("EmployeeSearch")
</p>
<script type="text/javascript">
$("#EmployeeSearch").autocomplete({
source: function (request, response) {
$.ajax({
url: "#(Url.Action("FindEmployee", "Employee"))",
type: "POST",
dataType: "json",
data: { term: request.term },
success: function (data) {
response($.map(data, function (item) {
return { label: item.DisplayName, value: item.DisplayName, id: item.Id };
}))
}
})
},
select: function (event, ui) {
if (ui.item) {
GetEmployeeDetails(ui.item.id);
}
}
});
function GetEmployeeDetails(id) {
$("partialView").empty();
$.ajax({
type: "POST",
url: "#(Url.Action("GetEmployee", "Employee"))",
data: { id: id },
success:function(result)
{
$("#partialView").html(result);
},
failure: function (response) {
alert(response.d);
}
});
#*$(document).on('click', "#empEdit", function(){
$.ajax({
type: "POST",
url: "#(Url.Action("GetEmployeeForEdit", "Employee"))",
data: #Html.Raw(Json.Encode(Model)),
success:function(result)
{
$("#partialView").html(result);
},
failure: function (response) {
alert(response.d);
}
})
});*#
$(document).on('click', "#empEdit", function(){
$.ajax({
type: "POST",
url: "#(Url.Action("GetEmployeeForEdit", "Employee"))",
data: {id: $("#editEmployeeId").val()},
success:function(result)
{
$("#partialView").html(result);
},
failure: function (response) {
alert(response.d);
}
})
});
$(document).on('click', "#empEditCancel", function(){
GetEmployeeDetails($("#editEmployeeId").val());
});
}
</script>
<div id="partialView">
</div>
Partial View - Details
The details is intended to display details and an edit button. The JavaScript I have in the Parent View.
#model HumanResources.Web.Models.EmployeeModel
#{
Layout = null;
}
#Html.HiddenFor(model => model.Employee.Id, new { id = "editEmployeeId" })
#Html.DisplayTextFor(model => model.Employee.FirstName)
<input id="empEdit" type="button" value="Edit"/>
Partial View - Edit
The Edit View displays the same values as the details partial view, but as editable fields.
#model HumanResources.Web.Models.EmployeeModel
#{
Layout = null;
}
#using (Html.BeginForm("Save", "Employee")) {
#Html.HiddenFor(model => model.Employee.Id, new { Id = "editEmployeeId" })
<div class="container">
<input type="submit" value="Save" />
<input id="empEditCancel" type="button" value="Cancel"/>
</div>
}
My Issue
Editing and cancelling (toggling between the two partial views) once works fine. Editing and cancelling more than once it seems that the functions for the on click are called increasingly number of times by a factor of 2. Causing the alerts to be called multiple times.
What am I doing wrong?
Related
Can somebody give me a hint how to pass a list from the controller to Model list in view page after call the Action Result whit ajax in page. (Meaning update current list model with ajax call back result)?
This is my default load view page code:
#model List<ChargeSystem.Models.Message>
#foreach (var item in Model)
{
<div class="container1">
<p>#item.Msg</p>
<span class="time-right">#item.MsgDate</span>
</div>
}
</div>
<div class="divContinMsg">
<input type="text" id="txtMsg" name="txtMsg" />
</div>
<script type="text/javascript">
$(document).ready(function () {
$("#txtMsg").keyup(function (e) {
if (e.keyCode == 13) {
$.ajax(
{
url: '/User/ajaxContactAdmin?msg=' + $("#txtMsg").val(),
type: 'Post',
data: "",
contentType: false,
success: function (result) {
//What can i do????
},
error: function () {
alert("error");
}
})
};
});
});
</script>
This is the Ajax call action result:
public ActionResult ajaxContactAdmin(string msg)
{
var result = new { model = messageRepository.Select().ToList()};
return Json(result, JsonRequestBehavior.AllowGet);
}
So, How can i refresh the model after ajax call back?
So what you would do is append the result to the existing result set.
Firstly I would add a container for easier reference, secondly you would add the item to the container:
#model List<ChargeSystem.Models.Message>
<div id="listContainer">
#foreach (var item in Model)
{
<div class="container1">
<p>#item.Msg</p>
<span class="time-right">#item.MsgDate</span>
</div>
}
</div>
</div>
<div class="divContinMsg">
<input type="text" id="txtMsg" name="txtMsg" />
</div>
<script type="text/javascript">
$(document).ready(function () {
$("#txtMsg").keyup(function (e) {
if (e.keyCode == 13) {
$.ajax(
{
url: '/User/ajaxContactAdmin?msg=' + $("#txtMsg").val(),
type: 'Post',
data: "",
contentType: false,
success: function (result) {
$('#listContainer').append('<div class="container1">'+
'<p>' + result.Msg + '</p>'+
'<span class="time-right">' + result.MsgDate +'</span>'+
'</div>');
},
error: function () {
alert("error");
}
})
};
});
});
</script>
It looks like you want to enter information in your text box and save and update it in the view.
I think you can do this.
Here is an example:
Your Controller:
public IActionResult GetUser ()
{
var messages = context.Messages.ToList();
return View(messages);
}
[HttpPost]
public IActionResult ajaxContactAdmin(string msg)
{
var message = new Message
{
Msg = msg,
MsgDate = DateTime.Now
};
context.Add(message);
context.SaveChanges();
return Json(message);
}
Js in your View:
#section scripts{
<script>
$(document).ready(function () {
$("#txtMsg").keyup(function (e) {
if (e.keyCode == 13) {
var msg = document.getElementById("txtMsg").value
$.ajax(
{
url: '/Home/ajaxContactAdmin?msg=' + $("#txtMsg").val(),
type: 'Post',
data: { "msg": msg},
contentType: false,
success: function (message)
{
console.log(message);
window.location.reload();
},
error: function () {
alert("error");
}
})
};
});
});
</script>
}
Result display:
I went through a lot of guides and stacloverflow posts, but i still don't manage to make it work. I'm still new in javascript, and it's hard for me to figure if it's the script or not.
The main issue i got is the fact I'm not able to debbug it properly, i mean, i can't find where and why it's not working, i just know it doesn't.
Here is my Controller :
Entities db = new Entities();
// GET: DynamicListe
public ActionResult Index()
{
return View();
}
[HttpPost]
public JsonResult Index(string Prefix)
{
//Searching records from list using LINQ query
var client = (from c in db.Clients
where c.Nom.Contains(Prefix)
select new { c.Nom });
return Json(client, JsonRequestBehavior.AllowGet);
}
Here is my View :
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script src="~/Scripts/jquery-ui-1.12.1.min.js"></script>
<script src="~/Scripts/jquery-ui-1.12.1.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#client").autocomplete({
source: function (request, response) {
var customer = new Array();
$.ajax({
url: "/DynamicListe/Index",
type: "POST",
dataType: "json",
data: { Prefix: request.term },
success: function (data) {
response($.map(data, function (item) {
return { label: item.Name, value: item.Name };
}))
for (var i = 0; i < data.length ; i++) {
customer[i] = { label: data[i].Value, Id: data[i].Key }
}
}
});
response(customer);
},
messages: {
noResults: "", results: ""
}
});
})
</script>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
<div class="client">
<div class="col-md-12">
#Html.TextBox("client")
</div>
</div>
</div>
}
I got the right amount of answers (when i press "w" i got 13 results which is correct according to my db), but it's all empty. I've tried severals ways to display the json datas, but i don't know how to make it work..
Edit : correct controller and view :
view :
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script src="~/Scripts/jquery-ui-1.12.1.min.js"></script>
<script src="~/Scripts/jquery-ui-1.12.1.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#client").autocomplete({
source: function (request, response) {
var customer = new Array();
$.ajax({
url: "/DynamicListe/Index",
type: "POST",
dataType: "json",
data: { Prefix: request.term },
success: function (data) {
response($.map(data, function (item) {
return { label: item.Text, value: item.Value};
}))
}
});
},
messages: {
noResults: "", results: ""
}
});
})
</script>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
<div class="client">
<div class="col-md-12">
#Html.TextBox("client")
</div>
</div>
</div>
}
controller :
[HttpPost]
public JsonResult Index(string Prefix)
{
List<SelectListItem> list = new List<SelectListItem>();
var client = (from c in db.Clients
where c.Nom.Contains(Prefix)
select c).ToArray();
for (int i = 0; i < client.Length; i++)
{
list.Add(new SelectListItem
{
Text = client[i].Nom,
Value = client[i].ClientID.ToString()
});
}
return Json(list, JsonRequestBehavior.AllowGet);
}
You're returning your response before it has been received.
In here
source: function (request, response) {
var customer = new Array();
$.ajax({
url: "/DynamicListe/Index",
type: "POST",
dataType: "json",
data: { Prefix: request.term },
success: function (data) {
response($.map(data, function (item) {
return { label: item.Name, value: item.Name };
}))
for (var i = 0; i < data.length ; i++) {
customer[i] = { label: data[i].Value, Id: data[i].Key }
}
}
});
response(customer);
},
Move the line response(customer) inside the ajac success callback.
You textbox does not have an ID. you have to add for yout textbox : #Id="client"
I have a select item as follows:
<select id="id_category">
<option> </option>
</select>
In run time there is a tree view used to fill up the select menu as follows:
<script>
$(document).ready(function () {
$('#data').jstree({
"plugins": ["checkbox"]
});
$("#data").on("changed.jstree", function (e, data) {
if (data.selected.length) {
$("#id_category").empty();
$(data.selected).each(function (idx) {
var node = data.instance.get_node(data.selected[idx]);
var s = document.getElementById('id_category');
s.options[s.options.length] = new Option(node.text, '1');
});
}
else
$("#id_category").empty();
});
});
</script>
and the html for the tree is not important now as it works well.
Now, I want when a user click on a button with HTML as follows:
<input id="btn3" type="button" value="Test 3" />
an ajax will be run to send all the items in the select to a controller in MVC as follows:
$("#btn3").click(function () {
$.ajax({
url: "/Products/Test03",
datatype: "text",
data: $.map($('#id_category')[0].options, function( elem ) { return (elem.value || elem.text); }),
type: "POST",
success: function (data) {
$('#testarea').html(data);
},
error: function () {
$("#testarea").html("ERROR");
}
});
});
and the controller:
[HttpPost]
public string Test03(Object str1)
{
// call with two parameters and return them back
this.myRetrievedData = str1;
return str1.ToString();
}
The above did not work with me, when I click on Test3 button nothing happened.
I am not sure how to pass the retrieved items to the function in the controller. Could anyone tell me how to do that?
The below logic must work for you. Many thanks to Mr.Stephen Muecke for assistance.
$("#btn3").click(function () {
var optionsData= $.map($('#id_category')[0].options, function(elem) {
return (elem.value || elem.text);
}); // create a variable to hold all the options array.
$.ajax({
url: "/Products/Test03",
datatype: "text",
data: JSON.stringify(optionsData), //pass this variable to post request as 'options'
contentType: "application/json; charset=utf-8",
type: "POST",
success: function (data) {
$('#testarea').html(data);
},
error: function () {
$("#testarea").html("ERROR");
}
});
});
Then you can have your controller as below.
[HttpPost]
public string Test03(IEnumerable<string> options ) // change here to this
{
//your logic goes here
}
I think it's because you have not added [HttpPost] attribute in your controller function
I am creating an ASP.NET MVC application. I am currently developing a search page where both the search box and the table of results are displayed on the same page. To do this I have used Partial Views and AJAX/JSON calls with a viewmodel. After entering the two search terms in the textbox, both are null in the controller after being passed through ajax.
Here is the code:
ViewModel:
public class ExampleViewModel
{
public string search { get; set; }
public string search2 { get; set; }
}
Controller:
[HttpPost]
public ActionResult Search(ExampleViewModel searchTerm)
{
var searchList = db.UserLists.Where(x => x.LastName.Contains(searchTerm.search));
return PartialView("_SearchResultsPartial", searchList);
}
Body of Index View:
<body>
<div>
#Html.TextBoxFor(model => model.search)
#Html.TextBoxFor(model => model.search2)
<input type="submit" value="Search" onclick="return getSearchResults()"/>
</div>
<div id="search-results">
</div>
<script>
var exViewModel = {
search: $('#search').val(),
search2: $('#search2').val()
}
function getSearchResults() {
$.ajax({
type: "POST",
data: JSON.stringify(exViewModel),
dataType: "json",
contentType: "application/json",
url : "/View/Search/",
success: function (result) {
$("#search-results").html(result);
}
});
}
</script>
Again, after setting a breakpoint on the Search [POST] method, the ExampleViewModel's terms are null.
At first sight, it seems that you have to retrieve the values within the function scope:
function getSearchResults() {
//Read these values on button click
var exViewModel = {
search: $('#search').val(),
search2: $('#search2').val()
}
$.ajax({
type: "POST",
data: JSON.stringify(exViewModel),
dataType: "json",
contentType: "application/json",
url : "/View/Search/",
success: function (result) {
$("#search-results").html(result);
}
});
}
Otherwise, the exViewModel is just determined on page load.
I rendering page with some tabs with content (inside tabs) dynamicly.
So I got
<div id="UpdateBlock">
#Html.Action("GeneratorTemplate", "FormTemplate", new { id = 8 })
</div>
it calls
public ActionResult GeneratorTemplate(int id)
{
//Description desk = new Description();
return PartialView("~/Views/FormTemplate/GeneratorTemplate.cshtml");
}
I want to make something like this
<div id="UpdateBlock">
#Html.Action("GeneratorTemplate", "FormTemplate", new { openedtab = getActiveTab() })
</div>
public ActionResult GeneratorTemplate(int openedtab)
{
return PartialView("~/Views/FormTemplate/GeneratorTemplate.cshtml", openedtab);
}
And there in partialview call ajax function with openedtab parameter. Like this
var g_id = openedtab;
function updateGenerators(g_id) {
var g_list;
$.ajax({
async: false,
url: '/Generator/GetCurrentGenerator',
type: 'POST',
data: {
generatorNumber: g_id
},
success: function (text) {
w2alert(text);
},
error: function (request, status, error) {
alert(request.responseText);
}
});
}
I tried to call Js inside razor but it not works that way. How could I do what I need?
Using what I can access to data which I pass with return PartialView("~/Views/FormTemplate/GeneratorTemplate.cshtml", openedtab);?