MVC autocomplete not working - asp.net-mvc

I know there are lot of posts out there but simply I can not figure out what I am doing wrong in autocomplete.
I have a ProductController like
public JsonResult AutocompleteMethod(string searchstring) //searchString null here
{
Product ob=new Product();
List<Product> newLst = ob.GetProducts();
var suggestions = from s in newLst select s.productName ;
var namelist = suggestions.Where(n=>n.StartsWith(searchstring));
return Json(namelist, JsonRequestBehavior.AllowGet);
}
In view I have:
<p>
Find by name:<%: Html.TextBox("Txt") %>
</p>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.0/themes/base/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.8.3.js" type="text/javascript"></script>
<script src="http://code.jquery.com/ui/1.10.0/jquery-ui.js" type="text/javascript"></script>
<script type="text/jscript">
$(function () {
debugger;
$('#Txt').autocomplete({ source: '/Product/AutocompleteMethod' });
});
</script>
But always SearchString is NULL in controller function.
Can you figure out what is the mistake?

AFAIK the parameter is called term, not searchstring, so:
public ActionResult AutocompleteMethod(string term)
{
List<Product> newLst = new Product().GetProducts();
var namelist =
from p in newLst
where p.StartsWith(term)
select new
{
value = p.Id, // you might need to adjust the Id property name here to match your model
label = p.productName
};
return Json(namelist, JsonRequestBehavior.AllowGet);
}
Also I very much doubt that productName is a property that the autocomplete plugin will ever recognize. You could try using value and label as shown in the projection I performed in my example.

Related

How modelbinding my custom HelperResult from View

