how to create a menu within an ng-grid - javascript

we are really having problems finding a way on how to create a menu within an ng-grid.
Something similar to the ECB block within share point.
So, there would be a button that when clicked would show options for that particular row.
We may be looking in the wrong places, but we can't find any help or examples on the internet..

As I told you few days ago you should use row and celltemplates to achieve something like this.
Here is the changed code to better match the current state of your question:
$scope.gridOptions = {
data: 'myData',
rowTemplate: '<div ng-style="{\'cursor\': row.cursor, \'z-index\': col.zIndex() }" ' +
'ng-repeat="col in renderedColumns" ng-class="col.colIndex()" ' +
'class="ngCell {{col.cellClass}}" ng-cell></div>' +
'<div ng-show="showmenu" class="hmenu">' +
'<ul>' +
'<li><button ng-click="viewme(row.entity.name)">View</button></li>' +
'<li><button ng-click="editme(row.entity.name)">Edit</button></li>' +
'</ul>' +
'</div>',
columnDefs: [{
field: 'name',
displayName: 'Name'
}, {
field: 'age',
displayName: 'Age',
cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}' +
'<span ng-click="$parent.showmenu=!$parent.showmenu"><button>click me</button></span>' +
'</div>'
}]
};
True, this is no beauty, but it shows you how to go on. Do your styling in style.css and the row template. This is the best I can do with my weekend laptop.
Here is the Plunker

You could potentially set each CellTemplate to have its own ng-if/ng-show block that's hidden/shown based on a variable on your row.entity object. Then, when your function fires for the selection of the row, you can set that variable ($scope.whatever) to hide/show what's necessary. On my phone at the moment, but I'll try to make a plnkr/jsfiddle later.

Related

Tagfield with html encoded displayField in Extjs 6

Before upgrading to Extjs 6 we were using a tagfield component where its displayField was Ext.String.htmlEncode('description') where description was the description field of the store's record. This field doesn't only contain simple text but instead is in the form of: <img src="link..." style="..."/>&nbspRECORD_DESCRIPTION. Using the htmlEncode function it would actually render the tagfield's records with the linked image and the record's description.
However after upgrading to version 6 this stopped working. It now just produces the full text instead of rendering the image. Its like htmlEncode stopped working all of a sudden. The thing is that in an ItemSelector field where we do the same thing everything works perfectly using the exact same method. Did they break the tagfield component so as to not be able to show html?
Regardless, how can I reproduce what I did before? I tried with displayTpl config but it doesn't seem to work.
Instead of Ext.String.htmlEncode('description') try just 'description' in displayField. DisplayField affects what you see when you are selecting, and for that, it will display your HTML. It also affects how it displays the selections you have made, and there doesn't seem to be a way to display HTML there. It displays as plain text. There is another attribute, labelTpl, that formats the items you have already selected. You can use that to display just the names of things you have already selected. (LabelTpl used to display formatted HTML, but doesn't in ExtJs6.) Suppose your store record also had a 'name' field that is just plain text; you would put that inside curly braces:
xtype:'tagfield',
displayField: 'description',
labelTpl: '{name}',
...
Then you will get formatted HTML while making a selection, and plain text in the selected items. That's the best I've come up with so far.
Using ExtJS 6.5.3
This is the best I was able to figure out for a tag field in terms of creating a complex display statement for both list and tags.
The display supports CSS and other HTML tags
The labelTpl does not support anything but plain text, but you can override it's x-tagfield-item-text style however, it's all or nothing.
{
cls: "triggerstagfield",
displayField: '[(values.key != "all") ? values.label + " (<b>" + values.key + "</b>)" : values.label]',
labelTpl: '{[(values.key != "all") ? values.label + " (" + values.key + ")" : values.label]}',
valueField: "key",
store: [{
"key": "all",
"label": "All"
}, {
"key": "880",
"label": "International House of Pancakes"
}]
},
and this is the CSS
.triggerstagfield .x-tagfield-item-text {
font-weight: bold;
font-size: 0.9em;
}
I worked around it by extending the built in tag field, overriding the function getMultiSelectItemMarkup. In that function I removed the call to Ext.String.htmlEncode on the label.
With this you can use
{
xtype: 'tagfieldhtmllabel',
labelTpl: '<span style="background-color:#{colorbg};">{name}</span>',
...
}
This is the code that works on Ext 6.2.1
Ext.define("Private.ui.TagFieldHtmlLabel", {
extend: 'Ext.form.field.Tag',
alias: 'widget.tagfieldhtmllabel',
// TODO EXT UPGRADE. WHEN UPGRADING FROM 6.2.1 update this
getMultiSelectItemMarkup: function() {
var me = this,
childElCls = (me._getChildElCls && me._getChildElCls()) || '';
// hook for rtl cls
if (!me.multiSelectItemTpl) {
if (!me.labelTpl) {
me.labelTpl = '{' + me.displayField + '}';
}
me.labelTpl = me.lookupTpl('labelTpl');
if (me.tipTpl) {
me.tipTpl = me.lookupTpl('tipTpl');
}
me.multiSelectItemTpl = new Ext.XTemplate([
'<tpl for=".">',
'<li data-selectionIndex="{[xindex - 1]}" data-recordId="{internalId}" role="presentation" class="' + me.tagItemCls + childElCls,
'<tpl if="this.isSelected(values)">',
' ' + me.tagSelectedCls,
'</tpl>',
'{%',
'values = values.data;',
'%}',
me.tipTpl ? '" data-qtip="{[this.getTip(values)]}">' : '">',
'<div role="presentation" class="' + me.tagItemTextCls + '">{[this.getItemLabel(values)]}</div>',
'<div role="presentation" class="' + me.tagItemCloseCls + childElCls + '"></div>',
'</li>',
'</tpl>',
{
isSelected: function(rec) {
return me.selectionModel.isSelected(rec);
},
getItemLabel: function(values) {
// UPGRADE - removed htmlEncode here
return me.labelTpl.apply(values);
},
getTip: function(values) {
return Ext.String.htmlEncode(me.tipTpl.apply(values));
},
strict: true
}
]);
}
if (!me.multiSelectItemTpl.isTemplate) {
me.multiSelectItemTpl = this.lookupTpl('multiSelectItemTpl');
}
return me.multiSelectItemTpl.apply(me.valueCollection.getRange());
}
});

