ASP.NET: How to get from Dropdownlist to Autocomplete - asp.net-mvc

I have a dropdownlist and want to turn it into autocomplete using jquery.
The dropdown looks like this and works:
#Html.DropDownListFor(m => m.CategoryID, new SelectList(Model.Categories, "ID", "Name", Model.CategoryID), "Categories", new { #class = "form-control" })
I also added an autocomplete field using jquery that works. But so far I can only populate it with dummy data:
$(function () {
var availableTags = [
"ActionScript",
"AppleScript",
"Asp"
];
$("#tags").autocomplete({
source: availableTags
});
});
How can I populate my dropdown field with the data that is available in the dropdown?
Thank you in advance!

You need to set the source as an action method which returns data you want to show as autocomplete option in JSON format.
$(function(){
$("#tags" ).autocomplete({
source: "#Url.Action("SearchCategories","Home")",
minLength: 1,
select: function (event, ui) {
//If you want to do something on the select event, you may do it here
//$("#tags").html(ui.item.label);
}
});
})
Make sure you have an action method called SearchCategories in your HomeController which returns the data you want.
public ActionResult SearchCategories(string term)
{
var db= new MyDbContext();
var results = db.Categories.Where(s => s.Name.StartsWith(term))
.Select(x=>new { id =x.Id,
label =x.Name }).ToList();
return Json(results,JsonRequestBehavior.AllowGet);
}
This should enable the autocomplete on an input with id tags,assuming you have jQuery ui library(and it's dependencies) loaded properly in your page and you do not have any other script errors in your page. I have used Url.Action helper method to generate the correct relative url to the action method. It will work fine if your js code is inside a razor view. But if your code is inside an external js file, you should follow the approach described in this post.

Related

jquery ui helper mvc Select event

I'm trying to access "select" event when user select from jquery ui autocomplete populated list i want to fire an event when jquery ui autocomplete "Select" event called.
My Problem is
I am using JqueryUiHelper MVC and dont know how to use select event using htmlHelper http://jqueryuihelpers.apphb.com/Docmo/Autocomplete
#using JQueryUIHelpers
#Html.JQueryUI().AutocompleteFor(x => x.SearchText, Url.Action("SearchFilter"), new { #class = "form-control", placeholder = "Company name here for search..", style = "max-width:none;" }
)
#section Styles {
#Styles.Render("~/Content/jqueryui")
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryui")
}
any help would be greatly appreciated.
I came with solution got from https://api.jqueryui.com/autocomplete/#event-select
Bind an event listener to the autocompleteselect event:
$(function () {
$("#SearchText").on("autocompleteselect", function (event, ui) {
event.preventDefault();
$(this).val(ui.item.value);
$('#btnGo').click();
});
});

JQuery UI Autocomplete widget not working on a bootstrap modal

