I would like to know how to successfully connect to spo service url with a IP address.
Connect-SPOService https://13.xxx.xxx.9-admin.sharepoint.com
How about triggering the Excel export manually on button click using kendo.ooxml.Workbook combined with kendo.saveAs?
I have made up a Kendo Dojo example. Let me know if this is what you need. Additionally, if you need to retrieve the name of your screen, there are some examples of how to do this here
EDIT
Below is an example of the export generated by the Dojo example when the "Click to Export" button is pressed. Note that the title is custom.
Not sure why this would not work for you, but try the following example with your code and see what happens. Basically, you can hook up the custom function to handle the export button click as follows:
$("#exportButton").kendoButton({
click: function () {
var grid = $("#yourGrid").getKendoGrid();
// declare `rows` and supply your own column names
var rows = [{
cells: [
{ value: "ContactTitle" },
{ value: "CompanyName" },
{ value: "Country" }
]
}];
var trs = grid.dataSource;
// will get any filters applied to grid dataSource
var filteredDataSource = new kendo.data.DataSource({
data: trs.data(),
filter: trs.filter()
});
filteredDataSource.read();
var data = filteredDataSource.view();
for (var i = 0; i < data.length; i++) {
var dataItem = data[i];
rows.push({
cells: [ // dataItem."Whatever Your Attributes Are"
{ value: dataItem.ContactTitle },
{ value: dataItem.CompanyName },
{ value: dataItem.Country }
]
});
}
excelExport(rows);
}
});
This sets up the rows to be exported, and the excelExport function carries out the export:
function excelExport(rows) {
var workbook = new kendo.ooxml.Workbook({
sheets: [
{
columns: [
{ autoWidth: true },
{ autoWidth: true }
],
title: "Name of Tab",
rows: rows
}
]
});
var nameOfPage = "Test-1"; // insert here however you are getting name of screen
kendo.saveAs({ dataURI: workbook.toDataURL(), fileName: nameOfPage + " Export.xlsx" });
}
Let me know the outcome.
Related
I have multiple series lets call them
A, B, C, D
I have pulled the series data like so
data:[1,2,3], data:[4,5,6], data[3,5,7], data[7,8,9]
The data is showing correctly on the bar chart
But when I click the series name/identifier on the y-Axis while the bar shows the correct data, the label that appears beside the bar, is incorrect.It seems to use an index based correlation between series and labels
Here is my code:
axios.get('/api/getData')
.then((response) => {
let data= response.data
//initialize series, category arrays
let series = [];
let categories = [];
//group data by product types
let productTypeGroups = _.groupBy(stockData, (product) => {
return product.type;
});
//loop through grouped data and create series for each product type
for(const[key,value] of Object.entries(productTypeGroups)){
let dataValues= _.map(value, (product)=>{
//push product names into category array
categories.push(product.name)
return product.current_balance < 0 ? 0 : product.current_balance;
})
//set default visibility to true if product is vaccine
let visibility = key === 'A' ? true : false
series.push({
name:key,
data:dataValues,
visible:visibility
})
}
this.dataValuesChart.highchartOptions.xAxis.categories = categories
this.dataValuesChart.dataValues.series = series
Here is the HighCharts Config:
highchartOptions: {
chart: {
type: 'bar',
height: 500
},
title: {
text: 'Stock Balance'
},
subtitle: {
text: ''
},
yAxis: {
title: {
text: 'Doses'
},
labels: {
format: '{value}'
}
},
xAxis: {
categories: [],
labels:{
step:1
}
},
plotOptions: {
series: {
label: {
connectorAllowed: false
}
}
},
series: [],
responsive: {
rules: [{
condition: {
maxWidth: 500
},
chartOptions: {
legend: {
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom'
}
}
}]
}
}
Here is a screenshot of how the chart displays:
How does the click event know what labels to pull, should we use some sort of dynamic category setting for this to work? Is there another way to do this even?
Credit #ppoctaczek for pointing out the data array can also be a multidimensional array [x, y] as documented here: https://api.highcharts.com/highcharts/series.bar.data
In terms of hiding the unclicked series #ppoctaczek suggested I edit the plotOption section like so. NB default behaviour on click is to add or remove clicked series to already clicked series - you can retain these defaults if that works for you.
plotOptions: {
series: {
label: {
connectorAllowed: false
},
grouping:false,
events:{
legendItemClick: function(){
this.chart.series.forEach(s=>{
s.hide();
});
this.show();
return false;
}
}
}
},
Then in terms of the data array I needed to make it multidimensional, and have the x value referencing the serial indices of the categories across the multiple series. I achieved this by:
//initialize index counter
let i = 0;
//loop through grouped data and create series for each product type
for(const[key,value] of Object.entries(productTypeGroups)){
let balances = [];
_.each(value, (product)=>{
//push product names into category array
categories.push(product.name)
//push index and balance into balances array
balances.push([i, product.current_balance]);
//increment index
i++;
})
//set default visibility to true if product is vaccine
let visibility = key === 'vaccine' ? true : false
series.push({
name:key,
data:balances,
visible:visibility
})
}
Your data array on console.log your series data should look like this:
I'm working on a custom language extension and I'm having issues with how to show functions for a variable.
I'm importing my language in the form of json, so i've created a typescript-file that i import into my extensions.ts:
export interface CustomIntellisense {
text: string;
help: string;
}
const data = [{
"text": "Void.String",
"help": "<h1>String String()</h1><p>Default constructor.<code>String something;</code></p>"
},
{
"text": "String.toInteger",
"help": "<h1>Integer toInteger()</h1><p>Converts a String to its numeric representation."
},
{
"text": "Void.Integer",
"help": "<h1>Integer Integer()</h1><p>Default constructor.</p>"
}];
export let json: CustomIntellisense[] = data;
My idea here is that the elements containing "Void" in text gets created as a variable, while the other element gets added as a method.
const provider1 = vscode.languages.registerCompletionItemProvider({ language: 'myLanguage', scheme: 'file' }, {
provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext) {
let items: vscode.CompletionItem[] = [];
let re = /\"/gi;
json.forEach(element => {
const item = new vscode.CompletionItem(element.text.split('.')[1]);
item.insertText = new vscode.SnippetString(element.help);
const markdownDocumentation = new vscode.MarkdownString();
markdownDocumentation.supportHtml = true;
markdownDocumentation.appendMarkdown(element.help);
item.documentation = markdownDocumentation;
if (element.text.includes('Void.')) { //If text includes Void this should be a variable
item.kind = vscode.CompletionItemKind.Variable;
}
else {
item.kind = vscode.CompletionItemKind.Method;
}
items.push(item);
});
return items;
}
});
The items gets added to the view, but I can't figure out how to 'filter' what is shown.
The official example on how to achieve this can be found here:
https://github.com/microsoft/vscode-extension-samples/blob/main/completions-sample/src/extension.ts
But this only explains how to filter based on the text/name, and i cant filter this specifically for each variableName i use.. If i somehow could detect what kind of Variable i'm working on I could possibly create a function that fetches if its a String/Int, then parse through my file and add methods in my 2nd CompletionItemProvider. But I havent found any good way of deciding the type of variable..
What i want is this:
If i click ctrl+space i want toInteger() to be the only thing that shows up, but instead it lists up everything all the time:
Anyone have a clue how to achieve this?
I am working with sap.m.table. I have requirement to apply or change the background color for some of the rows based on the data in one of the column in those rows in table.
I am using the following code but it is not working
created the CSSfile: test.css
<style type="text/css">
.Total {
background-color: LightSteelBlue !important;
}
</style>
The above CSS file declare in Component.js like the following way ( correct me if this not right way to make the css file available to access in whole ui5 project.
"resources": {
"css": [
{
"uri": "css/test.css"
}
]
}
In Controller.i have defined the following method to apply the style sheet for the particular rows alone in table.
rowColours: function() {
var oController = this;
console.log("rowColours() --> Start ");
var oTable = this.oView.byId("tblAllocation");
var rows = oTable.getItems().length; //number of rows on tab
//start index
var row;
var cells = [];
var oCell = null;
for (i = 0; i < oTable.getItems().length; i++) {
//console.log("rowColours() :: row--> "+row);
//actualRow = oTable.getItems(); //content
if (i == 0) {
row = oTable.getItems()[i];
cells = cells.concat(oTable.getItems()[i].getCells());
//getting the cell id
oCell = cells[2];
oCell = oCell.toString().substring(29, oCell.length);
otemp = this.getView().byId(oCell).getText();
if (otemp.toString() == "TotalAllocation") {
oTable.getItems()[i].$().taggleClass("grandTotal");
}
}
}
console.log("rowColours() --> end ");
}
In the above method. I am checking the cell2 data ( in table cell 2 i was using the Textview control to display the data. when call this method to get the data in that cell. I am getting the following error.
otemp = this.getView().byId(oCell).getText());
error:
Uncaught TypeError: Cannot read property 'getText' of undefined
is the following code is possible to change the row bg color.
if (otemp.toString() == "TotalAllocation") {
oTable.getItems()[i].$().taggleClass("Total");
}
Please let me know how to change the bg color or applying the style for the perticular row in sap.m.table
Thanks
The approach your following is not right. Better you can use a formatter.
Example:
var oTable = new sap.m.Table({
columns: [
new sap.m.Column({
header: new sap.m.Label({
text: "Name"
}),
}),
],
items: {
path: 'modelList>/',
template: new sap.m.ColumnListItem({
cells: [
new sap.m.Text({
//formatter to the text property on sap.m.Text control.
text: {
parts: [{
"path": "modelList>Name"
}],
formatter: function(name) {
if (name == "TotalAllocation") {
// use this.getParent().. until u get the row. like this below and add class.
this.getParent().getParent().addStyleClass("Total");
}
}
}
})
]
})
}
});
I have a dynamic form:
var Form = React.createClass({
log: function(e) {
console.log(e.target.value);
},
getInitialState: function () {
return {counter: 2};
},
handleChange : function(e) {
this.setState({counter: parseInt(e.target.value)});
},
render: function () {
var fields = [
React.createElement('input', {key: -2, onChange: this.handleChange}),
React.createElement('input', {key: -1, onChange: this.log})
];
for (var x = 0; x < this.state.counter; x++) {
fields.push(React.createElement('input', {key: x, onChange: this.log}));
}
return React.createElement('div', {}, fields);
}
});
The form is in a separate node module and I require it as:
var Form = require('custom-forms');
In the first input field I control the number of input fields. The log method of the newly created input fields is never invoked. There are no listeners for the new input fields.
When I move the form in the main project, everything is ok. The values are logged on the console when there is a change in the input.
Does anyone know where the problem could come from?
I've seen similar things, where people have wanted to do this in ASP .NET, generic JavaScript, PHP, etc., but now here we have KnockOut that throws a wrench in things, since its fields are already rendered dynamically. Now here I go wanting to rewrite a dropdown when another is changed... dynamic loading on top of dynamic loading, all in old-fashioned cascading style....
I have a dropdown, "ourTypes", I've called it, that when changed, should re-write the options of the "slots" dropdown to its left. I have a .subscribe() function that creates new options based on a limit I get from the "ourTypes" value. All well and good, but how do we make the dropdown actually reflect those new values?
HTML:
<select data-bind="options: $root.slots, optionsValue: 'Value', optionsText: 'Text', value: $data.SlotPosition"></select>
<select data-bind="options: $root.ourTypes, optionsValue: 'ID', optionsText: 'Name', value: $data.OurTypeId"></select>
JavaScript:
var slots = [
{ Text: "1", Value: "1" },
{ Text: "2", Value: "2" },
{ Text: "3", Value: "3" }
];
var ourTypes = [
{ ID:"1", Name:"None", Limit:0 },
{ ID:"2", Name:"Fruits", Limit:5 },
{ ID:"3", Name:"Vegetables", Limit:5 },
{ ID:"4", Name:"Meats", Limit:2 }
];
var dataList = [
{ SlotPosition: "1", OurTypeId: 4 },
{ SlotPosition: "2", OurTypeId: 2 },
{ SlotPosition: "3", OurTypeId: 3 }
];
var myViewModel = new MyViewModel(dataList);
ko.applyBindings(myViewModel);
function MyViewModel(dataList) {
var self = this;
self.slots = slots;
self.ourTypes = ourTypes;
self.OurTypeId = ko.observable(dataList.OurTypeId);
self.SlotPosition = ko.observable(dataList.SlotPosition);
self.OurTypeId.subscribe(function() {
if (!ko.isObservable(self.SlotPosition))
self.SlotPosition = ko.observable("1");
// Get our new limit based on value
var limit = ko.utils.arrayFirst(ourTypes, function(type) {
return type.ID == self.OurTypeId();
}).Limit;
// Build options here
self.slots.length = 0;
self.slots.push({Text:"",Value:""});
for (var i=1; i < limit+1; i++) {
self.slots.push({Text:i, Value:i});
}
// What else do I do here to make the dropdown refresh
// with the new values?
});
}
Fiddle: http://jsfiddle.net/navyjax2/Lspwc4n4/
Well just made small changes in you code
View Model:
self.slots = ko.observableArray(slots); //should make it observable
self.ourTypes = ko.observableArray(ourTypes);
self.OurTypeId = ko.observable(dataList[0].OurTypeId); // initial value setting
self.SlotPosition = ko.observable(dataList.SlotPosition);
//Inside subscribe
self.slots([]); // clearing before filling new values
Working fiddle here