afterLabelTextTpl usage in extjs4 - javascript

I need to display an image after a field label.
I am trying to see if I can use afterLabelTextTpl. But didnt find an example online
as how to use it.
Here is an idea of what I am trying to do. Can someone correct me syntatically..
{
xtype: 'combobox',
fieldLabel: 'Role',
editable:false,
store: roles_store,
triggerAction:'all',
name: 'role_id',
valueField: 'role_id',
displayField:'role_name',
afterLabelTextTpl : function() {
{
xtype: 'image',
src:'../www/css/slate/btn/question.png',
padding: '5 0 0 0',
cls:'pointer',
listeners: {
el:{
click: function() {
Ext.create('Ext.tip.Tip', {
closable:true,
padding: '0 0 0 0',
maxWidth:300,
html: "<b>read-only</b>: Has read access to all pages, but can make no changes.<br><br><b>user</b>: Can edit rules and commit to production.<br><br><b>admin</b>: Can edit rules, commit to production, and add/delete users.<br><br> "+supertext
}).showAt([810, 340]);
}
}
}
}
}

The afterLabelTextTpl is a template config, meaning that it takes either a string, an array of strings, or an instance of Ext.XTemplate and uses that to generate HTML.
There's no built-in way of creating a component via XTemplate (although a forum member created an extension called CTemplate that allows this). So if you want to go pure Ext JS, you're going to do a little more work.
NOTE: I don't have access to Ext JS 4.1.3 so what follows is an approximation, based on my experience with 4.1.0. You may need to tweak the code to get it just right, but it should provide a sufficient starting point.
Step 1: Setting up your afterLabelTextTpl. Try something like this:
afterLabelTextTpl:'<img id="combo_icon" style="padding-top:5px" class="pointer" src="../www/css/slate/btn/question.png"/>'
That should get your icon showing.
Step 2: Adding the click listener. There are two ways to go about this. Both methods assume you have a function called My.Name.Space.onImageClick. Obviously you can replace this name with whatever you want. Here's the function:
My.Name.Space.onImageClick = function(){
Ext.create('Ext.tip.Tip', {
closable: true,
padding: 0,
maxWidth: 300,
html: '<b>whatever you want here</b>'
}).showAt([810, 340]);
};
One method is to add the listener directly to the DOM.
'<img onclick="My.Name.Space.onImageClick();" /* the rest of the HTML here */ />'
The other method is to add the listener via Ext.dom.Element which is probably the better choice. You would need something like this in your combobox config:
listeners: {
afterrender: function(me){
var imgEl = Ext.get("combo_icon");
if(imgEl){
imgEl.on("click", My.Name.Space.onImageClick);
}
}
}
If you're having specific trouble getting this working, leave a comment and I'll help clarify what I can.

Its an XTemplate instance or a string.
From the docs:
An optional string or XTemplate configuration to insert
in the field markup after the label text. If an XTemplate is used, the
component's render data serves as the context.
So a string "Hello" will do, or anything that XTemplate will take

Related

How to set the value of GhostDown Markdown editor

I'm working on a simple note taking application and using GhostDown Markdown editor. It's pretty nice, I like it, but I am stuck trying to set it's value programatically.
I can get values out pretty easily. $('.entry-markdown-content textarea').val()
Setting it however is another story... :(
Prototype of what I'm working on can be seen at http://potusnotes.com
For the editor part, Ghost-Markdown-Editor uses CodeMirror editor.
So, to set value programmatically, we would call CodeMirror's instance and do
editor.setValue(txt);
But how to get that CM instance? It was created by the widget with which Ghost-Markdown-Editor was created. See jquery.ghostdown.js file:
$.widget( "b4m.ghostDown", {
editor: null,
// ...
_create: function() {
// ...
this.editor = CodeMirror.fromTextArea(this.element.find('textarea')[0], {
mode: 'markdown',
tabMode: 'indent',
lineWrapping: true
});
}
}
As the widget was made with jQuery Widget factory, a widget instance is kept inside .data("plugin-name") element of the object it was used on.
Thus we can access widget instance and set editor value like this:
var ghostdown = $(".editor").data("b4m-ghostDown");
ghostdown.editor.setValue("# Hello, SO");
Or simply
$(".editor").data("b4m-ghostDown").editor.setValue("# Hello, SO");

Extjs 4.1 pagingtoolbar default page

I want to change default page of pagination toolbar to 1 of 1 instead 0 of 0 in case of no record.Plus I am not using store proxy to request any records, so is there any way to accomplish it without using store proxy. According to my requirement user can add rows manually to the grid with the pagination toolbar showing page 1 and when rows exceeds 10 it moves to 2nd page.
In Ext it is possible to overload a component like Ext.toolbar.Paging with your own custom version. Simply specify an alias in your definition and you can us it just like the "native control."
In order to be sure that the approach would work, I set up a test project with a simple datasource and implemented enough of a replacement definition that I could see the "Ext.toolbar.Paging".getPagingItems method being fired in my custom definition.
From that point you can replace the code inside the definition of the original method to allow for a custom minimum in addition to the opportunity to overload the "updateInfo" method to make sure that during data reloads you're not plowing through your customizations.
In addition to these two things, you should (with a relatively small amount of effort) be able to implement on top of the control to support dynamically changing it's values based on the contents of your grid.
If you look at the documentation for ux.data.PagingStore you should be able to suss out the differences in using a remotely supplied store from something that is served with data locally.
Hope this helps you.
Code Sample:
Ext.define(
"Test.view.testview.TvPageBar",
{
extend: "Ext.toolbar.Paging",
alias: "widget.tvpagebar",
title: "Bob",
strictInit: function () {
"use strict";
console.log("TvPageBar init");
},
getPagingItems: function () {
console.log("getPagingItems", this);
this.callParent(arguments);
},
initComponent: function () {
this.strictInit();
this.callParent(arguments);
}
}
);

How to (properly) render additional data in grid with RowExpander

I'm trying to render some data in the rowbody in a grid (with the RowExpander plugin).
My problem is that the ol' rowBodyTpl isn't enough for me as this data is from Records on Stores from the record being rendered (hmmm...).
Putting it simply: Every record of the grid has a store in it (lets call it Items). So, I want to render the record data and some data of the Items records aswell.
What would be the best(ish) way of doing so?
Override the renderer function of the rowexpander plugin, override the getAdditionalData, or none of these?
Thank you.
I know this question is a few years old, but here's a trick I currently use to handle this kind of situation. It takes advantage of "verbatim" blocks that XTemplates allow. These allow you to execute arbitrary code inside an XTemplate by wrapping it with {% ... %}. Inside those code blocks, this is set to the XTemplate itself. The XTemplate has an owner property that, in our case, references the RowExpander plugin itself, which, in turn, has a grid property to reference the grid. So, something like this allows you to add arbitrary data to the values passed into rowBodyTpl.
Ext.create('Ext.grid.Panel', {
...
injectRowBodyData: function(values) {
values.MyInjectedContent = "Here's some extra data!";
},
plugins: [
{
ptype: 'rowexpander',
rowBodyTpl: [
'{% this.owner.grid.injectRowBodyData(value); %}',
'<div>',
'<h1>{Title}</h1>',
'<p>{Content}</p>,
'<p>{MyInjectedContent}</p>',
'</div>'
]
}
]
});
Hhopefully Sencha will fix the plugin to provide a way to handle this in the future. But for now this works well. I tested this with v4.2.1.883, but this should work with any previous version of Ext 4. The only thing I can think of that may prevent it from working in the future is the XTemplate's owner property no longer being pointed to the plugin, or the plugin not having a reference to the grid with it's grid property.
How I "solve" this problem, it might help somebody else:
I overrode the getRowBodyFeatureData of the rowexpander plugin, as this function not only receives the data to be applied on the template, but also the record itself, so I just data added the extra stores/arrays from the record.
Not sure if its the best way, but hey... at least it works.
You can also use if else statements in rowBodyTpl:
Check for ":"
"<tpl if='phone == \":\"'>",
"<tpl else>",
"</tpl>"
Check for empty string
"<tpl if='phone == \"\"'>",
"</tpl>"
this sample is taken from here: link
This is how I usually do:
Ext.create('Ext.grid.Panel',{
border: true,
store: 'ds',
columns: []
plugins: [{
ptype: 'rowexpander',
rowBodyTpl : ['<p><b>Title:</b>{name}<br/><b>Description:</b> {description}<br/><b>Experiment Design:</b> {experimentdesign}</p>']
}],
renderTo:
});

ExtJs ComboBox: style entries

i would like to make some of my entries in a Combobox italic.
Is there something like the renderer of a Column or how can i achive this?
Edit: Sorry but i didn't provide enough information, and i'm realizing that this is nonsense what i wanted do before...
I will write some more words to this atfter i completely understand my problem...
If you just want to style the list items itself it's sufficient to provide a getInnerTpl() function for the internal bound list used in the dropdown:
var combo = new Ext.form.field.ComboBox({
// ...
listConfig: {
getInnerTpl: function() {
return '{field1}: {field2}';
}
},
// ...
});
If you'd like to change the whole content of the dropdown, provide a tpl parameter in the listConfig:
var combo = new Ext.form.field.ComboBox({
// ...
listConfig: {
tpl: '<div><tpl for="."><span class="item">{field1}: {field2}</span></tpl></div>',
itemSelector: 'span.item' // you need to provide an itemSelector if you change the template
},
// ...
});
As Tanel Tähepõld suggested, you should read the documentation for Ext.XTemplate.
Ext.form.field.ComboBox has config property "renderTpl", you can create your own Ext.XTemplate and use it (html markup). XTemplate also allows to use if caluses inside template so you can create if caluse for italic text.
Doc for Ext.XTemplate: http://docs.sencha.com/ext-js/4-0/#/api/Ext.XTemplate

Dojo widget defaults

i'm currently writing a large scale application heavily based on the dojo toolkit. The whole app is working and standing, but one issue i can not find my way out with, is the creation of custom widgets. It would be useful because it would clean up my source code and also i can reuse this 'widgets' in later projects.
For example: i have a main toolbar, which i would like to call using
myapp.toolbar = new myapp.mainToolbar();
instead of using
myapp.toolbar = new new dijit.Toolbar({}, containerID);
var button1 = new dijit.form.Button({
label: 'Delete',
id: 'toolbarbutton1',
showLabel: true,
iconClass: "dijitEditorIcon dijitEditorIcon Delete"
});
myapp.toolbar.addChild(button1);
...
So in short: how do i set up the whole toolbar somewhere else and call it as a simple object? Trying to figure out dojo.declare('myapp.mainToolbar', dijit.Toolbar, {...}) but then i get a bunch of errors like 'startup function not existing' etc...
I'd like to do all this programmatically, so without the template html and css files in a custom widget.
A link to a good tutorial or howto would be nice, although google nor yahoo! will reveal any extra's on this matter for me... :)
There are multiple ways to do this.
It seems like your method of extending Toolbar should work (not sure why it didn't).
You can also declare a class that embeds Toolbar and the buttons, using widgetsInTemplate:
dojo.declare("MyToolbar", [dijit._Widget, dijit._Templated], {
_widgetsInTemplate: true,
templateString: '<div> <div dojoType=dijit.Toolbar>' +
' <button dojoType=dijit.form.Button ...
Note that the top node in MyToolbar can't have a dojoType, so I put Toolbar one level down.
Alternately you can do the same thing by using dijit.Declaration, see http://docs.dojocampus.org/dijit/Declaration.
It works for me when I use declare with the superclass inside of an array:
dojo.declare('myapp.mainToolbar', [ dijit.Toolbar ],
{
....
}
);
var x = new myapp.mainToolbar({ ... });
x.startup();
Which kind of violates the docs. It should take one Function or an array of Functions.

Categories

Resources