JSTree Select Open Node - javascript

I have a problem with the JSTree.
I'm filling the selected item with data from DB.
But I want the item I selected to open automatically after it is filled. I could not do the automatic opening part.
I added one button to the page (btn_test).
I wrote the following in the click event of this button.
$("#TreeElement").jstree("toggle_node","#34B526D0-1E2C-4170-829E-1995782DB831");
When I click on the btn_test button, the node whose ID is written opens and closes. But I could not set this to open automatically when selecting and filling the corresponding node.
$("#btn_test").click(function () {
$("#TreeElement").jstree("toggle_node","#34B526D0-1E2C-4170-829E-1995782DB831");
});
JS side is as follows;
var TreeElement = $("#TreeElement");
TreeElement.jstree({
"core" : {
"check_callback" : true
},
state : { "opened" : true }
});
TreeElement.bind("select_node.jstree", function (e, data) {
GetSelectedElementChildrenNodes(data.node.id);
});
function GetSelectedElementChildrenNodes(SelectedNodeId) {
$.getJSON('http://serveripadress/api/browser.php?getchildren='+SelectedNodeId,function (data) {
$.each(data,function (index,element) {
TreeElement.jstree().create_node(SelectedNodeId
, { "id" : element.nodeid, "text" : element.nodename}, "last");
TreeElement.jstree(true).set_icon(element.nodeid,element.icon);
});
});
}
I get a different result when I change the code as follows.
I click on Node1, it is filled with relevant data, but it does not open, then I click on Node2, but node1 is opening :)
TreeElement.bind("select_node.jstree", function (e, data) {
GetSelectedElementChildrenNodes(data.node.id);
$("#"+data.node.id).jstree("open_all");
});
I've been changing the code for a while, but I just couldn't get it to work. If someone can help me with this, I really thank him.
Thank you so much!

Problem solved.
In the function where I pulled the data with Json, I added the following code to the end of getJson.
TreeElement.jstree("toggle_node",NodeId);
The new state of the function is as follows;
function GetSelectedElementChildrenNodes(SelectedNodeId) {
$.getJSON('http://serveripadress/api/browser.php?getchildren='+SelectedNodeId,function (data) {
$.each(data,function (index,element) {
TreeElement.jstree().create_node(SelectedNodeId
, { "id" : element.nodeid, "text" : element.nodename}, "last");
TreeElement.jstree(true).set_icon(element.nodeid,element.icon);
});
TreeElement.jstree("toggle_node",NodeId);
});
}

Related

How to turn ON the jsTree contextmenu only for the nodes that are beyond level 2?

So my issue is that i need have contextmenu only on the nodes of my tree that are nested after the 2nd level or deeper. For example :
I want to have the default context menu on the nodes "1.1.1", "1.1.1.1", etc... but i dont want this context menu to appear when i right-click on "1" or "1.1".
How i'm supposed to choose on which nodes to appear and on which not ?
I found some examples like this one :
function customMenu(node) {
//Show a different label for renaming files and folders
if ($(node).hasClass("jstree-closed") || $(node).hasClass("jstree-open")) { //If node is a folder
var renameLabel = "Rename Folder";
}
else {
var renameLabel = "Rename File";
}
var items = {
"upload" : {
"label" : "Upload File",
"action" : function () { ... }
},
"rename" : {
"label" : renameLabel, //Different label (defined above) will be shown depending on node type
"action" : function () { ... }
},
"delete" : {
"label" : "Delete File",
"action" : function () { ... }
}
};
//If node is a folder do not show the "delete" menu item
if ($(node).hasClass("jstree-closed") || $(node).hasClass("jstree-open")) {
delete items.remove;
}
return items;
}
I need something like this, but i dont know how to check on which level my folder is nested. The checks in my example are for "folder or file".
Has anyone a clue ?
I don't think jsTree has a out-of-the-box method for it, so you can suppress the menu showing up for nodes at level 1 and 2 with the code as below. Check demo - Fiddle Demo.
.on('show_contextmenu.jstree', function(e, reference, element) {
if ( reference.node.parents.length < 3 ) {
$('.vakata-context').remove();
}
});

Getting Data from button click for Jquery

