My Kendo Tree-view has many child nodes and sub nodes .Problem with getting sub child's nodes with redundant code
Here is my code .
nodes = rep.GetTreeViewData(CompanyId);
var productTreeData = nodes.Select(p => new
{
Text = p.CategoryName,
Url = p.ActionLink,
hasChildren = p.SubCategories.Any(),
// Expanded = true,
EntityType = p.EntityType,
Selected = currurl.ToLower() == p.ActionLink.ToLower() ? true : false,
ImageUrl = p.EntityType == "Company" ? "/Content/Images/company.gif" : "/Content/Images/geolocation1.gif",
Children = p.SubCategories.Select(c => new
{
Text = c.SubCategoryName,
Url = c.ActionLink,
// Expanded = true,
hasChildren = c.SubCategories.Any(),
EntityType = c.EntityType,
Selected = currurl.ToLower() == c.ActionLink.ToLower() ? true : false,
ImageUrl = c.EntityType == "Company" ? "/Content/Images/company.gif" : "/Content/Images/geolocation1.gif",
Children = c.SubCategories.Select(d => new
{
Text = d.SubCategoryName,
Url = d.ActionLink,
// Expanded = true,
hasChildren = d.SubCategories.Any(),
EntityType = d.EntityType,
Selected = currurl.ToLower() == d.ActionLink.ToLower() ? true : false,
ImageUrl = d.EntityType == "Company" ? "/Content/Images/company.gif" : "/Content/Images/geolocation1.gif",
Children = d.SubCategories.Select(f => new
{
Text = f.SubCategoryName,
Url = f.ActionLink,
//Expanded = true,
hasChildren = f.SubCategories.Any(),
EntityType = f.EntityType,
Selected = currurl.ToLower() == f.ActionLink.ToLower() ? true : false,
ImageUrl = f.EntityType == "Company" ? "/Content/Images/company.gif" : "/Content/Images/geolocation1.gif",
Children = f.SubCategories.Select(g => new
{
Text = g.SubCategoryName,
Url = g.ActionLink,
// Expanded = true,
hasChildren = g.SubCategories.Any(),
EntityType = g.EntityType,
Selected = currurl.ToLower() == g.ActionLink.ToLower() ? true : false,
ImageUrl = g.EntityType == "Company" ? "/Content/Images/company.gif" : "/Content/Images/geolocation1.gif",
})
})
})
})
});
This is my view
#(Html.Kendo().TreeView()
.Name("treeview-right")
.ExpandAll(true)
//.LoadOnDemand(false)
//.Events(events=>events.DataBound("DataBound"))
.DataSource(d => d
.Model(m => m
.HasChildren("hasChildren")
.Children("Children"))
.Read(r => r.Action("_ProductTree", "Home")))
.DataTextField("Text")
.DataUrlField("Url")
.DataImageUrlField("ImageUrl")
)
By this process am getting all child's and sub child's of individual parent up to four level hierarchy ..if i need another level i need to write one more children code.
Am struggling from 2 days to simplify this process .
Thanks
This looks like it could be solved with recursion. This should be pretty close.
var productTreeData = new ListofYourTreeViewModelHere();
foreach (var node in rep.GetTreeViewData(CompanyId))
{
productTreeData.Add(FillTree(node));
}
...
}
private YourTreeViewModelHere FillTree(p)
{
var tv = new YourTreeViewModelHere();
tv.Text = p.CategoryName,
tv.Url = p.ActionLink,
tv.hasChildren = p.SubCategories.Any(),
tv.EntityType = p.EntityType,
tv. Selected = currurl.ToLower() == p.ActionLink.ToLower() ? true : false,
tv.ImageUrl = p.EntityType == "Company" ? "/Content/Images/company.gif" : "/Content/Images/geolocation1.gif";
foreach(var sub in p.SubCategories)
{
tv.Children.Add(FillTree(x));
}
}
Related
we have used forge Aggregate Viewer to display the multiple BIM models. But if we click/double click any of the equipment in the Aggregate Forge Viewer the equipment will be zoomed.
but not able to get the selected equipment object id by using the c# code.
Note: If we upload the single file, we are able to get the selected equipment object id in the Forge Viewer.
We used below code, but its not get hitted when we select equipment.
viewer.addEventListener(Autodesk.Viewing.SELECTION_CHANGED_EVENT, (args) => {
Kindly help us to get the selected equipment object id in Aggregate Forge View while displaying the multiple files.
Kindly share the sample code for our reference.
FITTOVIEW AND SELECTION CHANGE CODE
const Loadedevent = () => {
var objval = document.getElementById('<%=hid_objectid.ClientID%>').value;
if (objval != '') {
var mdlurn = "";
mdlurn = document.getElementById('<%=hid_mdlurn.ClientID%>').value;
const models = viewer.getVisibleModels().find(m => m.getData().urn === mdlurn);
viewer.fitToView([parseInt(objval)], models);
viewer.select([parseInt(objval)], models, Autodesk.Viewing.SelectionType.OVERLAYED);
}
}
SelectionChangeEvent
viewer.addEventListener(Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT, (args) => {
if (args.dbIdArray.length === 1) {
viewer.getProperties(args.dbIdArray[0], function (data) {
if (FromPage == '') {
if (FromSelection == '') {
if (Count === 0) {
var instanceTree = viewer.model.getData().instanceTree;
var parentId = instanceTree.getNodeParentId(args.dbIdArray[0]);
viewer.select([parentId], viewer.model, Autodesk.Viewing.SelectionType.OVERLAYED);
Count = 1;
} else {
itemobject = args.dbIdArray[0];
Count = 0;
}
} else {
FromSelection = '';
itemobject = args.dbIdArray[0];
}
} else {
FromPage = '';
itemobject = args.dbIdArray[0];
}
});
}
});
Edited Code:
viewer.addEventListener(Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT, (args) => {
if (!args.selections || args.selections.length <= 0)
return;
if (args.selections.length == 1 ) {
viewer.getProperties(args.selections[0].dbIdArray[0], function (data) {
if (FromPage == '') {
if (FromSelection == '') {
if (Count === 0) {
var instanceTree = viewer.model.getData().instanceTree;
var parentId = instanceTree.getNodeParentId(args.selections[0].dbIdArray);
viewer.select([parentId], viewer.model, Autodesk.Viewing.SelectionType.OVERLAYED);
Count = 1;
} else {
const dbIds = args.selections[0].dbIdArray;
itemobject = dbIds[0];
Count = 0;
}
} else {
FromSelection = '';
const dbIds = args.selections[0].dbIdArray;
itemobject = dbIds[0];
}
} else {
FromPage = '';
const dbIds = args.selections[0].dbIdArray;
itemobject = dbIds[0];
}
});
}
});
In the multiple models scenario, you must use Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT instead. See https://forge.autodesk.com/blog/multi-model-refresher
/**
* Triggered when objects are selected or deselected.
* Event payload:
* {
* type: 'aggregateSelection',
* target: Viewer3D,
* selections: Array<{
* model: Model,
* nodeArray: Array<number>,
* dbIdArray: Array<number>,
* fragIdsArray: Array<number>
* }>
* }
*/
viewer.addEventListener(
Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT,
(event) => {
// codes for selecting changed
});
To get selected objects, call viewer.getAggregateSelection() instead.
Update
Here are the revised code snippets for you:
FITTOVIEW AND SELECTION CHANGE CODE
const Loadedevent = () => {
let objval = document.getElementById('<%=hid_objectid.ClientID%>').value;
if (objval != '') {
let mdlurn = "";
mdlurn = document.getElementById('<%=hid_mdlurn.ClientID%>').value;
let model = viewer.getVisibleModels().find(m => m.getData().urn === mdlurn); //!<<< find() will return first found item only, so defining the variable in the singular form instead to avoid confusion.
let dbId = parseInt( objval );
viewer.select( [ dbId ] , model, Autodesk.Viewing.SelectionType.OVERLAYED );
// or viewer.setAggregateSelection([ { ids: [ dbId ], model, selectionType: Autodesk.Viewing.SelectionType.OVERLAYED } ]);
viewer.fitToView( [ dbId ], model );
}
}
SelectionChangeEvent
viewer.addEventListener(Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT, (event) => {
if (!event.selections || event.selections.length <= 0 || event.selections.length > 1)
return;
let selSet = event.selections[0];
const dbIds = selSet.dbIdArray;
const model = selSet.model;
const dbId = dbIds[0];
model.getProperties(dbId, function(data) {
if (FromPage == '') {
if (FromSelection == '') {
if (Count === 0) {
let instanceTree = model.getInstanceTree();
let parentId = instanceTree.getNodeParentId(dbId);
viewer.select(parentId, model, Autodesk.Viewing.SelectionType.OVERLAYED);
// or viewer.setAggregateSelection([ { ids: [parentId ], model, selectionType: Autodesk.Viewing.SelectionType.OVERLAYED } ])
Count = 1;
} else {
itemobject = dbId;
Count = 0;
}
} else {
FromSelection = '';
itemobject = dbId;
}
} else {
FromPage = '';
itemobject = dbId;
}
});
});
I'm currently on an Angular project (I'm a begineer) and I created a function to create a HTML form depending on the content of a JSON (the form then allows me to push new data in the JSON). It works, displays the form, but I didn't think ahead, and don't know how to retrieve the input values from the user.
createNewLineForm() {
if (this.allowForm) {
let indiceList = 0;
this.formOn = true;
for (let jsonCol of this.columnData) {
if (jsonCol.visible === true && jsonCol.type === "Boolean") {
var content = document.getElementById("formcontent");
var listTitle = document.createElement("header");
listTitle.textContent = jsonCol.name;
content.appendChild(listTitle);
var selectList = document.createElement("select");
selectList.id = "trueFalse";
content.appendChild(selectList);
var option = document.createElement("option");
option.value = "true";
option.text = "true";
selectList.appendChild(option);
var option2 = document.createElement("option");
option2.value = "false";
option2.text = "false";
selectList.appendChild(option2)
}
if (jsonCol.visible === true && jsonCol.type === "String" && jsonCol.dropdownList === null) {
var content = document.getElementById("formcontent");
var inputTitle = document.createElement("header");
inputTitle.textContent = jsonCol.name;
content.appendChild(inputTitle);
var formInput = document.createElement("input");
formInput.type = "text";
formInput.placeholder = jsonCol.name;
formInput.name = "text";
content.appendChild(formInput);
}
if (jsonCol.visible === true && jsonCol.type === "String" && jsonCol.dropdownList != null) {
var content = document.getElementById("formcontent");
var listTitle = document.createElement("header");
listTitle.textContent = jsonCol.name;
content.appendChild(listTitle);
var selectListLong = document.createElement("select");
selectListLong.name ="longList";
indiceList++;
content.appendChild(selectListLong);
for (const options of jsonCol.dropdownList) {
var option = document.createElement("option");
option.value = options;
option.text = options;
selectListLong.appendChild(option);
}
}
}
var submit = document.createElement("input");
submit.type = "submit";
content.appendChild(submit);
}
}
It's then conditionnally called in my HTML window with a simple <div id="formcontent"> </div>
I tried using document.getElementByName('...').value, doesn't seem to work.
Btw, if you have another idea on how to make that form, I'd like hearing it as well, this method seems a bit messy I think.
var content = document.getElementById("formcontent").value;
You can try it by ID
I know this question was asked before but those answers are not helpful to me.Here i'm using iscroll, i get this console error "Cannot read property 'children' of null at object.Iscroll" when reloading page. Can anyone help me.
function IScroll (el, options) {
this.wrapper = typeof el == 'string' ? document.querySelector(el) : el;
this.scroller = this.wrapper.children[0];
this.scrollerStyle = this.scroller.style; // cache style for better performance
this.options = {
resizeScrollbars: true,
mouseWheelSpeed: 20,
snapThreshold: 0.334,
// INSERT POINT: OPTIONS
startX: 0,
startY: 0,
scrollY: true,
directionLockThreshold: 5,
momentum: true,
bounce: true,
bounceTime: 600,
bounceEasing: '',
preventDefault: true,
preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT)$/ },
HWCompositing: true,
useTransition: true,
useTransform: true
};
for ( var i in options ) {
this.options[i] = options[i];
}
// Normalize options
this.translateZ = this.options.HWCompositing && utils.hasPerspective ? ' translateZ(0)' : '';
this.options.useTransition = utils.hasTransition && this.options.useTransition;
this.options.useTransform = utils.hasTransform && this.options.useTransform;
this.options.eventPassthrough = this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough;
this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault;
// If you want eventPassthrough I have to lock one of the axes
this.options.scrollY = this.options.eventPassthrough == 'vertical' ? false : this.options.scrollY;
this.options.scrollX = this.options.eventPassthrough == 'horizontal' ? false : this.options.scrollX;
// With eventPassthrough we also need lockDirection mechanism
this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough;
this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold;
this.options.bounceEasing = typeof this.options.bounceEasing == 'string' ? utils.ease[this.options.bounceEasing] || utils.ease.circular : this.options.bounceEasing;
this.options.resizePolling = this.options.resizePolling === undefined ? 60 : this.options.resizePolling;
if ( this.options.tap === true ) {
this.options.tap = 'tap';
}
if ( this.options.shrinkScrollbars == 'scale' ) {
this.options.useTransition = false;
}
this.options.invertWheelDirection = this.options.invertWheelDirection ? -1 : 1;
// INSERT POINT: NORMALIZATION
// Some defaults
this.x = 0;
this.y = 0;
this.directionX = 0;
this.directionY = 0;
this._events = {};
// INSERT POINT: DEFAULTS
this._init();
this.refresh();
this.scrollTo(this.options.startX, this.options.startY);
this.enable();
}
The above issue is fixed, some undefined value stored in my 'el',i fix it, now it is working fine, Thanks for your views.
i'm trying to sort an arraycollection that uses letters and numbers
Currently I'm getting "b12,c1,b1,b3,b4,b5,b6,b7,b8,b9,b10,b11,b0,b13,b14,b15" but want "b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,b15,c1"
Please can anyone suggest when're I have gone wrong?
var dataSortField:SortField = new SortField();
dataSortField.name = "order";
dataSortField.numeric = false;
dataSortField.compareFunction = sortAlphaNumeric;
var numericDataSort:Sort = new Sort();
numericDataSort.fields = [dataSortField];
pageArrCol.sort = numericDataSort;
private function sortAlphaNumeric(a:String, b:String):int {
var reA:RegExp = /[^a-zA-Z]/g;
var reN:RegExp = /[^0-9]/g;
var aA:String = a.replace(reA,"");
var bA:String = b.replace(reA,"");
if (aA === bA) {
var aN:int = parseInt(a.replace(reN,""),10);
var bN:int = parseInt(b.replace(reN,""),10);
return aN === bN ? 0 : aN > bN ? 1 : -1;
} else {
return aA > bA ? 1 : -1;
}
}
myArrayCollectionToSort.source.sortOn("order", sortAlphaNumeric);
private function sortAlphaNumeric(a:String, b:String):int {
var reA:RegExp = /[^a-zA-Z]+/g;
var reN:RegExp = /[^0-9]+/g;
var aA:String = a.match(reA)[0];
var bA:String = b.match(reA)[0];
if (aA == bA) {
var aN:int = parseInt(a.match(reN)[0],10);
var bN:int = parseInt(b.match(reN)[0],10);
return aN == bN ? 0 : aN > bN ? 1 : -1;
}
return aA > bA ? 1 : -1;
}
I don't test it but it should works, and array is way faster than an ArrayCollection. (arraycollection.source is an array). If the sorted ArrayCollection is binded you need to dispatch a refresh event if you want the bind to works:
myArrayCollectionToSort.dispatchEvent(new CollectionEvent(CollectionEvent.COLLECTION_CHANGE, false, false, CollectionEventKind.REFRESH));
or
myArrayCollectionToSort.refresh();
Assuming that b12,c1,b1 is your input format
You may have meant, a.match(regex)[0]
var reA:RegExp = /[a-zA-Z]+/g;
var reN:RegExp = /[0-9]+/g;
var aA:String = a.match(reA)[0];
var bA:String = b.match(reA)[0];
if (aA === bA) {
var aN:int = parseInt(a.match(reN)[0],10);
var bN:int = parseInt(b.match(reN)[0],10);
return aN === bN ? 0 : aN > bN ? 1 : -1;
}else {
return aA > bA ? 1 : -1;
}
I have not tested this, but you should not be using replace, use match instead. Also, the regular expression is wrong. You have to revisit the regular expression.
How do you get the first item only? It seems like I have to do the following otherwise i will get an error as if it was a multiple item and i can't get just the first element of it.
My goal is i would like to remove the foreach loop from the code below.
MetaDataPropertyBag propertyBag = new MetaDataPropertyBag();
var dbResultsOfType = db.spi_GetTypesByCaseType(caseType);
foreach (var item in dbResultsOfType)
{
if (item.ASSOC_TYPE_ID == primaryChildTypeID)
{
propertyBag.CaseTypeDesc = item.DESCRIPTION;
propertyBag.Required = item.IS_REQUIRED == 'Y' ? true : false;
propertyBag.Parent = item.PARENT_ID.Value;
propertyBag.Child = item.CHILD_ID.Value;
propertyBag.AssocTypeID = item.ASSOC_TYPE_ID;
propertyBag.CaseTypeID = item.CASE_TYPE_ID;
break; // Only one entry is requested
}
}
FirstorDefault should do it:
MSDN article on firstordefault
Here is one way to do it:
var first = dbResultsOfType.FirstOrDefault(item => item.ASSOC_TYPE_ID == primaryChildTypeID);
if (first != null) {
propertyBag.CaseTypeDesc = first.DESCRIPTION;
propertyBag.Required = first.IS_REQUIRED == 'Y' ? true : false;
propertyBag.Parent = first.PARENT_ID.Value;
propertyBag.Child = first.CHILD_ID.Value;
propertyBag.AssocTypeID = first.ASSOC_TYPE_ID;
propertyBag.CaseTypeID = first.CASE_TYPE_ID;
}