Kendo Grid Custom Reordering - drag-and-drop

I am using Kendo Grid UI. The following is an example of the same.
<!DOCTYPE html>
<html>
<head>
<title></title>
<link href="http://cdn.kendostatic.com/2013.3.1324/styles/kendo.common.min.css" rel="stylesheet" />
<link href="http://cdn.kendostatic.com/2013.3.1324/styles/kendo.rtl.min.css" rel="stylesheet" />
<link href="http://cdn.kendostatic.com/2013.3.1324/styles/kendo.silver.min.css" rel="stylesheet" />
<link href="http://cdn.kendostatic.com/2013.3.1324/styles/kendo.dataviz.min.css" rel="stylesheet" />
<link href="http://cdn.kendostatic.com/2013.3.1324/styles/kendo.dataviz.silver.min.css" rel="stylesheet" />
<link href="/kendo-ui/content/shared/styles/examples.css" rel="stylesheet" />
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="http://cdn.kendostatic.com/2012.1.515/js/kendo.all.min.js"></script>
</head>
<body>
<div id="main">
<h1 id="exampleTitle">
<span class="exampleIcon gridIcon"></span>
<strong>Grid /</strong> Column resizing </h1>
<div id="theme-list-container"></div>
<div id="exampleWrap">
<script>preventFOUC()</script>
<div id="example" class="k-content">
<div id="grid"></div>
<script>
$(document).ready(function() {
gridDataSource = new kendo.data.DataSource({
transport: {
read: "http://demos.telerik.com/kendo-ui/service/Northwind.svc/Orders"
},
});
$("#grid").kendoGrid({
dataSource: gridDataSource,
scrollable: true,
resizable: true,
columns: [
{
field: "OrderID",
title: "ID"
}, {
field: "OrderDate",
title: "Order Date"
},
{
field: "ShipCountry",
title: "Ship Country"
},
{
field: "ShipCity",
title: "Ship City"
},
{
field: "ShipName",
title: "Ship Name"
},
{
field: "ShippedDate",
title: "Shipped Date"
}
]
});
});
</script>
</div>
</div>
</div>
I want a customized reorder on columns. I have disabled drag and drop on OrderID. But columns other than OrderID can be reordered and these columns can be placed before OrderID column.
Is there a way where I can disable dropping of columns before OrderID?

You should do it in two steps:
Disable dropping into first column.
Disable dragging first column.
For the first part after creating the grid you can do:
$("th:nth(0)", "#grid").data("kendoDropTarget").destroy();
This gets from a grid which identifier is grid and the first head cell th:nth(0) the KendoUI DropTarget and destroys it (no longer a valid drop target).
For the second part, you should define a dragstart event that checks that you are dragging the first column and if so, you do not allow to drag it.
$("#grid").data("kendoDraggable").bind("dragstart", function(e) {
if (e.currentTarget.text() === "ID") {
e.preventDefault();
}
});
NOTE: Here I detected the first column asking for its text (ID) but you might change it to check for its position in the list of th in the grid and if so invoke preventDefault.
Check it running here: http://jsfiddle.net/OnaBai/jzZ4u/1/

check this for more elegant implementation:
kendo.ui.Grid.fn._reorderable = function (reorderable) {
return function () {
reorderable.call(this);
var dropTargets = $(this.element).find('th.disable-reorder');
dropTargets.each(function (idx, item) {
$(item).data("kendoDropTarget").destroy();
});
var draggable = $(this.element).data("kendoDraggable");
if (draggable) {
draggable.bind("dragstart", function (e) {
if ($(e.currentTarget).hasClass("disable-reorder"))
e.preventDefault();
});
}
}
}(kendo.ui.Grid.fn._reorderable);
where .disable-reorder class is for disabling column

Related

Why UI5 controls rendered inside a custom control are not rerendered on property change?