I am using the "Second Solution" from this problem:
call the same jQuery function in multiple buttons
I am dynamically creating my buttons, based on an input, so there is currently 45 buttons! (used to select page number)
Is there a way to use the value of the button as data in my $.get so I can pull the data for the page?
$('.bclick').click(function(){
$.getJSON("url", { page: [need button data here] }, function(data){
//Some actionable code
})
});
.bclick is the class given to each of the buttons created.
when you are inside of the function, the reserved word this is a reference to your clicked button.
$('.bclick').click(function(){
var page = $(this).val();
$.getJSON("url", { page: page }, function(data){
//Some actionable code
})
});
If your buttons are created dinamically probably this solution won't work. I may suggest you to use $.on():
$("parent selector or form selector").on("click", ".bclick", function(){
var page = $(this).val();
$.getJSON("url", { page: page }, function(data){
//Some actionable code
})
})
If you are generating buttons dynamically, then use .on.
$(function(){
$(document).on("click", ".blick", function(){
var $this = $(this);
var buttonName = $this.attr("name");
});
});
Sample code
Yes you can by adding an extra attribute to your .bclick element, for example
<button class="bclick" data="your data here"></button>.
Then
$('.bclick').click(function(){
var buttonData = $(this).attr('data');
$.getJSON("url", { page: buttonData }, function(data){
//Some actionable code
})
});

Template not displaying collection when modal is open

Every time I load the bootbox.js modal the collections displayed in the template behind it vanish. See the pictures for clarity.
Before the the modal is clicked
https://gyazo.com/b00903331bcc690e98888a5b2ad3e486
While the modal is open the collections in the background vanish and will only comeback once you refresh the buy page example:
https://gyazo.com/a36d0e8df55bc2d5b63a5a04b92efb03
The orders table template helper code
Template.ordersTable.helpers({
orders : function () {
var orderType = Session.get('currentOrderTemplate');
//if order type == 2 then the active tab has been selected.
if(orderType == 3) {
return OrderList.find({createdBy : Meteor.userId()}).fetch();
} else {
return OrderList.find({orderType : orderType}).fetch();
}
}
});
Now, when I do the same thing on the active orders tab it works as I wanted. The collections are displayed in the background and update when the form is submitted.
Template.activeOrderTable.helpers({
activeOrders : function () {
return OrderList.find().fetch();
}
});
Completely forgot about bootbox code.
Template.loggedIn.events({
"click a" : function (event) {
var orderType = $(event.target).attr('data-order-type');
Session.set('currentOrderTemplate', orderType);
},
"click #createOrder" : function (event) {
bootbox.dialog({
title : 'Create Order',
message : "<div id='dialogNode'></div>"
});
Blaze.render(Template.createOrderForm, $("#dialogNode")[0]);
}
});
Any insight would be appreciated.
Thanks

How can I allow multiple rows in a table the ability to toggle on or off with a materialize switch?

What I'm trying to accomplish is to allow multiple rows inside a table to toggle on or off without affecting the other rows in that same table.
It works fine when I only have one row. But the moment I add another row , the switch starts turning off other rows.
Here's a video clip of what I mean->
https://www.youtube.com/watch?v=uLBrZND69Ps
And here's the code ->
// ClIENT CODE
Template.orionMaterializeLayout.events({
"change .switch input": function (event) {
var change = event.target.checked;
Meteor.call('toggleHidden', change);
}
});
// SERVER CODE
Meteor.methods({
'toggleHidden' : function(change){
console.log(change);
Banner.update({}, {$set:{hidden: change }});
}
});
// COLLECTIONS CODE, WHAT RENDERS THE ON/OFF SWITCH ON THE TABLE
Banner = new orion.collection('slideshow', {
title: 'Add Images', // The title of the page
link: {
title: 'Slideshow',
section: 'top',
image: '<i class="fa fa-picture-o"></i>'
},
tabular: {
columns: [
{ data: 'hidden', title: 'Visibility',
render: function(doc){
if (doc === true ){
return '<div class="switch"><label>Off<input type="checkbox" checked="checked"><span class="lever"></span>On</label></div>'
} else {
return '<div class="switch"><label>Off<input type="checkbox"><span class="lever"></span>On</label></div>'
}
}
}
]
}
});
It looks like you intend the toggling to write the change to the database on the backend (Mongo collection on the server). However, your Banner.update() call does not specify which document to update - so it updates every document in your collection!
You need to do two things (with your code as-is). First, capture the data context that has triggered the event handler. Normally, that will be this within your handler. So this._id should return the document ID. Second, you need to pass that ID to your method, to ensure it only updates that document.
Without all of your code, it is hard to guarantee a correct answer (especially not knowing the data context within the template) but the below is likely to work:
// ClIENT CODE
Template.orionMaterializeLayout.events({
"change .switch input": function (event) {
var change = event.target.checked;
Meteor.call('toggleHidden', change, this._id);
}
});
// SERVER CODE
Meteor.methods({
'toggleHidden' : function(change, docId){
console.log(change);
Banner.update({_id: docId}, {$set:{hidden: change }});
}
});

