How to add a custom text to a field (translatable) label - extjs

I have an object with a localizedfields data:
I want to customize the Backend UI for my DataObject, because it's not possible, that field(-s) is required only for one language.
I know, how can I check the mandatories in PHP Event Listener, but I can not find any info, how can I add an asterisk to a field label only for German language.
Here is my JS:
pimcore.registerNS('pimcore.test.plugin');
pimcore.test.plugin = Class.create(pimcore.plugin.admin, {
getClassName: function () {
return 'pimcore.test.plugin';
},
pimcoreReady: function (params,broker) {
},
initialize: function () {
pimcore.plugin.broker.registerPlugin(this);
},
postOpenObject: function (object, type) {
if (object.data.general.o_className === 'Product') {
// add an asterisk to field label
}
},
});
let PimcoreTestPlugin = new pimcore.test.plugin();
Update 1: I have found in Pimcore Sources the part, that adds an asterisk to any field, if field is required, but how can I extend / override them?
pimcore.registerNS("pimcore.object.helpers.edit");
pimcore.object.helpers.edit = {
getRecursiveLayout: function (l, noteditable, context, skipLayoutChildren, onlyLayoutChildren, dataProvider, disableLazyRendering) {
...
// add asterisk to mandatory field
l.titleOriginal = l.title;
if(l.mandatory) {
l.title += ' <span style="color:red;">*</span>';
}
...
}
};

I do not know how to do it with PimCore, but the solution would be to use data-binding:
In Modern
items: [{
xtype: 'textfield',
fieldLabel: 'Name',
bind: {required: '{isGerman}'}
}]
In Classic
Ext.define('MyApp.overrides.form.field.Text', {
override: 'Ext.form.field.Text',
config: {
allowBlank: true
}
});
...
items: [{
xtype: 'textfield',
fieldLabel: 'Name',
bind: {allowBlank: '{!isGerman}'}
}]
if allowBlank|required are will add the asterix.
required will add the asterix if true. allow
Blank will add the asterix if false.

You can create a custom data type, where you specify the languages that are allowed to be edited / where it should be shown. In Pimcore this is done via CoreExtensions on the backend side and a custom data tag in JS.
https://pimcore.com/docs/pimcore/current/Development_Documentation/Extending_Pimcore/Bundle_Developers_Guide/Adding_Object_Datatypes.html

Related

How does an end user clear the sorting for a grid column?

I use ExtJs 6.6.0 Classic. The grid component supports multi-column sorting (I use remoteSort: true, remoteFilter: true). Whenever the user clicks on a column header, that column becomes the first column in the order by list. But I cannot find how an end user is supposed to clear the sorting for a column. The context menu available through the column header doesn't have a "Clear Sort" option.
See also this kitchensink example.
I feel like I am missing something. There is a sortClearText config for the column inherited from the header, but I could not find a place where it's used (I thought that perhaps there is some config I can use to add the Clear Sort menu item to the column context menu).
I could add a button to execute the action of clearing the sorting of the store, as a last resort, but I don't like it.
Is there a simple way to add a Clear Sort option for a grid column through the Extjs components configuration?
Thank you
I also did not find, but you can use the following override:
Ext.define('overrides.grid.header.Container', {
override: 'Ext.grid.header.Container',
getMenuItems: function() {
var me = this,
menuItems = [],
hideableColumns = me.enableColumnHide ? me.getColumnMenu(me) : null;
if (me.sortable) {
menuItems = [{
itemId: 'ascItem',
text: me.sortAscText,
iconCls: me.menuSortAscCls,
handler: me.onSortAscClick,
scope: me
}, {
itemId: 'descItem',
text: me.sortDescText,
iconCls: me.menuSortDescCls,
handler: me.onSortDescClick,
scope: me
}, {
itemId: 'dropSortItem',
text: me.sortClearText,
//iconCls: me.menuSortDescCls, // Your icon
handler: me.onSortClearClick,
scope: me
}];
}
if (hideableColumns && hideableColumns.length) {
if (me.sortable) {
menuItems.push({
itemId: 'columnItemSeparator',
xtype: 'menuseparator'
});
}
menuItems.push({
itemId: 'columnItem',
text: me.columnsText,
iconCls: me.menuColsIcon,
menu: hideableColumns,
hideOnClick: false
});
}
return menuItems;
},
onSortClearClick: function() {
var menu = this.getMenu(),
activeHeader = menu.activeHeader,
store = this.up('grid').getStore();
store.getSorters().each(function(sorter) {
if(sorter.initialConfig.property == activeHeader.dataIndex) {
store.getSorters().remove(sorter)
}
}, this);
}
});