I have created a custom control my.Control that renders a sap.m.Text directly and receives another one by an aggregation.
Paste an example in one file for simplicity:
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
<title>SAPUI5 example</title>
<script id="sap-ui-bootstrap"
src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-theme="sap_belize"
data-sap-ui-libs="sap.m, sap.ui.core"
data-sap-ui-compatVersion="edge"
data-sap-ui-async="true">
</script>
<script>
sap.ui.getCore().attachInit(function () {
sap.ui.core.Control.extend("my.Control", {
metadata: {
aggregations: {
testControl: {
type: 'sap.m.Text',
multiple: false,
singularName: 'testControl'
}
}
},
renderer: function (oRm, oControl) {
oRm.openStart('div', oControl);
oRm.openEnd();
oRm.text('DIRECTLY GENERATED CONTROL : ');
oRm.renderControl(new sap.m.Text('direct-control', {text: 'initial value'}));
oRm.openStart('br');
oRm.openEnd();
oRm.text('AGGREGATION PASSED CONTROL : ');
oRm.renderControl(oControl.getTestControl());
oRm.close('div');
}
});
new my.Control({
testControl: [
new sap.m.Text('passed-control', {text: 'initial value'})
]
}).placeAt('content');
});
</script>
</head>
<body class="sapuiBody" id="content">
</body>
</html>
Both load OK. But when editing its text property via Javascript the passed control is updated and the other one is not:
sap.ui.getCore().byId('passed-control').setText('edited value')
Control is rerendered
sap.ui.getCore().byId('direct-control').setText('edited value')
Control is not rerendered
If I execute sap.ui.getCore().byId('direct-control').rerender() then "direct-control" is rerendered with "edited value" as text.
Why do they behave differently?
Is there a way to configure this behaviour?
Thanks.

Cell in ag-grid not clickable using a tags

I have 3 columns in an ag-grid (version 23.2.0). First column and third column should be clickable to a modal.
The 3rd column has a FA pencil and works fine.
The 1st column has a name. The name is displayed but there is no clickable behavior.
I have included the code below:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="Components" content="">
<meta name="Bryan Schmiedeler" content="">
<link rel="icon" href="../../favicon.ico">
<link rel="canonical" href="https://getbootstrap.com/docs/3.4/examples/navbar-fixed-top/">
<!-- Latest compiled and minified Bootstrap CSS -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<!-- Font Awesome CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<!-- jQuery-->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<!-- Popper.js, -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<!-- Bootstrap.js, -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<!-- ag-Grid.js, -->
<script src="https://unpkg.com/#ag-grid-enterprise/all-modules#23.2.0/dist/ag-grid-enterprise.min.js"></script>
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<script>
var columnDefs = [
{headerName: "Trucker Name", field: "name",cellRenderer: 'activateCellRenderer2', width:250, colSpan: function(params) {
return params.data === 2 ? 3 : 1;
},},
{headerName: "Businesses", field: "model", minWidth: 200,
maxWidth: 350, flex: 2,},
{headerName: "Actions", field: "price",type:"rightAligned", cellRenderer: 'activateCellRenderer',flex: 1}
];
// specify the data
var rowData = [
{name: "Ben Christy", model: "Salina", price: "A"},
{name: "Cindy Blideman", model: "Pratt", price: "I"},
{name: "Wes Woodson", model: "Waverly", price: "A"},
{name: "Bryan Schmiedeler", model: "Overland Park", price: "A"}
];
// let the grid know which columns and what data to use
var gridOptions = {
defaultColDef: {
resizable: true
},
columnDefs: columnDefs,
domLayout: 'autoHeight',
components: {
'activateCellRenderer': ActivateCellRenderer,
'activateCellRenderer2': ActivateCellRenderer2
},
rowData: rowData,
};
// cell renderer class
function ActivateCellRenderer() {
}
// init method gets the details of the cell to be renderer
ActivateCellRenderer.prototype.init = function(params) {
this.eGui = document.createElement('div');
this.eGui.innerHTML = '<a data-toggle="modal" href="#myModal">\
<i class="fa fa-pencil"</i>\
</a>'
};
ActivateCellRenderer.prototype.getGui = function() {
return this.eGui;
};
// cell renderer class
function ActivateCellRenderer2() {
}
// init method gets the details of the cell to be renderer
ActivateCellRenderer2.prototype.init = function(params) {
this.eGui = document.createElement('div');
this.eGui.innerHTML = '<a data-toggle="modal" href="#myModal">'; this.eGui.innerHTML += params.value;
this.eGui.innerHTML += '</a>';
};
ActivateCellRenderer2.prototype.getGui = function() {
return this.eGui;
};
document.addEventListener('DOMContentLoaded', function() {
var gridDiv = document.querySelector('#myGrid');
new agGrid.Grid(gridDiv, gridOptions);
});
</script>
</head>
<body>
<div class = "container"; style= "width: 100%";>
<div class = "row">
<div id="myGrid" class="ag-theme-alpine" style="width: 100%";></div>
</div>
</div>
<body>
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha384-nvAa0+6Qg9clwYCGGPpDQLVpLNn0fRaROjHqs13t4Ggj3Ez50XnGQqc/r8MhnRDZ" crossorigin="anonymous"></script>
<script src="../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../assets/js/ie10-viewport-bug-workaround.js"></script>
</body>
</html>
JS is not happy with the way you are building innerHTML. If you do not close the tag in one line then JS will do it for you and will ignore any matching closing tag it encounters later.
do it this way and cell will render like link and will be clickable.
this.eGui.innerHTML = '<a data-toggle="modal" href="#myModal">' + params.value + '</a>';
here is a fiddle containing your code snippet.
https://jsfiddle.net/dnfb0wop/
also check out this image explaining innerHTML fiasco.

