Add custom message (not error) under under combobox/text field - extjs

I'm new to extjs and I'm looking for a way to add some custom message under my combobox field.
Depending on some conditions (eg. value selected) the message needs to have different text and/or style.
I could play with errorEl associated with my combobox and change it's message/style depending on the state, but this doesnt look like a good approach.
Are you aware of any plugin allowing to add such a message, or is there a shorter way to do this?
Thank you for your suggestions. I ended up writing my own plugin, which then I attached to combobox.
I added new element after error element and I changed messages based on proper combobox events.
afterCmpRender : function() {
var me = this, cmp = me.getCmp();
var messageWrapper = {
tag : 'div'
};
var messageEl = cmp.errorEl.insertSibling(messageWrapper, "after");
cmp.messageEl = messageEl;
Ext.Array.each(me.messages, function(message) {
var messageConfig = {
tag : 'div',
style : {
display : 'none'
}
};
var newElement = messageEl.insertSibling(messageConfig, "after");
newElement.setHTML(message.value);
newElement.addCls(message.classes);
me.registerMessageEvents(me, cmp, message, newElement);
});
}

I almost always use multiple elements for this, and would not make an attempt to change the field.
Depending on your context, which you didn't provide, I'd say you could have a look at:
Ext.form.field.Display
Ext.form.Label
Ext.tip.Tip
Ext.tip.QuickTip

I'd work with the class Ext.tip.Tip.
You can create
Ext.create('Ext.tip.Tip', {
id: 'myTip',
header: false
});
and then
var tip = Ext.getCmp('myTip');
tip.update('your custom tip message');
tip.showBy(comboboxComponent);
You could also use showAt(..) instead of showBy.
For more information look into the Docu
Here is a Fiddle link to an example.

Related

How to get the value of selected row directly in HTML using ag-grid

i try to get the the value of number row selected, and print it in HTML using Angularjs, but no issue,
i have the count only when i clic in the grid column header.
The value of " selectedRowsCounter " is 0 in html, when i dosn't clic in the grid header
my code is like
var activeButtons = function() {
var countRowsSelected = $scope.gridOptions.api.getSelectedRows().length;
$scope.selectedRowsCounter = countRowsSelected;
console.log($scope.selectedRowsCounter);
$rootScope.count.selectedRows = countRowsSelected;
};
$scope.gridOptions = {
rowData: null,
angularCompileRows: true,
onSelectionChanged: activeButtons,
}
there is a screenshot
i have open the same subject here
https://github.com/ceolter/ag-grid/issues/1023
i have added this line to activeButtons function and it work fine
$scope.gridOptions.api.refreshView();
i dont knew if there is a good solution, but that work for now
The problem seems to be with Angular being unaware of the $scope property change because ag-grid does not tell Angular that it has modified something in the $scope. Although it is difficult to tell if you don't show your view.
You can use onSelectionChanged the way you are using it to know how many rows have been selected, but you need to tell Angular that something has changed in its $scope by applying it.
Something like this:
var activeButtons = function() {
var countRowsSelected = $scope.gridOptions.api.getSelectedRows().length;
$scope.selectedRowsCounter = countRowsSelected;
console.log($scope.selectedRowsCounter);
$rootScope.count.selectedRows = countRowsSelected;
window.setTimeout(function() {
this.$scope.$apply();
});
};
That way you can apply the $scope and the html view will reflect the changes.

Sencha: Set Dataview XTemplate when created Dynamically

I have some data that I'm getting from the server that depending on the situation may bring different fields, so what I have is this:
//This is the way i'm attaching the newly created template to the view
//Still no success
function processDataMethod(response){
//some processing here...
var details = Ext.widget('details');
details.config.itemTpl = new Ext.XTemplate(tplFields);
}
Ext.Ajax.request({
url: '...',
...,
success: function (response, request) {
var combinedData = processDataMethod(response);
operation.setResultSet(Ext.create('Ext.data.ResultSet', {
records: combinedData,
total: combinedData.length
}));
operation.setSuccessful();
operation.setCompleted();
if (typeof callback == "function") {
callback.call(scope || that, operation);
currentList.up().push(Ext.widget('details'));
}
}
});
Any help is appreciated, thanks!!
You have to make a distinction between a number of things:
currentList.up() returns a DOM element (Ext.dom.Element). This has no method push().
With Ext.widget('details', config); you can pass a config like {itemTpl: yourTemplate, data: yourData} to create an instance with a custom template and custom data.
To update your component after creation you can always do someWidget.update(data);.
A component can be rendered to an HTML element with the renderTo option.
A component can be appended to existing components in different ways and you can update the whole layout or parts of it in different ways. This is unnecessary if you are rendering to an HTML element.
Does that help you find your problem?

Add class to elements for values of attribute with Backbone.ModelBinder

