Kendo Grid Row Grouping Not Working - html

I am using Kendo for the first time and am attempting to convert an HTML table to a Kendo grid. Upon initialization, I want the table to be grouped by a specific column and not be groupable by any other column. Below is a contrived example of a table of cars to be grouped by the car's make which demonstrates how I am attempting to group by a specific column upon initialization.
This attempt does not cause the table to be grouped. I know the kendoGrid call is working, because if I set groupable to true I am able to group by any column via drag and drop, but the initial grouping still does not occur. I suspect that somehow the group field "make" is not being tied to my make column, but examples I've seen seem to indicate this can be accomplished using data-field as I have done.
<table id="carsGrid">
<thead>
<tr>
<th>Year</th>
<th>Color</th>
<th data-field="make">Make</th>
</tr>
</thead>
<tbody>
<tr>
<td>2010</td>
<td>Red</td>
<td>Dodge</td>
</tr>
<tr>
<td>2014</td>
<td>Blue</td>
<td>Ford</td>
</tr>
<tr>
<td>2016</td>
<td>Black</td>
<td>Dodge</td>
</tr>
</tbody>
</table>
And in the document's ready function:
$('#carsGrid').kendoGrid({
datasource: { group: { field: "make" } },
groupable: false //I do not want grouping on other columns
});

I found some solution for your problem: Check this example http://dojo.telerik.com/OhEta
You should add data-groupable="false" attribute in <th> element:
<thead>
<tr>
<th data-field="year" data-groupable="false">Year</th>
<th data-field="color" data-groupable="false">Color</th>
<th data-field="make">Make</th>
</tr>
</thead>

Instead of using an html <table> you can setup the columns and their values in the javascript.
First you can replace your entire <table></table> section with:
<div id="grid"></div>.
Then in your document's ready function, you can throw your values for each column into an array:
var productsArray = [{Year: 2010, Color: "Red", Make: "Dodge"},
{Year: 2014, Color: "Blue", Make: "Ford"},
{Year: 2016, Color: "Black", Make: "Dodge"}]
And update where you set the kendo grid with:
$("#grid").kendoGrid({
dataSource: {
data: productsArray,
group: {field: "Make"}
},
columns: [
{ field: "Year" },
{ field: "Color" },
{ field: "Make" }
]
});
Click Here for a working example that you can test with.

Related

Match and replace every 7th instance of a <td> tag