ExtJs - custom class resolution

Let's say I have a concrete view named "view." I would like, at runtime, be able to call Ext.create("view_1") or Ext.create({ xtype: "view_5" }) and they will create instances of "view".
So any xtype matching the regex: /view_[0-9]+/ should create a "view" instead.
Is this possible, if so how?
More details,
We added the ability for our users to create custom reports. They define the menu name, the title, the set of columns, and the data constraint to be used. Each custom report is constructed using the same xtype view.
The problem arise when we save the state for these custom reports. Normally, we use the xtype as key for storage. So if all custom reports are the same xtype they override each other's state.
The direct workaround is to have different xtype for each custom report. So "view_1", "view_5", "view_1008"...view_[0-9]+ are the xtypes associated with custom report #1, custom report #5, custom report #1008...custom report [0-9]+. But they all should be constructed using xtype view.
If we create aliases, we would need to add all reasonable/possible form of view_[0-9]+. I am not sure this approach scales very well when we have more types of dynamic views.
Isn't possible to create a view from regex.
In my opinion, the best way you can do is to set alias as list of strings.
Example:
Ext.define('SomeView', {
alias: ['widget.view_1', 'widget.view_2', 'widget.view_3', 'widget.view_4' ...],
});
Update ( according to the comment ) :
Maybe you want to create multiple views (same definition) with id like:
Ext.create("SomeView", {
id: "view_1",
});
Ext.create("SomeView", {
id: "view_2",
});
Update :
The other way is to override Ext.create function.
Example on https://fiddle.sencha.com/#view/editor&fiddle/32lj
Ext.apply(Ext, {
_create: Ext.create
});
Ext.override(Ext, {
create: function () {
var name = arguments[0],
nameType = typeof name;
if(nameType == 'string'){
let regex = /widget\.viewx_[0-9]+/;
let found = name.match(regex);
if (found) {
name = "widget.viewx";
}
}
return Ext._create(name, arguments[1], arguments[2], arguments[3]);
}
});
And usage:
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.create("Ext.panel.Panel", {
width: 300,
height: 300,
renderTo: Ext.getBody(),
items: [{
xtype: 'viewx',
fieldLabel: "AA"
}, {
xtype: 'viewx_1',
fieldLabel: "AA"
}, {
xtype: 'viewx_2',
fieldLabel: "AA"
}]
});
}
});

How to restrict file type using xtype filefield(extjs 4.1.0)?

I am trying to implement file upload feature using extjs 4.1.0. Whereas I want to restrict users to select only image files(jpg,png,gif). Is there any filter which can be applied so that users will only be able to see and then select the types of the files mentioned above?
You could stuff like this as well :
{
xtype: 'filefield',
buttonText: '....',
listeners:{
afterrender:function(cmp){
cmp.fileInputEl.set({
accept:'image/*' // or w/e type
});
}
}
}
See http://docs.sencha.com/ext-js/4-1/#!/api/Ext.form.field.VTypes VAlidation types for an example of a custom type. You could use a regexp to specify alphaMask as well.
{
xtype: 'fileuploadfield',
name: 'file',
fieldLabel: 'Photo',
labelWidth: 50,
allowBlank: false,
buttonText: 'SelectPhoto',
anchor: '100%',
reset: function () {
var me = this,
clear = me.clearOnSubmit;
if (me.rendered) {
me.button.reset(clear);
me.fileInputEl = me.button.fileInputEl;
me.fileInputEl.set({
accept: 'image/*'
});
if (clear) {
me.inputEl.dom.value = '';
}
me.callParent();
}},
listeners:{
change: 'fileInputChange',
afterrender:function(cmp){
cmp.fileInputEl.set({
accept:'image/*'
});
}
},
regex: /(.)+((\.png)|(\.jpg)|(\.jpeg)(\w)?)$/i,
regexText: 'Only PNG and JPEG image formats are accepted'
}
regex adds client side validation, to which a form bind can be put on whatever form or action you are planning on doing.

