How can I save the order of the tree? - javascript

It's a little bit complicated to explain. I would like to save the position on which the tree has been repositioned, and then when the user opens the page again it will appear the way the user left it (I do not want to make it only for one user but for all, because only the admin is going to have access to it anyway). it sounds ununderstandable, that's why I made an example right below:
Simplifying: 1 - Get the order of the tree's elements that the user left
2 - Send it to my server as a text file (Probably Ajax)
Thus, when I reload the page or/and clean up the cache, it will still be in that position that I left. I want the "position" to be sent as a text file using ajax to my server. Is there a way to do it?
Thanks in advance.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="./tree.jquery.js"></script>
<link rel="stylesheet" href="./jqtree.css">
<script src="./jquery-cookie/src/jquery.cookie.js"></script>
<style>
body{overflow-x:hidden}
#navdata{width:auto; height:auto; flex:1; padding-bottom:1px;}
#navgrid{width:50%; height:200px; overflow-x:hidden; overflow-y:scroll; border:solid 1px #79B7E7; background-color:white;}
#header{background-color: #79B7E7; width:100%; text-align: center;border: 1px solid white;}
.jqtree-element{background-color:#DDEBF7;border: 1px solid white;height:23px;color:red;}
.jqtree-tree .jqtree-title {color: black;}
ul.jqtree-tree ul.jqtree_common {margin-left: 0px;}
ul.jqtree-tree .jqtree-toggler {color: #325D8A;}
ul.jqtree-tree .jqtree-toggler:hover {color: #3966df;text-decoration: none;}
.jqtree-tree .jqtree-title.jqtree-title-folder {margin-left: 0;}
span.jqtree-dragging {background: #79B7E7;}
ul.jqtree-tree li.jqtree-selected > .jqtree-element,ul.jqtree-tree li.jqtree-selected > .jqtree-element:hover {background: -webkit-gradient(linear, left top, left bottom, from(#BEE0F5), to(#79B7E7));}
</style>
</head>
<body>
<div id="navgrid">
<div id="header">Header</div>
<div id="tree1"></div>
</div>
</body>
<script type="text/javascript">
var ExampleData = {};
ExampleData.data = [
{
label: 'node1', id: 1,
children: [
{ label: 'child1', id: 2 },
{ label: 'child2', id: 3 }
]
},
{
label: 'node2', id: 4,
children: [
{ label: 'child3', id: 5 }
]
}
];
ExampleData.getFirstLevelData = function(nodes) {
if (! nodes) {
nodes = ExampleData.example_data;
}
var data = [];
$.each(nodes, function() {
var node = {
label: this.label,
id: this.id
};
if (this.children) {
node.load_on_demand = true;
}
data.push(node);
});
return data;
}
ExampleData.getChildrenOfNode = function(node_id) {
var result = null;
function iterate(nodes) {
$.each(nodes, function() {
if (result) {
return;
}
else {
if (this.id == node_id) {
result = this;
}
if (this.children) {
iterate(this.children);
}
}
});
}
iterate(ExampleData.example_data);
return ExampleData.getFirstLevelData(result.children);
}
$('#tree1').tree({
data: ExampleData.data,
autoOpen: false,
dragAndDrop: true
});
</script>
</html>

I think earlier i got your question wrong. This will be your answer.
$(document).ready(function(){
//var data is a dynamic json file that should be created in the backend.
var data = [
{
label: 'node1', id: 1,
children: [
{ label: 'child1', id: 2 },
{ label: 'child2', id: 3 }
]
},
{
label: 'node2', id: 4,
children: [
{ label: 'child3', id: 5 }
]
}
];
$('#tree1').tree({
data: data,
autoOpen: true,
dragAndDrop: true
});
console.log($('#tree1').tree('toJson')); //This will give you the loading jqtree structure.
$('#tree1').bind(
'tree.move',
function(event) {
event.preventDefault();
// do the move first, and _then_ POST back.
event.move_info.do_move();
console.log($(this).tree('toJson')); //this will give you the latest tree.
// $.post('your_url', {tree: $(this).tree('toJson')}); //this will post the json of the latest tree structure.
}
);
});

Updating the Code with HTML/JS/PHP with
Folder Structure
Root Folder
stackoverflow-2.html
libs/jquery/jquery.js
libs/jqtree/tree.jquery.js
libs/jqtree/jqtree.css
scripts/stackoverflow-2.js //custom script created by me
json/stackoverflow-2.json //json file output to create the nodes and children.
php/stackoverflow-2.php //php commands to write.
stackoverflow-2.html //same as your reference. Changed only mapping of the library files.
<head>
<script type="text/javascript" src="libs/jquery/jquery.min.js"></script>
<script src="libs/jqtree/tree.jquery.js"></script>
<link rel="stylesheet" href="libs/jqtree/jqtree.css">
<script src="scripts/stackoverflow-2.js"></script>
<style>
body{overflow-x:hidden}
#navdata{width:auto; height:auto; flex:1; padding-bottom:1px;}
#navgrid{width:50%; height:200px; overflow-x:hidden; overflow-y:scroll; border:solid 1px #79B7E7; background-color:white;}
#header{background-color: #79B7E7; width:100%; text-align: center;border: 1px solid white;}
.jqtree-element{background-color:#DDEBF7;border: 1px solid white;height:23px;color:red;}
.jqtree-tree .jqtree-title {color: black;}
ul.jqtree-tree ul.jqtree_common {margin-left: 0px;}
ul.jqtree-tree .jqtree-toggler {color: #325D8A;}
ul.jqtree-tree .jqtree-toggler:hover {color: #3966df;text-decoration: none;}
.jqtree-tree .jqtree-title.jqtree-title-folder {margin-left: 0;}
span.jqtree-dragging {background: #79B7E7;}
ul.jqtree-tree li.jqtree-selected > .jqtree-element,ul.jqtree-tree li.jqtree-selected > .jqtree-element:hover {background: -webkit-gradient(linear, left top, left bottom, from(#BEE0F5), to(#79B7E7));}
</style>
</head>
<body>
<div id="navgrid">
<div id="header">Header</div>
<div id="tree1"></div>
</div>
</body>
stackoverflow-2.js
$(document).ready(function(){
$.ajax({ /*Makes a ajax call and gets the contents from the json file*/
method:"get",
url:"json/stackoverflow-2.json"
}).success(function(data){
$('#tree1').tree({
data: jQuery.parseJSON(data.tree),
autoOpen: true,
dragAndDrop: true
});
});
$('#tree1').bind(
'tree.move',
function(event) {
event.preventDefault();
// do the move first, and _then_ POST back.
event.move_info.do_move();
$.post('php/stackoverflow-2.php', {tree: $(this).tree('toJson')}); //this will post the json of the latest tree structure.
}
);
});
Initial stackoverflow-2.json
{
"tree": [
{
"label": "node1",
"id": 1,
"children": [
{
"label": "child1",
"id": 2
},
{
"label": "child2",
"id": 3
}
]
},
{
"label": "node2",
"id": 4,
"children": [
{
"label": "child3",
"id": 5
}
]
}
]
}
stackoverflow-2.php
<?php
file_put_contents("../json/stackoverflow-2.json", json_encode($_POST)); //calls the file and enters the new tree structure.
Code tested in my localhost.

Referring to the jqtree documentation you can have your code like this.
var lastOpenedByAUser = 0; // make a ajax call to get this value. This value is also stored in database or any file in your server end if the last user clicked another node.
$('#tree1').tree({
data: data,
autoOpen: lastOpenedByAUser //shall be 0 for node-1, 1 for node-2
});
Make sure, you run this $('#tree') code only after the code your ajax code is completed.

Related

How to detect if an element is outside of its container?

So I've created the the following codesandbox. I got a webapp that relies heavily on user input. For demonstration purposes I've kept it simple by displaying a bunch of authors on a a4 formatted page. The page and font-size both use vw unit to make it responsive.
As you can see in the codesandbox, the last few authors are forced off the page because it no longer fits inside the container. Ideally I'd like to detect the content that doesn't fit on the page anymore, and generate a second identical a4 page to display that particular content.
Currently in my webapp I've just added overflow: scroll; to the page div where all the content is placed in, so that it at least looks somewhat 'ok'. But it isn't a very good User Experience and I'd like to improve it.
I don't have a clue where to start so any help in the right direction would be very much appreciated.
Thanks in advance.
CSS
#app {
-webkit-font-smoothing: antialiased;
font: 12pt "Tahoma";
}
.book {
margin: 0;
padding: 0;
background-color: #FAFAFA;
font: 3vw "Tahoma";
}
* {
box-sizing: border-box;
-moz-box-sizing: border-box;
}
.page {
/* overflow: scroll; */
display: block;
width: calc(100 / 23 * 21vw);
height: calc(100 / 23 * 29.7vw);
margin: calc(100 / 23 * 1vw) auto;
border: 1px #D3D3D3 solid;
border-radius: 5px;
background: white;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
}
.subpage {
margin: calc(100 / 23 * 1vw);
width: calc(100 / 23 * 19vw);
height: calc(100 / 23 * 27.7vw);
line-height: 2;
border: 1px solid red;
outline: 0cm #FAFAFA solid;
}
.subpage-content {
height: 100%;
}
Javascript
export default {
name: "App",
data() {
return {
authors: [
{ id: 1, name: "Smith" },
{ id: 2, name: "Johnson" },
{ id: 3, name: "Williams" },
{ id: 4, name: "Jones" },
{ id: 5, name: "Brown" },
{ id: 6, name: "Davis" },
{ id: 7, name: "Miller" },
{ id: 8, name: "Wilson" },
{ id: 9, name: "Moore" },
{ id: 10, name: "Taylor" },
{ id: 11, name: "Anderson" },
{ id: 12, name: "Thomas" },
{ id: 13, name: "Jackson" },
{ id: 14, name: "White" },
{ id: 15, name: "Harris" },
{ id: 16, name: "Martin" },
{ id: 17, name: "Thomspson" },
{ id: 18, name: "Garcia" },
{ id: 19, name: "Martinez" },
{ id: 20, name: "Robinson" },
{ id: 21, name: "Clark" },
{ id: 22, name: "Rodeiquez" },
{ id: 23, name: "Lewis" },
{ id: 24, name: "Lee" }
]
};
}
};
HTML
<template>
<div id="app">
<div class="container-fluid">
<div class="book">
<div class="page">HEADER
<div class="subpage" id="editor-container">Authors:
<!-- <div class="subpage-content">The real content</div> -->
<div v-for="item in authors" :key="item.id">{{ item.name }}</div>
</div>
</div>
</div>
</div>
</div>
</template>
You can view a fork of your code sandbox here.
I changed the data structure (and template) to have a pages array in which each page has an authors array, instead of a single one. Initially, the first page holds all the authors.
data() {
return {
pages: [
{
authors: [
{ id: 1, name: "Smith" },
...
]
}
]
}
}
<div class="page" v-for="(page, pageIndex) in pages" :key="pageIndex">HEADER
<div class="subpage" id="editor-container">
<template v-if="pageIndex < 1">Authors:</template>
<!-- <div class="subpage-content">The real content</div> -->
<div v-for="item in page.authors" :key="item.id" class="author">{{ item.name }}</div>
</div>
</div>
I then created a method recalcPages that gets called when the component is mounted:
methods: {
recalcPages() {
let pageElements = this.$el.querySelectorAll(".page");
Array.from(pageElements).some((p, pi) => {
let authors = p.querySelectorAll(".author");
if (authors.length) {
return Array.from(authors).some((a, ai) => {
let offPage = a.offsetTop + a.offsetHeight > p.offsetHeight;
if (offPage) {
let currentAuthors = this.pages[pi].authors;
var p1 = currentAuthors.slice(0, ai);
var p2 = currentAuthors.slice(ai);
this.pages[pi].authors = p1;
this.pages.push({ authors: p2 });
}
return offPage;
});
}
return false;
});
}
},
It iterates the actual DOM nodes and uses offsetTop + offsetHeight to calculate whether an author is off the page or not. As soon as an element leaves the page, it and all following elements are split from the current page's authors and a second page is inserted.
You'll also need to call this.recalcPages() after updating the contents deleting all pages and set a new authors array on the first one to be split up automatically again, unless you're only adding to the last page. You could also try to use the updated hook to achieve this automatically, I haven't tried that.
Of course it's quite a heavy operation, as it renders the component just to trigger re-rendering again by modifying the data. But unless you don't know the exact height of every element, there's no way around it (at least none I'm aware of).
By the way (although your final data will probably look different, but just for the sake of completeness of this demonstration) I also wrapped your Authors: headline in <template v-if="pageIndex < 1">Authors:</template> in order to display it only on the first page.

How to dynamically render a tree of data in svelte?

I have a tree of data that i'm using to represent a directory of the file system. It look something like this.
{
isRoot: true
path: "/path/to/dir"
fileName: "dir",
isDirectory: true,
parent: null,
children: [
{
isRoot: false
path: "/path/to/dir/file1.txt"
fileName: "file1.txt",
isDirectory: true,
parent: {...spread parent node here},
children: null
},
{
isRoot: false
path: "/path/to/dir/subdir"
fileName: "subdir",
isDirectory: true,
parent: {...spread parent node here},
children: [
{
isRoot: false
path: "/path/to/dir/subdir/file2.txt"
fileName: "file2.txt",
isDirectory: false,
parent: {...spread parent node here},
children: null
}
]
}
]
}
I want to take each node and turn it into this.
<Node branch={some parent from that tree} >
<Node branch={a child of that parent} />
<Node branch={another child of that parent>
<Node branch={a child of the new parent />
</Node>
</Node
I know that svelte allows you to loop through arrays and render content based on each item however there is no way of knowing what the tree looks like.
Is there any way to dynamically render this tree in svelte?
This unanswered question came up in a search two years after being asked, so I'll go ahead and answer it while I'm here. The comments on the question just needed to be filled out to become a proper answer.
As the comments to your question have already explained, you'll need to use the recursive <svelte:self> component. It represents the component that is being defined in that particular module. In other words, if you are defining a <Folder> component and want to have other folders inside it, you would refer to them as <svelte:self> inside the definition of <Folder>. This is because a module cannot import itself.
The Svelte Tutorial has a specific module on this exact scenario, so everyone who writes code in Svelte should go through the entire tutorial (it's not long) and learn the basics of Svelte. You would want to do something quite similar to the example.
Here is the example shown in the tutorial:
App.svelte
<script>
import Folder from './Folder.svelte';
let root = [
{
name: 'Important work stuff',
files: [
{ name: 'quarterly-results.xlsx' }
]
},
{
name: 'Animal GIFs',
files: [
{
name: 'Dogs',
files: [
{ name: 'treadmill.gif' },
{ name: 'rope-jumping.gif' }
]
},
{
name: 'Goats',
files: [
{ name: 'parkour.gif' },
{ name: 'rampage.gif' }
]
},
{ name: 'cat-roomba.gif' },
{ name: 'duck-shuffle.gif' },
{ name: 'monkey-on-a-pig.gif' }
]
},
{ name: 'TODO.md' }
];
</script>
<Folder name="Home" files={root} expanded/>
File.svelte
<script>
export let name;
$: type = name.slice(name.lastIndexOf('.') + 1);
</script>
<span style="background-image: url(/tutorial/icons/{type}.svg)">{name}</span>
<style>
span {
padding: 0 0 0 1.5em;
background: 0 0.1em no-repeat;
background-size: 1em 1em;
}
</style>
And finally, Folder.svelte:
<script>
import File from './File.svelte';
export let expanded = false;
export let name;
export let files;
function toggle() {
expanded = !expanded;
}
</script>
<span class:expanded on:click={toggle}>{name}</span>
{#if expanded}
<ul>
{#each files as file}
<li>
{#if file.files}
<svelte:self {...file}/>
{:else}
<File {...file}/>
{/if}
</li>
{/each}
</ul>
{/if}
<style>
span {
padding: 0 0 0 1.5em;
background: url(/tutorial/icons/folder.svg) 0 0.1em no-repeat;
background-size: 1em 1em;
font-weight: bold;
cursor: pointer;
}
.expanded {
background-image: url(/tutorial/icons/folder-open.svg);
}
ul {
padding: 0.2em 0 0 0.5em;
margin: 0 0 0 0.5em;
list-style: none;
border-left: 1px solid #eee;
}
li {
padding: 0.2em 0;
}
</style>

How to get a row in Kendo UI TreeList / Grid?

I have a Kendo TreeList where I search for the row where myDataItem is (with help of the uid or value).
When I execute:
$("#treeList tbody").on("click", "tr", function (e) {
var rSelectedRow = $(this);
var getSelect = treeList.select();
console.log("'real' selected row: "+rSelectedRow);
console.log("selected row: "+getSelect);
});
and in another function, where I want to get a row (not the selected one, just a row where myDataItem is):
var grid = treeList.element.find(".k-grid-content");
var myRow = grid.find("tr[data-uid='" + myDataItem.uid + "']"));
//or
// myRow = treeList.content.find("tr").eq(myDataItem.val);
console.log("my row:" + myRow)
I get:
'real' selected row: Object [ tr.k-alt ... ]
selected row: Object { length: 0 ... }
my row: Object { length: 0 ... }
I need the same structure of rSelectedRow for myRow. So how can I get the ,real' tr-element?
UPDATE: I wrote this method to find the row of my new added item:
//I have an id of the item and put it in an invisible row in the treelist.
getRowWhereItem: function (itemId) {
treeList.dataSource.read();
$("#menuItemTree .k-grid-content tr").each(function (i) {
var rowId = $(this).find('td:eq(1)').text();
console.log(itemId);
console.log(rowId);
if (rowId == itemId) {
console.log("found");
console.log(itemId + " " + rowId);
var row = this;
console.log(row);
return row;
}
});
},
The each-iteration reaches all tr's until/except the new added one. Why?
Use the change event instead of binding a click event to the widget's DOM. Note that for change to work, you need to set selectable to true:
<!-- Orginal demo at https://demos.telerik.com/kendo-ui/treelist/index -->
<!DOCTYPE html>
<html>
<head>
<base href="https://demos.telerik.com/kendo-ui/treelist/index">
<style>html { font-size: 14px; font-family: Arial, Helvetica, sans-serif; }</style>
<title></title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.911/styles/kendo.common-material.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.911/styles/kendo.material.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.911/styles/kendo.material.mobile.min.css" />
<script src="https://kendo.cdn.telerik.com/2018.3.911/js/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2018.3.911/js/kendo.all.min.js"></script>
</head>
<body>
<div id="example">
<div id="treelist"></div>
<script id="photo-template" type="text/x-kendo-template">
<div class='employee-photo'
style='background-image: url(../content/web/treelist/people/#:data.EmployeeID#.jpg);'></div>
<div class='employee-name'>#: FirstName #</div>
</script>
<script>
$(document).ready(function() {
var service = "https://demos.telerik.com/kendo-ui/service";
$("#treelist").kendoTreeList({
dataSource: {
transport: {
read: {
url: service + "/EmployeeDirectory/All",
dataType: "jsonp"
}
},
schema: {
model: {
id: "EmployeeID",
parentId: "ReportsTo",
fields: {
ReportsTo: { field: "ReportsTo", nullable: true },
EmployeeID: { field: "EmployeeId", type: "number" },
Extension: { field: "Extension", type: "number" }
},
expanded: true
}
}
},
height: 540,
filterable: true,
sortable: true,
columns: [
{ field: "FirstName", title: "First Name", width: 280,
template: $("#photo-template").html() },
{ field: "LastName", title: "Last Name", width: 160 },
{ field: "Position" },
{ field: "Phone", width: 200 },
{ field: "Extension", width: 140 },
{ field: "Address" }
],
pageable: {
pageSize: 15,
pageSizes: true
},
/* See here */
selectable: true,
change: function() {
let $selectedItem = this.select(),
dataItem1 = this.dataItem($selectedItem),
uid1 = $selectedItem.data("uid"),
uid2 = dataItem1.uid,
dataItem2 = this.dataSource.getByUid(uid1);
console.log("selected item", $selectedItem);
console.log("dataItem", dataItem1);
console.log("dataItem(alternative way)", dataItem2);
console.log("uid", uid1);
console.log("uid(alternative way)", uid2);
}
});
});
</script>
<style>
.employee-photo {
display: inline-block;
width: 32px;
height: 32px;
border-radius: 50%;
background-size: 32px 35px;
background-position: center center;
vertical-align: middle;
line-height: 32px;
box-shadow: inset 0 0 1px #999, inset 0 0 10px rgba(0,0,0,.2);
margin-left: 5px;
}
.employee-name {
display: inline-block;
vertical-align: middle;
line-height: 32px;
padding-left: 3px;
}
</style>
</div>
</body>
</html>
The part that really matters:
selectable: true,
change: function() {
let $selectedItem = this.select(),
dataItem1 = this.dataItem($selectedItem),
uid1 = $selectedItem.data("uid"),
uid2 = dataItem1.uid,
dataItem2 = this.dataSource.getByUid(uid1);
console.log("selected item", $selectedItem);
console.log("dataItem", dataItem1);
console.log("dataItem(alternative way)", dataItem2);
console.log("uid", uid1);
console.log("uid(alternative way)", uid2);
}
Demo
I didn't find a solution where I can get the tr by datauid.
But in my case, I took the id of the item and put it in an invisible row in the treelist.
Therefore, the method getRowWhereItem(itemId) in the question works well when making it execute after a successfull Ajax Call. With the callback from my ajax call, I load the new item and then the method can find the row. So the issue was that I had to have the uptodate data from my database.
Another issue was with contexts. The method getRowWhereItem(itemId) was a method of a namespace. I tried to call that method outside the namespace and couldn't get its return. Now, I moved the method into the same context where I call it.
(note: My development follows the MVC pattern, Administration is a Controller-class)
$.ajax({
url: General.createMethodUrl("Administration", "Admin", "Add_New"),
data: { parentItemId: parentOfNewId },
type: "POST",
dataType: "json",
success: function (response) {
if (response) {
var addedItem = $.parseJSON(response);
//waiting for callback because otherwise the window opens a few milliseconds before the properties are loaded and newRow cannot be find
tManag.ajaxCallSelectedEntry(addedItem.Id, treeList, function () {
newRow = tManag.getRowWhereItem(addedItem.Id);
});
jQuery(newRow).addClass("k-state-selected")
} else {
tManag.alertDialog(dialog, "Adding New Item Notification", response.responseText);
}
},
error: function (response) {
tManag.alertDialog(dialog, "Adding New Item Error", "Error");
}
});

dynamic datasource in GetOrgChart

I am new to programming I am working on dynamic organization hierarchy chart using GetOrgChart. I want to remove hard code values in java script function and pass my mysql query result data in to javascript function i have get data from database through query and converted it in to json format to display in javascript function.
Here is my code :
<?php
require ('db.php');
$selectSql = "SELECT
emp.id, emp.employee_parent_id, emp.emp_name,
emp.email,hd.desg_name
FROM
hr_employees emp
LEFT JOIN
hr_employees_designations empd ON emp.id = empd.id
LEFT JOIN
hr_designations hd ON empd.id = hd.id";
$result = mysqli_query($conn, $selectSql);
$arrAssociate = [];
while ($value = mysqli_fetch_assoc($result))
{
$json_array = json_encode($value);
echo $json_array;
//echo '<pre>', print_r($value, 1) , '</pre>';
}
?>
<!DOCTYPE html>
<html>
<head>
<title>OrgChart | Create Your Own Theme 3</title>
<style type="text/css">
html, body {
margin: 0px;
padding: 0px;
width: 100%;
height: 100%;
overflow: hidden;
}
#people {
width: 100%;
height: 100%;
}
.get-org-chart rect.get-box {
fill: #ffffff;
stroke: #D9D9D9;
}
.get-org-chart .get-text.get-text-0 {
fill: #262626;
}
.get-org-chart .get-text.get-text-1 {
fill: #262626;
}
.get-org-chart .get-text.get-text-2 {
fill: #788687;
}
.get-green.get-org-chart {
background-color: #f2f2f2;
}
.more-info {
fill: #18879B;
}
.btn path {
fill: #F8F8F8;
stroke: #D9D9D9;
}
.btn {
cursor: pointer;
}
.btn circle {
fill: #555555;
}
.btn line {
stroke-width: 3px;
stroke: #ffffff;
}
</style>
</head>
<body>
<div id="people"></div>
<script type="text/javascript">
getOrgChart.themes.myTheme =
{
size: [330, 260],
toolbarHeight: 46,
textPoints: [
{ x: 20, y: 45, width: 300 },
{ x: 120, y: 100, width: 200 },
{ x: 120, y: 125, width: 200 }
],
// textPointsNoImage: [] NOT IMPLEMENTED,
box: '<rect x="0" y="0" height="260" width="330" rx="10" ry="10"
class="get-box"></rect>'
+ '
<g transform="matrix(0.25,0,0,0.25,123,142)"><path
d="M48.014,42.889l-9.553-
4.776C37.56,37.662,37,36.756,37,35.748v-3.381c0.229-0.28,0.47-
0.599,0.719-0.951 c1.239-1.75,2.232-3.698,2.954-
5.799C42.084,24.97,43,23.575,43,22v-4c0-0.963-0.36-1.896-1-
2.625v-5.319 c0.056-0.55,0.276-3.824-2.092-
6.525C37.854,1.188,34.521,0,30,0s-7.854,1.188-
9.908,3.53C17.724,6.231,17.944,9.506,18,10.056 v5.319c-
0.64,0.729-1,1.662-
};
var orgChart = new getOrgChart(document.getElementById("people"), {
theme: "myTheme",
enableEdit: false,
enableDetailsView: false,
primaryFields: ["Title", "Name", "Email", "Image"],
color: "green",
updatedEvent: function () {
init();
},
dataSource: [
// Want Dynamic data here instead of this hard code values
{ id : 1,
parentId : null,
Name : "Jasper Lepardo",
Title : "CEO",
Email : "jasper#example.com",
Image :
"http://www.getorgchart.com/GetOrgChart/getorgchart-
demos/images/f-11.jpg"
},
{ id : 2,
parentId : 1,
Name : "John Smith",
Title : "Front-endDeveloper",
Email : "john#example.com",
Image :
"http://www.getorgchart.com/GetOrgChart/getorgchart
demos/images/f-12.jpg"
},
{ id : 3,
parentId : 1,
Name : "Avaa Field",
Title : "Project Manager",
Email : "ava#example.com",
Image :
"http://www.getorgchart.com/GetOrgChart/getorgchart-demos/images/f-
14.jpg"
},
{ id : 4,
parentId : 1,
Name : "Ava Field",
Title : "Project Manager",
Email : "ava#example.com",
Image :
"http://www.getorgchart.com/GetOrgChart/getorgchart-demos/images/f-
14.jpg" }]
});
function getNodeByClickedBtn(el) {
while (el.parentNode) {
el = el.parentNode;
if (el.getAttribute("data-node-id"))
return el;
}
return null;
}
var init = function () {
var btns = document.getElementsByClassName("btn");
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", function () {
var nodeElement = getNodeByClickedBtn(this);
var action = this.getAttribute("data-action");
var id = nodeElement.getAttribute("data-node-id");
var node = orgChart.nodes[id];
switch (action) {
case "add":
orgChart.insertNode(id);
break;
case "edit":
orgChart.showEditView(id);
break;
case "preview":
orgChart.showDetailsView(id);
break;
}
});
}
}
init();
</script>
</body>
</html>
Look at this.
Using Laravel (Blade):
let json = JSON.parse('#json($your_array_here)');
No Framework (your case):
let json = JSON.parse('<?=json_encode($your_array_here)?>');
When you have an Array in PHP and need to use it in JS, you have two ways to implement:
Ajax (fetch, axios, xhr2);
Hard coding like you did.
But pay attention to you browser Console (Chrome, Firefox), you will be warned if your JSON is malformatted.
Take a look at JSON.parse and JSON.stringify, it is important to understand this functions too.
And don't forget the ' in the beginning and at the end of the declaration, like I did in the example below.
Hope it helps you.
Have a nice day.

Kendo Grid command column - how to replace buttons with icons?

I have locked command column in the Grid (see image below).
I would like to replace default buttons with custom icons (or with set of icons supplied with Kendo).
How can I easily do it?
I tried to find something in documentation but without luck.
Thanks for any advice.
EDIT: added button code
command:
[
{
name: "destroy",
text: $translate.instant('REMOVE'),
className: "btn-destroy"
},
{
name: "detail",
text: $translate.instant('DETAIL'),
click: function(e) {
var clickedRow = this.dataItem($(e.currentTarget).closest("tr"));
var id = clickedRow.id;
GlobalHelperService.redirectTo("/milestone-sequences/detail/"+id);
return false;
}
}
],
You can also use imageClass or iconClass within the command. I'm not sure what the difference is, but either one seems to work.
Thanks OnaBai, for the working example that I could fork.
Note, I added the FontAwesome stylesheet to easily swap out the icon via a class.
$(document).ready(function(e) {
$("#grid").kendoGrid({
columns: [
{ field: "name" },
{
command: [
{
name: "onabai",
text: " ",
imageClass: "fa fa-trash",
//iconClass: "fa fa-trash",
click: function (e) {
alert ("clicked");
}
}
]
}
],
dataSource: [ { name: "Jane Doe" } ]
});
});
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1316/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1316/styles/kendo.default.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://cdn.kendostatic.com/2014.3.1316/js/kendo.web.min.js"></script>
<div id="grid"></div>
If you don't want to manipulate the HTML generated by KendoUI you can simply play with the definition and CSS.
If your command definition is something like:
columns: [
{
command: [
{
name: "onabai",
text: " ",
click: function (e) {
alert ("clicked");
}
},
...
]
},
...
You can define the following CSS for changing the button to only your custom icon:
.k-grid-onabai, .k-grid-onabai:hover {
background-image: url(http://cdn.kendostatic.com/2014.3.1316/styles/Default/sprite_2x.png);
background-position: 192px -248px;
min-width: 32px !important;
min-height: 32px !important;
}
i.e. set text to an empty space ( ) and if the name of the command is onabai you need to define there the styles k-grid-onabai and k-grid-onabai:hover.
A running example following:
$(document).ready(function(e) {
$("#grid").kendoGrid({
columns: [
{ field: "name" },
{
command: [
{
name: "onabai",
text: " ",
click: function (e) {
alert ("clicked");
}
}
]
}
],
dataSource: [ { name: "Jane Doe" } ]
});
});
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1316/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1316/styles/kendo.default.min.css">
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://cdn.kendostatic.com/2014.3.1316/js/kendo.web.min.js"></script>
<div id="grid"></div>
<style>
.k-grid-onabai, .k-grid-onabai:hover {
background-image: url(http://cdn.kendostatic.com/2014.3.1316/styles/Default/sprite_2x.png);
background-position: 192px -248px;
min-width: 32px !important;
min-height: 32px !important;
}
</style>
The easy way : Just add the bootstrap icons on text property and override imageClass and iconClass with ""
command: [{
name: "destroy",
text: "<span class='glyphicon glyphicon-remove'></span>",
imageClass: "",
iconClass: "",
}]

Categories