I'm struggling to wrap my head around how to get this regex working in Visual Studio Code.
I'm trying to match every 7th instance of <td> tag to then replace it with <td data-order="">.
Original
<tr>
<td>1</td>
<td>Name</td>
<td>Owner</td>
<td>Value</td>
<td>Total</td>
<td>Percent</td>
<td>Ratio</td>
<td>Final</td>
</tr>
What I want
<tr>
<td>1</td>
<td>Name</td>
<td>Owner</td>
<td>Value</td>
<td>Total</td>
<td>Percent</td>
<td data-order="">Ratio</td>
<td>Final</td>
</tr>
I've tried variations on ((?:.*<td>){1}), but any number greater than 1 just gives me a "No results" message.
[You say "match every 7th instance" but I think you mean match the seventh instance, not the 7th, 14th, 21st, etc. Assuming that you mean the 7th only..."]
If your data is really as regular and structured as you showed, you could use this as the regex in a Find
Find: (?<=<tr>\n(?:<td>.*<\/td>\n){6})(<td)
Replace: <td data-order=""
If you might have newlines within a <td>...\n...</td> tag, use this
Find: (?<=<tr>\n(?:<td>[^/]*<\/td>\n){6})(<td)
Replace: <td data-order=""
Vscode's find/replace (in one file) can use a non-fixed length lookbehind like
(?<=<tr>\n(?:<td>.*<\/td>\n){6})
The search across files cannot do that so this regex would not work there. Also sites like regex101.com can't use it either so I'll show a demo in vscode itself:
You can use the extension Select By. And use the command moveby.regex.
In your keybindings.json define a keybinding to search for the next <td> tag.
{
"key": "ctrl+i ctrl+u", // or any other key combo
"when": "editorTextFocus",
"command": "moveby.regex",
"args": {
"regex": "<td[^>]*>",
"properties": ["next", "end"]
}
}
Select the first <tr> tag of where you want to start
Select every following <tr> tag with:
command: Add Selection to Next Find Match(Ctrl+D - editor.action.addSelectionToNextFindMatch)
menu option: Selection > Select All Occurrences
Apply the key binding as many times as you want
Your cursors are now after the n-th <td> tag
Make any edits you want
Press Esc to leave Multi Cursor mode
In Select By v1.2.0 you can specify a repeat count. The count can be fixed or asked from the user.
{
"key": "ctrl+i ctrl+u", // or any other key combo
"when": "editorTextFocus",
"command": "moveby.regex",
"args": {
"regex": "<td[^>]*>",
"properties": ["next", "end"],
"repeat": "ask"
}
}
If you leave out the property "regex" you are asked for a regular expression too.
Edit
Using a regular expression takes quite some time to get it correct
let testStr =`<tr>
<td>1</td>
<td>Name</td>
<td>Owner</td>
<td>Value</td>
<td>Total</td>
<td>Percent</td>
<td>Ratio</td>
<td>Final</td>
</tr>`;
var replace = '$1<td class="red">$2';
var regex = new RegExp("(<tr>[\n\r\s]*(?:<td[^>]*>(?:.|[\n\r\s])*?</td>[\n\r\s]*){6})<td>((?:.|[\n\r\s])*</tr>)");
var newstr=testStr.replace(regex,replace);
console.log(newstr);
document.getElementById("test").innerHTML=newstr
.red {
color: red
}
<table>
<tbody >
<tr id="test">
</tr>
</tbody>
</table>
I was interested in this as I don't know much of regex and need to learn, but I manged to make it so in two goes.
I hope someone will correct me and help with correct one way.
I tried to folow this: but cant make it to work: Find Nth Occurrence of Character
let testStr = '<td>1</td><td>Name</td><td>Owner</td><td>Value</td><td>Total</td><td>Percent</td><td>Ratio</td><td>Final</td>';
var replace = '<td class="red">';
var regex = new RegExp("((<td>.*?)){7}");
// tried with a lot of (?:...) combinations here but none works :(
var newstr=testStr.replace(regex,replace);
var regex2 = new RegExp("((</td>.*?)){6}");
var newstr2=testStr.match(regex2);
console.log(newstr);
console.log(newstr2[0]);
document.getElementById("test").innerHTML=newstr2[0]+newstr
.red {
color: red
}
<table>
<tbody >
<tr id="test">
</tr>
</tbody>
</table>
EDIT:
Got something :)
let testStr = '<td>1</td><td>Name</td><td>Owner</td><td>Value</td><td>Total</td><td>Percent</td><td>Ratio</td><td>Final</td>';
var replace = '<td class="red">';
var regex = new RegExp("(?:[</td>]){6}(<td>)");
var newstr=testStr.replace(regex,replace);
console.log(newstr);
document.getElementById("test").innerHTML=newstr
.red {
color: red
}
<table>
<tbody >
<tr id="test">
</tr>
</tbody>
</table>
And with #rioV8's help:
let testStr = '<td>1</td><td>Name</td><td>Owner</td><td>Value</td><td>Total</td><td>Percent</td><td>Ratio</td><td>Final</td>';
var replace = '$1<td class="red">';
var regex = new RegExp("((?:.*?</td>){6})<td>");
var newstr=testStr.replace(regex,replace);
console.log(newstr);
document.getElementById("test").innerHTML=newstr
.red {
color: red
}
<table>
<tbody >
<tr id="test">
</tr>
</tbody>
</table>

Filling a table with JSON data

