Passing data from MVC controller to jsTree through ajax calls. - javascript

I have a jsTree with a parent node and 5 children nodes. They function fine. I am trying to implement a dynamic jsTree where with click of a node, an ajax call should pass that node's ID to my java MVC spring-boot controller and a Map with keys as child nodes' IDs and value as names of child nodes.
So far I have managed to get the value of the clicked child node's ID and pass it to my java controller through ajax call. But I'm not able to proceed further as I am not sure how to structure the data that is passed from controller to ajax call which in turn has to implement the jsTree.
Here's the code of my existing jsTree -
<div id="container">
<ul>
<li id = "id1">Root
<ul>
<li id="id 1-1">child 1</li>
<li id="id 1-2">child 2</li>
<li id="id 1-3">child 3</li>
<li id="id 1-4">child 4</li>
<li id="id 1-5">child 5</li>
</ul>
</li>
</ul>
</div>
Here's the code of my ajax -jquery call that passes the nodeID to the controller-
$(function() {
$('#container').on('changed.jstree', function (e, data) {
var i, j, r = [], rid = [];
for(i = 0, j = data.selected.length; i < j; i++) {
r.push(data.instance.get_node(data.selected[i]).text);
rid.push(data.instance.get_node(data.selected[i]).id);
}
console.clear();
console.log('Selected: ' + r.join(', '));
console.log('Selected id: ' + rid.join(', '));
$.ajax({
type: 'GET',
url: "http://localhost:8080/tree/object?nodeID="+rid.join(', '),
contentType: 'text/plain',
crossDomain: false,
async:true,
success:function() {
}
});
})
.jstree();
});
I'm limited by my knowledge of jsTree, ajax and jquery. Any help would be appreciated. I am looking into the documentation of jsTree: filling the tree through ajax calls here.

You don't want to do your own AJAX call - You can set a URL to use as per: https://www.jstree.com/api/#/?f=$.jstree.defaults.core.data and JSTree will perform the Ajax calls for you.
set the url property to your url, and data to a function that returns the node id;
'url' : 'ajax_nodes.html',
'data' : function (node) {
return { 'id' : node.id };
}
If returning the data from an Ajax call - you should probably return it in JSON instead, not in HTML.
So this page is what you should be looking at: https://www.jstree.com/docs/json/
The minimum you need is a JSON object like so;
{
id : "string" // will be autogenerated if omitted
text : "string"
children : false
}
Where Children should be true if that node can expand and trigger another all with itself as the ID passed to get its children and false if it is a leaf node.

Related

jstree disable_node not working when id is string