Implement searchfield functionality in sencha touch

I am getting problem that how to implement search field on tree store getting data from the server in sencha touch.Any working code will be appreciated.
In Search field You can use key up event and filter a store as type charterer match to store and show filter data in list and on select on item in list you hide list as bellow done
{
xtype: 'searchfield',
name : 'Name',
label: 'Name: ',
id : 'Name',
record:'Details',
placeHolder: 'Name',
listeners: {
focus: function( field, e, eOpts ){
Ext.getCmp('FilterDropDown').show();
},
keyup: function(field) {
var value = field.getValue();
var Store = Ext.getStore('Details');
var FilterStore = Ext.getStore('FilterDetails');
FilterStore.removeAll();
count=0;
var thisRegEx = new RegExp(value, 'i');
for(cnt=0;cnt<Store.getCount();cnt++){
if(thisRegEx.test(Store.data.items[cnt].data.name)){
FilterStore.add({
'id':Store.data.items[cnt].data.id,
'name': Store.data.items[cnt].data.name,
'email': Store.data.items[cnt].data.email
});
}
}
}
}
},
{
xtype:'FilterList',
id: 'FilterDropDown',
height:200,
hidden : true,
listeners: {
itemtap: function( field, index, target, record, e, eOpts ){
Ext.getCmp('Name').setValue(record.data.name);
Ext.getCmp('Email').setValue(record.data.email);
Ext.getCmp('Mobile').setValue(record.data.mobileno);
Ext.getCmp('FilderDropDown').hide();
}
}
},
xtype FilterList code is
Ext.define('appname.view.FilterList', {
extend: 'Ext.dataview.List',
xtype: 'FilterList',
require: ['FilterDetails'],
config:{
store: 'FilterDetails',
scrollable: true,
cls: 'drop_down_list',
ui: 'round',
itemTpl: '<div>{name}</div>'
}
});
It will help you :)
Assuming the data is already in the store when you search this isn't too difficult to implement using the methods referenced by speznaz.
In your view have a xtype "searchfield" or "textfield".
{
xtype: "searchfield",
}
In the controller bind a "keyup" event to this field.
refs: {
searchfield: 'mypanel searchfield'
},
control: {
searchfield: {
keyup: 'doSearch'
}
}
For your function to search something like:
doSearch: function(searchfield, e, eOpts) {
var searchterm = searchfield.getValue();
var store = Ext.getStore('myStore');
// Now just customise the search options
store.find(fieldName, value, [startIndex], [anyMatch], [caseSensitive], [exactMatch] );
}
This is assuming you want to search on keyup. You may want to use the "action" event instead.
Assuming you already have data in the store.
Here is the working code:
{
xtype: "searchfield",
name:'searchName'
}
In the controller bind a "keyup" event to this field.
refs: {
searchName: 'searchfield[name=searchName]'
},
control: {
searchName: {
keyup: 'doSearch'
}
}
For your function to search :
doSearch: function(field, e, eOpts) {
var searchterm = field.getValue();
var store = Ext.getStore('myStore');
// Now just customise the search options
store.filter(fieldName,searchterm);
}
Use try.sencha.com it has lot of examples on how to use the framework.
You need to use an Ajax store for getting data from server. I think this guide will be a good start for that, it also implements a tree store.
This example explains how to filter data in a list based on what you type in a searchfield.
Hope it helps

