jQuery UI Widgets › Forums › Navigation › Tree › jqxTree questions and/or issues
Tagged: added, checkboxes, dragEnd, dragItem, dragStart, icons, initialized, jqxListBox, jqxtree, ListBox, removeItem, Tree
This topic contains 16 replies, has 2 voices, and was last updated by Nadezhda 10 years ago.
-
Author
-
I am testing jqxTree, and have the following questions:
1. How to drag an item from a jqxListBox and drop it in a jqxTree, without having it be removed from the jqxListBox.
2. Is it, or will it be, possible to have an icon/image in place of or in addition to the checkbox on a jqxTree item?
3. Is it, or will it be, possible to include user-defined data (as in html data-*) within a jqxTree item?
4. Is there a complete list by jqx item (jqxTree, jqxListBox, etc.) of available events and their arguments/parameters? In jqxTree I see at least two different definitions for dragStart and dragEnd.
5. Is there an example of when dragging from one jqxTree to another jqxTree how to determine which item the dragged item was dropped on?
6. Is the only way to programmatically “walk” through the tree to use the getItems method?I also appear to be having the following issues:
1. I am dragging an item from one jqxTree to another jqxTree and no ‘added’ event code is executed. I would rather drag from the jqxListBox to the jqxTree, but that points to questions #1 and #5 above.
2. None of the code in my ‘initialized’ event appears to be executing.Using:
Windows 7
Firefox 32.0
jQuery JavaScript Library v1.8.3
jQWidgets v3.4.0 (2014-June-23)Thank you.
Hello Craig Matthews,
Answers to the questions:
1) Here is an example how to drag item from jqxListBox to jqxTree:<!DOCTYPE html> <html lang="en"> <head> <meta name="keywords" content="jQuery Tree, Tree Widget, TreeView" /> <meta name="description" content="The jqxTree displays a hierarchical collection of items. You can populate it from 'UL' or by using its 'source' property." /> <title></title> <link rel="stylesheet" href="../../jqwidgets/styles/jqx.base.css" type="text/css" /> <script type="text/javascript" src="../../scripts/jquery-1.10.2.min.js"></script> <script type="text/javascript" src="../../scripts/demos.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxcore.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxbuttons.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxscrollbar.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxpanel.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxdragdrop.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxtree.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxcheckbox.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxlistbox.js"></script> <script type="text/javascript"> $(document).ready(function () { var data1 = [ "Affogato", "Americano", "Bicerin", "Breve", "Café Bombón", "Café au lait", "Caffé Corretto", "Café Crema", "Caffé Latte", "Caffé macchiato", "Café mélange", "Coffee milk", "Cafe mocha" ]; // Create jqxTree $("#listBoxA").jqxListBox({allowDrop: true, allowDrag: true, source: data1, width: 200, height: 250}); $('#treeB').jqxTree({allowDrag: true, allowDrop: true, height: '300px', width: '220px'}); $('#listBoxA').css('visibility', 'visible'); $('#treeB').css('visibility', 'visible'); $("#listBoxA").on('dragEnd', function (event) { $("#dragEndLog").text("Drag End"); if (event.args.label) { var ev = event.args.originalEvent; var x = ev.pageX; var y = ev.pageY; var item = $('#treeB').jqxTree('hitTest', x, y); $('#treeB').jqxTree('addTo', { label: event.args.label }, item.element); } }); }); </script> </head> <body class='default'> <div id='jqxWidget'> <div style='float: left;'> <div id='listBoxA' style='visibility: hidden; float: left; margin-left: 0px;'> </div> <div style='visibility: hidden; float: left; margin-left: 20px;' id="treeB"> <ul> <li>Products </li> <li item-expanded='true'>Support <ul> <li>Support home</li> <li>Customer Service</li> </ul> </li> <li>Knowledge base</li> <li>Forum</li> </ul> </div> </div> </div> </body> </html>
2) Here is an example how to use checkboxes with icons in jqxTree:
<!DOCTYPE html> <html lang="en"> <head> <meta name="keywords" content="jQuery Tree, Tree Widget, TreeView" /> <meta name="description" content="The jqxTree can easily display images next to each item. In order to achieve that, you need to add 'img' element inside a 'li' element." /> <title></title> <link rel="stylesheet" href="../../jqwidgets/styles/jqx.base.css" type="text/css" /> <script type="text/javascript" src="../../scripts/jquery-1.10.2.min.js"></script> <script type="text/javascript" src="../../scripts/demos.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxcore.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxbuttons.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxscrollbar.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxpanel.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxtree.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxexpander.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxcheckbox.js"></script> <script type="text/javascript"> $(document).ready(function () { // Create jqxExpander $('#jqxExpander').jqxExpander({ showArrow: true, toggleMode: 'click', width: '300px', height: '370px' }); // Create jqxTree var source = [ { icon: "../../images/mailIcon.png", label: "Mail", expanded: true, items: [ { icon: "../../images/calendarIcon.png", label: "Calendar" }, { icon: "../../images/contactsIcon.png", label: "Contacts", selected: true } ] }, { icon: "../../images/folder.png", label: "Inbox", expanded: true, items: [ { icon: "../../images/folder.png", label: "Admin" }, { icon: "../../images/folder.png", label: "Corporate" }, { icon: "../../images/folder.png", label: "Finance" }, { icon: "../../images/folder.png", label: "Other" }, ] }, { icon: "../../images/recycle.png", label: "Deleted Items" }, { icon: "../../images/notesIcon.png", label: "Notes" }, { iconsize: 14, icon: "../../images/settings.png", label: "Settings" }, { icon: "../../images/favorites.png", label: "Favorites" } ]; $('#jqxTree').jqxTree({ source: source, width: '100%', height: '100%', checkboxes: true }); $('#jqxTree').jqxTree('selectItem', null); }); </script> </head> <body class='default'> <div id='jqxWidget'> <div id='jqxExpander'> <div> Folders </div> <div style="overflow: hidden;"> <div style="border: none;" id='jqxTree'> </div> </div> </div> </div> </body> </html>
3) This is possible. Here is an example:
<!DOCTYPE html> <html lang="en"> <head> <link rel="stylesheet" href="../../jqwidgets/styles/jqx.base.css" type="text/css" /> <script type="text/javascript" src="../../scripts/jquery-1.10.2.min.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxcore.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxbuttons.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxscrollbar.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxpanel.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxtree.js"></script> <script type="text/javascript"> $(document).ready(function () { $('#jqxTree').jqxTree({ height: '300px', width: '300px' }); $('#jqxTree').bind('select', function (event) { var htmlElement = event.args.element; alert($(htmlElement).attr("data-info")); }); }); </script> </head> <body class='default'> <div id='jqxTree'> <ul> <li item-selected='true' data-info="ABC">Home</li> <li item-expanded='true' data-info="DEF">Solutions <ul> <li data-info="GHI">Education</li> <li data-info="JKL">Financial services</li> </ul> </li> </ul> </div> </body> </html>
4) These lists are available in each widget’s API Documentation. There is a difference between the two dragStart (or dragEnd) – one is a property (callback function) and the other one is event.
5) Please check the jqxTree Drag & Drop demo: http://www.jqwidgets.com/jquery-widgets-demo/demos/jqxtree/dragdrop.htm?arctic. Note the dragEnd callback function.
6) Yes, this is the only way.
About the issues:
1. “added” is not called for trees when dropping an item. If you implement our solution with listBox, however, the event will be called.
2. Make sure that “initialized” event binding is before the jqxTree initialization code (example).Best Regards,
NadezhdajQWidgets team
http://www.jqwidgets.com/Hello Nadezhda,
Thank you for your prompt and helpful response.
As it always goes with questions, the answers lead to more questions.
1. It appears that there is no expanded dragEnd information for the jqxListBox as there is with the jqxTree. Dragging from the list to the tree works, but you can’t drag from the tree to the list. What I am building is like an organizational chart (the tree), and when a position is dragged from the “positions” list to the tree a position is created in the tree. When a person is dragged from the “employee” list and dropped on a position in the tree, the name can be added to the tree. What I am looking for is when someone is removed from a position, or when a vacant position is removed from the orgranization. Dragging from the tree, I wouldn’t know which list it was dropped on to then know what to do with the dragged tree item.
2. Given that I wouldn’t be able to use the jqxListBox as a drop destination due to not knowing where in the tree the data came from, I am using three jqxTree for my example for #1 above. Is there a way to keep the dragged item from being removed from either the position or employee tree when an item is dragged to the organization tree?
3. I found, as your example shows, that when building the tree in html with LI and UL tags I can include the data-* elements. What I am looking for is if there is a way to include the data-* elements when building from a data source. That is where it would be nice to know the internals available. I have seen that name, label, selected, expanded and now icon are available as part of a data source. Are there any others that I could potentially use to store data in if the data-* is not available?
4. Given that getItems is the only way to “walk” the tree, how can I use the information returned to be able to write the interpretation of the tree contents to a file or database? I would need to know the order of who reported to whom in the organization tree.Thank you.
Hi Craig Matthews,
1) The two widgets are not directly “compatible”. Custom code should be written to enable dragging from one to the other. The example shows dragging from the listbox to the tree but can be expanded to include the other way around.
2) It is not possible to keep the dragged item which is removed from either the position or employee tree when an item is dragged to the organization tree.
3) The tree source object has a “value” field which can be used for that purpose. For more information, please refer to the jqxTree API Documentation.
4) Please, find the following topic which contains possible solution for export tree: http://www.jqwidgets.com/community/topic/export-tree-data-to-json/
Best Regards,
NadezhdajQWidgets team
http://www.jqwidgets.com/I am now using release 3.5.0, and nearly have everything working on my organizational tree.
The current problem is after a removeItem call. I then end the dragEnd callback with a return false, and the following error occurs:
TypeError: this.position is undefined
…veContainer.offset();h=[this._restricter[0]+g.left,this._restricter[1]+g.top,thi…
jqxdragdrop.js (line 7)
The pertinent code is:
$(‘#treeApproval’).jqxTree(‘removeItem’, dragItem.element);
msgBox(‘Approvals’, ‘Position “‘ + pos + ‘” removed from the Tree’);
return false; // prevent moving from treeApproval to treePositionsI have tried both dragItem and dragItem.element with the same results.
If I return true, the item is removed from treeApproval and appears in treePositions, where I don’t want it.
If I remove the removeItem call, the item remains in treeApproval and does not drop into treePositions.
When the error message is logged to the console, the dragged item is left “hanging” in the treePositions tree.
Thank you.
Hi Craig Matthews,
This code is insufficient for us to determine the source of the issue. Please provide us with a JSFiddle example and steps to reproduce it.
Best Regards,
NadezhdajQWidgets team
http://www.jqwidgets.com/Hello Nadezhda,
I have stripped the html/javascript down to a readable minimum and it is 231 lines and 11,697 bytes.
I have never used JSFiddle to post code, and don’t really have the time to learn it right now.
Unless you have a quick-start tutorial on how to post to JSFiddle, I can supply the OrgTree.html file zipped, however I don’t see a way to attach files here. Or would you prefer all 231 lines here?
Hi Craig Matthews,
Please, post your html/javascript code here and remember to format it by selecting it and pressing the
code
button in the toolbar.Best Regards,
NadezhdajQWidgets team
http://www.jqwidgets.com/Hello Nadezhda,
In order to recreate the problem, simply select any secretary in the right tree and drag it to the left tree. You can drag any item from the right tree to the left, but the secretary items would be the easiest.
The code is below:
<script language=”javascript” type=”text/javascript” src=”../../static/js/jquery.js”></script>
<script language=”JavaScript” type=”text/javascript” src=”../../static/js/jqwidgets/jqxcore.js”></script>
<script language=”javascript” type=”text/javascript” src=”../../static/js/jqwidgets/jqxdragdrop.js”></script>
<script language=”JavaScript” type=”text/javascript” src=”../../static/js/jqwidgets/jqxbuttons.js”></script>
<script language=”JavaScript” type=”text/javascript” src=”../../static/js/jqwidgets/jqxpanel.js”></script>
<script language=”JavaScript” type=”text/javascript” src=”../../static/js/jqwidgets/jqxscrollbar.js”></script>
<script language=”javascript” type=”text/javascript” src=”../../static/js/jqwidgets/jqxtree.js”></script>
<link rel=”stylesheet” type=”text/css” href=”../../static/js/jqwidgets/styles/jqx.base.css” />
<link rel=”stylesheet” type=”text/css” href=”../../static/js/jqwidgets/styles/jqx.energyblue.css” /><script language=”JavaScript” type=”text/javascript”>
console.log(‘Script start …’);
var positionsData,
treeApprovalData;
$(document).ready(function () {
console.log(‘Entering document ready …’);
document.title = “Organization Tree”
addPageEventListeners();
createPageElements();
$(‘#treeApproval’).jqxTree(‘expandAll’);
$(‘#treeApproval’).jqxTree(‘focus’);
console.log(‘Exiting document ready …’);
});
function addPageEventListeners() {
$(‘#treeExpandAll’).on(‘click’, function(event) {
$(‘#treeApproval’).jqxTree(‘expandAll’);
});
$(‘#treeCollapseAll’).on(‘click’, function(event) {
$(‘#treeApproval’).jqxTree(‘collapseAll’);
});
}
function createPageElements() {
$(‘#treeExpandAll’).jqxButton({ width: ‘125px’, height: ’25px’, theme: ‘energyblue’ });
$(‘#treeCollapseAll’).jqxButton({ width: ‘125px’, height: ’25px’, theme: ‘energyblue’ });
// ================================================================================
$(‘#treePositions’).jqxTree({
height: ‘300px’, width: ‘300px’,
theme: ‘energyblue’,
allowDrag: true,
allowDrop: true,
source: positionsData,
dragStart: function(item) {
return true; // allow the drag
},
dragEnd: function(dragItem, dropItem, args, dropPosition, tree) {
if (tree.attr(‘id’) == ‘treePositions’) {
msgBox(‘Positions’, ‘Reordering within Positions is not allowed’);
return false; // prevent reordering within treePositions
} else {
if (tree.attr(‘id’) == ‘treeApproval’) {
if (dropPosition == ‘inside’) {
if (dropItem.value.substr(0, 4) == ‘root’) {
msgBox(‘Positions’, ‘The BOE Item cannot be modified’);
return false; // prevent dropping on root
}
}
if (dropPosition == ‘before’) {
if (dropItem.value.substr(0, 4) == ‘root’) {
msgBox(‘Positions’, ‘There can be nothing above the BOE in the Tree’);
return false; // prevent dropping above root
} else {
if (dropItem.value.substr(23, 4) == ‘root’) {
msgBox(‘Positions’, ‘There can be only one Top Approver (a)’);
return false; // prevent dropping above first item below root
}
}
}
if (dropPosition == ‘after’) {
if (dropItem.value.substr(0, 4) == ‘root’ || dropItem.value.substr(23, 4) == ‘root’) {
if (approvalData.length > 2) {
if (approvalData[1].level == ‘1’) {
msgBox(‘Positions’, ‘There can be only one Top Approver (b)’);
return false; // prevent dropping after root if there is already a position there (Top Approver)
}
}
}
}
}
}
return false; // prevent drop
}
});
$(‘#treePositions’).css(‘visibility’, ‘visible’);
// ================================================================================
$(‘#treeApproval’).jqxTree({
height: ‘300px’,
width: ‘600px’,
theme: ‘energyblue’,
allowDrag: true,
allowDrop: true,
source: treeApprovalData,
dragStart: function(item) {
return true; // allow drag
},
dragEnd: function(dragItem, dropItem, args, dropPosition, tree) {
if (tree.attr(‘id’) == ‘treePositions’) {
var okToRemove = true;
if (okToRemove) {
var items = $(‘#treeApproval’).jqxTree(‘getItems’),
pos = getPositionName(dragItem.value.substr(8, 4)),
x = 0;
for (x = 0; x < items.length; x++) {
if (items[x].parentId == dragItem.id) {
msgBox(‘Approvals’, ‘This Position cannot be removed while there are other positions subordinate to it’);
return false; // prevent moving from treeApproval to treePositions
break;
}
}
$(‘#treeApproval’).jqxTree(‘removeItem’, dragItem.element);
msgBox(‘Approvals’, ‘Position “‘ + pos + ‘” removed from the Tree’);
}
return false; // prevent moving from treeApproval to treePositions
} else {
if (tree.attr(‘id’) == ‘treeApproval’) {
if (dropPosition == ‘inside’) {
if (dropItem.value.substr(0, 4) == ‘root’) {
msgBox(‘Approvals’, ‘The BOE item cannot be modified’);
return false; // prevent dropping on root
}
} else {
if (dropPosition == ‘before’) {
if (dropItem.value.substr(0, 4) == ‘root’) {
msgBox(‘Approvals’, ‘There can be nothing above the BOE in the Tree’);
return false; // prevent dropping above root
} else {
if (dropItem.value.substr(23, 4) == ‘root’) {
msgBox(‘Approvals’, ‘There can be only one Top Approver’);
return false; // prevent dropping above first item below root
}
}
}
}
}
}
return true; // allow the drop
}
});
$(‘#treeApproval’).css(‘visibility’, ‘visible’);
}
// ================================================================================
positionsData = [ { value: ‘0010’, label: ‘Superintendent’, selected: true },
{ value: ‘0020’, label: ‘Principal’ },
{ value: ‘0030’, label: ‘Vice Principal’ },
{ value: ‘0040’, label: ‘Department Head’ },
{ value: ‘0050’, label: ‘Secretary’ },
{ value: ‘0060’, label: ‘Board Secretary/Business Administrator’ }
];
// ================================================================================
treeApprovalData = [ { id: 1, parentid: -1, label: ‘Board Of Education’, value: ‘root ???????????????????????0’, items: [
{ id: 2, parentid: 1, label: ‘Superintendent’, value: ‘001000010010???00000001root 1’, items: [
{ id: 3, parentid: 2, label: ‘Secretary’, value: ‘005000010050???00000005001000012’},
{ id: 4, parentid: 2, label: ‘Principal’, value: ‘002000010020???00000002001000012’, items: [
{ id: 5, parentid: 4, label: ‘Secretary’, value: ‘005000020050???00000006002000013’ },
{ id: 6, parentid: 4, label: ‘Vice Principal’, value: ‘003000010030???00000003002000013’, items: [
{ id: 7, parentid: 6, label: ‘Secretary’, value: ‘005000030050???00000007003000014’ },
{ id: 8, parentid: 6, label: ‘Department Head’, value: ‘004000010040???00000004003000014’, items: [
{ id: 9, parentid: 8, label: ‘Secretary’, value: ‘005000040050???00000008004000015’ }
]
},
{ id: 10, parentid: 6, label: ‘Department Head’, value: ‘004000020040???00000009003000014’, items: [
{ id: 11, parentid: 10, label: ‘Secretary’, value: ‘005000050050???00000010004000025’ }
]
},
{ id: 12, parentid: 6, label: ‘Department Head’, value: ‘004000030040???00000011003000014’, items: [
{ id: 13, parentid: 12, label: ‘Secretary’, value: ‘005000060050???00000012004000035’ }
]
},
{ id: 14, parentid: 6, label: ‘Department Head’, value: ‘004000040040???00000013003000014’, items: [
{ id: 15, parentid: 14, label: ‘Secretary’, value: ‘005000070050???00000014004000045’ }
]
}
]
}
]
}
]
},
{ id: 16, parentid: 2, label: ‘Board Secretary/Business Administrator’, value: ‘006000010060???00000015001000012’ }
]
}
];
console.log(‘treeApprovalData:’);
console.log(treeApprovalData);
// ================================================================================
function msgBox(title, msg) {
alert(‘From ‘ + title + ‘:\n’ + msg);
$(‘#treeExpandAll’).jqxButton(‘focus’);
}
//
function getPositionName(position) {
var positionName = ”,
x = 0;
for (x = 0; x < positionsData.length; x++) {
if (positionsData[x].value == position) {
positionName = positionsData[x].label;
break;
}
}
return positionName;
}
//
console.log(‘Script end …’);
</script><form id=”ApprovalTree” name=”ApprovalTree” action=”{{=URL(‘default’, ‘DisplayApprovalTree’)}}”>
<div id=”jqxWidget”>
<table>
<tr>
<td>
<div style=”float: left; margin-top: 5px; margin-left: 0px; font-size: 14pt; color: blue;”>Positions</div>
</td>
<td>
<div style=”float: left; margin-top: 5px; margin-left: 20px; font-size: 14pt; color: blue;”>Approval Tree</div>
</td>
<td style=”text-align: right;”>
<input type=”button” id=”treeExpandAll” value=”Expand All” tabindex=”4″ />
<input type=”button” id=”treeCollapseAll” value=”Collapse All” tabindex=”5″ />
</td>
</tr>
<tr>
<td>
<div id=”treePositions” style=”visibility: hidden; float: left; margin-top: 0px; margin-left: 0px;” tabindex=”1″></div>
</td>
<td colspan=”2″>
<div id=”treeApproval” style=”width: 200px; height: 200px; float: left; margin-top: 0px; margin-left: 20px;” tabindex=”0″ autofocus></div>
</td>
</tr>
</table>
</div>
</form>Hello Nadezhda,
Sorry about the code posting. I did use the “code” button, but it did not maintain the indentations.
Hello Craig Matthews,
Please, paste again your html/javascript code, mark it and after that click on
code
button (paste your code between this symbol `).Best Regards,
NadezhdajQWidgets team
http://www.jqwidgets.com/<script language="javascript" type="text/javascript" src="../../static/js/jquery.js"></script> <script language="JavaScript" type="text/javascript" src="../../static/js/jqwidgets/jqxcore.js"></script> <script language="javascript" type="text/javascript" src="../../static/js/jqwidgets/jqxdragdrop.js"></script> <script language="JavaScript" type="text/javascript" src="../../static/js/jqwidgets/jqxbuttons.js"></script> <script language="JavaScript" type="text/javascript" src="../../static/js/jqwidgets/jqxpanel.js"></script> <script language="JavaScript" type="text/javascript" src="../../static/js/jqwidgets/jqxscrollbar.js"></script> <script language="javascript" type="text/javascript" src="../../static/js/jqwidgets/jqxtree.js"></script> <link rel="stylesheet" type="text/css" href="../../static/js/jqwidgets/styles/jqx.base.css" /> <link rel="stylesheet" type="text/css" href="../../static/js/jqwidgets/styles/jqx.energyblue.css" /> <script language="JavaScript" type="text/javascript"> console.log('Script start ...'); var positionsData, treeApprovalData; $(document).ready(function () { console.log('Entering document ready ...'); document.title = "Organization Tree" addPageEventListeners(); createPageElements(); $('#treeApproval').jqxTree('expandAll'); $('#treeApproval').jqxTree('focus'); console.log('Exiting document ready ...'); }); function addPageEventListeners() { $('#treeExpandAll').on('click', function(event) { $('#treeApproval').jqxTree('expandAll'); }); $('#treeCollapseAll').on('click', function(event) { $('#treeApproval').jqxTree('collapseAll'); }); } function createPageElements() { $('#treeExpandAll').jqxButton({ width: '125px', height: '25px', theme: 'energyblue' }); $('#treeCollapseAll').jqxButton({ width: '125px', height: '25px', theme: 'energyblue' }); // ================================================================================ $('#treePositions').jqxTree({ height: '300px', width: '300px', theme: 'energyblue', allowDrag: true, allowDrop: true, source: positionsData, dragStart: function(item) { return true; // allow the drag }, dragEnd: function(dragItem, dropItem, args, dropPosition, tree) { if (tree.attr('id') == 'treePositions') { msgBox('Positions', 'Reordering within Positions is not allowed'); return false; // prevent reordering within treePositions } else { if (tree.attr('id') == 'treeApproval') { if (dropPosition == 'inside') { if (dropItem.value.substr(0, 4) == 'root') { msgBox('Positions', 'The BOE Item cannot be modified'); return false; // prevent dropping on root } } if (dropPosition == 'before') { if (dropItem.value.substr(0, 4) == 'root') { msgBox('Positions', 'There can be nothing above the BOE in the Tree'); return false; // prevent dropping above root } else { if (dropItem.value.substr(23, 4) == 'root') { msgBox('Positions', 'There can be only one Top Approver (a)'); return false; // prevent dropping above first item below root } } } if (dropPosition == 'after') { if (dropItem.value.substr(0, 4) == 'root' || dropItem.value.substr(23, 4) == 'root') { if (approvalData.length > 2) { if (approvalData[1].level == '1') { msgBox('Positions', 'There can be only one Top Approver (b)'); return false; // prevent dropping after root if there is already a position there (Top Approver) } } } } } } return false; // prevent drop } }); $('#treePositions').css('visibility', 'visible'); // ================================================================================ $('#treeApproval').jqxTree({ height: '300px', width: '600px', theme: 'energyblue', allowDrag: true, allowDrop: true, source: treeApprovalData, dragStart: function(item) { return true; // allow drag }, dragEnd: function(dragItem, dropItem, args, dropPosition, tree) { if (tree.attr('id') == 'treePositions') { var okToRemove = true; if (okToRemove) { var items = $('#treeApproval').jqxTree('getItems'), pos = getPositionName(dragItem.value.substr(8, 4)), x = 0; for (x = 0; x < items.length; x++) { if (items[x].parentId == dragItem.id) { msgBox('Approvals', 'This Position cannot be removed while there are other positions subordinate to it'); return false; // prevent moving from treeApproval to treePositions break; } } $('#treeApproval').jqxTree('removeItem', dragItem.element); msgBox('Approvals', 'Position "' + pos + '" removed from the Tree'); } return false; // prevent moving from treeApproval to treePositions } else { if (tree.attr('id') == 'treeApproval') { if (dropPosition == 'inside') { if (dropItem.value.substr(0, 4) == 'root') { msgBox('Approvals', 'The BOE item cannot be modified'); return false; // prevent dropping on root } } else { if (dropPosition == 'before') { if (dropItem.value.substr(0, 4) == 'root') { msgBox('Approvals', 'There can be nothing above the BOE in the Tree'); return false; // prevent dropping above root } else { if (dropItem.value.substr(23, 4) == 'root') { msgBox('Approvals', 'There can be only one Top Approver'); return false; // prevent dropping above first item below root } } } } } } return true; // allow the drop } }); $('#treeApproval').css('visibility', 'visible'); } // ================================================================================ positionsData = [ { value: '0010', label: 'Superintendent', selected: true }, { value: '0020', label: 'Principal' }, { value: '0030', label: 'Vice Principal' }, { value: '0040', label: 'Department Head' }, { value: '0050', label: 'Secretary' }, { value: '0060', label: 'Board Secretary/Business Administrator' } ]; // ================================================================================ treeApprovalData = [ { id: 1, parentid: -1, label: 'Board Of Education', value: 'root ???????????????????????0', items: [ { id: 2, parentid: 1, label: 'Superintendent', value: '001000010010???00000001root 1', items: [ { id: 3, parentid: 2, label: 'Secretary', value: '005000010050???00000005001000012'}, { id: 4, parentid: 2, label: 'Principal', value: '002000010020???00000002001000012', items: [ { id: 5, parentid: 4, label: 'Secretary', value: '005000020050???00000006002000013' }, { id: 6, parentid: 4, label: 'Vice Principal', value: '003000010030???00000003002000013', items: [ { id: 7, parentid: 6, label: 'Secretary', value: '005000030050???00000007003000014' }, { id: 8, parentid: 6, label: 'Department Head', value: '004000010040???00000004003000014', items: [ { id: 9, parentid: 8, label: 'Secretary', value: '005000040050???00000008004000015' } ] }, { id: 10, parentid: 6, label: 'Department Head', value: '004000020040???00000009003000014', items: [ { id: 11, parentid: 10, label: 'Secretary', value: '005000050050???00000010004000025' } ] }, { id: 12, parentid: 6, label: 'Department Head', value: '004000030040???00000011003000014', items: [ { id: 13, parentid: 12, label: 'Secretary', value: '005000060050???00000012004000035' } ] }, { id: 14, parentid: 6, label: 'Department Head', value: '004000040040???00000013003000014', items: [ { id: 15, parentid: 14, label: 'Secretary', value: '005000070050???00000014004000045' } ] } ] } ] } ] }, { id: 16, parentid: 2, label: 'Board Secretary/Business Administrator', value: '006000010060???00000015001000012' } ] } ]; console.log('treeApprovalData:'); console.log(treeApprovalData); // ================================================================================ function msgBox(title, msg) { alert('From ' + title + ':\n' + msg); $('#treeExpandAll').jqxButton('focus'); } // function getPositionName(position) { var positionName = '', x = 0; for (x = 0; x < positionsData.length; x++) { if (positionsData[x].value == position) { positionName = positionsData[x].label; break; } } return positionName; } // console.log('Script end ...'); </script> <form id="ApprovalTree" name="ApprovalTree" action="{{=URL('default', 'DisplayApprovalTree')}}"> <div id="jqxWidget"> <table> <tr> <td> <div style="float: left; margin-top: 5px; margin-left: 0px; font-size: 14pt; color: blue;">Positions</div> </td> <td> <div style="float: left; margin-top: 5px; margin-left: 20px; font-size: 14pt; color: blue;">Approval Tree</div> </td> <td style="text-align: right;"> <input type="button" id="treeExpandAll" value="Expand All" tabindex="4" /> <input type="button" id="treeCollapseAll" value="Collapse All" tabindex="5" /> </td> </tr> <tr> <td> <div id="treePositions" style="visibility: hidden; float: left; margin-top: 0px; margin-left: 0px;" tabindex="1"></div> </td> <td colspan="2"> <div id="treeApproval" style="width: 200px; height: 200px; float: left; margin-top: 0px; margin-left: 20px;" tabindex="0" autofocus></div> </td> </tr> </table> </div> </form>
Hello Craig Matthews,
Please, try calling ‘removeItem’ in setTimeout as the following example shows:
dragEnd: function (dragItem, dropItem, args, dropPosition, tree) { if (tree.attr('id') == 'treePositions') { var okToRemove = true; if (okToRemove) { var items = $('#treeApproval').jqxTree('getItems'), pos = getPositionName(dragItem.value.substr(8, 4)), x = 0; for (x = 0; x < items.length; x++) { if (items[x].parentId == dragItem.id) { msgBox('Approvals', 'This Position cannot be removed while there are other positions subordinate to it'); return false; // prevent moving from treeApproval to treePositions break; } } setTimeout(function () { $('#treeApproval').jqxTree('removeItem', dragItem.element); }, 500); msgBox('Approvals', 'Position "' + pos + '" removed from the Tree'); } return false; // prevent moving from treeApproval to treePositions } else { if (tree.attr('id') == 'treeApproval') { if (dropPosition == 'inside') { if (dropItem.value.substr(0, 4) == 'root') { msgBox('Approvals', 'The BOE item cannot be modified'); return false; // prevent dropping on root } } else { if (dropPosition == 'before') { if (dropItem.value.substr(0, 4) == 'root') { msgBox('Approvals', 'There can be nothing above the BOE in the Tree'); return false; // prevent dropping above root } else { if (dropItem.value.substr(23, 4) == 'root') { msgBox('Approvals', 'There can be only one Top Approver'); return false; // prevent dropping above first item below root } } } } } } return true; // allow the drop }
Best Regards,
NadezhdajQWidgets team
http://www.jqwidgets.com/Hello Nadezhda,
I see what you were trying to do with the “delay”.
This works as long as the alert (called withing msgBox) is answered before the timeout value. I tried 3000 and then waited longer than 3 seconds (like a typical end-user may), and the error still appeared.
By altering the code to:
setTimeout(function () { $('#treeApproval').jqxTree('removeItem', dragItem.element); msgBox('Approvals', 'Position "' + pos + '" removed from the Tree'); }, 500);
placing the msgBox (alert) call withing the delay, the problem is solved.
At this point I am wondering if you plan to build in a processing delay in a future version or if the documentation will be altered to reflect the need for setTimeout?
Anyway, it is working once again.
Thank you for your help with these wonderful widgets.
Hello Craig Matthews,
For your information, calling “removeItem” in dragEnd callback function is not supported and the above example is workaround for your custom implementation.
Best Regards,
NadezhdajQWidgets team
http://www.jqwidgets.com/ -
AuthorPosts
You must be logged in to reply to this topic.