I'd like to give my users the chance to reformat table cells after data has been loaded into the table. I thought a neat way to do this, is adding the functionality to the column menu. So when clicking on a table column, the menu appends with the standard "filtering, sorting" but also has a row called "formatting" which provides a few options (E.g. format a numeric cell from 55555,55 to 55.555,55)
Unfortunately I was unable to find a way to add a new row to my column menu. My sorting and filtering is added like this:
oTable.bindColumns("/columns", function(index, context) {
var columnName = context.getObject().columnId;
return new sap.ui.table.Column({
label:columnName,
template: columnName,
sortProperty: columnName,
filterProperty: columnName,
});
});
How do I add new lines/functionalities to the column menu?
Update
This is how my table looks like in xml view:
<table:Table id="uploadData" visibleRowCountMode="Auto" rowSelectionChange="tableRowSelectionChange" enableCellFilter="true" fixedColumnCount="0" enableBusyIndicator="true" customData="{Type: 'sap.ui.core.CustomData', key:'table-style-type', value:'custom-styled', writeToDom: true }">
<table:extension>
<m:Button icon="sap-icon://download" press="onDataExportXLS" align="Right" />
</table:extension>
<table:columns>
<!-- Columns dynamically created in controller -->
</table:columns>
<table:rows>
<!-- Rows created in controller -->
</table:rows>
</table:Table>
The sap.ui.table.Column has an aggregation called menu just for this. It accepts any custom menu items which are shown when clicking on a Column. This aggregation takes sap.ui.unified.Menu control.
In the select function of the MenuItem aggregation, you can write the function to handle what needs to be done when the menu item is selected
sap.ui.table.Column documentation
sap.ui.unified.Menu documentation
Check it in this sample here and its code here, click on the Quantity column and you will see a My custom menu entry
A snippet of the code here in XML,
<Column id="quantity" width="6rem" hAlign="End" sortProperty="Quantity">
<m:Label text="Quantity" />
<template>
<m:Label text="{ path: 'Quantity', type: 'sap.ui.model.type.Integer'}" />
</template>
<menu>
<u:Menu ariaLabelledBy="quantity">
<u:items>
<u:MenuItem text="My custom menu entry" select="onQuantityCustomItemSelect" />
<u:MenuItem text="Sort" select="onQuantitySort" icon="sap-icon://sort" />
</u:items>
</u:Menu>
</menu>
</Column>
The code in JS,
var oColumn = new sap.ui.table.Column({
label: "Some column Name",
menu: new sap.ui.unified.Menu({
items: [new sap.ui.unified.MenuItem({
text: "My custom menu",
select: function (oEvent) {
pressEventOnItem(oEvent);
})
]
})
})
Related
I use Quasar framework in Version 1.6.2. and want to use a component (Drawer.vue) for my drawer. The component is used in my layout file (MainLayout.vue).
I get the following error message in my console:
Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "rightDrawerOpen"
The drawer works, but not on the first click – only on subsequent clicks.
What is the correct way to pass the parents model to my drawer?
Component: Drawer.vue
<template>
<q-drawer show-if-above v-model="rightDrawerOpen" side="right" bordered>
<q-list>
<q-item-label header>Menü</q-item-label>
</q-list>
</q-drawer>
</template>
<script>
export default {
name: "Drawer",
props: {
rightDrawerOpen: Boolean
}
};
</script>
Parent: MainLayout.vue
<Drawer :right-drawer-open="rightDrawerOpen" />
I would move the q-drawer component back into the MainLayout.vue component, then put the q-list into the child component. Then toggling "rightDrawerOpen" will occur in the "data" of MainLayout.vue instead of on the props of the child component which is where the error is coming from. Example:
MainLayout.vue:
<template>
<q-layout>
<q-drawer show-if-above v-model="rightDrawerOpen" side="right" bordered>
<DrawerContents />
</q-drawer>
<q-page-container>
<router-view />
</q-page-container>
</q-layout>
</template>
<script>
import DrawerContents from './DrawerContents.vue';
export default {
components: {
DrawerContents,
},
data() {
return {
rightDrawerOpen: true,
};
},
};
</script>
DrawerContents.vue:
<template>
<q-list>
<q-item-label header>Menü</q-item-label>
</q-list>
</template>
How to remove default tooltip from a menu item in a collapsible state with sidebar? It seems like the same question asked in the ant design GitHub also, but no response. Code and screenshot below.
<Menu.Item key="profile">
<Link to={`${baseConfig.page.profile.url}`}>
<span className="isoMenuHolder" style={{color:'#ffffff'}}>
<i className="icon-admin" />
<span className="nav-text">
Settings
</span>
</span>
</Link>
</Menu.Item>
Take it out with css
.ant-tooltip {
display: none;
}
Not sure if my workaround helps you or not but I have a collapse/expand button within the Menu and it displays the color of the button as the tooltip. So i removed the Menu.Item and the tooltip disappeared
<Menu
mode="inline"
theme="light"
inlineCollapsed={this.state.menuCollapsed}
className="CollapseButtonMenu"
>
<Button type="primary" onClick={this.toggleCollapsed} style={{ marginBottom: 16 }}>
<Icon type={this.state.menuCollapsed ? 'menu-unfold' : 'menu-fold'} />
</Button>
</Menu>
since the new changes on antd (> 4.23.3), the <Menu.Item /> component was deprecated, with the new API they provide a way to make the tooltip disappear is to define the title attribute as null or as an empty string on the items list like:
const items = [
{
key: "0",
title: "", //this makes the tooltip disappear
label: "Any Label"
}
];
Basically, I want to repeat q-select/q-tree for each item in the list:
<q-item v-for="item in list">
{{item}}
<q-select
v-model="selected_val"
radio
:options="option"
/>
</q-item>
In data section, I have following code
data(){
return{
list:['item1','item2','item3'],
option:[
{label:'first',value:'first'},
{label:'second',value:'second'},
{label:'third',value:'third'}
],
selected_val:''
}
The current result shown will reflect the value of each item.
i'm using quasar framework with Vue js.
Your selected_val model data should not be a string, but an array.
new Vue({
el: '#q-app',
data(){
return {
list:['item1','item2','item3'],
selected_val: [],
options: [
{label:'first',value:'first'},
{label:'second',value:'second'},
{label:'third',value:'third'}
]
}
}
})
<div id="q-app">
<q-item v-for="(item, index) in list">
<q-item-side>{{item}} </q-item-side>
<q-item-main>
<q-select v-model="selected_val[item]" radio :options="options" />
</q-item-main>
</q-item>
<q-list>
<q-item v-for="item in list"> {{item}} selected value: {{selected_val[item]}}</q-item>
</div>
See codepen for demonstration
Codepen
This is because you are using same v-modal for all the q-select. Each q-select needs to have unique v-modal.
You can achieve this by creating a similar array as list and adding it to v-modal
In a master-detail view, I have a list of work centers as master part, and a planning calendar as detail part.
<mvc:View controllerName="sap.ui.demo.wt.controller.Overview"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc"
xmlns:semantic="sap.m.semantic"
xmlns:unified="sap.ui.unified"
xmlns:core="sap.ui.core" displayBlock="true"
>
<Page title="{i18n>overviewPageTitle}">
<SplitContainer>
<masterPages>
<semantic:MasterPage title="{i18n>overviewMasterTitle}">
<List items="{data>/WorkCenterSet}">
<ObjectListItem
title="{data>WorkCntr}"
type="Active"
press="onWorkCtrPressed"
/>
</List>
</semantic:MasterPage>
</masterPages>
<detailPages>
<semantic:DetailPage title="{i18n>overviewDetailTitle}">
<VBox>
<PlanningCalendar id="PC"
startDate="{/StartDate}"
rows="{
path : 'data>/EmployeeSet',
parameters : {
expand : 'OrderOperation, EmployeeWorkCenter'
}
}"
>
<rows>
<PlanningCalendarRow
title="{data>UserFullname}"
appointments="{
templateShareable : true,
path : 'data>OrderOperation'
}"
>
<appointments>
<unified:CalendarAppointment
startDate="{data>EarlSchedStartdate}"
endDate="{data>EarlSchedFindate}"
title="{data>Description}"
/>
</appointments>
</PlanningCalendarRow>
</rows>
</PlanningCalendar>
</VBox>
</semantic:DetailPage>
</detailPages>
</SplitContainer>
</Page>
</mvc:View>
I want to filter the planning calendar according to the work center an employee belongs to.
Here is the controller :
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/json/JSONModel",
"sap/ui/model/odata/v2/ODataModel",
"sap/ui/model/Filter",
"sap/ui/model/FilterOperator"
], function(Controller,JSONModel,ODataModel,Filter,FilterOperator) {
"use strict";
return Controller.extend("sap.ui.demo.wt.controller.Overview", {
onInit: function(){
this.getView().setModel(new JSONModel({
"StartDate" : new Date("2016-06-12T08:00:00Z")
}));
},
onWorkCtrPressed: function(oEvent) {
var oContext = oEvent.getSource().getBindingContext("data");
var sWorkCntr = oContext.getPath().split("'")[1]; //get the work center's name
//What I tried first
//var aFilter = [];
//aFilter.push(new Filter("WorkCntr",FilterOperator.StartsWith,sWorkCntr))
//this.getView().byId("PC").getBinding("rows").filter(aFilter);
sap.m.MessageToast.show("Selected Work Center : " + sWorkCntr);
}
});
});
What I tried first doesn't work because of the query look for the property "WorkCntr" in the entity set "EmployeeSet". But this property exists only in the entity set "EmployeeWorkCenterSet" that I have expanded in the view. The problem is: I don't even know the query I need to use... Could you help ?
PS: My OData service is in version 2. Queries like
EmployeeSet?$expand=EmployeeWorkCenter($filter={any filter})
do not work.
I am using jquery-select2 (4.0.0). The issue is when I select an option, then select another option, item.selected remains true for both options - FOREVER. Is there some initial config option I am missing or is this a bug?
function formatResult(item) {
console.log("item selected = ", item.selected);
return item.text;
}
$('select').select2({
templateResult: formatResult,
minimumResultsForSearch: Infinity,
placeholder: "Please choose",
multiple: false,
maximumSelectionSize: 1
});
<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.js"></script>
<select>
<option></option>
<option>conan</option>
<option>kimmel</option>
<option>stewart</option>
<option>colbert</option>
</select>
I should start this off by saying that item.selected (the selected property of the data object) is not documented, and will change in the future. Why do I say it will? Because this bug only occurs on single select elements (as explained at the very end), but you can safely ignore it for now.
Right now the item.selected property is only used by Select2 on <input /> elements, and the item.element.selected property is used for <select> elements. This will always be your source of truth when using a <select> element, as item.element is a reference to the <option> element that your browser uses for determining what data should be sent to the server.
You can see after looking at item.element.selected that it is correctly updated when the selection changes.
function formatResult(item) {
console.log("item selected = ", item.selected);
console.log("item.element.selected = ", item.element && item.element.selected);
return item.text;
}
$('select').select2({
templateResult: formatResult,
minimumResultsForSearch: Infinity,
placeholder: "Please choose",
multiple: false,
maximumSelectionSize: 1
});
<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.js"></script>
<select>
<option></option>
<option>conan</option>
<option>kimmel</option>
<option>stewart</option>
<option>colbert</option>
</select>
And yes, the item.selected property will be fixed in the future so it is accurate. Right now it is not updated because in a single select, new options are selected and those implicitly unselect the old options. This is unlike a multiple select, where options are explicitly selected and unselected.