In my ASP.NET MVC 5 project, I have created a new HelperResult.
My goal is to create a reusable autocomplete dropdownlist component (that contains the bootstrap-select) and with a setting of several parameters can assume behaviors different on needed, but especially that use a controller method or API in POST to populate itself.
It seems It works well but not enough in postback action.
I can't bind my helper to retrieve data at the postback action.
I don't know how getting data selected from combobox...
To be more clear, I'd like to show you the interface
Well, when I press button I don't know how to get data in the controller.
Follow the View where I have put new HelperResult
View
#{
ViewBag.Title = "Test";
Layout = "";
}
<h2>Test</h2>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<link href="~/UIComponent/bootstrap-select/css/bootstrap-select.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.bundle.min.js"></script>
<script src="~/UIComponent/bootstrap-select/js/bootstrap-select.js"></script>
#using (Html.BeginForm("testpost", "Home"))
{
<br />
<div style="padding:30px">
Lists
#UIHelper.HubCombo("/HUB/GetMezziOrdinari", "ID", "Descrizione", false, "Seleziona un item", "cboItems", "<b>Selezionare un item</b>", "ID")
<input type="submit" value="submit" id="btnSubmit" />
</div>
}
This is my Helper defined in the "UIHelper.cshtml" within App_Code
Helper
#helper HubCombo(string UrlHub,
string nomecampoValue,
string nomecampoText,
bool MultiSelection = false,
string placeholder = "",
string controlID = "cboSelect",
string header = "",
string subText = ""
)
{
string _subText = subText.Trim();
<select class=""
id="#controlID"
data-live-search="true"
title="#placeholder"
data-hide-disabled="true"
data-header="#header"
data-width="auto"
#if (MultiSelection)
{
<text>multiple</text>
}
>
</select>
<script type="text/javascript">
$.ajax({
url: '#UrlHub',
type: 'POST',
contentType: 'application/json',
data: '',
success: function (response) {
var options = [], _options;
$.each(response.Data, function (idx, obj) {
#{
if (_subText.Length>0)
{
<text>
options.push("<option data-subtext='"+ obj.#_subText+"' value='" + obj.#nomecampoValue + "'>" + obj.#nomecampoText + "</option>");
</text>
}
else
{
<text>
options.push("<option value='" + obj.#nomecampoValue + "'>" + obj.#nomecampoText + "</option>");
</text>
}
}
});
_options = options.join('');
$('##controlID')[0].innerHTML = _options;
$('##controlID').selectpicker();
}
});
</script>
}
At the end my controller but I'm stuck!
Controller
[HttpPost]
public ActionResult testpost()
{
//How to get value of my custom Helper Result?
return View();
}
if you have other solutions, please let me know. thx
With this signature for controller action, now you can retrieve data:
[HttpPost]
public ActionResult testpost(List<string> cboItems)
{
ViewBag.cboItems = string.Join("<br />", cboItems);
return View();
}
even so
[HttpPost]
public ActionResult testpost(string[] cboItems)
{
...
so, I think the ViewModel class used by Controller and View should container those fields.

How to Remove Client-Side Validation on a textboxfor for multiple emails?

I am creating an MVC application in which I will have an input field for a list of emails. In order to do so, I added multiple in order to allow for the user to enter a comma separated list of emails. By doing it this way, I'm able to have input controls to check for the email(s) to be properly formatted (".+#gmail.com").
The problem is that when I test this, it automatically adds class="input-validation-error" (even if I set the #class="" prior) and will not allow me to post due to an invalid input, as a result. Is there any way to allow for this, or is my only option to make it an Email string property and parse it by commas into the EmailList property in the controller?
(Here is my code):
View:
#Html.TextBoxFor(model => model.EmailList, new { type = "email", placeholder
= "ex#gmail.com (',' Delimited)", title = "Make sure your email(s) are
formatted appropriately (and comma separated).", multiple = "" })
Model:
public List<string> EmailList { get; set; }
UPDATE:
I should also add that I am performing json serialization on post, so It needs to be in the form of a list. Ideally, I would be able to use the multiple for the input of type email tag, since it would allow for the necessary input controls that I would need without making me take it as a string and writing it to a list.
The new fiddle is here, click on it https://dotnetfiddle.net/ORYDVJ
View
#model Testy20161006.Controllers.MurphyModel
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Tut122</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
$("#emailField").change(function () {
var theList = {
emaillist: []
};
var array = $('#emailField').val().split(",");
$.each(array, function (i) {
theList.emaillist.push(
array[i]
);
});
$.ajax({
url: '/Home/Tut122',
traditional: true,
type: "POST",
contentType: "application/json",
data: JSON.stringify({ murphyModel: theList }),
success: function (data) {
console.log('success!!');
$("#theOutput").html(data)
}
});
})
})
</script>
</head>
<body>
#Html.TextBoxFor(model => model.EmailList, new
{
id = "emailField",
type = "email",
placeholder = "ex#gmail.com (',' Delimited)",
title = "Make sure your email(s) are formatted appropriately (and comma separated).",
multiple = ""
})
<span>The output data:</span>
<div id="theOutput">
</div>
</body>
</html>
Controller/View Model
public class MurphyModel
{
public List<string> EmailList { get; set; }
}
public class HomeController : Controller
{
[HttpPost]
public string Tut122(MurphyModel murphyModel)
{
//You need to get Newtonsoft.JSON
var json = JsonConvert.SerializeObject(murphyModel);
return json;
}
public ActionResult Tut122()
{
MurphyModel model = new MurphyModel();
return View(model);
}
https://dotnetfiddle.net/eadTjh
View
#model Testy20161006.Controllers.MurphyModel
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Tut122</title>
</head>
<body>
#if (ViewBag.Output != null)
{
<span>#ViewBag.Output</span>
}
#using (Html.BeginForm())
{
#Html.TextBoxFor(model => model.EmailList, new
{
type = "email",
placeholder = "ex#gmail.com (',' Delimited)",
title = "Make sure your email(s) are formatted appropriately (and comma separated).",
multiple = ""
})
<input type="submit" value="submit" />
}
</body>
</html>
Controller/View Model
namespace Testy20161006.Controllers
{
public class MurphyModel
{
//We don't want a list class, rather a string
public string EmailList { get; set; }
}
public class HomeController : Controller
{
[HttpPost]
public ActionResult Tut122(MurphyModel model)
{
var splitEmails = model.EmailList.Split(',');
var anEmail = "These are the different emails: ";
foreach (string email in splitEmails)
{
//set breakpoint here
anEmail+= email + " and ";
}
anEmail = anEmail.Substring(0, anEmail.Length - 5);
ViewBag.Output = anEmail;
return View(model); }
public ActionResult Tut122()
{
MurphyModel model = new MurphyModel();
return View(model);
}
add a js file hopefully u use jQuery
$(document).ready(function () {
$("#EmailList").removeClass("input-validation-error");
});
After Reviewing kblau's answer, I realized that was partially the reason. The other issue that I was running into (where MVC was stepping over any of my manually entered client-side validation) was the result of the unobtrusive validation:
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
After commenting this out, it allowed for me to have the input write to a string Email which I would then assign to a list of strings EmailList in the controller. This ended up working for me.

LINQ Query is not displaying mt data in my Google chart (Report)

I have a LINQ query which gets the Type and count of types, and I have it in my controller. In my view I am using a Pie Chart from Google Charts and I am trying to display the data acquired by the LINQ statement. However, when I run the program the Pie Chart doesn't display. No errors appear though. So I am struggling to see whether my problem is my View or the Controller
Controller:
public ActionResult Report_5()
{
return View();
}
public ActionResult GetChart5()
{
var result = from x in db.Submission
group x by x.Type into grp
select new
{
Type = grp.Key,
Count = grp.Count()
};
return Json(result, JsonRequestBehavior.AllowGet);
}
Report_5 View:
<h2 style="text-align:center">Type Count</h2>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/mvc/4.0/jquery.validate.unobtrusive.min.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", { packages: ["corechart"] });
google.setOnLoadCallback(drawChart);
function drawTable() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Type');
data.addColumn('string', 'Count');
$.getJSON("#Url.Action("GetChart5")", null, function (chartData) {
$.each(chartData, function (i, item) {
data.addRow([item.Type, item.Count]);
});
var chart = new google.visualization.PieChart(document.getElementById('donutchart'));
chart.draw(data, options);
});
}
</script>
<div id="donutchart" style="width: 900px; height: 500px;"></div>
Please let me know if I need to provide more information.
I made the following:
1. created view in folder Models.
public class ModelSubmission
{
public string Type { get; set; }
public int TotalSubmissions { get; set; }
}
In home controller created the following:
public ActionResult Report_5()
{
return View();
}
public ActionResult GetChart5()
{
List<ModelSubmission> result = new List<ModelSubmission>();
result.Add(new ModelSubmission() { Type="Book", TotalSubmissions = 3 });
result.Add(new ModelSubmission() { Type = "Book chapter", TotalSubmissions = 7 });
result.Add(new ModelSubmission() { Type = "Journal Article", TotalSubmissions = 3 });
return Json(result, JsonRequestBehavior.AllowGet);
}
And then copy/pasted your view. Then executed for debugging, and as you mentioned seen nothing special. After clicking F12 in chrome I noticed following error message:
Uncaught ReferenceError: drawChart is not defined.
It lead me to conclusion, that in your code instead of
google.setOnLoadCallback(drawChart);
you should write
google.setOnLoadCallback(drawTable);
After some debugging I noticed other errors in your code. Try to find them while watching the following view:
<h2 style="text-align:center">Type Count</h2>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"> </script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"> </script>
<script src="//ajax.aspnetcdn.com/ajax/mvc/4.0/jquery.validate.unobtrusive.min.js"> </script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", { packages: ["corechart"] });
google.setOnLoadCallback(drawTable);
function drawTable() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Type');
data.addColumn('number', 'Count');
$.getJSON("#Url.Action("GetChart5")", null, function (chartData) {
$.each(chartData, function (i, item) {
data.addRow([item.Type, item.TotalSubmissions]);
});
var chart = new google.visualization.PieChart(document.getElementById('donutchart'));
var options = {
'title': 'Forgotten input',
'width': 400,
'height': 300
};
chart.draw(data, options);
});
}
You should be more careful when copy/paste code from other pages

