I am trying to use the functionality of kendoTreeList through Jquery. The Tekerik Documentation is here:
https://docs.telerik.com/kendo-ui/api/javascript/ui/treelist
The code I am using is shown below:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="~/Scripts/jquery-1.12.4.js"></script>
<script src="#Url.Content("~/Scripts/kendo/kendo.all.min.js")"></script>
<script src="#Url.Content("~/Scripts/kendo/kendo.treelist.min.js")">
</script>
<script>
var search = document.getElementById("SearchTerm");
function SearchResults(results) {
$('#ResultsList').empty();
var items = {};
$.each(results, function (i, value) {
items += { id: i, parentId: null, Name: value.MacroName, Type:"Macro" }
if (value.Files.length > 0) {
$.each(value.Files, function (x, File) {
items += {parentId: i, Name: File, Type:"File"}
});
}
if (value.Servers.length > 0) {
$.each(value.Services, function (x, Server) {
items += { parentId: i, Name: Server, Type: "Server" }
});
}
if (value.Databases.length > 0) {
$.each(value.Databases, function (x, DB) {
items += { parentId: i, Name: DB, Type: "Databases"}
});
}
if (value.Services.length > 0) {
$.each(value.Services, function (x, Service) {
items += { parentId: i, Name: Service, Type: "Service" }
});
}
if (value.SecGroups.length > 0) {
$.each(value.SecGroups, function (x, PSI) {
items += { parentId: i, Name: PSI, Type: "SecGroup" }
});
}
});
$("#ResultsList").kendoTreeList({
columns: [
{ field: "Name" },
{ field: "Type"},
{
command: [{
name: "Display",
text: "Display",
click: function (e) {
// e.target is the DOM element representing the button
var tr = $(e.target).closest("tr"); // get the current table row (tr)
// get the data bound to the current table row
var data = this.dataItem(tr);
console.log("Details for: " + data.Name);
Display(data.Name, data.Type)
}
}]
}
],
editable: true,
dataSource: items
});
}
function Display(value,Type)...
</script>
There is more code but search results is all that's necessary, and it contains the kendoTreeList function. the Debugger is saying .kendoTreeList is not a function, but it should. Why is it saying it is not a function?
The issue was caused due to having more than one JQuery Script reference.
When working in MVC the _Layout page under Views->Shared->_Layout.cshtml had a reference at the bottom to #Scripts.Render("~/bundles/jquery") by default. This needs to be removed. Having more than one Jquery reference will cause issues with the scripts causing the compiler to be unable to find the function you are trying to use.
Related
Hi guys i have topic table where i am storing all topics along with sub topics..and subtopic id i am storing in parent_id column.
Here is my db structure:
i am getting all topics in dropdown like this.
But i would like to show my subtopics list like this
fractions
fractions>introductions to fractions
fractions>Fractions as division
So far i have create childTopics functions in my model:
public function childTopics()
{
return $this->hasMany(Topic::class, 'parent_id');
}
And i used in my create function in controller like this:
$topics = Topic::with('childTopics')->parent()->get(['id', 'name']);
Here is my ajax call where i am showing all my topics in one place.
function getSubjectsTopics(subject_id)
{
if(subject_id) {
loading_show();
axios.get("/master/topic/get-topic-by-subject-id/" + subject_id)
.then(function(response) {
var optionHtml = '<option value="0">Parent</option>';
if(response.data.status) {
$.each(response.data.subject_topics, function(i,v) {
optionHtml += `<option value="${v.id}">${v.name}</option>`;
});
}
$("#ddl_topic_type").html(optionHtml).attr('disabled', false).select2();
loading_hide();
})
.catch(function(error) {
loading_hide();
console.log(error);
Swal.fire({
type: 'error',
title: 'Oops...',
text: 'Something went wrong!'
})
})
} else {
$("#ddl_topic_type").attr('disabled', true);
}
}
In this ajax call itself i would like to show my subtopics with parent topic name itself.
Can anyone help me how can i show it.
Thanks in advance.
Edit:
Here is my response output
Here is functions to get topics based on subject:
public function getTopicsBySubjectID($subject_id)
{
$topics = Topic::where("subject_id", $subject_id)->get(['id', 'name']);
return response()->json(['status' => 'success', 'subject_topics' => $topics], 200);
}
You can use optGroup to group your sub option in a group where optGroup will have the name of the subject name .Your current ajax response show all subject_topics together so if the first value fractions is subject name you can put condition inside each loop to check if i(position) is 0 then append optgroup.
Demo code :
var response = {
'data': {
'status': 'success',
'subject_topics': [{
'id': 0,
'name': 'fractions'
}, {
'id': 1,
'name': 'fractions of booksss of subject'
}, {
'id': 2,
'name': 'fractions of sub'
}]
}
};
var optionHtml = '<option>Select....</option>';
if (response.data.status) {
$.each(response.data.subject_topics, function(i, v) {
if (i == 0) {
optionHtml += `<optGroup label="${v.name}">` //considering 1st id is subject name
} else {
optionHtml += `<option value="${v.id}">${v.name}</option>`;
}
});
optionHtml += `<optGroup>` //close optgroup
}
$("#ddl_topic_type").html(optionHtml).attr('disabled', false).select2();
//or
var response = {
'data': {
'status': 'success',
'subject': 'somesubjectname', //return subject name as well
'subject_topics': [{
'id': 0,
'name': 'fractions'
}, {
'id': 1,
'name': 'fractions of booksss of subject'
}, {
'id': 2,
'name': 'fractions of sub'
}]
}
};
var optionHtml1 = '<option>Select....</option>';
if (response.data.status) {
//append subject name
optionHtml1 += `<optGroup label="${response.data.subject}">`
$.each(response.data.subject_topics, function(i, v) {
optionHtml1 += `<option value="${v.id}">${v.name}</option>`;
});
//subject name ..
optionHtml1 += `<optGroup>`
}
$("#ddl_topic_type1").html(optionHtml1).attr('disabled', false).select2();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://rawgit.com/select2/select2/master/dist/css/select2.min.css">
<script src="https://rawgit.com/select2/select2/master/dist/js/select2.js"></script>
<select id="ddl_topic_type"></select>
<select id="ddl_topic_type1"></select>
In knockout JS I want to find out 1st duplicate object from my collection and return that object as modal. I have to check for 1st duplicate object from first array aginst 2nd Array based on my condition. Tried _findWhere & _.Some & _.each nothing worked. Can someone help
Here -- MyMainModal is my Moda which will have multiple objects
self.dupRecord= function (MyMainModal) {
var Modaldata= ko.mapping.toJS(MyMainModal);
return _.some(Modaldata, function (MD1) {
return _.some(Modaldata, function (MD2) {
if ((MD1.ID!== MD2.Id) &&
(MD1.Name === MD2.name));
});
});
};
How about incorporating the check for first duplicate into the mapping? Something like:
function Child(data) {
ko.mapping.fromJS(data, {}, this);
};
var model = {
children: [{
id: '1',
name: 'Billy'
}, {
id: '2',
name: 'Susy'
}]
};
var mapping = {
children: {
key: function(data) {
return ko.utils.unwrapObservable(data.id);
},
create: function(options) {
console.log('creating ' + options.data.name, options.parent);
var newChild = new Child(options.data);
if(options.parent.firstDuplicate() === undefined)
options.parent.children().forEach(function(child) {
if(child.name() === newChild.name())
options.parent.firstDuplicate([child, newChild]);
});
return newChild;
},
update: function(options) {
console.log(' updating ' + options.data.name);
return options.target;
}
}
};
var vm = {
children: ko.observableArray(),
firstDuplicate: ko.observable()
};
ko.mapping.fromJS(model, mapping, vm);
ko.applyBindings(vm);
model.children.push({
id: 3,
name: 'Billy'
});
setTimeout(function() {
console.log('--remapping--');
ko.mapping.fromJS(model, mapping, vm);
}, 2000);
I read that as, "if we're not updating the record, potentially set the first duplicate." Here's a fiddle: http://jsfiddle.net/ge1abt6a/
I'm relatively new to Ember and JS frameworks and I'm facing difficulty in connecting a model to the Ember Table view/component.
With the code I currently have, the table is rendering but the rows are not being populated with any data. Obviously, I'm doing something wrong and falling short of understanding how to make this work properly.
I have tried to implement something similar to the technique used here and here but can't get it to work.
I wanted to use the FixtureAdapter to populate the model with data for now but later on move to retrieving the data from my backend API via Ajax/JSON.
Any help is greatly appreciated.
The JS part:
window.App = Ember.Application.create({
LOG_TRANSITIONS: true,
LOG_TRANSITIONS_INTERNAL: true,
LOG_VIEW_LOOKUPS: true,
// LOG_ACTIVE_GENERATION: true,
LOG_BINDINGS: true
});
var stringAttr = DS.attr('string');
App.Item = DS.Model.extend({
name: stringAttr,
desc: stringAttr,
category: DS.attr('number'),
tags: stringAttr,
note: stringAttr
});
App.Item.FIXTURES = [
{ id: 0, name: 'XY Laptop', desc: 'test laptop', category: 1, tags: 'computers, laptops', note:"note"},
{ id: 1, name: 'ZZ Computer', desc: 'super computer!', category: 0, tags: 'computers', note:"note"},
{ id: 2, name: 'MM Radio', desc: 'FM Radio', category: 1, tags: 'radios, recorders', note:"note"}
];
App.Router.map(function() {
this.resource('inventory', function() {
this.resource('items', function() {
this.resource('item', { path: ':item_id' }, function() {
this.route('edit');
});
});
});
});
// Temporary buffer object that sites between Ember Table and the model object (the Item model object)
App.RowProxy = Ember.Object.extend({
object: null,
getObjectProperty: function(prop) {
var obj = this.get('object');
if(obj) { console.log(prop + " : " + obj.get(prop)); }
return obj ? obj.get(prop) : 'Loading ...';
},
isLoaded: function() { return !!this.get('object'); }.property('object'),
id: function() { return this.getObjectProperty('id'); }.property('object.id'),
name: function() { return this.getObjectProperty('name'); }.property('object.name'),
desc: function() { return this.getObjectProperty('desc'); }.property('object.desc'),
category: function() { return this.getObjectProperty('category'); }.property('object.category'),
tags: function() { return this.getObjectProperty('tags'); }.property('object.tags'),
note: function() { return this.getObjectProperty('note'); }.property('object.note')
});
App.LazyDataSource = Ember.ArrayProxy.extend({
requestPage: function(page) {
var content, end, start, url, _i, _results;
content = this.get('content');
start = (page - 1) * 3;
end = start + 3;
// find items and then update the RowProxy to hold the item object.
this.get('store').find('item').then(function(items) {
return items.forEach(function(item, index) {
var position = start + index;
content[position].set('object', item);
});
});
// fill the 'content' array with RowProxy objects
return (function() {
_results = [];
for (var _i = start; start <= end ? _i < end : _i > end; start <= end ? _i++ : _i--){ _results.push(_i); }
return _results;
}).apply(this).forEach(function(index) {
return content[index] = App.RowProxy.create({
index: index
});
});
},
objectAt: function(index) {
var content, row;
content = this.get('content');
row = content[index];
if (row && !row.get('error')) {
return row;
}
this.requestPage(Math.floor(index / 3 + 1));
return content[index];
}
});
App.ItemsController = Ember.Controller.extend({
hasHeader: false,
hasFooter: false,
rowHeight: 35,
numRows: 10,
store: null,
columns: Ember.computed(function() {
var columnNames, columns;
columnNames = ['Name','Desc','Category','Tags','Note'];
columns = columnNames.map(function(key, index) {
return Ember.Table.ColumnDefinition.create({
columnWidth: 150,
headerCellName: key.w(),
contentPath: key
});
});
return columns;
}).property(),
content: Ember.computed(function() {
return App.LazyDataSource.create({
content: new Array(this.get('numRows')),
store: this.get('store')
});
}).property('numRows')
});
While the requestPage method above is not strictly required now, it would be useful to use when I migrate to the RESTful API, I kept it.
The HTML template looks like this:
<script type="text/x-handlebars">
{{#link-to 'items'}}
<i class="icon-edit"></i>
Item Management
{{/link-to}}
<div class="page-content">
{{outlet}}
</div><!-- /.page-content -->
</script>
<script type="text/x-handlebars" data-template-name="items">
<div class="row">
{{table-component
columnsBinding="columns"
contentBinding="content"
}}
</div>
</script>
I wasn't too sure how to show the table but my attempt to define it via a View wasn't successful.
I'm using:
Ember 1.2.0
Handlebars 1.1.2
Ember-Data 1.0.0-beta.3
jQuery 2.0.3
Ember Table 0.0.2
so I've implemented the treeview of Fuel UX within my website. Whenever it's loaded, I need to reselect the items I want manually. Is there a possibility to preselect certain items after each reload?
Thanks in advance!
I was in the same situation since yesterday and could now solve the problem with the solution below. Just explaining that I used the methods present on the button "select nested Test Item 1" on this page. Here's the solution:
var preSelectFolder = function ($treeEl, folder, $parentEl) {
var $elParent = $parentEl || $treeEl;
if (folder.type == "folder") {
var $folderEl = $elParent.find("div.tree-folder-name").filter(function (_, treeFolder) {
return $(treeFolder).text() == folder.name;
}).parent();
$treeEl.one("loaded", function () {
$.each(folder.children, function (i, item) {
preSelectFolder($treeEl, item, $folderEl.parent());
});
});
$treeEl.tree("selectFolder", $folderEl);
}
else {
preSelectItem($treeEl, folder, $elParent);
}
};
var preSelectItem = function ($treeEl, item, $parentEl) {
var $elParent = $parentEl || $treeEl;
if (item.type == "item") {
var $itemEl = $elParent.find("div.tree-item-name").filter(function (_, treeItem) {
return $(treeItem).text() == item.name && !$(treeItem).parent().is(".tree-selected");
}).parent();
var itemId = $($itemEl).data() != null ? $($itemEl).data().id : "";
if (itemId == item.id)
$treeEl.tree("selectItem", $itemEl);
}
else if (item.type == "folder") {
preSelectFolder($treeEl, item, $elParent);
}
};
And in the event of 'loaded' I use this code:
element.on('loaded', function (e) {
angular.forEach(scope.items, function (item) {
preSelectItem($("#BuildTree"), item);
});
});
I use AngularJs so just replace "angular.forEach" for each function of Jquery and "scope.items" are items that should be pre-selected. In my case the items are in the following format:
[
{ name: 'Dir 1', type: 'folder', id: 'D1' },
{ name: 'Dir 2', type: 'folder', id: 'D2' },
{ name: 'Item 1', type: 'item', id: 'i1' },
{ name: 'Item 2', type: 'item', id: 'i2' }
]
Hope that helps.
If by manually, you mean you're actually clicking on the items again there should be a way to do this more programmatically.
I haven't tested it, but if you call $('#MyTree').tree('selectItem', $el) where $el is a .tree-item element, that should select the item.
It would be nice for your datasource to be able to tell the tree which items are selected. I see you've posted the feature request to https://fuelux.uservoice.com/forums/181290-general/suggestions/4097231-add-preselect-option-for-treeview which is great - anyone else reading this who agrees it would be useful should vote there.
I make if for ASP.NET MVC. I use a dynamic tree.
At first I received a route for selected item
[{
"id": 1, // parent category
"name": "Все категории",
}, {
"id": 56, // 1-st sub category
"name": "Для дома",
}, {
"id": 63, // item
"name": "Домашние растения",
}]
Then it need to switch off Async request for Ajax in dataSource function: 'async':false
This is all code:
#{
var jsonSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
string catRoute = jsonSerializer.Serialize(ViewBag.catRoute);
}
var catRoute = $.parseJSON('#Html.Raw(catRoute)'); // this is object of item route
function dynamicDataSource(openedParentData, callback) {
var childNodesArray = [];
$.ajax({
'type': 'post',
'url': '#Url.Action("getFuelUxTree", "Category", new { area = "Root" })',
'data': openedParentData,
'async':false // switch off ajax request
})
.done(function (data) {
childNodesArray = data;
lastTree = data;
callback({
data: childNodesArray
});
});
}
$('#categoryTree').tree({
dataSource: dynamicDataSource,
multiSelect: false,
folderSelect: false
});
// iterate all route items and open category
for (var i = 0; i < catRoute.length; i++) {
$('li#'+catRoute[i].id+' button', '#categoryTree').click();
}
I have object container <div id="dObjectContainer" class="dObjectContainer">
and a widget TreeObject.
$.widget('qs.TreeObject2', {
options: {
oID: '0',
IMGUrl: '../../Content/Images/noIMG.jpg',
Name: 'Name',
IsActive: true,
IsVisible: true
},
_create: function () {
var self = this,
o = self.options,
el = self.element;
el.attr("oID", o.oID);
el.addClass("dObject");
el.addClass("ui-widget-content");
var H1 = $("<h1></h1>").text(o.Name);
el.append(H1);
var img = $("<img></img>");
img.attr("src", o.IMGUrl);
img.attr("alt", o.Name);
el.append(img);
},
DoHide: function (strName, bActive) {
var self = this,
o = self.options;
if (((o.Name.toUpperCase().indexOf(strName.toUpperCase()) > -1) || (strName == "")) && ((o.IsActive) || (bActive == false))) {
if (!o.IsVisible) {
this.element.show();
o.IsVisible = true;
}
}
else {
if (o.IsVisible) {
this.element.hide();
o.IsVisible = false;
}
}
},
destroy: function () {
$.Widget.prototype.destroy.call(this);
}
});
I want to add multiple objects from javascript something like this:
$('#dObjectContainer').append($("<div></div>").TreeObject2({ oID: "1", IMGUrl: '../../Content/Images/StoredImages/Categories/images.jpg', Name: "n1", IsActive: true }));
$('#dObjectContainer').append($("<div></div>").TreeObject2({ oID: "2", Name: "n2", IsActive: false }));
This approach adds two elemets of each object instead of one. - Found reason - for some unknown reson ASP.MVC 3 razor view calls (function ($) {} (jQuery)); twice. First time it calls only view document.ready - second time layoutpage and view document ready.
For other part - how to access their metods:
$('.dObject').TreeObject2("DoHide", strName, bActive);
This works in case there is no more elements having class dObject.