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/
Related
Is there a way to get objectId parameter from js and send it as parameter to Url action?
JS:
function ButtonClick(objectId) {
App.testID.fireEvent("click", objectId);
}
Ext.net:
Html.X().ID("testID").DirectEvents
(
de =>
{
de.Click.Url = Url.Action("TestMethod", "TestController");
de.Click.ExtraParams.Add(new Parameter("objectId", "I need objectId here"));
}
)
I came with diferent solution when I saw compiled code in debugger.
You can create direct event like this:
Html.X().ID("testID")
.Listeners
(
l =>
{
l.AfterRender.Handler = #"App.testID.on('testEvent', function(id) {
Ext.net.directRequest({
url: '/TestController/TestMethod',
extraParams:
{
'objectId': id
}
});
});";
}
)
And fire it with:
function ButtonClick(objectId) {
App.testID.fireEvent("testEvent", objectId);
}
Just add the raw code as the value string and add ParameterMode.Raw to the Parameter instance, like this:
de.Click.ExtraParams.Add(new Parameter("objectId", "App.MyComponent.Id", ParameterMode.Raw));
(based on Examples Explorer - Layouts > CardLayout)
Or alternatively, a custom object:
de.Click.ExtraParams.Add(new
{
myTargetId = JRawValue.From("this.up('button').id")
});
(based on Examples Explorer - Models > Data Annotations)
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.
I am doing a ajax request to pass some data from Views.py to the HTML file and render it using DataTables() javascript library.
The problem I am facing is that the displayed datatable is not following the column order that I would like to.
I don´t know if the solution is to reorder the json data that the datatable receives or to use some functionallity of DataTables().
What should be the best solution to reorder the table´s column? And how can I apply it to the code bellow?
Views.py
...
def test_table(request):
data_pers = {
'Product':request.GET.get('Product'),
'Length':request.GET.get('Length'),
'Cod':request.GET.get('cod'),
'partnumbetr':'42367325'
}
return JsonResponse({'data_prod':data_prod})
...
HTML
...
$.get('{% url "test_table" %}',
{Product:Product,Length:Length,Cod:Cod},
function (data_prod) {
var data_json_prod=data_prod['data_prod'];
var data_array_prod = [];
var arr_prod = $.map(data_json_prod, function(el) { return el });
data_array_prod.push(arr_prod);
$('#id_prod').DataTable({
destroy: true,
data:data_array_prod,
});
...
On one of my pages I have a for loop to iterate through a list of "Projects" (which is the main model for my website) and display some of their data. The following code is nested in a table and the middle cells removed for redundancy.
foreach (var item in Model.Projects)
{
<tr>
<td>#Html.DisplayFor(modelItem => item.SubmissionNumber)</td>
<td>#Html.DisplayFor(modelItem => item.Status)</td>
<!-- and so on -->
<td>#Html.ActionLink("Detail", "DisplayDetails", new { id = item.ProjectID })</td>
</tr>
}
The "Detail" link in the last cell will ideally make a box pop up (I'm thinking of using a Modal via Bootstrap) containing all of the data for the project. The "DisplayDetails" controller action returns a partial view that presents this information, but since I'm not using JavaScript or anything to render the partial view on the current page it renders it as it's own unformatted page. This is the controller action:
[HttpGet]
public ActionResult DisplayDetails(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Project project = db.Projects.Find(id);
if (project == null)
{
return HttpNotFound();
}
return PartialView("~/Views/Projects/_Detail.cshtml", project);
}
Ideally I would pass the ID to the controller using AJAX like I did below (which is code from another page of my website, again edited to remove redudancy):
$("#show").on("click", function () {
$.ajax({
url: '/Projects/SearchTable',
type: "GET",
data: {
Line1: $('#' + '#Html.IdFor(m => m.Project.ProjectAddress.Line1)').val(),
// and so on
County: $('#' + '#Html.IdFor(m => m.Project.ProjectAddress.County)').val(),
}
}).done(function(partialViewResult) {
$(".wrapper").html(partialViewResult);
$(".wrapper").css('display', 'block');
});
});
And by doing this I can embed the partial view onto the current page instead of it opening as a new page. I'm just not sure how to pass the project ID for a specific row in the table as data to the controller. Is this even possible? If not is there another way to achieve the same result?
You can replace your ActionLink with this:
<td>Details</td>
Then,
$(".details").on("click", function (e) {
e.preventDefault();
var projectId = $(this).data('id');
// Make the AJAX call here...
});
I just followed this
JSFiddle example to create a little search box from an array object in my javascript. Now after some tweaking and research on search.object and filter:search:strict. Now that I have it filtering correctly, I modified a checkbox in the template that is checked upon loading the document and switched on or off based on a custom data attribute in the html that is updated by the json array.
How do I run this check once someone clears the search and the old items show back up again?
In the HTML I have this template
<div ng-repeat="o in objects | filter:search:strict | orderBy:'obj_name'" class="objectContainer">
<h3>{{o.obj_name}}</h3>
<label class="userToggleSwitch" >
<input class="userToggleInput" data-isactive="{{o.obj_isactive}}" type="checkbox">
<div class="slider round"></div>
</label>
</div>
In the JS
angular.element(document).ready(function(){
angular.module('searchApp',[])
.controller('searchCtrl', ['$scope','objHolder',function ($scope,objHolder) {
$scope.search = '';
$scope.objects = [];
$scope.objects = objHolder.getobjects();
}])
// fake service, substitute with your server call ($http)
.factory('objHolder',function(){
var objects = objList;
return {
getobjects : function(){
return objects;
}
};
});
});
The JS that modifies the items on document load is using jquery like this
$(document).ready(function(){
//console.log($('.userToggleInput'));
$.each($('.userToggleInput'), function(){
if($(this).data("isactive") == 1){$(this).attr('checked', true);}
if($(this).data("isactive") == 0){$(this).attr('checked', false);}
})
$('.userToggleInput').click(function(){
if ($(this).attr('checked') == undefined) {
// THIS IS WHERE WE WILL MAKE AN AJAX CALL TO A PHP CLASS
// TO REQUEST IF THE USER CAN BE TURNED ON - DUE TO LIC RESTRICTIONS
$(this).attr('checked',true);
} else {
$(this).attr('checked',false);
}
//console.log($(this).attr('checked'));
});
});
Created JS Fiddle to assist in Helping in this manner