displaying an individual integer in webix

I want to display a single number (that would change, that's why I'm not hard coding it) from am object. This, however, doesn't display anything.
var game_data = {
amount: 1,
yes_left: 3,
nos_left: 1
};
var game_panel = {
view: "form", id:"game_panel",
rows:[
{cols:[
{
template:'<span class="main_title">Money: $#amount#.00 </span>',
data:{amount:game_data.amount},align:"center"
},
}
]
};
I've also tried returning it as a variable:
template: function(game_data) {return '<span class="main_title">Money: ' + game_data.amount + '.00 </span>'}
Any ideas how to get that to display?
The code that you are using is correct. You can check the the next working snippet http://webix.com/snippet/82566e82
If you plan to update this number dynamically, it will be better to use a bit different syntax
id:"t1",
template:'<span class="main_title">Money: $#amount#.00 </span>',
data: game_data, align:"center"
and for number updating, be sure to call template.refresh, as template doesn't track data changes automatically.
game_data.amount += 2;
$$("t1").refresh();
http://webix.com/snippet/e3b0450d

How to use function in Kendo Grid Column Template with AngularJS

I have a column in a Kendo grid that I want to perform some specific logic for when rendering, and am using Angular. I have the grid columns set up using the k-columns directive.
After looking at the documentation, it seemed simple: I could add the template option to my column, define the function to perform my logic, and pass the dataItem value in. What I have looks something like this:
k-columns='[{ field: "Name", title: "Name",
template: function (dataItem){
// Perform logic on value with dataItem.Name
// Return a string
}
}]'
However, running this causes a syntax error complaining about the character '{' that forms the opening of the block in my function.
I have seen several examples of defining a template function in this format. Is there something else that needs to be done for this to work? Am I doing something incorrectly? Is there another way of defining the template as a function and passing the column data to it? (I tried making a function on my $scope, which worked, except I couldn't figure out how to get data passed into the function.)
Thank you for your help.
It appears that defining a column template in this fashion isn't supported when using AngularJS and Kendo. This approach works for projects that do not use Angular (standard MVVM), but fails with its inclusion.
The workaround that a colleague of mine discovered is to build the template using ng-bind to specify a templating function on the $scope, all inside of a span:
template: "<span ng-bind=templateFunction(dataItem.Name)>#: data.Name# </span>"
This is the default column templating approach that is implemented by Telerik in their Kendo-Angular source code. I don't know yet if the data.Name value is required or not, but this works for us.
Warning: Don't have access to Kendo to test the code at the moment, but this should be very close
In your case, you are assigning a a string to the value of k-columns and that string contains the the word function and your curly brace {
You need to make sure the function gets executed ... something like this:
k-columns=[
{
field: "Name",
title: "Name",
template: (function (dataItem){
// Perform logic on value with dataItem.Name
// Return a string
}())
}
];
Note the difference:
We create an object -- a real honest-to-goodness object, and we use an IIFE to populate the template property.
Maybe, it will be useful for someone - this code works for me too:
columns: [
{
field: "processed",
title:"Processed",
width: "100px",
template: '<input type="checkbox" ng-model="dataItem.processed" />'
},
and you get the two-way binding with something like this:
<div class="col-md-2">
<label class="checkbox-inline">
<input type="checkbox" ng-model="vm.selectedInvoice.processed">
processed
</label>
</div>
This can be done via the columns.template parameter by supplying a callback function whose parameter is an object representing the row. If you give the row a field named name, this will be the property of the object you reference:
$("#grid").kendoGrid({
columns: [ {
field: "name",
title: "Name",
template: function(data) {
return data.name + "has my respect."
}
}],
dataSource: [ { name: "Jane Doe" }, { name: "John Doe" } ]
});
More information is available on Kendo's columns.template reference page.
After hours of searching. Here is the conclusion that worked:
access your grid data as {{dataItem.masterNoteId}} and your $scope data as simply the property name or function.
Example
template: '<i class="fa fa-edit"></i>',
I really hope this safes somebody life :)
just use like my example:
}, {
field: "TrackingNumber",
title: "#T("Admin.Orders.Shipments.TrackingNumber")",
//template: '<a class="k-link" href="#Url.Content("~/Admin/Shipment/ShipmentDetails/")#=Id#">#=kendo.htmlEncode(TrackingNumber)#</a>'
}, {
field: "ShippingMethodName",
title: "#T("Admin.Orders.Shipments.ShippingMethodName")",
template:function(dataItem) {
var template;
var ShippingMethodPluginName = dataItem.ShippingMethodPluginName;
var IsReferanceActive = dataItem.IsReferanceActive;
var ShippingMethodName = dataItem.ShippingMethodName;
var CargoReferanceNo = dataItem.CargoReferanceNo;
var ShipmentStatusId = dataItem.ShipmentStatusId;
if (ShipmentStatusId == 7) {
return "<div align='center'><label class='label-control'><b style='color:red'>Sipariş İptal Edildi<b></label></div>";
} else {
if (ShippingMethodPluginName == "Shipping.ArasCargo" || ShippingMethodPluginName == "Shipping.ArasCargoMP") {
template =
"<div align='center'><img src = '/content/images/aras-kargo-logo.png' width = '80' height = '40'/> <label class='label-control'><b>Delopi Aras Kargo Kodu<b></label>";
if (IsReferanceActive) {
template =
template +
"<label class='label-control'><b style='color:red; font-size:20px'>"+CargoReferanceNo+"<b></label></div>";
}
return template;
}

ExtJS 4.2.1 - Updating XTemplate after store load

I have a bit of a weird situation...
I have a DataView that's backed by a store. However, in the XTemplate, I'm trying to show the quantity of a certain type of JSON record. Each record has a property value pair that denotes its type. For example:
data: [
{ type: 'W' },
{ type: 'A' },
{ type: 'W' },
{ type: 'W' }
]
So there are 3 JSON objects of 'W' and 1 JSON object of type 'A'. The number of 'W' should be displayed in the HTML element with the class 'total-pending'; 'A', in the HTML element with the class 'total-approved.'
My XTemplate:
tpl: Ext.create('Ext.XTemplate',
'<div style="text-align:center">Leave Requests</div>',
'<table cellpadding="0" class="table-wrap">',
'<tr>',
'<td class="x-leave-request approved"><span class="total-approved">0</span>Approved</td>',
'<td class="x-leave-request pending"><span class="total-pending">0</span>Pending</td>'denied">0</span>Denied</td>',
'</tr>',
'</table>'
)
I've read a bit about templates and stores, but I can't seem to figure out how to update those numbers. I tried to add a function callback to store.on('load', function{}) to change the HTML element via Ext.get(Ext.query('span.total-pending')[0]).update(3) but it had no effect.. Any ideas?
I am not sure will help your request but try and share result with us.
Try to make a function to count total values of W and A then call appropiate function inside the XTemplate via this.function()
tpl: Ext.create('Ext.XTemplate',
'<div style="text-align:center">Leave Requests</div>',
'<table cellpadding="0" class="table-wrap">',
'<tr>',
'<td class="x-leave-request approved"><span class="total-approved">{totalw:this.getTotalw()}</span>Approved</td>',
'<td class="x-leave-request pending"><span class="total-pending">{totala:this.getTotala()}</span>Pending</td>'denied">0</span>Denied</td>',
'</tr>',
'</table>'
)
I solved it using the hint that Oguz gave. What I ended up doing was creating an Ext.util.Hashmap instance, whose pairs were status type and total (e.g. <'W', 10>). Then I called:
<tpl for=".">
{[this.updateStatusTotal(values.type)]}
</tpl>
...
updateStatusTotal : function(type) {
var me = this,
map = me.map,
total = map.get(type);
map.put(type, ++total);
}
then later in the code where the <td> elements are, I call:
{[this.getStatusTotal('W')]}
Done :)

Dojo DataGrid filtering with complexQuery not working

I am trying to find out why the filter function isn't working, but I am stucked. This is the first time I am using Dojo but I am not really familliar with that framework. I am trying and searching for maybe 2 or 3 hours but I can't find a solution.
Waht I want, is to implement a filter or search mechanism. But it is not working, yet...
This is my code:
dojo.require('dojo.store.JsonRest');
dojo.require('dijit.layout.ContentPane');
dojo.require("dijit.form.Button");
dojo.require('dojox.grid.DataGrid');
dojo.require('dojo.data.ObjectStore');
dojo.require('dijit.form.TextBox');
dojo.require('dojox.data.AndOrReadStore');
dojo.require('dojo._base.xhr');
dojo.require('dojo.json')
dojo.require('dojo.domReady');
dojo.ready(
function(){
var appLayout = new dijit.layout.ContentPane({
id: "appLayout"
}, "appLayout");
var textBox = new dijit.form.TextBox({
name: "searchbox",
placeHolder: "Search ..."
});
var filterButton = new dijit.form.Button({
label: 'Filter',
onClick: function () {
searchWord = textBox.get('value');
query = "id: '"+searchWord
+"' OR date_A: '"+searchWord
+"' OR dateB: '"+searchWord
+"' OR product: '"+searchword+"'";
grid.filter({complexQuery: query}, true);
}
});
store = new dojo.store.JsonRest({target:'products/'});
grid = new dojox.grid.DataGrid(
{
store:dojo.data.ObjectStore({objectStore: store}),
structure:
[
{name:'id', field: 'id'},
{name:'date_A', field: 'dateA'},
{name:'date_B', field: 'dateB'},
{name:'product' , field: 'product'},
],
queryOptions: {ignoreCase: true}
});
textBox.placeAt(appLayout.domNode);
filterButton.placeAt(appLayout.domNode);
grid.placeAt(appLayout.domNode);
appLayout.startup();
}
);
Would be very nice if u can tell me what's wrong with this dojo code...
The result is, that the loading icon appears and after a while the unfiltered data is shown... There is no exception thrown.
Thanks in advance.
Ok, I have solved it with the AndOrReadWriteStore. You can also use an AndOrReadStore. The problem was, that the JSON data wasn't in the right format. You can see the right format here: dojotoolkit.org/api/dojox/data/AndOrReadStore. The other change is: I used the url instead the data attribute inside the store. So finally it is working now. Thx anyway.
Here's an example of a filter that uses both an AND and an OR:
grid.filter("(genre: 'Horror' && (fname: '" + searchWord + "' || lname:'" + searchWord + "'))")
So the users search word is filtered across fname and lname as an OR but it also searches for genre = Horror as an AND.
This document has other examples...
http://livedocs.dojotoolkit.org/dojox/data/AndOrReadStore

Categories

Resources