How to display values in uppercase in ExtJs textfield without showing user letter transition from lower to uppercase?

We are creating an application using ExtJS 4 which has a requirement that entry in a form textfield should always be in UPPERCASE.
For this, I found that I can call a function on change event and convert the current value to uppercase and set it back to the field in following way:
change: function(field, newValue){
field.setValue(newValue.toUpperCase());
}
What this does is that if a user enters a letter in lowercase, then it converts it to uppercase and puts it back in the field. During this, there is a slight transition displayed to the user from lower to upper case. That is, the user is able to see the letter in lower case and after a millisecond may be, the letter becomes uppercase.
The question is: Is there a way to avoid this 'transition/transformation' from lower to upper case and show letters in uppercase directly to the user as soon as he types something?
I tried using - style=text-transform:uppercase - but no luck.
Any help would be really appreciated.
Thanks in advance.
I tried using - style=text-transform:uppercase - but no luck.
You should have used fieldStyle instead. Here is demo.
Cheers!
The given answer works only for DISPLAYING the text in uppercase, but the value remains the same. I've extended the textfield to override the getValue() method to return the value in uppercase, not only for displaying, with an optional config flag:
Ext.define('Dev.ux.UpperTextField', {
extend: 'Ext.form.field.Text',
alias: 'widget.uppertextfield',
//configuration
config: {
uppercaseValue: true //defaults to true
},
constructor: function (config) {
this.initConfig(config);
this.callParent([config]);
},
initComponent: function () {
var me = this;
Ext.apply(me, {
fieldStyle: 'text-transform:uppercase',
});
me.callParent();
},
//overriden function
getValue: function () {
var val = this.callParent();
return this.getUppercaseValue() ? val.toUpperCase() : val;
}
});
Then I can easily add several textfields to a form:
{
xtype: 'uppertextfield',
uppercaseValue: false, //custom cfg available (default is true)
name: 'Descricao',
fieldLabel: 'Nome da Cidade',
allowBlank: false,
enforceMaxLength: true,
maxLength: 80
},
Works in EXT 4.2.1.
You can do it with a plugin too.
{
xtype: 'textfield',
plugins: ['uppertextfield']
}
Using this as the plugin in ExtJS 4.2.1
Ext.define('App.plugin.UpperTextField', {
extend: 'Ext.AbstractPlugin',
alias: 'plugin.uppertextfield',
init: function (cmp) {
Ext.apply(cmp, {
fieldStyle: (cmp.fieldStyle ? cmp.fieldStyle + ';' : '') + 'text-transform:uppercase',
getValue: function() {
var val = cmp.__proto__.getValue.apply(cmp, arguments);
return val && val.toUpperCase ? val.toUpperCase() : val;
}
});
}
});
Inspired by: https://www.sencha.com/forum/showthread.php?94599-Uppercase-TextField-plugin&p=522068&viewfull=1#post522068
PS: I had to call getValue on the prototype. If I would have called getValue on the cmp it would recursively continue to do that and never exit. I'm open to suggestions on how to change the component's getValue method through the plugin.
It Works for ExtJS 4.2
If you want only uppercase input for your text field then extend the base text field to change the field style to uppercase and also attach a listener to update the raw value on any text change to uppercase.
//define a new custom text field
Ext.define('IN.view.item.UpperCaseTextField', {
extend: 'Ext.form.field.Text',
alias : 'widget.myUpperCaseTextField',
fieldStyle: {
textTransform: "uppercase"
},
initComponent: function() {
this.callParent(arguments);
},
listeners: {
change: function (obj, newValue) {
console.log(newValue);
obj.setRawValue(newValue.toUpperCase());
}
}
});
//use the newly created custom text field in your view definition using the alias
xtype: 'form',
items: [
{
xtype: 'myUpperCaseTextField',
itemId: 'itemNumber',
name : 'item',
allowBlank: false,
msgTarget: 'side',
fieldLabel: 'Item Number',
size: 11,
maxLength: 10
},
]

Resources