Related
I have the following ContextualMenu structure inside my SPFx Extension build with Fluent UI React:
const menuProps: IContextualMenuProps = {
items: [
{
key: 'Access',
itemType: ContextualMenuItemType.Section,
sectionProps: {
topDivider: true,
bottomDivider: true,
title: 'Sites you have access to',
items: [
{ key: 'DynamicValue1.1', text: 'DynamicValue1.2' },
{ key: 'DynamicValue2.1', text: 'DynamicValue2.2' },
],
},
},
],
};
I also a MS Graph call running getting me some SharePoint Sites & Teams.
I would now like to push those dynamic responses to the to the menuProps at the right place.
So basically add the dynamic array into the nested items object.
items: [
{ key: 'DynamicValue1.1', text: 'DynamicValue1.2' },
{ key: 'DynamicValue2.1', text: 'DynamicValue2.2' },
],
How can I target that "object"? (hope I understand correctly and items is an object...)
Is there a way to do this using array.push()?
To make this library agnostic, it would look something like this:
const obj = {
items: [
{
key: 'Access',
itemType: '',
sectionProps: {
topDivider: true,
bottomDivider: true,
title: 'Sites you have access to',
items: [
{ key: 'DynamicValue1.1', text: 'DynamicValue1.2' },
{ key: 'DynamicValue2.1', text: 'DynamicValue2.2' },
],
},
},
],
};
obj.items[0].sectionProps.items.push({ key: 'DynamicValue3.1', text: 'DynamicValue3.2' })
console.log(obj.items[0].sectionProps.items)
Your console.log would return this:
[
{ key: 'DynamicValue1.1', text: 'DynamicValue1.2' },
{ key: 'DynamicValue2.1', text: 'DynamicValue2.2' },
{ key: 'DynamicValue3.1', text: 'DynamicValue3.2' }
]
If you can access menuProps: IContextualMenuProps, then just replace obj with the necessary variable.
I try to create sidebar component in React and I have a data structure like bellow
const links = [
{
label: 'Item-1',
url: '/item-1',
},
{
label: 'Item-2',
children: [
{
label: 'Item-2-1',
url: '/item-2-1',
},
{
label: 'Item-2-2',
url: '/item-2-2',
},
{
label: 'Item-2-3',
url: '/item-2-3',
},
],
},
{
label: 'Item-3',
children: [
{
label: 'Item-3-1',
url: '/item-3-1',
},
{
label: 'Item-3-2',
url: '/item-3-2',
},
],
},
];
So the problem is let's say the user changed URL and URL something like that http://localhost:90/item-2-3.
And I need to activate this sidebar item from the sidebar and it can be nested. So firstly I need to deactivate all other sidebar items (I don't want multiple selected items in the sidebar) and after that activate the selected sidebar item.
Because that (if I'm correct) I need update all tree items let's say I add active:false field to all JSON and after that I need to find the correct tree item from tree (URL === item-2-3) add active:true and also update all parent json to active:true (for there are look selected/opened)
So my question is am I correct if I correct how can write this code optimal way? :/
Actually, I want to create a function and when calling this function like that selectItemFromTree(links, '/item-2-2') I get results like in bellow.
const links = [
{
label: 'Item-1',
url: '/item-1',
active: false
},
{
label: 'Item-2',
active: true,
children: [
{
label: 'Item-2-1',
url: '/item-2-1',
active: false
},
{
label: 'Item-2-2',
url: '/item-2-2',
active: true,
},
{
label: 'Item-2-3',
url: '/item-2-3',
active: false
},
],
},
{
label: 'Item-3',
active: false,
children: [
{
label: 'Item-3-1',
url: '/item-3-1',
active: false
},
{
label: 'Item-3-2',
url: '/item-3-2',
active: false
},
],
},
];
You have to traverse the tree recursively and update all the active statuses.
const links=[{label:"Item-1",url:"/item-1"},{label:"Item-2",children:[{label:"Item-2-1",url:"/item-2-1"},{label:"Item-2-2",url:"/item-2-2"},{label:"Item-2-3",url:"/item-2-3"}]},{label:"Item-3",children:[{label:"Item-3-1",url:"/item-3-1"},{label:"Item-3-2",url:"/item-3-2"}]}];
const updateActiveLink = (links, url, parent = null) => {
for (link of links) {
link.active = false;
if (link?.children) {
updateActiveLink(link.children, url, link)
}
if (link.url === url) {
link.active = true;
if (!!parent) parent.active = true;
}
}
}
updateActiveLink(links, '/item-2-3');
console.log(links);
.as-console-wrapper {min-height: 100%!important; top: 0}
Note that this method will mutate the links array.
I am new to javascript and jquery and want to download image from datatable column where i have saved my image in public/images folder of laravel framework but when i click on download link some random files downloads which failed to download.
here is my code and screenshot of what i am actually trying to do
columns: [
// render:function(data,type,full,meta){
// return '<a href="'+data.filepath+'/'+data.fileName + '" download>Download</a>'
// },
// "targets": 0
// { data: 'rownum', orderable: false, searchable: false },
{ data: 'doc_type', name: 'doc_type' },
{ data: 'doc_number', name: 'doc_number' },
{ data: 'doc_date', name: 'doc_date'},
{ data: 'amount', name: 'amount' },
{ data: 'currency', name: 'currency' },
{ data: 'partener', name: '{{ TBL_PARTENER }}.id'},
{ data: 'image', name: 'image',render:function(data,type,full,meta){
// return 'Download'
return 'Download'
} },
//'image' => ['name' => 'image', 'data' => 'image'],
{ data: 'comments', name: 'comments' },
{ data: 'action', orderable: false, searchable: false}
],
Please view this screenshot of output
Much appreaciated your help
I cann't comment so i write here!
What happens if you remove "data:"?
I’m working with datatables and trying to figure out what I’m doing wrong. I am trying to display the total number of rows when the table hits the draw event on the table. Right now with the code, I’m showing below I am not getting any console errors. The element where the number is supposed to be updated is correct. I am just not getting it to render with the correct count.
("use strict");
const renderStatusCell = (data, type, full, meta) => {
const status = {
0: { title: "Inactive" },
1: { title: "Active" }
};
if (typeof status[data] === "undefined") {
return data;
}
return status[data].title;
};
var table = $('[data-table="users.index"]');
// begin first table
table.DataTable({
// Order settings
order: [[1, "desc"]],
ajax: "/titles",
columns: [
{ data: "id", title: "User ID" },
{ data: "name", title: "Name" },
{ data: "slug", title: "Slug" },
{ data: "introduced_at", title: "Date Introduced" },
{ data: "is_active", title: "Status", render: renderStatusCell },
{
data: "action",
title: "Actions",
orderable: false,
responsivePriority: -1
}
]
});
var updateTotal = function() {
table.on("draw", function() {
$("#kt_subheader_total").html(table.fnSettings().fnRecordsTotal());
});
};
I expected when the table was rendered to update the dom with the correct number of rows however the div does not get updated.
I don't understand your problem, but I think you need something like that.
table
.row($(this).parents('tr'))
.remove()
.draw();
or
table.ajax.reload();
I believe you need to wait until the HTML loads before running all your javascript code. Also, if you are storing the total, you not make it a function but rather just store the value.
'use strict';
// this will make sure all the HTML loads before the JavaScript runs.
$(function() {
var table = $('[data-table="users.index"]');
var updateTotal = null; // store in a variable
const renderStatusCell = (data, type, full, meta) => {
const status = {
0: { title: "Inactive" },
1: { title: "Active" }
};
if (typeof status[data] === "undefined")
return data;
return status[data].title;
};
// begin first table
table.DataTable({
// Order settings
order: [[1, "desc"]],
ajax: "/titles",
columns: [
{ data: "id", title: "User ID" },
{ data: "name", title: "Name" },
{ data: "slug", title: "Slug" },
{ data: "introduced_at", title: "Date Introduced" },
{ data: "is_active", title: "Status", render: renderStatusCell },
{
data: "action",
title: "Actions",
orderable: false,
responsivePriority: -1
}
]
});
table.on("draw", function() {
updateTotal = table.fnSettings().fnRecordsTotal();
$("#kt_subheader_total").html(table.fnSettings().fnRecordsTotal());
});
});
I'm teaching myself ExtJS by building a really simple 'scrum' development tracking application. I'm currently displaying the "Backlog" as a grid panel that displays the properties of the card(user story).
Card.js (Card model)
Ext.define('AM.model.Card', {
extend: 'Ext.data.Model',
fields: [
'id',
'name',
'priority_id',
...
]
});
Priority.js (Priority model)
Ext.define('AM.model.Priority', {
extend: 'Ext.data.Model',
fields: [
'id',
'name',
'short_name'
]
});
So the data for the card will look something like this:
backlogcards.json (data)
{
success: true,
backlogcards: [
{
id: 1,
name: 'ONEs',
priority_id: 2,
...
},
{
id: 2,
name: 'TWOs',
priority_id: 3,
...
}
]
}
And the priorities looks like this:
priorities.json (data)
{
success: true,
priorities: [
{
id : 1,
name : "High",
short_name : "H"
},
{
id : 2,
name : "Medium",
short_name : "M"
},
{
id : 3,
name : "Low",
short_name : "L"
}
]
}
So ideally what I would like to do is have the grid panel display the short_name for the corresponding priority_id. When the item is clicked on to be edited inline, a combo box will be displayed that shows the name property. I'm half way there already.
BacklogList.js (view)
Ext.define('AM.view.card.BacklogList', {
extend: 'Ext.grid.Panel',
alias: 'widget.backlogcardlist',
title: 'Backlog',
store: 'BacklogCards',
selType: 'cellmodel',
plugins: [
Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1
})
],
columns: [
{ header: 'ID', dataIndex: 'id' },
{ header: 'Name', dataIndex: 'name', field: 'textfield' },
{
header: 'Priority',
dataIndex: 'priority_id',
width: 130,
field: {
xtype: 'combobox',
typeAhead: true,
store: 'Priorities',
displayField: 'name',
valueField: 'id',
listClass: 'x-combo-list-small'
}
}
]
});
So I know the 'dataIndex' property is what I need to modify in order to change the display, but I'm not sure how to tie those two stores together.
As you can see above, priority is being displayed as a number instead of the short_name.
Is this a situation where I would need to use associations? (I only know OF them) Sencha Docs
Thank you!
EDIT1: Oh I realize I could 'hard code' a renderer property that does this change, but I would like to avoid that and instead use values from the priorities store.
renderer: function(value){
if (value==3)
{
return "L";
}
else if (value==2)
{
return "M";
}
else
{
return "H";
}
},
EDIT2 for Evan:
Priorities store
Ext.define('AM.store.Priorities', {
extend: 'Ext.data.Store',
model: 'AM.model.Priority',
autoLoad: true,
proxy: {
type: 'ajax',
api: {
read: 'app/data/priorities.json',
update: 'app/data/updateUsers.json'
},
reader: {
type: 'json',
root: 'priorities',
successProperty: 'success'
}
}
});
The store.each refers to this store, right? If so, how do I perform the each operation on it?
I tried changing the declaration line to:
var test = Ext.define('AM.store.Priorities', {
And then tried changing your code to test.each but was unsuccessful.
Thanks again!
You need to use a renderer, however there's nothing stopping you from looping over the values in the priorities store and checking, something like:
renderer: function(value) {
var display = '';
store.each(function(rec){
if (rec.get('id') === value) {
display = rec.get('name');
return false;
}
});
return display;
}