How to Enable/Disable JEditable

SOLUTION
Thanks to Arman's P. proof of concept, finally got it to work with my site.
CODE
//Edit Note
$(function(){
function makeEditable() {
$(".edit").editable('ajax/save.php?editnotetext', {
type : 'mce',
submit : '<button class="save_button">Save</button>',
event: 'dblclick',
indicator : 'Saving...',
tooltip : 'Doubleclick to edit...',
onblur: 'ignore',
width : '700px',
height : '100px',
callback : function(value, settings){
console.log('unlocked');
$.post('ajax/save.php?unlocknotetext', {"id" : $(this).attr('id')});
$(this).effect("highlight", {}, 3000);
$(this).parents('.panel').effect("highlight", {}, 3000);
},
'onreset' : function(){
console.log('unlocked');
$.post('ajax/save.php?unlocknotetext', {"id" : $(this).attr('id')});
}
});
};
makeEditable();
$('.edit').live('click', function() {
console.log('locked');
$.post('ajax/save.php?locknotetext', {"id" : $(this).attr('id')});
});
$(".edit").click(function() {
$.post('ajax/save.php?checklock', {"id" : $(this).attr('id')},
function(data) {
// USE SAME OPTION IN BOTH PLACES
// IF YOU USE 1ST OPTION, YOU CAN TAKE JEDITABLE OUT OF makeEditable() and do everything without that function
if (data[0].is_locked == 1) {
// Option 1
//$(this).editable('disable');
//alert(data[0].username.toUpperCase() + " is editing this note!");
// Option 2
$(".edit").unbind('dblclick');
} else {
// Option 1
//$(this).editable('enable')
// Option 2
makeEditable();
}
},
"json"
);
});
});
UPDATE
So now, as per what I think Arman suggested, I made JEdtiable only work if a custom event is triggered. I'm trying to trigger the event only if I find no lock. But now JEditable doesn't get called. There's something wrong with how I'm trying ot trigger it. [Note that JEditable does get called if if I test it with a button like <button onclick="$('.edit').trigger('custom_event');">Click to Edit</button>]
CODE
So here's my new code
$(function(){
$(".edit").bind("dblclick",function() {
$.ajax({ // first check to see if locked
type: "POST",
url: "ajax/save.php?locknotetext",
data: {"id" : $(this).attr('id')},
dataType: "json",
success: function(data){
if (data[0].is_locked == 1){ // if locked then alert someone is editing ntoe
alert(data[0].username.toUpperCase() + " is editing this note!");
}
else{
$(this).trigger('custom_event');
$(this).unbind('custom_event.editable');
}
}
}); //close $.ajax(
});
});
Here's the JEditable pieces
$(function(){
$(".edit").editable('ajax/save.php?editnotetext', {
type : 'mce',
submit : '<button class="save_button">Save</button>',
event: 'custom_event',
indicator : 'Saving...',
tooltip : 'Doubleclick to edit...',
onblur: 'ignore',
width : '700px',
height : '100px',
callback : function(value, settings){
console.log(this, value, settings);
$(this).effect("highlight", {}, 3000);
$(this).parents('.panel').effect("highlight", {}, 3000);
$.ajax({
type: "POST",
url: "ajax/save.php?unlocknotetext",
data: {"id" : $(this).attr('id')}
}); //close $.ajax(
//$(this).addClass("edit");
}
// },
// function(value, settings) {
// $(this).unbind('settings.event');
});
});
BACKGROUND
I'm creating a website where people can share and edit notes. What I would like to do is if someone is editing a note, the note gets locked so that another user can't edit the note.
I'm using JEditable. Users can double click so edit a note.
If a user doubleclicks, I do an AJAX call to see if there's a lock in the note. If there isn't then I lock the note and the user can edit. If there is a lock, I alert the user the "userX is currently editing the note".
PROBLEM
My problem is that I only want to call JEditable when there is no lock. Otherwise, I just want to alert the user that someone else is editing it. The problem I'm getting with my code below is that JEditable is called no matter what. I've also tried using another class name for the editable and adding the class only when there is no lock in that callback of the first AJAX call, but that doesn't work either.
Any suggestions would be much appreciated!
JEditable supports this natively at this point:
$.fn.editable = function(target, options) {
if ('disable' == target) {
$(this).data('disabled.editable', true);
return;
}
if ('enable' == target) {
$(this).data('disabled.editable', false);
return;
}
This seems to work:
$(...).editable("disable")
$(...).editable("enable")
Try to unbind previous event (probably dblclick) that jeditable added to the element, add your own with alert and then when the element is unlocked call jeditable again.
Another solution would be to add transparent div or something with absolute positioning on your elements when they're locked and bind dblclik event with your own message to that transpatrent elements. .remove() them when your original elements've been unlocked.
The problem I see in your code is: when first user dblclicks element you apply jeditable and lock it and when second user dbclicks it you want to alert, but the problem is that jeditable has already applied dblclick event to element. Instead of this change your check for lock to mouseenter event and if your condition for lock succeeds unbind dblclick event (see unbind), if nobody is editing simply apply jeditable, the function body of editText(). There is no need to have seperate function for it. And why are using .live(). Do you have dinamically added elements?
You can find also some answers to your question here JQuery JEditable - How to Disable on click editing
The solution I came up for you looks like this.
HTML file:
<html>
<head>
<title>Lock wirh jEditable</title>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
<script type="text/javascript" src="http://www.appelsiini.net/download/jquery.jeditable.mini.js"></script>
<script type="text/javascript">
$(function() {
function makeEditable() {
$('#editable').editable("save.php", {
tooltip : 'Doubleclick to edit...',
event : 'dblclick',
onblur : 'ignore',
callback : function(value, settings) {
console.log('unlocked');
},
'onreset' : function() {
console.log('unlocked');
$.post('unlock.php');
}
});
};
makeEditable();
$('#editable input').live('focus', function() {
console.log('locked');
$.post('lock.php');
});
$('#editable').hover(function() {
$.post('checklock.php', function(response) {
// USE SAME OPTION IN BOTH PLACES
// IF YOU USE 1ST OPTION, YOU CAN TAKE JEDITABLE OUT OF makeEditable() and do everything without that function
if (response) {
// Option 1
$('#editable').editable('disable');
// Option 2
//$('#editable').unbind('dblclick');
} else {
// Option 1
$('#editable').editable('enable')
// Option 2
//makeEditable();
}
});
});
});
</script>
</head>
<body>
<div id="editable">Here is the text that can be edited.</div>
</body>
</html>
LOCK.PHP
<?php
$fileName = 'lock.txt';
file_put_contents($fileName, '1');
?>
UNLOCK.PHP
<?php
$fileName = 'lock.txt';
file_put_contents($fileName, '0');
?>
CHECKLOCK.PHP
<?php
$fileName = 'lock.txt';
$locked = file_get_contents($fileName);
if ($locked == '0') {
echo false;
} else {
echo true;
}
?>
SAVE.PHP
<?php
$fileName = 'lock.txt';
file_put_contents($fileName, '0');
echo $_POST['value'];
?>
LOCK.TXT (Initial)
0
You can grab the idea from the example. Of course you can do it more elegantly. This is rough example. You can try on your own simply by creating those files in same directory on your web server and copy-pasting contents. Sorry for not putting demo online, jsFiddle doesn't support ajax with change state (at least I think so). If you need any further assistance, let me know. Good Luck.
This does require a bit of messing with classes, and placement, but it works well.
Here is the jquery UI based code to create a button that controls its own state and the state of the editable text
function makeEditable(params){ //params excluded for now
$("div#body").append("<button id='editTable'>Edit Table</button>"); //inserts a button into a div
$("div#body button#editTable").button({icons: {primary:'ui-icon-pencil'}}); //creates button
$("div#body button#editTable").unbind(); //removes all listeners
$("div#body button#editTable").hover( //sets hover behaviour
function(event){ //over
$(this).addClass("ui-state-hover");
},
function(event){ //over
$(this).removeClass("ui-state-hover");
}
);
//uses a class called editText which is assigned to the td elements of the blocks you want to make editable
$("div#body table .editText").editable("http://www.blah.com/Controller/CEditTable.php", {
indicator : 'Saving...',
tooltip : 'Click to edit...'
}); //basic editable initialization
$("div#body table .editText").editable("disable"); //disables by default
//adds a toggle to the button which enables/disables the editable functionality
$("div#body button#editTable").toggle(
function(event){
$("button#editTable").removeClass("ui-state-default");
$("button#editTable").addClass("ui-state-active");
$("div#body table .editText").editable("enable");
},
function(event){
$("button#editTable").removeClass("ui-state-active");
$("button#editTable").addClass("ui-state-default");
$("div#body table .editText").editable("disable");
}
);
$("div#body button#editTable").appendTo("div#body div#tableControls"); //move button to wherever to want it.
}

Categories

Resources