I'm trying to see if this is possible with the library Select2. Say I have a list of data as follows:
Apple
Basketball
Banana
Orange
Football
Is there a way to show only Apple, Banana, and Orange when I type in "fruit," and show Basketball and Football when I type "Sports." Meaning is there a "related search/tagging" type of functionality?
Thanks!
you could do something like this:
The search documentation: https://select2.org/searching
function matchCustom(params, data) {
const term = $.trim(params.term);
if (term === "fruit" || term === "sports") {
if (data.type === term) {
return data;
}
return null;
}
return data;
}
const data = [
{
id: 0,
type: "fruit",
text: "apple"
},
{
id: 1,
type: "fruit",
text: "orange"
},
{
id: 2,
type: "sports",
text: "football"
},
{
id: 3,
type: "sports",
text: "basketball"
}
];
$(document).ready(() => {
$(".js-example-basic-single").select2({ data, matcher: matchCustom });
});
.js-example-basic-single {
width: 100%;
}
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
<link href="https://cdn.jsdelivr.net/npm/select2#4.0.13/dist/css/select2.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2#4.0.13/dist/js/select2.min.js"></script>
</head>
<body>
<div id="app"></div>
<select class="js-example-basic-single" name="state"></select>
</select>
</body>
</html>
Related
I am having a kendo grid where the multiple row selection is enabled. With multiple selection functionality, when users try to copy custom text like any value from the column, it enables multiple select features thus users cannot copy custom text.
Below is the sample:
https://dojo.telerik.com/#erpuneet507/ivAfoFup
The issue is, in the above example you can select text from a single cell/ or any partial text from the cell.
If you have multiple selection enabled, then your app has to handle the copy text to clipboard. In doing so, you'll need the clipboard.js library and add a Kendo ContextMenu. Handle the copy text in the ContextMenu select event. Copy Text should pop up on right click.
Try the code below in the Telerik DOJO:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Kendo UI Snippet</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2021.2.616/styles/kendo.default-v2.min.css"/>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2021.2.616/js/kendo.all.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.7.1/clipboard.min.js"></script>
</head>
<body>
<div id="grid"></div>
<ul id="context-menu">
<li id="copyText">Copy Text</li>
</ul>
<script>
$(document).ready(function() {
$("#grid").kendoGrid({
selectable: "multiple row",
allowCopy: true,
columns: [
{ field: "productName" },
{ field: "category" }
],
dataSource: [
{ productName: "Tea", category: "Beverages" },
{ productName: "Coffee", category: "Beverages" },
{ productName: "Ham", category: "Food" },
{ productName: "Bread", category: "Food" }
]
});
$("#context-menu").kendoContextMenu({
target: "#grid",
filter: "td",
select: function (e) {
var cell = e.target;
var row = $(cell).parent()[0];
var grid = $("#grid").data("kendoGrid");
var itemId = e.item.id;
var cellText = cell.innerText;
if (itemId === 'copyText') {
new Clipboard('#copyText', {
text: function (trigger) {
return cellText;
}
});
};
}
});
});
</script>
</body>
</html>
Here's a revised version of the above. You'll no longer need the clipboard.js. This will show/pop up the text (e.g. coffee) when you right click so that you can copy the 'ffee'.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Kendo UI Snippet</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2021.2.616/styles/kendo.default-v2.min.css"/>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2021.2.616/js/kendo.all.min.js"></script>
</head>
<body>
<div id="grid"></div>
<ul id="context-menu">
<li id="copyText">
<input id="valueText"></input>
<span id="closeValueText" class="k-icon k-i-close"></span>
</li>
</ul>
<script>
$(document).ready(function() {
$("#grid").kendoGrid({
selectable: "multiple row",
allowCopy: true,
columns: [
{ field: "productName" },
{ field: "category" }
],
dataSource: [
{ productName: "Tea", category: "Beverages" },
{ productName: "Coffee", category: "Beverages" },
{ productName: "Ham", category: "Food" },
{ productName: "Bread", category: "Food" }
]
});
var closeContextMenu = false;
var contextMenu = $("#context-menu").kendoContextMenu({
target: "#grid",
filter: "td",
close: function(e) {
if (!closeContextMenu) {
e.preventDefault();
}
},
open: function(e) {
var cell = e.target;
var row = $(cell).parent()[0];
var grid = $("#grid").data("kendoGrid");
var itemId = e.item.id;
var cellText = cell.innerText;
$(e.item).find("#valueText").val(cellText);
closeContextMenu = false;
}
}).data("kendoContextMenu");
$("#closeValueText").on("click", function(e) {
closeContextMenu = true;
contextMenu.close();
});
});
</script>
</body>
</html>
I didn't know what had went wrong where i had defined the function but it still giving error.
var sampleData = [
{ id: 1, name: "name", items: ["foo", "bar"] }
];
var defaultColumns=[
{ field: "id" },
{ field: "name" },
{ field: "items", "template":kendo.template("#= showItems(items) #") }
];
$("#grid").kendoGrid({
dataSource: {data:sampleData},
columns:defaultColumns
});
function showItems(arr) {
return arr.join("</br>") ;
}
My sample code
Make sure that showItems is defined in the global JavaScript scope in your actual application. This is required for custom functions called from inside Kendo UI templates:
http://docs.telerik.com/kendo-ui/framework/templates/overview#handle-external-templates-and-expressions
var sampleData = [
{ id: 1, name: "name", items: ["foo", "bar"] }
];
var defaultColumns=[
{ field: "id" },
{ field: "name" },
{ field: "items", template: showItems }
];
$("#grid").kendoGrid({
dataSource: {data:sampleData},
columns:defaultColumns
});
function showItems(arr) {
return arr.items.join("</br>") ;
}
I was able to solve the solution by declaring the showItems in global and it perfectly fine.
function showItems(arr) {
return arr.join("</br>");
}
var sampleData = [{
id: 1,
name: "name",
items: ["foo", "bar"]
}];
var defaultColumns = [{
field: "id"
}, {
field: "name"
}, {
field: "items",
"template": kendo.template("#= showItems(items) #")
}];
$("#grid").kendoGrid({
dataSource: {
data: sampleData
},
columns: defaultColumns
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Kendo UI Grid</title>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.914/styles/kendo.common.min.css" />
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.914/styles/kendo.silver.min.css" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.3.914/js/kendo.all.min.js"></script>
</head>
<body>
<div id="grid"></div>
</body>
</html>
I've got some code here where I am trying to set a background color of a cell based on the value of the data item: http://dojo.telerik.com/#solidus-flux/eHaMu
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Kendo UI Snippet</title>
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1411/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1411/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1411/styles/kendo.default.min.css">
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1411/styles/kendo.dataviz.min.css">
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1411/styles/kendo.dataviz.default.min.css">
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1411/styles/kendo.mobile.all.min.css">
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://cdn.kendostatic.com/2014.3.1411/js/kendo.all.min.js"></script>
</head>
<body>
<div id="grid"></div>
<script>
$("#grid").kendoGrid({
columns: [ {
field: "name",
title: "Name",
attributes: function(e) {
return {
"class": "table-cell",
style: e.name == "Jane Doe" ? "background-color: red" : "background-color: green"
};
}
//attributes: {
//"class": "table-cell",
//style: "text-align: right; font-size: 14px"
//}
} ],
dataSource: [ { name: "Jane Doe" }, { name: "John Doe" }]
});
</script>
</body>
</html>
I realize I could do this with a template, but that would require an extra html element, since you can't change the markup of the td itself. I'd like to use a function to return attributes if that is supported.
You said you don't want to use templates, but I think you were talking about column templates.
You can change the markup of the td itself by using a row template:
<script id="template" type="text/x-kendo-template">
<tr data-uid="#= uid #">
# this.columns.forEach(function(col) {
var val = data[col.field],
css,
style = ''
cClasses = '';
if (typeof col.attributes === 'function') {
css = col.attributes(data);
cClasses = css["class"];
style = css.style
}
#
<td class='#= cClasses #' style='#= style #'>
#= data[col.field] #
</td>
# }) #
</tr>
</script>
For the loop to work, you need to bind your template to the grid though:
var grid = $("#grid").kendoGrid({
columns: [{
field: "name",
title: "Name",
attributes: function (e) {
return {
"class": "table-cell",
style: e.name == "Jane Doe" ?
"background-color: red" : "background-color: green"
};
}
}, {
field: "title",
title: "Title"
}],
dataSource: [{name: "Jane Doe", title: "Dr. Dr."},
{name: "John Doe", title: "Senior Citizen"}]
}).data("kendoGrid");
var template = kendo.template($("#template").html()).bind(grid);
grid.setOptions({
rowTemplate: template
});
(demo)
As an alternative, you could also create attributes like this:
{
field: "name",
title: "Name",
attributes: {
"class": "# if(data.name === 'Jane Doe') { # red # } else { # green # } #"
}
},
This would have the advantage of not using the row template, but you'd have to use the template syntax for the logic.
(demo)
Please try with the below code snippet.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Kendo UI Snippet</title>
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1411/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1411/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1411/styles/kendo.default.min.css">
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1411/styles/kendo.dataviz.min.css">
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1411/styles/kendo.dataviz.default.min.css">
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1411/styles/kendo.mobile.all.min.css">
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://cdn.kendostatic.com/2014.3.1411/js/kendo.all.min.js"></script>
<style>
.greenBG {
background-color:green;
}
.redBG {
background-color:red;
}
</style>
</head>
<body>
<div id="grid"></div>
<script>
$("#grid").kendoGrid({
columns: [{
field: "name",
title: "Name",
attributes: function (e) {
return {
"class": "table-cell",
style: e.name == "Jane Doe" ? "background-color: red" : "background-color: green"
};
}
}],
dataSource: [{ name: "Jane Doe" }, { name: "John Doe" }],
dataBound: function () {
dataView = this.dataSource.view();
for (var i = 0; i < dataView.length; i++) {
if (dataView[i].name === "Jane Doe") {
var uid = dataView[i].uid;
$("#grid tbody").find("tr[data-uid=" + uid + "]").addClass("greenBG");
}
else {
var uid = dataView[i].uid;
$("#grid tbody").find("tr[data-uid=" + uid + "]").addClass("redBG");
}
}
}
});
</script>
</body>
</html>
In angular kendo callback e not work
Use this
attributes: {
"ng-confirm-message": "{{this.dataItem.is_active ? \'Are you sure deactive ?\' : \'Are you sure active ?\'}}",
"confirmed-click": "vm.inlineSubmit(this.dataItem.toJSON() ,true)"
}
For Kendo-JQuery.
<div id="grid"></div>
<script>
$("#grid").kendoGrid({
columns: [{
field: "name",
headerAttributes: {
"class": "table-header-cell",
style: "text-align: right; font-size: 14px"
}
}]
});
</script>
And this Kendo-MVC
.Columns(columns =>
{
columns.Bound(c => c.ActiveReason).Title("ActiveReason").HeaderHtmlAttributes(new { #class = "table-header-cell" });
})
Some years later but ... the attributes function is not working at all for me, is not even hit, seems pretty but not working (Why is needed a manual class toggle if a functions is provided to do the work? something seems weird).
I make editable cells based on other fields values but also I needed to change the styles
1) Add the validation on field that you want to inject the css class,
//Your other fields configuration
field:"dependentField",
attributes:
{
"class": "# if(data.ImportantField!==true) { # nonEditableCellStyle # } else { # editableCellStyle # }# ",
}
//Your other fields configuration
2) Bind the grid change event and check if some important field has changes, if is the field that controls the style of other cells just call the refresh method
var _kendoGrid = $('#myGrid').data("kendoGrid");
_kendoGrid.dataSource.bind("change", function (e) {
if (e.action === "itemchange") {
if (e.field === "ImportantField") {
_kendoGrid.refresh();
}
}
});
The refresh method will render your grid again, that means your functions weather is a template or an attribute function ( and again, that does not work at all for me) will run and apply the correct sytles, or classes in this case.
I use Angular, this is my view:
<div class="col-sm-6" ng-repeat="contact in service.contacts">
<label class="control-label mb10">{{contact.textDescription | decodeURIComponent}}</label>
<select multiple="multiple" selectize>
<option>{{contact.value}}</option>
</select>
</div>
I have one problem and I can't figure out a way to solve it. For contact.textDescription, I need to put only unique values, so if that contact.textDescription is duplicate, don't create field twice, but add that contact.value to options of that same contact.textDescription which already exists.. So, something like this:
if(contact.textDescription is duplicate) {
contact.value.addTo(contact.textDescription which already exists)
}
Maybe some filter to apply or?
By the understanding of what you mentioned I think the filter mention in the following answer will help you to do what you want
Use this link to go to the question
You can use ng-options to group and display unique value.
You can use uniqFilter of angular-filter module.
Usage: collection | unique: 'property' or nested.property
Aliases: uniq
Example:
JS:
function MainController ($scope) {
$scope.orders = [
{ id:1, customer: { name: 'John', id: 10 } },
{ id:2, customer: { name: 'William', id: 20 } },
{ id:3, customer: { name: 'John', id: 10 } },
{ id:4, customer: { name: 'William', id: 20 } },
{ id:5, customer: { name: 'Clive', id: 30 } }
];
}
HTML:
<th>Customer list:</th>
<tr ng-repeat="order in orders | unique: 'customer.id'" >
<td> {{ order.customer.name }} , {{ order.customer.id }} </td>
</tr>
RESULT:
Customer list:
- John 10
- William 20
- Clive 30
Grouping your contacts by textDescription should resolve your problem. Try something like this:
html:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example - GroupBy Filter</title>
<script src="angular-1.4.7.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="app">
<div ng-controller="MainController">
<div ng-repeat="(key, contacts) in (service.contacts | groupBy: 'textDescription')">
<label class="control-label">{{key}}</label>
<select multiple="multiple" selectize>
<option ng-repeat="contact in contacts">{{contact.value}}</option>
</select>
</div>
</div>
</body>
script.js:
var app = angular.module("app", []);
app.controller("MainController", function ($scope) {
$scope.service = {};
$scope.service.contacts = [{
"textDescription": "td1",
"value": "1"
}, {
"textDescription": "td2",
"value": "2"
}, {
"textDescription": "td3",
"value": "3"
}, {
"textDescription": "td1",
"value": "4"
}, {
"textDescription": "td3",
"value": "5"
}, {
"textDescription": "td1",
"value": "6"
}];
});
app.filter('groupBy', function () {
var results={};
return function (data, key) {
if (!(data && key)) return;
var result;
if(!this.$id){
result={};
}else{
var scopeId = this.$id;
if(!results[scopeId]){
results[scopeId]={};
this.$on("$destroy", function() {
delete results[scopeId];
});
}
result = results[scopeId];
}
for(var groupKey in result)
result[groupKey].splice(0,result[groupKey].length);
for (var i=0; i<data.length; i++) {
if (!result[data[i][key]])
result[data[i][key]]=[];
result[data[i][key]].push(data[i]);
}
var keys = Object.keys(result);
for(var k=0; k<keys.length; k++){
if(result[keys[k]].length===0)
delete result[keys[k]];
}
return result;
};
});
Now you have all the contacts grouped by textDescription, so the field for it (<label>) is created only once and the values are added to <option> tags
I am using this https://github.com/Textalk/angular-schema-form plugin to generate my form will not display .I study all documentation and add all js required i didn't get any error but it not display why ?
http://plnkr.co/edit/FO5iEs6ulmP3aR0PW4nt?p=preview
<!DOCTYPE html>
<html >
<head>
<link data-require="bootstrap-css#3.x" data-semver="3.2.0" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" />
<script data-require="angular.js#*" data-semver="1.3.0-beta.5" src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
<script data-require="ui-bootstrap#0.10.0" data-semver="0.10.0" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.10.0.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
<script src="https://dl.dropboxusercontent.com/s/8fq4c4t7jct4w4h/schema-form.js?m="></script>
<script src="https://dl.dropboxusercontent.com/s/unk0id7tmc9w0mm/angular-sanitize.js?m="></script>
<script src="https://dl.dropboxusercontent.com/s/icrciconaesuw29/tv4.js?m="></script>
<script src="https://dl.dropboxusercontent.com/s/rk0dfetihiqs7bi/ObjectPath.js"></script>
</head>
<body>
<div ng-controller="FormController">
<form sf-schema="schema" sf-form="form" sf-model="model"></form>
</div>
<script>
function FormController($scope) {
$scope.schema = {
type: "object",
properties: {
name: { type: "string", minLength: 2, title: "Name", description: "Name or alias" },
title: {
type: "string",
enum: ['dr','jr','sir','mrs','mr','NaN','dj']
}
}
};
$scope.form = [
"*",
{
type: "submit",
title: "Save"
}
];
$scope.model = {};
}
</script>
</body>
</html>
The problem was the javascript plugins included were not in a proper order.
Also use angular.module() to initialize the controller.
JS:
angular.module('test',['schemaForm']).controller('FormController', function($scope,$http){
$scope.schema = {
type: "object",
properties: {
name: { type: "string", minLength: 2, title: "Name", description: "Name or alias" },
title: {
type: "string",
enum: ['dr','jr','sir','mrs','mr','NaN','dj']
}
}
};
$scope.form = [
"*",
{
type: "submit",
title: "Save"
}
];
$scope.model = {};
})
Demo