I am taking mmy first steps in Angular and was about to try populating a table with data stored in a JSON file. Facing a bit of an odd/unexpected situation there as the table doesn't look exactly how I expected it to look. First things first.
Table code:
<table class="table table-sm table-bordered">
<thead>
<tr>
<th>Transfers</th>
<th>Tools</th>
</tr>
</thead>
<tbody>
<tr *ngFor = "let data of linksArray">
<td>{{ data.Transfers}}</td>
<td>{{ data.Tools}}</td>
</tr>
</tbody>
</table>
What I would like to achieve is that the columns Transfers and Tools get filled with data that uses the corresponding keywords in my JSON file. And here it is
[{"Type":"Transfers","Name":"1","Hyperlink":"#"}, {"Type":"Transfers","Name":"2","Hyperlink":"#"},
{"Type":"Tools","Name":"1","Hyperlink":"#"}, {"Type":"Tools","Name":"2","Hyperlink":"#"}]
The array gets loaded by using this in my .ts file
this.http.get('../../assets/templatefiles/links.json').subscribe(data => {this.linksArray = data as
any [];
console.log(this.linksArray);
},
(err: HttpErrorResponse) => {
console.log (err.message);
}
);
So far all looks good, I see the array popping up in console, but then look at the table and am confused
I would have expected the entries in the 2nd column to start in the first cell. Instead they start in the 3rd? What am I missing here? Been marveling for quite a while now :)
https://stackblitz.com/edit/angular-ivy-hvcyfq
To get this
Transfers Tools
1 10
2 20
You want code roughly like this
<hello name="{{ name }}"></hello>
<table class="table table-sm table-bordered">
<thead>
<tr>
<th>Transfers</th>
<th>Tools</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of linksArray">
<td>{{data.Transfers.Name}}</td>
<td>{{data.Tools.Name}}</td>
</tr>
</tbody>
</table>
And, this is the main bit, json roughly like this
linksArray = [
{
Transfers: {
Name:"1",
Hyperlink:"#"
},
Tools: {
Name:"10",
Hyperlink:"#"
}
},
{
Transfers: {
Name:"2",
Hyperlink:"#"
},
Tools: {
Name:"20",
Hyperlink:"#"
}
},
Your existing json looks like this, where the '{' represents one row
[
{
"Type":"Transfers",
"Name":"1",
"Hyperlink":"#"
},
{
"Type":"Transfers",
"Name":"2",
"Hyperlink":"#"
},
{
"Type":"Tools",
"Name":"1",
"Hyperlink":"#"
},
{
"Type":"Tools",
"Name":"2",
"Hyperlink":"#"
}
]

How to display the value returned by avg function (mysql) in angular

After executing a query, I received the following data which is in Json format which is in myDocData:
data: [
RowDataPacket {
updatedAt: 2020-01-03T18:30:00.000Z,
email: 'charles#hotmail.com',
name: 'charles',
money_spent: 1,
'avg(e.money_spent)': 1
},
RowDataPacket {
updatedAt: 2020-01-11T18:30:00.000Z,
email: 'ank#gmail.com',
name: 'ank',
money_spent: 10,
'avg(e.money_spent)': 6
}
]
angular code:
<table class="content-table" >
<thead>
<tr>
<th>EMAIL</th>
<th>NAME</th>
<th>money spent</th>
<th>UPDATED</th>
<th>AVERAGE</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of myDocData">
<td>{{item.email}}</td>
<td>{{item.name}}</td>
<td>{{item.money_spent}}</td>
<td>{{item.updatedAt}}</td>
<td>{{item.avg(e.money_spent)}}</td>
</tr>
</tbody>
</table>
Issue is that I am unable to display the value given by avg function
(other attributes are displayed correctly).
Change the line:
<td>{{item.avg(e.money_spent)}}</td>
to:
<td>{{item['avg(e.money_spent)']}}</td>
In JS, you can use square bracket notation to get properties of objects.
If you have the control over the back-end code then you can change the query which is returning "avg(e.money_spent)" to "avg(e.money_spent) as avg_money_spent" in this way will not be facing the issue and you can access the value using
<td>{{item.avg_money_spent}}</td>
Or you could also use the previous answer by #Viqas

How to use CSS grid with a dynamic number of columns and rows?

I'm trying to create a table in Angular with a dynamic number of columns and rows. I've found this easy to accomplish using the HTML table element by doing something like this:
<table class="html-table">
<tr class="headers">
<th>Name</th>
<th>Age</th>
<th>Sex</th>
<th *ngIf="columns == 4">Species</th>
</tr>
<tr>
<td>Ryan</td>
<td>30</td>
<td>M</td>
<td *ngIf="columns == 4">Human</td>
</tr>
</table>
In this example there might be some button that toggles the value of columns between 3 and 4.
Every explanation I have looked at online involves changing CSS variables, which seems like a somewhat hacky way to accomplish something that should be simple. Is there some way I can specify that something should be a new column in CSS grid rather than that having to specify the number of columns in grid-template-columns?
In Angular you can use ng-repeat to have a dynamic table
A typical example could be
<table ng-table="tableParams" class="table table-striped">
<tr ng-repeat="data in datas">
<td title="Title_Of_First_Variable">{{data.variable1}}</td>
<td title="Title_Of_Second_Variable">{{data.variable2}}</td>
<td title="Title_Of_Third_Variable">{{data.variable3}}</td>
...
</tr>
</table>
Of course with your controller you should pass your dynamic data into the correct $scope, in this case should be $scope.datas (usually an object)...maybe something like this, using NodeJS:
$http.post('route_of_your_method')
.success(function (result) {
$scope.datas = result;
})
.error(function (err) {
...
});
I explained fastly but i hope this is enough

Inserting HTML code when passing values to templates for given conditions

I have a table I am creating that looks like this:
<table>
<thead>
<tr>
<th>Value1</th>
<th>Value2</th>
<th>Value3</th>
<th>Value4</th>
</tr>
</thead>
<tbody>
{{#each []}}
<tr>
<td>{{this.val1}}</td>
<td>{{this.val2}}</td>
<td>{{this.val3}}</td>
<td>{{this.val4}}</td>
</tr>
{{/each}}
</tbody>
I want it to be the case that if val1, for instance, is greater than some value X, it will appear red.
How can I pass HTML into the template once some pre-defined condition - like the above example - is satisfied?
Ideally you should be driving this functionality using your models.
You could achieve the desired functionality using Marionette CollectionView. Each model in the collection should look something like:
var Model = Backbone.Model.extend({
initialize: function(){
/* On initialize, we call our method to set additional computed properties */
this.setProperty();
}
setProperty: function() {
if (this.get("someProperty") > x) {
this.set("className", "css-class")
}
}
});
Then from within your ItemView template you should be able to set the class on your table row item
<tr class="{{this.className}}">
<td>{{this.val1}}</td>
<td>{{this.val2}}</td>
<td>{{this.val3}}</td>
<td>{{this.val4}}</td>
</tr>