I have a bootstrap modal dialog on which I have a textbox that I want to leverage the functionality of jQuery UI Autocomplete widget. However the autocomplete widget isn't being fired at all. I know this as I placed a breakpoint on the action on my controller that should return the Json to be rendered by the autocomplete textbox. The action is never hit
Out of curiosity that I was doing something wrong, I copy pasted the textbox onto a View and to my dismay, the breakpoint on my action in the controller is hit. I have narrowed this down to the fact that may be the textbox is never wired to use the autocomplete feature once the DOM has loaded.
Here is the textbox on my modal
<input type="text" name="someName" id="autocomplete" data-autocomplete-url="#Url.Action("Autocomplete", "warehouses")" />
Here is the action method that returns the Json
public ActionResult Autocomplete(string term)
{
string[] names = { "Auma", "Dennis", "Derrick", "Dylan", "Mary", "Martha", "Marie", "Milly", "Abel", "Maria", "Bergkamp", "Arsene", "Alex", "Mwaura", "Achieng" };
var filtered = names.Where(a => a.IndexOf(term, StringComparison.OrdinalIgnoreCase) >= 0);
return Json(filtered, JsonRequestBehavior.AllowGet);
}
And here is how I wire up the textbox to use the autocomplete widget
$(document).ready(function () {
$('#autocomplete').autocomplete({
source: $(this).data('autocomplete-url'),
data: {term: $(this).val() }
});
});
I have seen similar questions asked but none of them was due to the action not being hit.
As per the documentation for Bootstrap 3, they expose a set of events that you can hook into with most of their JS features.
In this case the events are:
show, shown, hide, hidden and loaded
The following code will initialize your autocomplete input field after the modal has been shown. (replace myModal with the id of the modal you are going to show)
$(document).ready(function () {
$('#myModal').on('shown.bs.modal', function (e) {
$("#autocomplete').autocomplete('destroy'); //remove autocompete to reattach
$('#autocomplete').autocomplete({
source: $(this).data('autocomplete-url'),
data: {term: $(this).val() }
});
});
});
If you are fetching a partial that contains the input field and appending it to the modal during the toggle, it will be better to do this initialization in the callback from that ajax request.

how to catch PageSizeChanged event of telerik MVC Grid (NOT KENDO GRID)

I am working on asp.net MVC 4 application in which i am using telerik MVC Grid (NOT KENDO GRID).
http://www.telerik.com/help/aspnet-mvc/telerik-ui-components-grid-client-api-and-events.html
in my page (cshtml) i am having the grid using the common partial page.
in the page, i am also having other input elements ( which acts as filter criteria for grid data).User selects the values from input elements and click on submit button and data in grid is filled accordingly (using post requst in MVC code).
I am using paging in grid and user may select the page size.
Grid set up
Html.Telerik().Grid(Model)
.Name("Employees")
.Columns(cols =>
{
cols.Bound(e => e.FirstName).Title("First Name");
cols.Bound(e => e.LastName).Title("Last Name");
cols.Bound(e => e.SSN).Title("SSN");
cols.Bound(e => e.HireDate).Format("{0:MM/dd/yyyy}").Title("Hire Date");
cols.Bound(e => e.GroupName).Title("Department GROUP");
})
.Groupable()
.Sortable(x => x.OrderBy(z=>z.GetType()))
.Pageable(p => p.PageSize(5).Style(GridPagerStyles.PageSizeDropDown | GridPagerStyles.NextPreviousAndNumeric).PageTo((Model.Any()&&!string.IsNullOrWhiteSpace(Model.First().PageNumber)?Convert.ToInt32(Model.First().PageNumber):1)))
.Filterable()
.Render();
the POST method in employee controller returns the filtered data by accepting the model values and querying the database.
now when changes the page size of the grid,request is sent to GET method of the controller instead of post.
How to catch PageSizeChanged like event of grid in JavaScript, so that i can manually post the form wherever user change page size?
EDIT : I have written following code to get click event whenever user clicks on number in page size dropdown
$(document).on('click', 'ul.t-reset > li.t-item', function (e) {
//how to avoid default functionality of server call?
//tried following
//event.unbind();
//event.preventDefault();
//alert("Was preventDefault() called: " + event.isDefaultPrevented());
//event.stopImmediatePropagation()
//return false;
});
MVC Grids just get turned into Kendo Grid javascript, so all the API methods/events and so on can be used with the MVC Grid.
Check out the kendo grid page change event and just use that.
http://docs.telerik.com/kendo-ui/api/javascript/ui/pager#events-change
var grid = $("#Employees").data('kendoGrid');
Now you have the grid, you can do whatever you wish to it. Subscribe to the page event change like the example from Kendo API documentation;
<div id="pager"></div>
<script>
function pager_change() {
console.log("pager change event");
}
var dataSource = new kendo.data.DataSource({
data: [
{ productName: "Tea", category: "Beverages" },
{ productName: "Coffee", category: "Beverages" },
{ productName: "Ham", category: "Food" },
{ productName: "Bread", category: "Food" }
],
pageSize: 2
});
dataSource.read();
var pager = $("#pager").kendoPager({
dataSource: dataSource
}).data("kendoPager");
pager.bind("change", pager_change);
</script>
I like to set up the grid with MVC and if I need to get into its workings and do a lot of client side magic I'll just grab it as a Kendo grid.

Connect knockout and jQueryUI autocomplete

I have a jQueryUI autocomplete that pulls from a list of customers and is attached based on the selector [input data-role="customer-search"]. Once a customer is selected, I make a AJAX call to get the full customer detail. This part I have working fine. The issue is that I am having trouble figuring out a way to incorporate knockout into this. My ideal situation is a custom binding like "onSelect: customerSelected", which would take in the selected Customer JSON and integrate it into the overall model, which would then cause updates to a bunch of fields on the page with bingings such as model.Customer.Address, model.Customer.Type.
The place I am butting my head against is that connection point after I've gotten the Customer JSON back from the AJAX call, how to send it to the "customerSelected" method on the viewmodel tied to the same input I attached the jQuery autocomplete.
Here is a simplified version of a bindinghandler my team wrote for handling autocomplete. When an item is selected, the item is inserted into an observable array in the view model. It is bound in the following manner:
<input type="text" data-bind="autoComplete:myObservableArray, source:'myUrl'" />
You can customize what happens when an item is selected in the 'select:' area.
ko.bindingHandlers.autoComplete = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var postUrl = allBindingsAccessor().source; // url to post to is read here
var selectedObservableArrayInViewModel = valueAccessor();
$(element).autocomplete({
minLength: 2,
autoFocus: true,
source: function (request, response) {
$.ajax({
url: postUrl,
data: { term: request.term },
dataType: "json",
type: "POST",
success: function (data) {
response(data);
}
});
},
select: function (event, ui) {
var selectedItem = ui.item;
if (!_.any(selectedObservableArrayInViewModel(), function (item) { return item.id == selectedItem.id; })) { //ensure items with the same id cannot be added twice.
selectedObservableArrayInViewModel.push(selectedItem);
}
}
});
}
};
Hopefully, it's something like this that you're looking for. If you need something clarified, let me know.
Note Besides jquery and knockout, this example uses underscore.js ( the _.any() function)
valueUpdate: blur
data-bind="value: textbox, valueUpdate: blur" binding fixed the problem for me:
$(function() {
$(".autocomplete").autocomplete({
source: [
"ActionScript",
"AppleScript",
"Asp",
"BASIC",
"C",
"C++",
"Clojure",
"COBOL",
"ColdFusion",
"Scheme"]
});
});
var viewModel = {
textbox: ko.observable()
};
ko.applyBindings(viewModel);
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//code.jquery.com/ui/1.11.3/jquery-ui.min.js"></script>
<input type="text" class="autocomplete" data-bind="value: textbox, valueUpdate: blur"/>

Cascading Combobox with default values on telerik mvc

I have a search page and want to add some filters to it, my setup is quite simple, I have a CombobBox for Countries and a ComboBox for States.
I want to show ALL the states if no country is selected(actually, the first item of the countries combobox is "All") here is my code:
#(Html.Telerik().ComboBoxFor(m => m.Country)
.Name("cbxCountry")
.BindTo(this.Model.CountryList)
.SelectedIndex(0).CascadeTo("cbxStates"))
#(Html.Telerik().ComboBoxFor(m=>m.State)
.Name("cbxStates")
.DataBinding(binding => binding.Ajax()
.Select("AjaxLoadStates","States")))
Note that even if the .SelectedIndex is set to 1, 3, 1231231 the second combobox keeps disabled until I select a value. Is there any way to make this work?
You can do this with the client API in javascript:
<script type="text/javascript">
function SelectFirstCountry() {
var cbxCountry = $("#cbxCountry").data('tComboBox')
var cbxStates = $("#cbxStates").data('tComboBox')
cbxCountry.select(1);
cbxStates.enable();
}
$(document).ready(function () {
#{
Html.Telerik().ScriptRegistrar().OnDocumentReady("SelectFirstCountry()");
}
});
</script>

Resources