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
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>
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":"#"
}
]
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
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
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>