I have the following script that is rendered inside my _layout view:-
$(document).ready(function () {
$("input[data-autocomplete-source]").each(function () {
var target = $(this);
target.autocomplete({
source: target.attr("data-autocomplete-source"),
minLength: 1,
delay: 1000
});
});
});
and i added the following field to apply autocomplete on it:-
<input name="term" type="text" data-val="true"
data-val-required= "Please enter a value."
data-autocomplete-source= "#Url.Action("AutoComplete", "Staff")" />
now if i render the view as partial view then the script will not fire, and no autocomplete will be performed, so i added the autocomplete inside ajax-success as follow:-
$(document).ready(function () {
$(document).ajaxSuccess(function () {
$("input[data-autocomplete-source]").each(function () {
var target = $(this);
target.autocomplete({
source: target.attr("data-autocomplete-source"),
minLength: 1,
delay: 1000
});
});
});
});
now after adding the AjaxSuccess the action method will be called, and when i check the response on IE F12 developers tools i can see that the browser will receive the json responce but nothing will be displayed inside the field (i mean the autocomplete results will not show on the partial view)?
EDIT
The action method which is responsible for the autocomplete is:-
public async Task<ActionResult> AutoComplete(string term)
{
var staff = await unitofwork.StaffRepository.GetAllActiveStaff(term).Select(a => new { label = a.SamAccUserName }).ToListAsync();
return Json(staff, JsonRequestBehavior.AllowGet);
}
EDIT2
here is the script which is responsible to show the modal popup:-
$(document).ready(function () {
$(function () {
$.ajaxSetup({ cache: false });
//$("a[data-modal]").on("click", function (e) {
$(document).on('click', 'a[data-modal]', function (e){
$('#myModalContent').css({ "max-height": screen.height * .82, "overflow-y": "auto" }).load(this.href, function () {
$('#myModal').modal({
//height: 1000,
//width: 1200,
//resizable: true,
keyboard: true
}, 'show');
$('#myModalContent').removeData("validator");
$('#myModalContent').removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse('#myModalContent');
bindForm(this);
});
return false;
});
});
function bindForm(dialog) {
$('form', dialog).submit(function () {
$('.btn.btn-primary,.btn.btn-danger').prop("disabled", "disabled");
$('#progress').show();
if ($(this).valid()) {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
if (result.ISsuccess) {
$('#myModal').modal('hide');
$('#progress').hide();
$('.btn.btn-primary,.btn.btn-danger').prop("disabled", false);
location.reload();
// alert('www');
} else {
$('#progress').hide();
$('#myModalContent').html(result);
$('.btn.btn-primary,.btn.btn-danger').prop("disabled", false);
bindForm();
}
}
});
}
else {
$('.btn.btn-primary,.btn.btn-danger').prop("disabled", false);
$('#progress').hide();
return false;
}
return false;
});
}
});
First, you don't need to wrap you ajaxSuccess fucntion in ready function.
Second, it's better to use POST when you get Json from server.
I tried to seproduce your problem, but have no luck.
Here how it works in my case(IE 11, MVC 4)
script on _Layout:
$(document).ajaxSuccess(function () {
$("input[data-autocomplete-source]").each(function () {
var target = $(this);
target.autocomplete({
source: function (request, response) {
$.post(target.attr("data-autocomplete-source"), request, response);
},
minLength: 1,
delay: 1000
});
});
});
Controller method:
[HttpPost]
public JsonResult AutoComplete()
{
return Json(new List<string>()
{
"1",
"2",
"3"
});
}
Partial View html:
<input name="term" type="text" data-val="true"
data-val-required="Please enter a value."
data-autocomplete-source="#Url.Action("AutoComplete", "Stuff")" />
UPDATE:
I find out what your problem is. Jquery autocomplete needs array of objects that have lable and value properties. So if you change your controller code like this and it will work.
public async Task<ActionResult> AutoComplete(string term)
{
var staff = await unitofwork.StaffRepository.GetAllActiveStaff(term)
.Select(a => new { label = a.SamAccUserName, value = a.SamAccUserName })
.ToListAsync();
return Json(staff, JsonRequestBehavior.AllowGet);
}
Also you can do it on client side with $.map jquery function you can see example here
Related
Ajax post:
<script type="text/javascript">
$(document).ready(function () {
$('#btn').click(function () {
// var vals = [];
// $('input:checkbox[name=Blanks]:checked').each(function () {
// vals.push($(this).val());
// });
// alert(vals);
//
var checkboxData = $(':checked').val();
$.ajax({
// Check the value.
type: 'POST',
url: '/Home/Extract',
data: { 'name': checkboxData },
// contentType: 'application/json; charset=utf-8', // No need to define contentType
success: function (result) {
},
error: function (err, result) {
alert("Error in delete" + err.responseText);
}
});
});
Controller method:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Extract(string[] name)
{
}
My problem is that I am getting null values in my string[] name when I use array and single checkBox values when I use other case. Any suggestions or ideas as to why the post looks good?
View:
<input type="button" id="btn" value="Extract" style="float:right "/>
#foreach (var m in (List<string>)ViewData["list"])
{
<ul>
<li>
<input type="checkbox" class="myCheckbox" name="Blanks" id="chk" value="#m"/>
<img src="#m" alt=""/>
First start by fixing your markup and remove the id="chk" from your checkboxes because you cannot have 2 elements with the same id.
Alright, and then simply generate a javascript array containing the values of the selected checkboxes and POST this array to the server:
$('#btn').click(function () {
var values = $('input[type="checkbox"].myCheckbox:checked').map(function() {
return $(this).val();
}).toArray();
$.ajax({
type: 'POST',
url: '/Home/Extract',
data: JSON.stringify({ name: values }),
contentType: 'application/json',
success: function (result) {
},
error: function (err, result) {
alert("Error in delete" + err.responseText);
}
});
return false;
});
And your controller action signature might look like this:
[HttpPost]
public ActionResult Extract(string[] name)
{
...
}
But all this would have been completely unnecessary if you had used a view model and the strongly typed Html.CheckBoxFor helper.
how we can have autocomplete combo with infinit scroll?
i found an autocomplete jquery ui with infinit scroll, but this autocomplete gets data by pagemethods. but i want to use it in mvc application and want to use an action of a controller to retrieving data.
to use this autocomplete by pagemethods should do this:
$(document).ready(function () {
//Input for testing purposes
$("#inp").smartautocomplete({
getDataFunc: getData,
pageSize: 15,
autoFocus: true
});
});
//Function the SA plugin called when data is needed.
var getData = function (input, pageIndex, pageSize, callback) {
PageMethods.GetData(input, pageIndex, pageSize, function (response) {
if (response) {
response = $.map(response, function (item) {
return {
label: item,
value: item
}
});
callback(response);
}
else callback();
});
};
but i change the way of getting data by using $.ajax:
var getData = function (input, pageIndex, pageSize, callback) {
$.getJSON(
{ url: '#Url.Action("GetData", "Home")' },
{ input: input, pageIndex: pageIndex, pageSize: pageSize },
function (response) {
if (response) {
response = $.map(response, function (item) {
return {
label: item,
value: item
};
});
callback(response);
}
else callback();
});
};
but it does not work, and the action does not called.
this autocomplete is accessible here:
http://www.codeproject.com/Articles/325719/JQueryUI-smartAutocomplete?fid=1683905
i want to know if there is any other solution to have autocomplete with infinit scroll
Replace PageMethod call with AJAX call
$.ajax({
url: '#Url.Action("GetData", "Default")',
type: 'GET',
dataType: 'json',
data: {
input: input,
pageIndex: pageIndex,
pageSize: pageSize
},
success: function (response) {
//alert(response);
if (response) {
response = $.map(response, function (item) {
return { label: item, value: item };
});
callback(response);
} else {
callback();
}
},
error: function (e) {
alert('error' + e);
},
contentType: 'application/json; charset=utf-8'
});
Make sure your controller action is returning JSONResult
return new JsonResult {JsonRequestBehavior = JsonRequestBehavior.AllowGet, Data = data };//new {result = data}
Hope this helps.
I have a list of div's.
When I click on a button in a div I switch div content with partial view which contain form.
This is code that happens when I click on that button:
#Html.ActionLink("edit", "EditUserLanguage", "UserLanguage", new { userLanguageId = Model.UserLanguageId }, new { #class = "editButton" })
...
$(document).on('click', '.editButton', function (e) {
$.ajax({
url: this.href,
cache: false,
success: function (html) {
var id = $(e.target).closest("div").attr("id");
$("#" + id).empty();
$("#" + id).append(html);
}
});
return false;
});
Html (partial view) that I add has:
#using (Html.BeginForm("UpdateUserLanguage", "UserLanguage", FormMethod.Post, new { id = "updateUserLanagegeForm" }))
{
...
This main view where is the list of div's and where I add this new partial view I have this code:
$(function () {
$('#updateUserLanagegeForm').submit(function () {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
alert("work");
}
});
return false;
});
}); //update
When I click on submit action method is invoked and I get new partial view returned but not via ajax.
I only get that partial view returned. alert("work"); is never called.
What could be the reason that this ajax call doesn't work?
submit handler is not being attached to form as form gets loaded after dom ready. So change your code to -
$('body').on('submit','#updateUserLanagegeForm',(function () {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
alert("work");
}
});
return false;
});
This will attach handler to form even if it is added dynamically.
I have links like following.
Deneme Müşteri 2
Deneme Müşteri 2
I want to use jquery ajax post like this:
$(".customer_details").click(function () {
$.ajax({
url: $(this).attr("href"),
type: 'POST',
beforeSend: function () {
},
complete: function () {
},
success: function (result) {
$("#customer_operations_container").html(result);
},
error: function (result) {
alert("Hata!");
}
}); //end ajax
});
Or this:
$(".customer_details").click(function () {
$("#customer_operations_container").load($(this).attr("href"));
});
And Action Method
public ActionResult _EditCustomer(int CustomerId)
{
// get customer from db by customer id.
return PartialView(customer);
}
But I cant do what I wanted. When I click to link, PartialView does not load. It is opening as a new page without its parent. I tried prevent.Default but result is the same.
How can I load the partialView to into a div?
Note: If I use link like this <a href="#"> it works.
Thanks.
Maybe the problem is with the actionresult, try with Content to see if that changes anything.
public ActionResult _EditCustomer(int CustomerId)
{
// get customer from db by customer id.
return Content(customer.ToString());
}
Try one of these...
$(".customer_details").click(function (e) {
e.preventDefault()
$.ajax({
url: $(this).attr("href"),
//I think you want a GET here? Right?
type: 'GET',
beforeSend: function () {
},
complete: function () {
},
success: function (result) {
$("#customer_operations_container").html(result);
},
error: function (result) {
alert("Hata!");
}
}); //end ajax
});
Or
$(".customer_details").click(function (e) {
e.preventDefault();
$("#customer_operations_container").load($(this).attr("href"));
});
Or
$(".customer_details").click(function (e) {
e.preventDefault();
$.get($(this).attr("href"), function(data) {
$("#customer_operations_container").html(data);
});
});
If none of this works, check if there's any js errors
The problem is when you click on the link you already start navigation to it. So just use e.preventDefault() or return false from the click method to prevent the default behavior
$(".customer_details").click(function (e) {
e.preventDefault();
...
}
This should help you out:
$.ajax({
url: $(this).attr("href"),
type: 'POST',
beforeSend: function () {
},
complete: function () {
},
success: function (result) {
$("#customer_operations_container").html(result);
},
error: function (result) {
alert("Hata!");
}
}); //end ajax
return false;
The only thing you where missing is the prevention of A tag working. By returning false your custom event is called and the default event is not executed.
Try this
$(function(){
$(".customer_details").click(function (e) {
e.preventDefault();
});
});
Using ready event
Demo: http://jsfiddle.net/hdqDZ/
What is wrong if no validation errors are shown when the submitted data is null/empty? An error should be shown.
In the code block result.success == false, should I reload the view or tell jQuery to invalidate my model?
From my Post action in the controller I return the model errors so I have them on the client side.
What should I do now?
I am using MVC 3.0 with latest jQuery/UI 1.7.2/1.8.20:
<script type="text/javascript">
$(document).ready(function () {
// the div holds the html content
var $dialog = $('<div></div>')
.dialog({
autoOpen: false,
title: 'This is the dialogs title',
height: 400,
width: 400,
modal: true,
resizable: false,
hide: "fade",
show: "fade",
open: function (event, ui) {
$(this).load('#Url.Action("Create")');
},
buttons: {
"Save": function () {
var form = $('form', this);
$.ajax({
url: $(form).attr('action'),
type: 'POST',
data: form.serialize(),
dataType: 'json',
success: function (result) {
// debugger;
if (result.success) {
$dialog.dialog("close");
// Update UI
}
else {
// Reload the dialog to show model/validation errors
} // else end
} // success end
}); // Ajax post end
},
"Close": function () {
$(this).dialog("close");
}
} // no comma
});
$('#CreateTemplate').click(function () {
$dialog.dialog('open');
// prevent the default action, e.g., following a link
return false;
});
});
</script>
my form is:
#using (Html.BeginForm("JsonCreate", "Template"))
{
<p class="editor-label">#Html.LabelFor(model => model.Name)</p>
<p class="editor-field">#Html.EditorFor(model => model.Name)</p>
<p class="editor-field">#Html.ValidationMessageFor(model => model.Name)</p>
}
My controller is:
[HttpGet]
public ActionResult Create()
{
return PartialView();
}
[HttpPost]
public ActionResult JsonCreate(Template template)
{
if (ModelState.IsValid)
{
_templateDataProvider.AddTemplate(template);
// success == true should be asked on client side and then ???
return Json(new { success = true });
}
// return the same view with model when errors exist
return PartialView(template);
}
The working version is:
I changed this in my $.ajax request:
// dataType: 'json', do not define the dataType let the jQuery infer the type !
data: form.serialize(),
success: function (result)
{
debugger;
if (result.success) {
$dialog.dialog("close");
// Update UI with Json data
}
else {
// Reload the dialog with the form to show model/validation errors
$dialog.html(result);
}
} // success end
The Post action has to look like this:
[HttpPost]
public ActionResult JsonCreate(Template template)
{
if (!ModelState.IsValid) {
return PartialView("Create", template);
_templateDataProvider.AddTemplate(template);
return Json(new { success = true });
}
}
Either return the partialview which is the form (success == false) or return the JSON which is success == true.
Someone could still return a list of items to update the UI on client side:
return Json(new { success = true, items = list});
You got to make sure you are returning a JSON data and not html or any other kind of data. Use the browsers console to find out more about your ajax request and response to be sure that you are getting the right response, as you expect.
well, the mistake I see is --
you are doing a return in the controller, you are supposed to do a
Response.Write(Json(new { success = true, items = list}));