The model has variables from SUM_01 to SUM_31.
I did not want the code to be long, so I tried to write with the FOR statement as follows. But I get an error saying that I gave STRING instead of model type.
for (int i = 1; i < 32; i++)
{
string col = "o => o.SUM_0" + i;
string title = i + "DAY";
columns.Bound(col)
.Title(title)
.Width(85)
.HeaderHtmlAttributes(new { style = "text-align:center;vertical-align:middle;" })
.HtmlAttributes(new { style = "text-align:center;" });
}
Is there a way? oh, the grid using ZbdModels
#( Html.Kendo().Grid<TEST.Models.ZbdModels>()
You cannot specify the column definition like this: col = "o => o.SUM_0" + i. First of all, Kendo cannot interpret it. Also, you would end up with column names like SUM_023. Something like col = "SUM_" + i.ToString().PadLeft(2, '0') should work.
Related
I'm trying to make a script that replaces information in a template document (a contract). I've had it working looking through the columns of a google spreadsheet, but when trying to rewrite it to make it look through the rows of the spreadsheet instead of the columns it does not seem to work. It only returns information contained in the first row. I suspect it might have to do with the for-loop.
Here's a snippet of the code:
function lagkontrakt() {
const docFile = DriveApp.getFileById("DOC_FILE_ID");
const tempFolder = DriveApp.getFolderById("TEMP_FOLDER_ID");
const pdfFolder = DriveApp.getFolderById("PDF_FOLDER_ID");
var date = Utilities.formatDate(new Date(), "GMT+1", "dd/MM/yyyy");
//copies the template//
let copyFile = DriveApp.getFileById("FILE_ID").makeCopy(tempFolder);
let copyId = copyFile.getId();
let copyDoc = DocumentApp.openById(copyId);
//fetches the content of the template//
let copyBody = copyDoc.getBody();
let copyHeader = copyDoc.getHeader();
//defines active sheet//
let activeSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SHEETNAME");
let numOfRow = activeSheet.getLastRow();
//getRange(row, column, numRows, numColumns)//
let activeCol = activeSheet.getRange(1,2,numOfRow,1).getValues();
let headerCol = activeSheet.getRange(1,1,numOfRow,1).getValues();
let rowIndex = 0
//search loop//
for (; rowIndex < headerCol[0].length; rowIndex++){
copyBody.replaceText('{' + headerCol[rowIndex][0] + '}', activeCol[rowIndex][0]);
copyBody.replaceText("{dato}", date);
copyHeader.replaceText('{' + headerCol[rowIndex][0] + '}', activeCol[rowIndex][0]);
}
copyDoc.saveAndClose();
}
This is the column-version of the same script, that works just fine:
let numOfCol = activeSheet.getLastColumn();
let activeRow = activeSheet.getRange(2,1,1,numOfCol).getValues();
let headerRow = activeSheet.getRange(1,1,1,numOfCol).getValues();
let columnIndex = 0
for (; columnIndex < headerRow[0].length; columnIndex++){
copyBody.replaceText('{' + headerRow[0][columnIndex] + '}', activeRow[0][columnIndex]);
copyBody.replaceText('{dato}', date);
copyHeader.replaceText('{' + headerRow[0][columnIndex] + '}', activeRow[0][columnIndex]);
}
It looks like you have the variable in column A and the value in column B. Your For loop currently is limiting the rows that it searches to the length of the first row, which is to say that it will always be less than 1.
You need to change:
for (; rowIndex < headerCol[0].length; rowIndex++){
To:
for (; rowIndex < headerCol.length; rowIndex++){
If I'm not correct about how your data is laid out then you have reversed the array reference in a couple places and got an entire column instead of the entire row.
I'm trying to create a generic composite chart that would take any csv file, read the columns and create a composite line chart with one line per column.
In this use case, the first column is always TimeStamp in all csv's and this will not be changed, while the rest of the columns may vary.
To get the column names from any csv, I am using the following line of code.
var mappedArray = d3.entries(data[0]);
Say, my mappedArray is like this :
["Date", "c1", "c2", "c3"]
I have created the Dimension for timestamp as follows:
var DateDim = ndx.dimension(function(d){return timeFmt(d[mappedArray[0].key]); });
For a single valued group, i would use something like this:
var testGrp = DateDim.group().reduceSum(function(d){return +d[mappedArray[1].key]; });
For a multi valued group, I tried something like this:
var testGrp1 = testDim.group().reduce(
function(p,v){
++p.count;
p.col1 = +v[mappedArray[1].key];
p.col2 = +v[mappedArray[2].key];
...
p.coln = +v[mappedArray[n].key];
return p;
},...
But, I cannot hard code like this, as the 'n' in mappedArray[n] may keep changing.
How can I recreate this group by using mappedArray.length?
You recreate by using the index field operator []. Use a for loop to create as many p.colX fields as needed.
var testGrp1 = testDim.group().reduce(
function(p,v){
++p.count;
for (let i = 1; i < mappedArray.length; i++) {
p["col" + i] = +v[mappedArray[i].key];
}
return p;
},...
Edit
The answer to your question in the comment about the chart.compose.
A possible way of doing is to create a function that constructs the array needed.
function makeComposeArray() {
var composeArr = [];
for(let i=1; i<=mappedArray.length; i++) {
composeArr.push(
dc.lineChart(chart)
.group(testGrp1, function(d){return d['col'+i]})
.valueAccessor(function(d){return d.value["col" + i]})
);
}
return composeArr;
}
chart.compose(makeComposeArray());
IList<Item> items = new List<Item>();
items.Add(new Item
{
tag = "{" + Ann + "}",
value = "Anny"
});
items.Add(new Item
{
tag = "{" + John + "}",
value = "Johnny"
});
How can I use Linq to select tag with {John} and replace value with "Jane"?
LINQ is, as the name suggests, more of a query tools. So you can get specific item(s) that you want to modify from a collection using LINQ, but the modification itself is out-of-scope for LINQ.
Assuming that there is always maximum one match to your criteria, you can do as follows :
var john = items.FirstOrDefault(o => o.tag == "{John}");
if(john != null)
{
john.value = "Jane";
}
Otherwise, you can use LINQ Where(o => o.tag == "{John}") to get the target items for modification. But then you'll need to iterate through the result to actually update the value of each matched item.
items.Where(o => o.tag == "{"+John+"}").ToList().ForEach(item =>{
item.value = "Jane";
});
Here is working fiddle
I'm trying to create a chess game for Android and would like to avoid having to declare every button when they are all named so similarly. I tried to generate all of the A + Num button using this for loop.
int RowNum ;
for (RowNum = 1; RowNum < 8; RowNum++) {
String Position = "A" + RowNum;
Button Position = (Button)findViewById(R.id.Position);
}
But I have an error: Variable 'Position' is already defined in the scope.
I would really appreciate if someone could explain to me the best way to go about doing this.
Thanks in advance.
R.Id.A1, R.id.A2, etc. are identifiers and each of them is mapped to a single integer during compilation of R class. Thus, you cannot manipulate the 'R.id.sth' as a string because it will not compile properly.
A way to solve that is search for the string in resources dynamically with a code like this:
Button[] buttons=new Button[8];
for(int RowNum=0; RowNum<8; RowNum++) {
String buttonID = "A"+(RowNum+1);
int resID = getResources().getIdentifier(buttonID, "id", getPackageName());
buttons[RowNum] = ((Button) findViewById(resID));
}
Alternatively, to avoid the time overhead of dynamic search you can add a resource array:
int[] butIds = {R.id.A1, R.id.A2,...};
Button[] buttons= new Button[8];
for(int RowNum=0; RowNum<8, RowNum++) {
buttons[RowNum]= ((Button) findViewById(butIds[RowNum]));
}
You can even store the resource array in XML form and retrieve it as a TypedArray.
You called your String and Button object both Position. Give them different names, e.g.
for (int RowNum = 1; RowNum < 8; RowNum++) {
String currentPosition = "A" + RowNum;
//Why doesn this not use the Position (now 'currentPosition' variable)?
Button currentButton = (Button)findViewById(R.id.Position);
}
Semantically I still don't get that piece of code because Position is not used within the argument of findViewById, to which you pass a static variable R.id.Position.
I have been trying for a long time to get this to work..
Basically I am assigning columns and templates dynamically to the kendo grid. Each column can be of any type. If the type is 'address' type, then I am assigning a html template to that column to split the address string and display in a nice way.
I am doing this by creating a map of possible column types and their corresponding templates. The problem is with 'address' map.
uiTemplateMap["date"] = "#= kendo.toString(kendo.parseDate(" + fieldName + "), 'MM/dd/yyyy') #";
uiTemplateMap["address"] = eval("kendo.template($('\\#address-template').html())");
The 'address-template' is defined as
<script id="address-template" type="text/x-kendo-template">
# var addr = ${addresses} ; #
# var splitaddr = addr.split(','); #
# for (int i=0; i < splitaddr.length(); i++) { #
<i> #= splitaddr[i] # </i>
# } #
</script>
I get a invalid template exception. I have two questions.
how can I assign a column value to a javascript variable? The ${addresses} assignment does not seem to work.
I dont want to hard-code the 'addresses' column in the template. Can I pass the column name or value to the template like $('#address-template').html(columnName) ??
Any help will be highly appreciated, thanks
You can access the column value in data[columnName] where columnName is the field's name (a string), or, because the template function is using a with block, simply in columnName, so you could define a template generator like this:
function createAddressTemplateFor(columnName) {
return "# var address = data['" + columnName + "']; #" + // or: var address = columnName;
"# var splitaddr = address.split(','); #" +
"# for (var i = 0; i < splitaddr.length; i++) { #" +
"<i> #= splitaddr[i] # </i><br />" +
"# } #";
}
(demo)
If you want to use external templates, you'll probably have to hardcode the names (since the property name of the current column is not passed to the template), unless you want to modify the Kendo UI source code.