displaying an individual integer in webix - javascript

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

Related

How to refresh ui-grid cell which has a cellFilter to display multiple fields of the bound entity in one cell

I use a cell filter to show multiple properties of a bound entity in one cell. Therefore there is no one field name because it is a computed field. How can I force the grid to reevaluate the cell filter if one of the involved properties changes?
The column definition:
columnDefs: [
{ field: 'xxx', displayName: 'Something', cellFilter: 'concatSomeProps:this' }
]
The filter:
myApp.filter('concatSomeProps', function () {
return function (cellValue, scope) {
var entity = scope.row.entity;
return entity.prop1 + ", " + entity.prop2;
};
});
If have tried to use notifyDataChanged or the refresh function of the grid api but it doesn't work.
I'd probably use a cellTemplate, and not a filter in this case:
{ field: 'xxx', displayName: 'Something', cellTemplate:'template.html' }
And
<script type="text/ng-template" id="template.html">
<div>
{{row.entity.name + row.entity.age}}
</div>
</script>
See this Plnkr I made for you to see what I'm talking about. Edit either one of the first two fields and you will see the concat field change. You'd also change your template to use row.entity.prop1 + row.entity.prop2 to make it work, as my template is for my columns.

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());
}
});

Select2: add new tag dynamically using code

I'm using select2 for tagging and I have it setup such that a user can add new tags as well. The issue that I'm dealing with is validating the user entry and adding the sanitized tag to selection.
To be more specific, when a user enters a space in a tag, i use formatNoMatches to display a js link to sanitize the tag and then add the tag programmatically. This code seems to run without errors but when sanitize is called all selections of the input are cleared.
Any clues where i might be going wrong?
var data=[{id:0,tag:'enhancement'},{id:1,tag:'bug'},{id:2,tag:'duplicate'},{id:3,tag:'invalid'},{id:4,tag:'wontfix'}];
function format(item) { return item.tag; }
function sanitize(a){
$("#select").select2('val',[{
id: -1,
tag: a
}]);
console.log(a);
};
$("#select").select2({
tags: true,
// tokenSeparators: [",", " "],
createSearchChoice: function(term, data) {
return term.indexOf(' ') >= 0 ? null :
{
id: term,
tag: term
};
},
multiple: true,
data:{ results: data, text: function(item) { return item.tag; } }, formatSelection: format, formatResult: format,
formatNoMatches: function(term) { return "\"" + term + "\" <b>Is Invalid.</b> <a onclick=\"sanitize('"+ term +"')\">Clear Invalid Charecters</a>" }
});
Only this solution works for me:
function convertObjectToSelectOptions(obj){
var htmlTags = '';
for (var tag in obj){
htmlTags += '<option value="'+tag+'" selected="selected">'+obj[tag]+'</option>';
}
return htmlTags;
}
var tags = {'1':'dynamic tag 1', '2':'dynamic tag 2'}; //merge with old if you need
$('#my-select2').html(convertObjectToSelectOptions(tags)).trigger('change');
After hacking on it some more i realized that I should be setting the new item to the "data" property and not value.
var newList = $.merge( $('#select').select2('data'), [{
id: -1,
tag: a
}]);
$("#select").select2('data', newList)
You can set new value (if tags you can pass array) and trigger 'change' event.
var field = $('SOME_SELECTOR');
field.val(['a1', 'a2', 'a3']) // maybe you need merge here
field.trigger('change')
About events: https://select2.github.io/options.html#events

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;
}

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