select id and label for bootstrap autocomplete

I get typeahead working in my project but only for names. I am not able to process id of that particular label coming in autocomplete.
Bootstrap typeahead-
<input type="text" name="names" value="" id="typeahead" data-provide="typeahead" />
Script-
<script type="text/javascript">
$(function () {
$('#typeahead').typeahead({
source: function (term, process) {
var url = '#Url.Content("~/Invoice/GetNames")';
return $.getJSON(url, { term: term }, function (data) {
return process(data);
});
}
});
})
</script>
Json method-
[HttpGet]
public JsonResult GetNames(string term)
{
var names = (from u in db.Contacts
where u.name.Contains(term)
select u).ToArray();
var results = names.Select(u => u.name);
return new JsonResult()
{
Data = results,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
I am selecting whole table row on match. But How do I get Id with label name.
Or-
I can select whole row at server's side, But the problem persist for filtering result for label and name.
I used this info to also get the ID: http://fusiongrokker.com/post/heavily-customizing-a-bootstrap-typeahead (More complex... part)

autocomplete in asp.net mvc (razor)

I'm trying to implement the autocomplete function in my website, but won't work properly.
Here is the code of my view:
<script src="~/Scripts/jquery-ui-1.8.20.js" type="text/javascript"></script>
<script src="~/Scripts/jquery-ui-1.8.20.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$("#SearchString").autocomplete({
source: "/Test/AutocompleteSuggestions",
minLength: 1,
select: function (event, ui) {
if (ui.item) {
$("#SearchString").val(ui.item.value);
$("form").submit();
}
}
});
});
</script>
#using (Html.BeginForm())
{
<p>
Find by name: #Html.TextBox("SearchString")
<input type="submit" value="Search" /></p>
}
Here is code of my autoComplete controller action:
public JsonResult AutocompleteSuggestions(string searchstring)
{
var suggestions = from s in db.Students
select s.Name;
var namelist = suggestions.Where(n => n.ToLower().StartsWith(searchstring.ToLower()));
// return namelist.ToList();
return Json(namelist, JsonRequestBehavior.AllowGet);
}
Can anyone help me ?
Thanks in advance
you are trying to pass IQueryable. try replacing it with
return Json(namelist.ToList(), JsonRequestBehavior.AllowGet);
if that still doesnt work.
try replacing "searchString" to "term"
public JsonResult AutocompleteSuggestions(string term)
Ive read an article that you must use the "term" query string. but Im not pretty sure about it.

Resources