I'm using jqGrid in a project, and have managed to replace some of the controls on the edit/input modal with a jQuery autocomplete control, but would prefer something like a combobox.
How would it be possible to replicate the functionality, as I'm struggling to get any of the jQuery combobox add-ons working.
My data set is in json format, so it would be cool if I can keep it that way.
I think the jQuery plugin you're looking for is Flexselect which implements the Liquid metal search ranking algorithm to create the desired affect.
This is what I did to turn my autocompletes into comboboxes.
initImpactEdit = function (elem) {
setTimeout(function () {
$(elem).autocomplete({
source: function (request, response) {
$.ajax({
url: '#Url.Action("ImpactOptions")',
dataType: "json",
data: {
filter: request.term
},
success: function (data) {
response($.map(eval(data), function (item) {
return {
label: item.Impact_name,
value: item.Impact_name,
DTI_ID: item.DTI_ID
}
})
);
}
})
}
}
});
$(elem).addClass('customAutoCompleteWidth');
$('<button class="customDropdown"> </button>')
.attr("tabIndex", -1)
.attr("title", "Show All Items")
.insertAfter(elem)
.button({
icons: {
primary: "ui-icon-triangle-1-s"
},
text: false
})
.removeClass("ui-corner-all")
.addClass("ui-corner-right ui-button-icon")
.click(function () {
var widg = $(elem);
if (widg.autocomplete("widget").is(":visible")) {
widg.autocomplete("close");
return;
}
if (widg.val().length == 0) {
// pass empty string as value to search for, displaying all results
widg.autocomplete("search", "*");
} else { widg.autocomplete("search", widg.val()); }
widg.focus();
});
}, 100);
};
{ name: 'Impact', index: 'Impact', editoptions: { dataInit: initImpactEdit } },
Related
The Problem
So i am currently trying to implement a color picker inside of a Kendo grid, that will hopefully send the chosen color to my Sql Table. Unfortunately, It doesn't seem as though the Update controller is being reached. I am relatively new to Kendo UI, so there might be some incredibly dumb errors shown.
Questions
I guess my main question would be: How can i call the update method when update is clicked on the grid. Essentially, the color picker and the edit command are showing up in beautiful fashion. I just want to know how i can be sure that the method is being called when 'Update' is clicked, seeing as it is not reaching my controller. Feel free to ask if you need to see more code or perhaps a screen shot.
Code
Config.cshtml ( Grid )
#model IEnumerable<STZN.Models.AGCData.ErrorCode>
#{
ViewBag.Title = "Config";
}
#section HeadContent{
<script src="~/Scripts/common.js"></script>
<script>
$(document).ready(function () {
$("#grid").kendoGrid({
editable: "inline",
selectable: "row",
dataSource: {
schema: {
model: {
id: "error_code",
fields: {
color: { type: 'string' }
}
}
},
transport: {
read: {
type: "POST",
dataType: "json",
url: "#Url.Action("ErrorCodes")"
},
update: {
type: "POST" ,
dataType: "json",
url: "#Url.Action("UpdateErrorCodes")",
}
}
},
columns: [
{ command : [ "edit" ] },
{
field: "error_code", title: "Error Code",
},
{
field: "error_description", title: "Error Description"
},
{
field: "color",
width: 150,
title: "Color",
template: function (dataItem) {
return "<div style = 'background-color: " + dataItem.color + ";' </div>"
},
editor: function (container, options) {
var input = $("<input/>");
input.attr("color",options.field);
input.appendTo(container);
input.kendoColorPicker({
value: options.model.color,
buttons: false
})
},
}
]
});
});
</script>
}
Update Controller
public JsonResult UpdateErrorCodes(ErrorCode model)
{
using (var db = new AgcDBEntities())
{
db.Entry(model).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
db.Configuration.ProxyCreationEnabled = false;
var data = db.ErrorCodes.Where(d => d.error_code == model.error_code).Select(x => new
{
error_code = x.error_code,
description = x.error_description,
color = x.color,
});
return new JsonResult()
{
JsonRequestBehavior = System.Web.Mvc.JsonRequestBehavior.AllowGet,
};
}
}
I actually managed to fix my issue by adding an additional input attribute to my editor function in the "color" field. It looks like this:
input.attr("data-bind","value:" + options.field);
There are still some present issues (unrelated to the fix/server update) , but as far as updating to the server, It work's as intended.
I have a cascade Select2 ddl and when I select the master ddl, I populate the Detail ddl without no problem. On the other hand, when I select another item on master and then click the detail, at the first time the detail ddl lists the previous items just a miliseconds. So, I need to clear all of the list items besides the selected item when the main ddl's selected index changed. Is it possible? I have tried to all of the solution methods below, but they only clear the selected item. Any idea?
$('#ProjectId').select2('data', null);
$('#ProjectId').select2('data', { id: null, text: null })
$('#ProjectId').empty();
$('#ProjectId').val(null).trigger("change");
$("#ProjectId").remove();
$('#ProjectId').val('').trigger('change');
#Html.DropDownListFor(m => m.ProjectId, Enumerable.Empty<SelectListItem>(), "Select")
$(document).ready(function () {
var issueType = $("#ProjectId");
issueType.select2({
allowClear: true,
ajax: {
url: '/Controller/GetProjects',
dataType: 'json',
delay: 250,
data: function (params) {
return {
query: params.term, //search term
page: params.page,
id: selectedMasterId
};
},
processResults: function (data, page) {
var newData = [];
$.each(data, function (index, item) {
newData.push({
id: item.Id,
text: item.Description
});
});
return { results: newData };
},
cache: true
},
escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
});
});
$('#MasterId').change(function () {
selectedMasterId = $(this).val();
$('#ProjectId').select2('val', '');
$('#ProjectId').select2('data', null);
}
});
$('#id').empty().trigger("change");
Where '#id' is the jQuery selector for your select2 element.
On the select element put onchange="removeOthers(this)" in js code write this function:
function removeOthers(that){
$('option', that).not(':eq(0), :selected').remove();
//now refresh your select2
}
I am working on autocomplete component from jquery UI. Though my auto complete working fine but If I type suggested letter "I" it was showing all the list which is available from json data where i need only the relevant letter for example if I type letter I "India", Indonesia etc,. And I need to show only max 10 values in the list. Here I have updated the latest code I am trying to do the slice in the autocomplete and i am trying to getting the same value in the next text box.
Here is the current jquery code
$("#ipt_Countryres").autocomplete({
source: function( request, response ) {
var regex = new RegExp(request.term, 'i');
//var filteredArray = filteredArray.slice(0,10);
$.ajax({
url: "json/countries.json",
dataType: "json",
data: {term: request.term},
success: function(data) {
response($.map(data, function(item) {
if(regex.test(item.label)){
return {
id: item.id,
label: item.label,
value: item.value
};
}
}));
},
minlength:2,
select: function (event, ui) {
$("#get_country").val(ui.item.label);
}
});
}
});
Here is the HTML Code
<input type="text" id="ipt_Countryres" name="ipt_Countryres" class="ipt_Field"/>
<input type="text" class="ipt_Field" id="get_country" name="get_country"/ disabled>
Here is my sample JSON data
[
{
"value":"Afghanistan",
"label":"Afghanistan",
"id":"AF"
},
{
"value":"Åland Islands ",
"label":"Åland Islands",
"id":"AX"
},
{
"value":"Albania ",
"label":"Albania",
"id":"AL"
},
{
"value":"Algeria ",
"label":"Algeria",
"id":"DZ"
},
{
"value":"American Samoa ",
"label":"American Samoa",
"id":"AS"
},
{
"value":"AndorrA ",
"label":"AndorrA",
"id":"AD"
},
{
"value":"Angola ",
"label":"Angola",
"id":"AO"
},
{
"value":"Anguilla ",
"label":"Anguilla",
"id":"AI"
},
{
"value":"Antarctica ",
"label":"Antarctica",
"id":"AQ"
},
{
"value":"Antigua and Barbuda ",
"label":"Antigua and Barbuda",
"id":"AG"
}]
Kindly please help me.
Thank in advance
Mahadevan
Try this:
var orignalArray = [
{
"id":"Afghanistan",
"label":"Afghanistan",
"value":"AF"
},
{
"id":"Åland Islands ",
"label":"Åland Islands",
"value":"AX"
},
{
"id":"Albania ",
"label":"Albania",
"value":"AL"
}]
$("#ipt_Countryres").autocomplete({
minLength:1,
source: function(request, response) {
var filteredArray = $.map(orignalArray, function(item) {
if( item.id.startsWith(request.term)){
return item;
}
else{
return null;
}
});
filteredArray = filteredArray.slice(0,10);
response(filteredArray);
},
select: function(event, ui) {
event.preventDefault();
// Prevent value from being put in the input:
$('#ipt_Countryres').val(ui.item.label);
$('#get_country').val(ui.item.label);
// Set the next input's value to the "value" of the item.
},
focus: function(event, ui) {
event.preventDefault();
$('#ipt_Countryres').val(ui.item.label);
}
});
<link href="http://api.jqueryui.com/jquery-wp-content/themes/jquery/css/base.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.8.24/jquery-ui.min.js"></script>
<input type="text" id="ipt_Countryres" name="ipt_Countryres" class="ipt_Field"/>
<input type="text" class="ipt_Field" id="get_country" name="get_country"/ disabled>
Try to add below code for filtering the values with start with regex,
$.ui.autocomplete.filter = function (array, term) {
var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(term), "i");
return $.grep(array, function (value) {
return matcher.test(value.label || value.value || value);
});
};
See more jqueryui-autocomplete-filter-words-starting-with-term
You can reduce the minLength for getting more results:
$("#ipt_Countryres").autocomplete({
source: country_list,
minLength: 3,
max:10,
select: function (event, ui) {
// Prevent value from being put in the input:
$('#ipt_Countryres').val(ui.item.label);
$('#get_country').val(ui.item.label);
// Set the next input's value to the "value" of the item.
}
});
Please find below the running code :
JS Fiddle : http://jsfiddle.net/vafus4qb/
Thank you so much for your suggestion.
Here is my final output which i get right now.
$("#ipt_Countryres").autocomplete({
highlightClass: "bold",
source: function( request, response ) {
var regex = new RegExp(request.term, 'i');
//var filteredArray = filteredArray.slice(0,10);
$.ajax({
url: "json/countries.json",
dataType: "json",
data: {term: request.term},
success: function(data) {
response($.map(data, function(item) {
if(regex.test(item.label)){
return {
id: item.id,
label: item.label,
value: item.value
};
}
}));
}
});
},
minlength:3,
select: function (event, ui) {
$("#get_country").val(ui.item.label);
}
});
Thanks & Regards
Mahadevan
I have an input (textarea) that has Select2's tags applied to it. So when a user types in the name of an item that exists in my data base, it shows a list of matching items and the user can select one and a tag is created.
Here is my code so far for basic tag functionality:
$('#usualSuppliers').select2({
placeholder: "Usual suppliers...",
minimumInputLength: 1,
multiple: true,
id: function(e) {
return e.id + ":" + e.name;
},
ajax: {
url: ROOT + 'Ajax',
dataType: 'json',
type: 'POST',
data: function(term, page) {
return {
call: 'Record->supplierHelper',
q: term,
page_limit: 10
};
},
results: function(data, page) {
return {
results: data.suppliers
};
}
},
formatResult: formatResult,
formatSelection: formatSelection,
initSelection: function(element, callback) {
var data = [];
$(element.val().split(",")).each(function(i) {
var item = this.split(':');
data.push({
id: item[0],
title: item[1]
});
});
//$(element).val('');
callback(data);
}
});
Is there a way for a new tag to be created if the text typed does not exist? Initially I thought this could some how be done by delimiting with spaces, but some items (supplier names) will have spaces in them, so that won't work.
I think when no matches are found the user needs to somehow "create" the tag by pressing a button that could appear in the drop down box, but I have no idea how to do this.
How can I allow users to create new tags that may have spaces in them and still be able to carry on adding more tags, existing or otherwise?
Yes you can do it. There is a example in the documentation. Look at http://ivaynberg.github.io/select2/#events
$("#e11_2").select2({
createSearchChoice: function(term, data) {
if ($(data).filter( function() { return this.text.localeCompare(term)===0;
}).length===0) {
return {id:term, text:term};
}
},
multiple: true,
data: [{id: 0, text: 'story'},{id: 1, text: 'bug'},{id: 2, text: 'task'}]
});
You have to create a function like createSearchChoice, that returns a object with 'id' and 'text'. In other case, if you return undefined the option not will be created.
I have a form working with JQuery Autocomplete and it works fairly well. Now I need another element to force a user to select a valid choice in the autocomplete input. The can type whatever they want and everything is filtered by autocomplete. But they have to select something from the served list.
If they don't the inputfield must get blanked. Tried out a few things with change and select to no avail. This is the code of my autocomplete. I saw some examples operation with data instead of source. This seems to make a big difference
$(function () {
$("#sp_name").autocomplete({
minLength: 2,
delay: 300,
source: function (request, response) {
$.ajax({
url: "./Search/",
dataType: "json",
data: {
term: request.term,
zoekterm: $("#al").html()
},
success: function (data) {
response($.map(data, function (item) {
return {
label: item.naam,
value: item.naam
}
}));
}
});
}
})
});
Try this:
I am using a local list here, but you can achieve this via json data source too.
Just add a change event. The only problem this can have is that if user does not click on
the suggestion, it will turn blank (even if user is entering the same text as suggestion).
It will be mandatory for user to click on the suggestion.
var list = ["c", "c++", "c#","Basic","Mongo"];
$('#auto').autocomplete({
source: list,
select: function (event, ui) {
$(this).val(ui.item ? ui.item : " ");},
change: function (event, ui) {
if (!ui.item) {
this.value = '';}
//else { Return your label here }
}
});
JsFidle for it: http://jsfiddle.net/sarcastic/7KdZP/112/
In your case, Change function would be something like this:
change: function (event, ui)
{
if (!ui.label) { this.value = ''; }
}