Polymer conditional class derived from child component

I'm learning Polymer;
I can't get a conditional class name to appear in my tabs (parent) component. A 'active' class should be added to a <li> element depending on the 'selected' property of a child component.
I'm not really sure my way of communicating between parent and child component is right in the first place. It is working, but it doesn't feel right..
My index.html file
<link rel="import" href="components/tabs.html">
<link rel="import" href="components/tab.html">
<ikb-tabs>
<ikb-tab heading="Tab #1">
<p>Content of the first tab</p>
</ikb-tab>
<ikb-tab heading="Tab #2" selected>
<p>Content of the second tab</p>
</ikb-tab>
</ikb-tabs>
My components/tabs.html file
<link rel="import" href="../../bower_components/polymer/polymer.html">
<dom-module id="ikb-tabs">
<template>
<style>
.active button {
color: red;
}
</style>
<nav>
<ul>
<template is="dom-repeat" items="{{tabs}}">
<li>
<button on-tap="openTab">{{item.heading}}</button>
</li>
</template>
</ul>
</nav>
<content></content>
</template>
<script>
Polymer({
is: 'ikb-tabs',
properties: {
activeTab: Number
},
ready: function () {
this.tabs = Polymer.dom(this).children;
},
openTab: function (e) {
Polymer.dom(this).children.forEach(function (tab, index) {
tab.selected = index === e.model.index;
});
}
});
</script>
</dom-module>
My components/tab.html file
<link rel="import" href="../../bower_components/polymer/polymer.html">
<dom-module id="ikb-tab" attributes="heading">
<template>
<template is="dom-if" if="{{selected}}">
<div>
<content></content>
</div>
</template>
</template>
<script>
Polymer({
is: 'ikb-tab',
properties: {
heading: String,
selected: {
type: Boolean
}
}
});
</script>
</dom-module>
I've figured it out myself, there were two main issues with my code:
Updating an Array didn't trigger an update:
Only adding, removing are replacing items in an Array triggers an update. I changed a property of an Object inside an Array. Polymer only checks the reference to that Object, that reference remained unchanged. So no change got triggered. Solution: update the Array with the set function (see code below).
Computed classes need a special syntax:
My class="{{getClassName(item.selected}}" wasn't adding any classes. I now know the correct syntax is class$="{{getClassName(item.selected)}}".
More info: https://www.polymer-project.org/1.0/docs/devguide/data-binding#native-binding
The simplified working code:
<dom-module id="ikb-tabs">
<template>
<nav>
<ul>
<template is="dom-repeat" items="{{tabs}}">
<li class$="{{getClassName(item.selected)}}">
<button on-tap="openTab">{{item.heading}}</button>
</li>
</template>
</ul>
</nav>
<div>
<content></content>
</div>
</template>
<script>
Polymer({
is: 'ikb-tabs',
properties: {
tabs: {
type: Array
}
},
ready: function () {
this.tabs = Polymer.dom(this).children;
},
openTab: function (e) {
var self = this;
this.tabs.forEach(function (tab, index) {
self.set('tabs.' + index + '.selected', index === e.model.index)
});
},
getClassName: function (isSelected) {
return isSelected ? 'active' : null;
}
});
</script>
</dom-module>