I'm using Backbone.ModelBinder in a Backbone.js Marionette project. I've a scenario which I can't work out how to use ModelBinder to automatically update my model/UI.
My model has a 'status' string attribute, with multiple states. In this example I'll show the code for two: 'soon', 'someday'
In my UI I have a list on which I use click events to set the model status, and update classes to highlight the relevant link in the UI.
<dd id="status-soon"><a>Soon</a></dd>
<dd id="status-someday" class="active"><a>Someday</a></dd>
events: {
'click #status-soon': 'setStatusSoon',
'click #status-someday': 'setStatusSomeday'
},
setStatusSoon: function () {
this.model.set('status', 'soon');
this.$el.find('.status dd').removeClass('active');
this.$el.find('#status-soon').addClass('active');
},
... etc
It feels like I doing this a long-winded and clunky way! The code bloat increases with the number of states I need to support. What's the best way of achieving the same outcome with ModelBinder?
You could probably simplify things with a data attribute, something like this:
<dd data-status="soon" class="set-status"><a>Soon</a></dd>
<dd data-status="someday" class="set-status active"><a>Someday</a></dd>
and then:
events: {
'click .set-status': 'setStatus'
},
setStatus: function(ev) {
var $target = $(ev.target);
var status = $target.data('status');
this.model.set('status', status);
this.$el.find('.status dd.set-status').removeClass('active');
$target.addClass('active');
}
You might not need the set-status class, just keying things on the <dd>s might be sufficient; I prefer separating my event handling from the nitty gritty element details though.
Unfortunately, it is going to be pretty difficult to do exactly what you want with ModelBinder. The main reason being that ModelBinder wants to provide the same value for all elements that are part of a single selector. So doing this with ModelBinder, while possible, is going to be pretty verbose as well.
The cleanup offered by mu is likely to be better than trying to use ModelBinder. 1) because you need a click handler to do the this.model.set no matter what and 2) you would need individual bindings for ModelBinder because the converter function is called once for a single selector and then the value is set on all matching elements (rather than looping through each one).
But if you do want to try and do something with ModelBinder it would look something like this:
onRender : function () {
var converter = function (direction, value) {
return (value == "soon" ? "active" : "");
};
var bindings = {
status : {selector : "#status-soon", elAttribute : "class", converter : converter}
};
this.modelBinder.bind(this.model, this.el, bindings);
}
This would do what you want. Of course the down side as I said above is that you will need multiple selector bindings. You could generalize the converter using this.boundEls[0] but you will still need the separate bindings for it to work.
In case you want to access to the bound element, it is possible to declare 'html' as elAttrbute, modify the element and return its html with converter function:
onRender : function () {
var converter = function (direction, value, attribute, model, els) {
return $(els[0]).toggleClass('active', value === 'soon').html();
};
var bindings = {
status : {
selector : "#status-soon",
elAttribute : "html",
converter : converter
}
};
this.modelBinder.bind(this.model, this.el, bindings);
}

openlayers: get length of selected feature

i'm using openlayers and geoExt.
what i have is this:
var options = {
hover : true,
box : true,
onSelect : saveToJ
};
var select = new OpenLayers.Control.SelectFeature(vecLayer, options);
map.addControl(select);
select.activate();
now in saveToJ function i want to get length of selected feature (let's say feature = lineString):
function saveToJ(feature) {
feature.getLength()
...
}
gives an error TypeError: Object #<Object> has no method 'getLength', but from this
i thought i can use it.
So: how can i get a length of selected feature?
getLength is a method of Geometry, not Feature.
So you should write feature.geometry.getLength(), see http://dev.openlayers.org/docs/files/OpenLayers/Geometry-js.html#OpenLayers.Geometry.getLength

TinyMCE plug-ins not firing in Composite C1

I've created a new plug in as I could not find one that actually "works", hoping that if I do it from scratch it might fire.
The plug-in simply wraps selected text with a mailto: link.
I've added the plug-in to the includes file, as per the following response on a previous question: http://bit.ly/vGyQlE however, it's not working.
I've gone into the localization directory, identified the Composite.Web.VisualEditor.en-us.xml as the file that handles the localization, added my entry under :
<string key="ToolBar.ToolTipMailTo" value="Mail To" />
But when I hover of the "blank" block where the menu item should appear, it returns (?). This is the first part where I picked up on something wierd. When you actually click on where the item should appear, nothing happens. So, I can't assume that the click event has got to do with an image, I re-wrote the command to return an alert, when clicked:
tinymce.create('tinymce.plugins.MailTo', {
init : function(ed, url) {
ed.addButton('mailto', {
title : 'mailto.mailto_desc',
cmd : 'mceMailTo',
image : url + '/images/mailto.gif'
});
ed.addCommand('mceMailTo', function() {
var selectedText = ed.selection.getContent({format : 'text'});
var MailToLink = "alert(" + selectedText + ");";
ed.execCommand('mceInsertContent', false, MailToLink);
});
I've added the "mailTo" element to visualeditor.js:
plugins : "...,paste,lists,mailto",
And ensured that the "mailto" plug-in is situated under the plug-ins directory for tiny_mce. I've gone as far as to clear my cache several times, but nothing? Can it be this difficult to add new plug-ins to tiny-mce in Composite?
1) Composite C1 does not support internal tiny_mce buttons
Do you add button to editor?
In file Composite\content\misc\editors\visualeditor\includes\toolbarsimple.inc add
<ui:toolbargroup>
<ui:toolbarbutton cmd="mceMailTo" tooltip="Mail to" image="${icon:paste}" isdisabled="false" />
</ui:toolbargroup>
2) Do you write valid plugin code?
(function () {
tinymce.create('tinymce.plugins.MailTo', {
init: function (ed, url) {
ed.addCommand('mceMailTo', function () {
var selectedText = ed.selection.getContent({ format: 'text' });
var MailToLink = "alert(" + selectedText + ");";
ed.execCommand('mceInsertContent', false, MailToLink);
});
}
});
tinymce.PluginManager.add('mailto', tinymce.plugins.MailTo); })();

Resources