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

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");
}
});

Related

jQuery UI Droppable items

Hello
I have a problem. The problem is, when I move an item to multiple slots it works perfectly.
But when i have two items of the same type, and I put them together it turns into a single item with the value of 2.
But I can't figure out how i could separate that two items into two separate items with the value of one.
if($(this)[0].querySelector('.size').innerText > 1) {
$(this).children().children().html(1);
}
Project: https://codepen.io/KsenonAdv/pen/bGRaRjR
Consider the following example.
$(function() {
function log(string) {
console.log(Date.now(), string);
}
function makeGrid() {
log("Make Grid...");
for (var i = 0; i < 36; i++) {
$("<div>", {
class: "slot"
}).data({
count: 0,
stackable: true
}).appendTo(".slots");
}
log("-* Grid Complete *-");
}
function makeDraggable(target) {
log("Make Drag, Current Class: " + $(target).attr("class"));
console.log(target);
$(target).draggable({
scroll: false,
helper: "clone",
cursor: "pointer",
zIndex: 27,
revert: "invalid"
});
log("After Make Drag, Current Class: " + $(target).attr("class"));
console.log(target);
}
function refreshSlot(target) {
log("Refresh Slot");
$(".size", target).html($(target).data("count"));
}
function addItem(slot, item) {
log("Add Item " + item.id);
$.extend(item, {
stackable: (item.category != 0),
count: (item.count == undefined ? 1 : item.count)
});
slot = $(slot);
var newItem = $("<div>", {
class: "item",
id: item.id,
})
.data(item)
.css("background-image", "url(" + item.img + ")");
newItem.appendTo(slot);
$("<div>", {
class: "size"
}).appendTo(slot);
slot.data({
count: item.count,
stackable: item.stackable
});
log("Item Added - Refreshing");
refreshSlot(slot);
}
function emptySlot(target) {
log("Empty Slot " + $(target).index());
$(target).data({
count: 0,
stackable: true
}).empty();
}
function loadPlayerItems(items) {
log("Loading Player Items...");
$.each(items, function(index, item) {
addItem($(".slots > .slot").eq(index), item);
});
log("-* Loading Complete *-");
}
function isAcceptable(item) {
if ($(this).children().length == 0 || $(".item", this).data("stackable")) {
return true;
}
return false;
}
var pItems = {
playerItems: [{
img: 'https://i.imgur.com/5cjSI9X.png',
name: 'bat',
id: 1,
category: 0
},
{
img: 'https://i.imgur.com/HLQORBk.png',
name: 'axe',
id: 2,
category: 1
},
{
img: 'https://i.imgur.com/HLQORBk.png',
name: 'axe',
id: 3,
category: 1
}
]
};
makeGrid();
loadPlayerItems(pItems.playerItems);
makeDraggable(".item");
$(".slots > .slot").droppable({
accept: isAcceptable,
drop: function(event, ui) {
var origin = ui.draggable.parent();
var target = $(this);
log("Drop Accepted; From: " + origin.index() + ", To: " + target.index());
// Increase the Count
target.data("count", target.data("count") + 1);
// Check for Stack
if (target.children().length == 0) {
addItem(target, ui.draggable.data());
} else {
refreshSlot(target);
}
// Check Orginal Stack
if (origin.data("count") > 1) {
origin.data("count", origin.data("count") - 1);
refreshSlot(origin);
} else {
emptySlot(origin);
}
makeDraggable($(".item", this));
}
});
});
body {
display: flex;
justify-content: space-between;
background: url(http://img.playground.ru/images/5/1/GTA5_2015-05-07_00-53-36-07.png);
}
#inventory {
height: 56.25vw;
background: rgba(0, 0, 0, .5);
}
.list-slots {
position: relative;
background: rgba(0, 0, 0, .7);
max-width: 80%;
}
.slots {
max-width: 87%;
margin: auto;
padding-top: 3.125vw;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.slots .slot {
width: 100px;
height: calc(100px + 1em);
background-color: #ccc;
margin-bottom: 0.781vw;
}
.slots .slot .item {
background-repeat: no-repeat;
width: 100px;
height: 100px;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div id="inventory">
<div class="list-slots">
<div class="slots"></div>
</div>
</div>
As discussed in the comment, this updates the Count of items in the Slot by 1. When an items is dragged out, the count is lowered by 1.
To make things easier, I created a number of functions. You may choose to handle it in another manner if you like.

Update the dom instead of append with jQuery

I have a question about jQuery: I now render content from an array to the dom with:
errors.forEach(error => {
let message = error.message;
let fileName = error.fileName;
$('.errors').append("<li class=\"error-item\">".concat(fileName, " : ").concat(message, "</li><br>"));
});
but I got some actions that update the array where I render the content from, but when I run this function after the update of the array, it appends. I use the .empty() before now but that feels like a hack around but I want it to update
I hope this make sense
What can I do that it updates the dom instead of appending?
I hope someone can help me with this
The jQuery method .html() overwrites the content of the targeted element(s) with a given htmlString. The following demo function logger() will accept an array of objects and render the data in a <ul>.
let failData = [{
DOM: '.fail',
title: 'Errors: ',
header: ['File', 'Message']
},
{
item: '12ffda8a99.log',
message: 'Connection failed'
},
{
item: 'bb6200c400.log',
message: 'Corrupted download'
},
{
item: 'd93ba66731.log',
message: 'Encryption key needed'
},
{
item: '08caa5240f.log',
message: 'Mismatched certification'
},
{
item: 'dead0b8a99.log',
message: 'Insecure protocol'
}
];
let warnData = [{
DOM: '.warn',
title: 'Alerts: ',
header: ['System', 'Message']
},
{
item: 'network',
message: '1GB of data left before limit is exceeded'
},
{
item: 'file',
message: '1GB of storage left before partition is full'
},
{
item: 'power',
message: '5% of battery remains'
}
];
let infoData = [{
DOM: '.info',
title: 'Updates: ',
header: ['Priority', 'Message']
},
{
item: 'critical',
message: 'Anti-virus update required'
},
{
item: 'optional',
message: 'Media encoding update available'
}
];
const logger = array => {
let html = '';
let list;
for (let [index, object] of array.entries()) {
list = $(array[0].DOM);
if (index === 0) {
list.prev('header').html(`<u><b>${object.title}</b><output>${array.length-1}</output></u><u><b>${object.header[0]}</b><b>${object.header[1]}</b></u>`);
} else {
html += `<li><b>${object.item}</b><b>${object.message}</b></li>`;
}
}
list.html(html);
return false;
}
logger(failData);
logger(warnData);
logger(infoData);
header {
margin: 10px 0 -15px;
}
ul {
padding: 5px 0 10px;
border: 3px ridge #777;
overflow-y: hidden;
}
ul,
header {
display: table;
table-layout: fixed;
width: 90%;
}
li,
u {
display: table-row;
}
b {
display: table-cell;
width: 50%;
border-bottom: 1px solid #000;
padding-left:5px
}
output {
display: inline-block;
width: 10ch;
}
<main>
<section class='logs'>
<header></header>
<ul class='fail'></ul>
<header></header>
<ul class='warn'></ul>
<header></header>
<ul class='info'></ul>
</section>
</main>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

how to add css class to a quill selection?

How can I add my own style with a class css in quilljs?
I have this following css class
.ql-editor spanblock {
background-color: #F8F8F8;
border: 1px solid #CCC;
line-height: 19px;
padding: 6px 10px;
border-radius: 3px;
margin: 15px 0;
}
and an event targeting this CSS transformation
var toolbarOptions = [
[{ "header": [false, 1, 2, 3, 4, 5, 6] }, "bold", "italic"],
[{ "list": "ordered"}, { "list": "bullet" }, { "indent": "-1"}, { "indent": "+1" }],
["blockquote","code-block", "span-block","link", "hr"]
];
var quill = new Quill("#form_field_" + options.id + " .editor-container > .editor", {
modules: {
toolbar: toolbarOptions
},
theme: "snow"
});
var toolbar = quill.getModule("toolbar");
toolbar.addHandler("span-block", function(){});
var spanBlockButton = document.querySelector(".ql-span-block");
spanBlockButton.addEventListener("click", () => {
let range = quill.getSelection(true);
// what should I add here
}
I cannot find anything in the documentation of quilljs
https://quilljs.com
thank you
Basically you have to extend Parchment blots to have custom styled element in quill.
I went through this tutorial here and here.
Following is the simple html
<link href="http://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
<link href="http://cdn.quilljs.com/1.3.6/quill.bubble.css" rel="stylesheet">
<link href="http://cdn.quilljs.com/1.3.6/quill.core.css" rel="stylesheet">
<style>
.ql-spanblock:after {
content: "<spanblock/>";
}
.spanblock {
background-color: #F8F8F8;
border: 1px solid #CCC;
line-height: 19px;
padding: 6px 10px;
border-radius: 3px;
margin: 15px 0;
}
</style>
<div id="editor">
</div>
Here is the actual answer,I have extended blots/inline in following way to wrap selected text into a div with desired class.
<script src="http://cdn.quilljs.com/1.3.6/quill.min.js"></script>
<script type="text/javascript">
let Inline = Quill.import('blots/inline');
class SpanBlock extends Inline{
static create(value){
let node = super.create();
node.setAttribute('class','spanblock');
return node;
}
}
SpanBlock.blotName = 'spanblock';
SpanBlock.tagName = 'div';
Quill.register(SpanBlock);
var toolbarOptions = [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
['blockquote', 'code-block'],
[{ 'header': 1 }, { 'header': 2 }], // custom button values
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
[{ 'script':'sub'}, { 'script': 'super' }], // superscript/subscript
[{ 'indent': '-1'}, { 'indent': '+1' }], // outdent/indent
[{ 'direction': 'rtl' }], // text direction
[{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
[{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme
[{ 'font': [] }],
[{ 'align': [] }],
['clean'], // remove formatting button
['link', 'image', 'video'],
['spanblock']
];
var quill = new Quill('#editor', {
modules: {
toolbar: toolbarOptions
},
theme: 'snow'
});
var spanBlockButton = document.querySelector('.ql-spanblock');
//event listener to spanblock button on toolbar
spanBlockButton.addEventListener('click', function() {
var range = quill.getSelection();
if(range){
quill.formatText(range,'spanblock',true);
}else{
}
}
);
</script>
Codepen-demo.
Quite late to the scene, but it seems there's a better way to do this (than the previous answers) through Parchment's Attributor Class, hence this post.
Parchment Class Attributors and the Quill toolbar handlers are in-built ways to let you do exactly that, without having to create a new Blot.
Just register a new Class Attributor for span-block:
Parchment = Quill.import('parchment');
let config = { scope: Parchment.Scope.BLOCK };
let SpanBlockClass = new Parchment.Attributor.Class('span-block', 'span', config);
Quill.register(SpanBlockClass, true);
and attach a handler to format (or removeFormat if already formatted) for the toolbar button (rather than a separate event listener):
// ...
toolbar: {
container: toolbarOptions,
handlers: {
'span-block': function() {
var range = quill.getSelection();
var format = quill.getFormat(range);
if (!format['span-block']) {
quill.format('span-block', 'block');
} else {
quill.removeFormat(range.index, range.index + range.length);
}
}
}
}
// ...
Here's a demo (Or if you prefer, see it on Codepen)
Parchment = Quill.import('parchment');
let config = { scope: Parchment.Scope.BLOCK };
let SpanBlockClass = new Parchment.Attributor.Class('span-block', 'span', config);
Quill.register(SpanBlockClass, true)
var toolbarOptions = [
[{ "header": [false, 1, 2, 3, 4, 5, 6]}, "bold", "italic"],
[{"list": "ordered"}, {"list": "bullet"}, {"indent": "-1"}, {"indent": "+1"}],
["blockquote", "code-block", "span-block", "link"]
];
var icons = Quill.import('ui/icons');
icons['span-block'] = 'sb';
var quill = new Quill("#editor-container", {
modules: {
toolbar: {
container: toolbarOptions,
handlers: {
'span-block': function() {
var range = quill.getSelection();
var format = quill.getFormat(range);
if (!format['span-block']) {
quill.format('span-block', 'block');
} else {
quill.removeFormat(range.index, range.index + range.length);
}
}
}
}
},
theme: "snow"
});
#editor-container {
height: 375px;
}
.ql-editor .span-block {
background-color: #F8F8F8;
border: 1px solid #CCC;
line-height: 19px;
padding: 6px 10px;
border-radius: 3px;
margin: 15px 0;
}
<link href="//cdn.quilljs.com/1.2.4/quill.snow.css" rel="stylesheet" />
<script src="//cdn.quilljs.com/1.2.4/quill.js"></script>
<div id="editor-container"></div>
#moghya's answer has a problem for me: I can't redraw the content from generated html, the element will loose the added class name.
I fixed it by add a formats() method and set the className. See my demo below.
let Block = Quill.import('blots/block');
var icons = Quill.import('ui/icons');
// Lottery tooltip
class LotteryTitle extends Block {
static create() {
let node = super.create();
node.setAttribute('class', this.className);
return node;
}
static formats(domNode) {
return true;
}
}
LotteryTitle.blotName = 'lottery-title';
LotteryTitle.className = "sc-lottery-title"
Quill.register(LotteryTitle);
icons['lottery-title'] = icons.header["2"];

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.

Using Basicprimitive with Angularjs Error: jQuery(...).orgDiagram is not a function

I am trying to convert this sample http://www.basicprimitives.com/index.php?option=com_content&view=article&id=71&Itemid=116&lang=en into my angular application.
But every time I get below error
TypeError: jQuery(...).orgDiagram is not a function
at link (http://localhost:32150/app/BasicPrimitives.js:14:45)
at http://localhost:32150/scripts/angular.js:7094:44
at nodeLinkFn (http://localhost:32150/scripts/angular.js:6692:13)
at compositeLinkFn (http://localhost:32150/scripts/angular.js:6086:13)
at compositeLinkFn (http://localhost:32150/scripts/angular.js:6089:13)
at nodeLinkFn (http://localhost:32150/scripts/angular.js:6686:24)
at compositeLinkFn (http://localhost:32150/scripts/angular.js:6086:13)
at compositeLinkFn (http://localhost:32150/scripts/angular.js:6089:13)
at compositeLinkFn (http://localhost:32150/scripts/angular.js:6089:13)
at compositeLinkFn (http://localhost:32150/scripts/angular.js:6089:13)
<div bp-org-diagram="" data-options="myOptions" data-on-highlight-changed="onMyHighlightChanged()" data-on-cursor-changed="onMyCursorChanged()" style="width: 800px; height: 600px; border-style: dotted; border-width: 1px;" class="ng-isolate-scope"> (anonymous function)
# angular.js:10046$get
# angular.js:7343(anonymous function)
# config.exceptionHandler.js:21nodeLinkFn
# angular.js:6695compositeLinkFn
# angular.js:6086compositeLinkFn
# angular.js:6089nodeLinkFn
# angular.js:6686compositeLinkFn
# angular.js:6086compositeLinkFn
# angular.js:6089compositeLinkFn
# angular.js:6089compositeLinkFn
# angular.js:6089compositeLinkFn
# angular.js:6089nodeLinkFn
# angular.js:6686compositeLinkFn
# angular.js:6086publicLinkFn
# angular.js:5982link
# angular-route.js:919nodeLinkFn
# angular.js:6692compositeLinkFn
# angular.js:6086publicLinkFn
# angular.js:5982$get.boundTranscludeFn
# angular.js:6106controllersBoundTransclude
# angular.js:6713update
# angular-route.js:869$get.Scope.$broadcast
# angular.js:12937(anonymous function)
# angular-route.js:550deferred.promise.then.wrappedCallback
# angular.js:11546deferred.promise.then.wrappedCallback
# angular.js:11546(anonymous function)
# angular.js:11632$get.Scope.$eval
# angular.js:12658$get.Scope.$digest
# angular.js:12470$get.Scope.$apply
# angular.js:12762done
# angular.js:8357completeRequest
# angular.js:8571xhr.onreadystatechange
# angular.js:8510
angular.js:10046 [app] [HT Error] jQuery(...).orgDiagram is not a function Object {exception: TypeError: jQuery(...).orgDiagram is not a function
at link (http://localhost:32150/app/BasicPri…, cause: "<div bp-org-diagram="" data-options="myOptions" da…ed; border-width: 1px;" class="ng-isolate-scope">"}
If I take the above sample its working fine. in my main app module I have several other modules injected. but on injection of basic primitive module I get above error
App Module :
var app = angular.module('app', [
// Angular modules
'ngAnimate', // animations
'ngRoute', // routing
'ngSanitize', // sanitizes html bindings (ex: sidebar.js)
'ui.grid',
// Custom modules
'common', // common functions, logger, spinner
'common.bootstrap', // bootstrap dialog wrapper functions
'LocalStorageModule',
'angular-loading-bar',
'angularFileUpload',
'BasicPrimitives',
// 3rd Party Modules
'ui.bootstrap' // ui-bootstrap (ex: carousel, pagination, dialog)
]);
HTML:
<div id="centerpanel" style="overflow: hidden; padding: 0px; margin: 0px; border: 0px;">
<div bp-org-diagram data-options="myOptions" data-on-highlight-changed="onMyHighlightChanged()" data-on-cursor-changed="onMyCursorChanged()"
style="width: 800px; height: 600px; border-style: dotted; border-width: 1px;"></div>
</div>
JsController:
(function () {
'use strict';
var controllerId = 'orgdepartmentJsController';
angular.module('app').controller(controllerId, ['$scope', 'common', '$location','ngAuthSettings', 'orgdepartmentJsService', orgdepartmentJsController]);
function orgdepartmentJsController($scope, common, $location,ngAuthSettings, orgdepartmentJsService) {
var getLogFn = common.logger.getLogFn;
var log = getLogFn(controllerId);
var vm = this;
$scope.title = 'Departments';
activate();
$scope.index = 10;
$scope.Message = "";
$scope.orgdepartmentList = [];
$scope.editMode = 'List';
$scope.objorgdepartment = {};
$scope.addNew = function () {
$scope.editMode = 'New';
};
$scope.cancel = function () {
getorgdepartment();
$scope.editMode = 'List';
};
$scope.save = function (objorgdepartment) {
$scope.editMode = 'List';
orgdepartmentJsService.save(objorgdepartment).then(function (results) {
}, function (error) {
alert(error.data.message);
});
};
function getorgdepartment() {
orgdepartmentJsService.getall().then(function (results) {
//debugger;
$scope.orgdepartmentList = results.data;
$("#grid").kendoGrid({
toolbar: ["excel"],
excel: {
fileName: "Kendo UI Grid Export.xlsx",
//proxyURL: "//demos.telerik.com/kendo-ui/service/export",
filterable: true
},
dataSource: {
data: $scope.orgdepartmentList,
schema: {
model: {
fields: {
DepartmentName: { type: "string" },
Description: { type: "string" }
}
}
},
pageSize: 20
},
height: 550,
scrollable: true,
sortable: true,
filterable: true,
pageable: {
input: true,
numeric: false
},
columns: [
{ field: "departmentName", title: "DepartmentName", width: "130px" },
{ field: "description", title: "Description", width: "130px" }
]
});
}, function (error) {
// debugger;
alert(error.data.message);
});
}
function activate() {
common.activateController([], controllerId)
.then(function () { log('Activated Departments View'); });
getorgdepartment();
}
var serviceBase = ngAuthSettings.apiServiceBaseUri;
//OrgChart
$scope.orgChart = function () {
$scope.editMode = 'OrgChart';
}
$scope.index = 10;
$scope.Message = "";
var options = {};
var items = [
new primitives.orgdiagram.ItemConfig({
id: 0,
parent: null,
title: "Scott Aasrud",
description: "Root",
phone: "1 (416) 001-4567",
email: "scott.aasrud#mail.com",
image: "demo/images/photos/a.png",
itemTitleColor: primitives.common.Colors.RoyalBlue
}),
new primitives.orgdiagram.ItemConfig({
id: 1,
parent: 0,
title: "Ted Lucas",
description: "Left",
phone: "1 (416) 002-4567",
email: "ted.lucas#mail.com",
image: "demo/images/photos/b.png",
itemTitleColor: primitives.common.Colors.RoyalBlue
}),
new primitives.orgdiagram.ItemConfig({
id: 2,
parent: 0,
title: "Joao Stuger",
description: "Right",
phone: "1 (416) 003-4567",
email: "joao.stuger#mail.com",
image: "demo/images/photos/c.png",
itemTitleColor: primitives.common.Colors.RoyalBlue
}),
new primitives.orgdiagram.ItemConfig({
id: 3,
parent: 2,
title: "Hidden Node",
phone: "1 (416) 004-4567",
email: "hidden.node#mail.com",
description: "Dotted Node",
image: "demo/images/photos/e.png",
itemTitleColor: primitives.common.Colors.PaleVioletRed
})
];
options.items = items;
options.cursorItem = 0;
options.highlightItem = 0;
options.hasSelectorCheckbox = primitives.common.Enabled.True;
options.templates = [getContactTemplate()];
options.defaultTemplateName = "contactTemplate";
$scope.myOptions = options;
$scope.setCursorItem = function (item) {
$scope.myOptions.cursorItem = item;
};
$scope.setHighlightItem = function (item) {
$scope.myOptions.highlightItem = item;
};
$scope.deleteItem = function (index) {
$scope.myOptions.items.splice(index, 1);
}
$scope.addItem = function (index, parent) {
var id = $scope.index++;
$scope.myOptions.items.splice(index, 0, new primitives.orgdiagram.ItemConfig({
id: id,
parent: parent,
title: "New title " + id,
description: "New description " + id,
image: "demo/images/photos/b.png"
}));
}
$scope.onMyCursorChanged = function () {
$scope.Message = "onMyCursorChanged";
}
$scope.onMyHighlightChanged = function () {
$scope.Message = "onMyHighlightChanged";
}
function getContactTemplate() {
var result = new primitives.orgdiagram.TemplateConfig();
result.name = "contactTemplate";
result.itemSize = new primitives.common.Size(220, 120);
result.minimizedItemSize = new primitives.common.Size(5, 5);
result.minimizedItemCornerRadius = 5;
result.highlightPadding = new primitives.common.Thickness(2, 2, 2, 2);
var itemTemplate = jQuery(
'<div class="bp-item bp-corner-all bt-item-frame">'
+ '<div name="titleBackground" class="bp-item bp-corner-all bp-title-frame" style="background:{{itemTitleColor}};top: 2px; left: 2px; width: 216px; height: 20px;">'
+ '<div name="title" class="bp-item bp-title" style="top: 3px; left: 6px; width: 208px; height: 18px;">{{itemConfig.title}}</div>'
+ '</div>'
+ '<div class="bp-item bp-photo-frame" style="top: 26px; left: 2px; width: 50px; height: 60px;">'
+ '<img name="photo" src="{{itemConfig.image}}" style="height: 60px; width:50px;" />'
+ '</div>'
+ '<div name="phone" class="bp-item" style="top: 26px; left: 56px; width: 162px; height: 18px; font-size: 12px;">{{itemConfig.phone}}</div>'
+ '<div class="bp-item" style="top: 44px; left: 56px; width: 162px; height: 18px; font-size: 12px;"><a name="email" href="mailto::{{itemConfig.email}}" target="_top">{{itemConfig.email}}</a></div>'
+ '<div name="description" class="bp-item" style="top: 62px; left: 56px; width: 162px; height: 36px; font-size: 10px;">{{itemConfig.description}}</div>'
+ '</div>'
).css({
width: result.itemSize.width + "px",
height: result.itemSize.height + "px"
}).addClass("bp-item bp-corner-all bt-item-frame");
result.itemTemplate = itemTemplate.wrap('<div>').parent().html();
return result;
}
}
})();
Script Links on Index Page
<script src="scripts/jquery-2.1.1.js"></script>
<script src="scripts/jquery-ui.min.js"></script>
<script src="Scripts/primitives.min.js"></script>
<script src="scripts/angular.js"></script>
<script src="scripts/angular-animate.js"></script>
<script src="scripts/angular-route.js"></script>
<script src="scripts/angular-file-upload.js"></script>
<script src="Scripts/angular-ui/ui-bootstrap.min.js"></script>
<script src="scripts/angular-cookies.min.js"></script>
<script src="scripts/angular-resource.min.js"></script>
<script src="scripts/angular-sanitize.js"></script>
<script src="scripts/angular-local-storage.min.js"></script>
<script src="scripts/loading-bar.min.js"></script>
<script src="Scripts/ui-grid-unstable.js"></script>
<script src="scripts/bootstrap.js"></script>
<script src="scripts/toastr.js"></script>
<script src="scripts/moment.js"></script>
<script src="scripts/ui-bootstrap-tpls-0.10.0.js"></script>
<script src="scripts/spin.js"></script>
<script src="//kendo.cdn.telerik.com/2015.2.805/js/jquery.min.js"></script>
<script src="//kendo.cdn.telerik.com/2015.2.805/js/jszip.min.js"></script>
<script src="//kendo.cdn.telerik.com/2015.2.805/js/kendo.all.min.js"></script>
<!--<script src="app/login.js"></script>-->
<!-- Bootstrapping -->
<script src="app/BasicPrimitives.js"></script>
<script src="app/app.js"></script>
You are referring two jquery versions in your scripts. Please remove following reference and hopefully it will solve your problem.
<script src="//kendo.cdn.telerik.com/2015.2.805/js/jquery.min.js"></script>

Categories