Ionic ng-click will be executed after on-hold

I have a problem with elements which has the ng-click and on-hold property. The problem is after on-hold event the ng-click event will be executed.
I think this is a common issue and I hope there is a solution for this.
Example:
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link href="lib/ionic/css/ionic.min.css" rel="stylesheet">
<script src="lib/ionic/js/ionic.bundle.min.js"></script>
<script src="js/ListCtrl.js"></script>
<script src="js/app.js"></script>
</head>
<body ng-app="starter">
<ion-nav-bar class="bar-positive">
</ion-nav-bar>
<ion-nav-view></ion-nav-view>
</body>
</html>
list.html
<ion-view view-title="Test">
<ion-content>
<ion-list show-delete="data.deleteMode">
<ion-item class="item-icon-right"
ng-repeat="item in items track by $index"
on-hold="data.deleteMode = ! data.deleteMode;"
ng-click="onClick(item)">
<ion-delete-button class="ion-trash-a" ng-click="onRemoveTaskBtn(task)"></ion-delete-button>
<p>{{item.text}}</p>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
app.js
angular.module('starter', [
'ionic',
'starter.list'
]).run(function ($ionicPlatform) {
$ionicPlatform.ready(function () {
});
}).config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/list');
});
ListCtrl.js
angular.module('starter.list', [])
.config(function ($stateProvider) {
$stateProvider.state('list', {
url: '/list',
templateUrl: 'js/list.html',
controller: 'ListCtrl'
});
}).controller('ListCtrl', [
'$scope',
function ($scope) {
$scope.data = {
deleteMode : false
};
$scope.items = [
{ text : 'Text 1' },
{ text : 'Text 2' },
{ text : 'Text 3' },
{ text : 'Text 4' },
{ text : 'Text 5' }
];
$scope.onClick = function(item) {
console.log('Clicked on item with text: ' + item.text);
}
}
]);
Just found exactly the same problem.
The solution is to use the on-tap instead of the ng-click.
For what I've seen, Ionic classifies its events on tap duration and stop propagating the event to its own listeners. Since ng-click is not a Ionic event, the event will be propagated.

How to trigger a button as clicked present inside "template" tag using jquery

I've created a simple "helloworld" web component, in that I put a "button" tag and I want that button to be clicked by triggering it but i'm unable to trigger it. What am I doing wrong?
Here is my code for "Index.html" file in which i've called my Own component and values for my button:
<!doctype html>
<html>
<head>
<title>First Polymer component</title>
<script src="bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<script src="bower_components/lib/jquery-1.11.2.js"></script>
<link rel="stylesheet" type="text/css" href="bootstrap_theme/css/bootstrap.css" />
<link rel="stylesheet" type="text/css" href="bootstrap_theme/css/bootstrap-theme.css" />
<script src="bootstrap_theme/js/bootstrap.js"></script>
<link rel="import" href="hello-world.html">
<script>
var button_data = [{
"name": "litrary vocabulary",
"span_id": "mostbasic",
"description": "This is a sample description about litrary vocabulary"
}, {
"name": "no contractions",
"description": "This is a sample description about no contractions"
}];
window.addEventListener('WebComponentsReady', function(e) {
var element = document.querySelector('hello-world');
element.buttonsdata = button_data;
});
</script>
</head>
<body>
<hello-world> </hello-world>
<script>
$('.answerButtons').trigger("click");
function k12() {
window.open("http://www.w3schools.com");
}
</script>
</body>
</html>
And the 2nd file contain code for my web component:
<link rel="import" href="bower_components/polymer/polymer.html">
<dom-module id="hello-world">
<style>
p {
color: red;
}
</style>
<template>
<template is="dom-repeat" items="{{buttonsdata}}" as="button_data">
<button type="button" class="btn btn-info answerButtons" onclick = "k12()">{{_getButtonName(button_data)}} </button>
</template>
<p>This is my first own component </p>
<p>This is my first ....... </p>
<p>Kumaran is IDIOT </p>
</template>
<script>
Polymer({
is: 'hello-world',
_getButtonName: function(buttondata) {
return buttondata.name;
}
});
</script>
</dom-module>
button_data should be a property in hello-world
onclick should be on-click for Polymer binding https://www.polymer-project.org/1.0/docs/devguide/events.html