I want to disable some nodes in jstree plugin. I used the following code for this purpose and everything was fine.
var tidlist = ['17f6171a-4da6-4904-ae75-c290eb101717', '3fbb9e60-13f2-48e9-9323-003cb46dbb5d'];
for (var i = 0; i < tidlist.length; i++)
{
$.jstree.reference('#jstree1').disable_node(tidlist[i]);
}
In this example, the IDs are defined as fixed. But the IDs are not fixed and come from the controller.
Controller
ViewBag.rlist = JsonConvert.SerializeObject(tQuery.Select(t => t.CenterUserID).ToList());
View
var tidlist = [];
tidlist = '#ViewBag.rlist';
for (var i = 0; i < tidlist.length; i++)
{
$.jstree.reference('#jstree1').disable_node(tidlist[i]);
}
But this code does not work.
Try to set the break point the debug the JavaScript via F12 developer tools, then, you can see the tidlist value should be System.Collections.Generic.List1[System.String];`, instead of the string array.
The issue is that we can't directly access the ViewBag value in the JavaScript.
To transfer the string array from controller to JavaScript script, first, in the controller, convert the array or list to a string (with separator), then, in the View page, use a hidden field to store the ViewBag value, finally, in the JavaScript script, get value from the hidden field and call the Split () method to convert the string value to an array.
Code as below:
Controller:
var strlist = new List<string>() { "17f6171a-4da6-4904-ae75-c290eb101717", "3fbb9e60-13f2-48e9-9323-003cb46dbb5d" };
ViewBag.rlist = string.Join(',', strlist);
View Page:
<div id="jstree">
<!-- in this example the tree is populated from inline HTML -->
<ul>
<li>
Root node 1
<ul>
<li id="17f6171a-4da6-4904-ae75-c290eb101717">Child node 1</li>
<li>Child node 2</li>
<li id="3fbb9e60-13f2-48e9-9323-003cb46dbb5d">Child node 3</li>
<li>Child node 4</li>
</ul>
</li>
<li>Root node 2</li>
</ul>
</div>
<button>demo button</button>
<input type="hidden" id="myInput" data-myValue="#ViewBag.rlist" />
#section Scripts{
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js"></script>
<script>
$(function () {
// 6 create an instance when the DOM is ready
$('#jstree').jstree();
// 7 bind to events triggered on the tree
$('#jstree').on("changed.jstree", function (e, data) {
console.log(data.selected);
});
// 8 interact with the tree - either way is OK
$('button').on('click', function () {
// var tidlist = ['17f6171a-4da6-4904-ae75-c290eb101717', '3fbb9e60-13f2-48e9-9323-003cb46dbb5d'];
var tidlist = $("#myInput").attr("data-myValue").split(","); //the result is an string array, like: ['17f6171a-4da6-4904-ae75-c290eb101717', '3fbb9e60-13f2-48e9-9323-003cb46dbb5d']
for (var i = 0; i < tidlist.length; i++) {
$.jstree.reference('#jstree').select_node(tidlist[i]);
}
});
});
</script>
}
The result as below:

Send order of jQuery sortable to Laravel controller

I have a collection of Article objects that have a public attribute int priority. This field ist used to display the articles in the intended order. However, I'd like to be able to rearrange the order of the articles in the admin area.
I included jQuery and with this Laravel/Blade snippet
<ul class="selectable-demo-list" id="sortable-list-basic">
#FOREACH($articles as $article)
<li> {{ $article->label}} </li>
#ENDFOREACH
</ul>
I can produce this HTML output:
<ul class="selectable-demo-list" id="sortable-list-basic">
<li> My article (ID: 1) </li>
<li> Another article (ID: 2) </li>
<li> ... </li>
</ul>
I can access the respective priority via $article->priority and their unique IDs via $article->id if these elements should be included in the code.
The <ul> posted above is rendered correctly: All <li> elements are displayed as sortable jQuery elements. If I drag an item to a certain position, it stays there for the time being.
Unfortunately, I have no idea how to save the new order (= update the items priorities according to the list positions).
This shouldn't be done directly. Instead, I want to use an update button. Maybe I can use a form and send an array like this to my controller:
$priorities = [1=>3; 2=>1; 3=>2] // ID => new priority
Is this possible? Or should I use a different approach? Any help is greatly appreciated!
Add id with each of your li like id="id-{{ $article['id'] }}"
You can call an ajax request when you are changing any order using this sortable plugin like below code
$("#sortable-list-basic").sortable({
update: function (e, u) {
var data = $(this).sortable('serialize');
$.ajax({
url: "{{ url('controller/sorting_method') }}",
type: 'post',
data: data,
success: function (result) {
},
complete: function () {
}
});
}
});
Then inside your method, take your new order for each item & save it to database such as
$ids = $request->id;
foreach($ids as $order => $id){
$article = Article::findOrFail($id);
$article->order = $order;
$article->save();
}

appending via Ajax to .closest() parent not working jquery

I'm commenting an specific post from a list. This is why I'm using .closest() parent.
JQUERY
$('.comment').on('click', function(){
var parent = $(this).closest('.post');
$(document).CommentButton(id_user,comment);
});
FUNCTION The comments posts via Ajax and retrieve a value....
jQuery.fn.CommentButton=function(id_user,comment){
$.ajax({
type: 'POST',
url: "comment.php",
data: {
"comment":comment,
"id_user":id_user,
},
success: function(data) {
//alert(data)
parent.find(".container").append(comment);//problem
}
});
}
HTML I choose a random post to comment from the list.
<ul>
<li class="post"></li>
<li class="post"></li>
<li class="post">
<div class="container"></div>
<button class="comment"></button>
</li>
<li class="post"></li>
</ul>
PROBLEM
I cant append the comment in its specific container of his parent. How should I do that?

jstree html and json

I am using JSTree to create a tree structure of the data I have.
I am using Scala templates. The templates files create the html. the html has a SJTree div tag and also displays the first level subtree correctly, but I want to make an ajax call to expand the tree further.
Below is the code I have
#(course:models.CourseDetails,realtedCourses:List[models.CourseDetails])
#import helper._
#importhelper.twitterBootstrap._
#main() {
#wflash()
<div id="jstree">
<!-- in this example the tree is populated from inline HTML -->
<ul>
<li id="#{course.wnCourseName}"><font color="black">#course.wnCourseName</font>
<ul>
#for(children1 <- realtedCourses) {
<li id="#{children1.wnCourseName}"> <b><font color="blue">#children1.wnCourseName</font></b></li>
}
</ul>
</li>
</ul>
</div>
<div id="CourseData" class="tree well">
#views.html.display.displayCourseInfo(course)</div>
</div>
and the JavaScript code is
$('#jstree').jstree();
$('#jstree').jstree({
'core' : {
'data' : {
'url' : function (node){
if (node.id === '#')
{
return "http://localhost:9000/getCourses/" ;
}else
return "http://localhost:9000/getCourses/" + node.id;
},
'data' : function (node) {
return { 'id' : node.id };
}
}
}
});
I want to call the ajax function only for the subtree on click event. I saw the events section in the JSTree plugin, but not sure how to make an ajax call to the server on event and update the tree.
server side JSON response
[
{
"data":"Science",
"attr":{
"id":"Science"
},
"state":"closed"
},
{
"data":"Commerce",
"attr":{
"id":"Commerce"
},
"state":"closed"
},
{
"data":"Arts",
"attr":{
"id":"Arts"
},
"state":"closed"
}
]
should I include the parent attribute as well?
Ideally, I would like to make an ajax call on event and update the tree.
You should not create the tree twice. Keep in mind mixing HTML and JSON data sources will be complicated to achieve. It would be better if you could create a JS variable, which will hold the initial tree, and then move to AJAX. In any case, you need to use core.data as a function.
If you insist on combining HTML with JSON, you will have to first store the original HTML, and then proceed to AJAX, like this:
var tmp = $('#jstree').html();
$('#jstree').jstree({
"core" : {
"check_callback" : true,
"data" : function (node, cb) {
if(node.id === "#") {
cb(tmp);
}
else {
// enhance the AJAX call as needed (verb, data)
$.ajax({ url : "http://localhost:9000/getCourses/" + node.id })
.done(function (data) { cb(data) });
}
}
}
});
Here is a working demo (without the AJAX of course):
http://jsfiddle.net/DGAF4/542/

angular js calling ng-init on ng-repeat

I am calling ng-int() on ng-repeat like this:
<ul class="title_page1" style="margin:0; padding:0;">
<li ng-init='some(val.id);' ng-repeat="(key,val) in menu">{{val.name}}</span><span>{{size}}</span></li>
</ul>
I have three elements in menu, by this ng-init is getting called for each ng-repeat but {{size}} from some(val.id). I am getting same size for all the 3 elements. Please kelp me in sorting out this.
$scope.some={function(id){
return $http({
url : 'url+id',
method : 'GET',
async : false,
}).success(function(data) {
$scope.size = data.length;
});
};
$scope.menu=[{java,php,micro}];
And this the thins I am doing but the size i am getting for all the elements is same.
but i have seen in the google but i did not get any result from google
You are retrieving the data for 3 id's, however your saving them in the scope where your controller resides, which can only have one size variable. What I would do is save the size variable into the val object.
<ul class="title_page1" style="margin:0; padding:0;">
<li ng-init='some(val);' ng-repeat="(key,val) in menu">{{val.name}}</span><span>{{val.size}}</span></li>
</ul>
$scope.some={function(val){
return $http({
url : 'url'+val.id,
method : 'GET',
async : false,
}).success(function(data) {
val.size = data.length;
});
};
$scope.menu=[{java,php,micro}];

Categories

Resources