I am trying to dynamically set the padding on a grid panel I have showing some data. On the event that my checkbox was clicked, it should apply the padding cls.
Here is the relevant ExtJS code:
var permissionsGrid = Ext.create('Ext.grid.Panel', {
//...
items: [{
xtype: 'checkbox',
name: 'EditRoles',
boxLabel: 'Edit User Roles',
handler: function(field, value) {
userRoleFilter = '';
permissionsGrid.removeCls('permissions_panel_nopadding');
console.log(permissionsGrid.hasCls('permissions_panel_nopadding'));
permissionsGrid.addCls('permissions_panel_padding');
console.log(permissionsGrid.hasCls('permissions_panel_padding'));
}
}],
//...
});
Here is my CSS
.permissions_panel_nopadding {
padding: 0px;
}
.permissions_panel_padding {
padding: 5px;
}
When the checkbox is clicked, currently nothing happens. I tried to use:
permissionsGrid.getView().refresh();
...but to no prevail.
You are always removing one class and always adding another class. You need to "switch" the classes. If you don't need special styling when the checkbox isn't clicked, you should add/remove only one class.
handler: function(field, value) {
userRoleFilter = '';
if ( value === true) {
permissionsGrid.removeCls('permissions_panel_nopadding');
permissionsGrid.addCls('permissions_panel_padding');
}
else {
permissionsGrid.addCls('permissions_panel_nopadding');
permissionsGrid.removeCls('permissions_panel_padding');
}
console.log(permissionsGrid.hasCls('permissions_panel_padding'), permissionsGrid.hasCls('permissions_panel_nopadding'));
}
Here is my fiddle with basic panel and only one CSS class: https://fiddle.sencha.com/#fiddle/ne3
EDIT:
ExtJS 6.0+
Since ExtJS 6.0.0, you can use the toggleCls method:
handler: function(field, value) {
permissionsGrid.toggleCls('permissions_panel_padding', value);
permissionsGrid.toggleCls('permissions_panel_nopadding', !value);
console.log(permissionsGrid.hasCls('permissions_panel_padding'), permissionsGrid.hasCls('permissions_panel_nopadding'));
}
Related
I want to create a component that provides a list of selections to the user but allows only one selection to be made at any given time. The functionality of the mat-radio-group seems to fit that bill the best, but I don't want the actual radio button to be rendered next to the labels within my radio group. I want to expand the label and make any (change) event fire from a click event on the label itself.
What is the least "hacky" way to eliminate the radio buttons from my radio group, while keeping the labels as they were?
you can also make a custom form control. The idea is that has a .html like
<select-component [(ngModel)]="valor">
<div select value="1">One</div>
<div select>Two</div>
</select-component>
We are going to make a directive that the selector was [select]
#Directive({
selector: '[select]',
})
export class SelectDirective implements AfterViewInit {
#Input('value')value:any;
control:any;
#HostBinding('class.selected')
get isSelected(){
return this.control && this.control.value==this.value?true:undefined
}
#HostBinding('class.select')setClass(){return true}
#HostListener('click') onclick() {
console.log(this.value);
if (this.control)
this.control.setValue(this.value)
}
constructor(private el:ElementRef){}
ngAfterViewInit()
{
this.value=this.value ||this.el.nativeElement.innerHTML
}
}
See that, in ngAfterViewInit we give value to this.value as the innerHTML of the div case you has not defined the value
There're two class binding, one .select -this alow us give .css to our component from app.main.component, one .selected, when the div was "selected".
The SelectComponent is a tipical custom form control, the "interesting" is that, in ngAfterViewInit, we ask about the "select" directive inside to allow comunicate the directive and the component
#Component({
selector: 'select-component',
template: `<ng-content></ng-content>`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => SelectComponent),
multi: true
}
]
})
export class SelectComponent implements ControlValueAccessor,AfterViewInit {
#ContentChildren(SelectDirective)selects:QueryList<SelectDirective>;
value:any;
disabled:boolean=false;
onChange:any;
onTouched:any;
writeValue(value: any[]|any): void {
this.value=value;
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
setDisabledState(isDisabled: boolean): void {
this.disabled=isDisabled
}
ngAfterViewInit()
{
this.selects.forEach(x=>{
x.control=this
})
}
setValue(value)
{
this.value=value
this.onChange(value)
}
}
And, voila!, the stackblitz
I'm looking to add a react element with H.ui.Control. Is this possible? and how might it be done?
// sudo code of what I did
componentDidMount() {
...
let button = new H.ui.Control(this.myButtonControl);
button.setPosition('top-left');
this._ui.addControl('button-control', button);
...
}
myButtonControl() {
return <button className="H_btn">Hello World</button>
}
A new <div class="H_ctl"></div>, appears where the control was suppose to be, but not the button.
While it's not exactly what I wanted to do, I did find a solution. I created a generic class that extends H.ui.Control, in this case ButtonGroupControl.
class ButtonGroupControl extends H.ui.Control {
constructor(buttons: []) {
super();
this._buttons = buttons;
this.addClass('H_grp');
}
renderInternal(el, doc) {
this._buttons.forEach((button, i) => {
let btn = doc.createElement('button');
btn.className = 'H_btn';
btn.innerText = this._buttons[i].label;
btn.onclick = this._buttons[i].callback;
el.appendChild(btn);
})
super.renderInternal(el, doc);
}
}
export default ButtonGroupControl;
Then, inside my map component, I created passed array of items into the control, like so:
const mapToolsControl: ButtonGroupControl = new ButtonGroupControl([
{
label: 'Add Field',
callback: () => {
console.log('callback: adding field');
}
},
{
label: 'Remove Field',
callback: () => {
console.log('callback: remove field');
}
}
]);
Lastly, I added the control to the map like:
this._map.addControl('map-tools-control', mapToolsControl);
This results in the following (it's a link because I don't have enough points to embed yet):
Screenshot of Result
Here is what i have done (adding two buttons to the map)
var U_I = new H.ui.UI(map);
var container = new H.ui.Control();
container.addClass('here-ctrl here-ctrl-group');
var button = new H.ui.base.Element('button', 'here-ctrl-icon map_control');
container.addChild(button);
button.addEventListener('click', function() { alert(1); });
var button = new H.ui.base.Element('button', 'here-ctrl-icon map_center');
container.addChild(button);
button.addEventListener('click', function() { alert(2); });
container.setAlignment('top-right');
U_I.addControl('myControls', container );
U_I.addControl('ScaleBar', new H.ui.ScaleBar() );
the rendering is made by css (here is an extract)
button.here-ctrl-icon {
width: 25px;
height: 25px;
margin: 2px 0 0 2px;
}
.map_control { background: url("images/map_control.png") no-repeat scroll 0 0 transparent; }
.map_center { background: url("images/map_center.png") no-repeat scroll 0 0 transparent; }
H.ui.base.Button(); is not working ... it creates a div
It is not possible to add attributes to button such as alt or title thru the api.
I still have to deal with the addEventListener ... (not working !)
the result :
my new nice controls
I have implemented dropdown using react-select using which on typeahead options are shown, but initially the dropdown list is huge and its occupying whole page .
I want to know how to style the react-select dropdown list to fixed height and on overflow provide scroll.
react-select
Following is my partial code
class Project extends React.Component {
render() {
const selectStyles = {
input: base => ({
...base,
color: theme.palette.text.primary,
'& input': {
font: 'inherit',
},
})
};
return ( <
SelectN inputProps = {
{
name: 'headedByUserId',
id: 'headedByUserId',
}
}
classes = {
classes
}
styles = {
selectStyles
}
options = {
suggestions
}
components = {
components
}
value = {
this.state.fields["headedByUserId"]
}
onChange = {
this.handleChangeDropdown.bind(this, "headedByUserId")
}
placeholder = "select owner"
/
>
)
}
}
react-select has a attribute
maxMenuHeight="200"
using this we can set height of the dropdown list, also if dropdown inside a material dialog you can set dialog property "overflow":"visible" for dropdown to be displayed
This is a dumb question - but I've been stuck on it for awhile and cannot find an answer.
I'm trying to override the color of an Ext.js checkbox for only certain elements.
CSS:
.x-field-checkbox .x-field-mask::after, .x-field-radio .x-field-mask::after .emptyCell{
color: white;
}
Notice the class there - .emptyCell
Now the Sencha code:
if(noCheckBox) {
var checkbox =
{
xtype: 'checkboxfield',
cls: 'opBuyoffCheckBoxCell emptyColumn',
readOnly: true
};
return checkbox;
} else {
var checkbox =
{
xtype: 'checkboxfield',
cls: 'opBuyoffCheckBoxCell',
listeners: {
change: function (checkbox) {
//Todo put in logic on checkbox change
}
}
};
return checkbox;
}
},
What is the problem here? I have three checkboxes. Two of them should render white and the other one should be normal based on my CSS and logic. I've debugged and it is going into the right code. But when I launch my application it is always using the emptyColumn css class.
Help is appreciated.
Apply this css:
.emptyColumn .x-input-el:checked+.x-field-mask::after {
color: #fff;
}
One thing to notice, write same cls in CSS and HTML.
I'm using Redactor and need to dynamically add elements to a custom dropdown menu. I can't find any way of doing this in the documentation - does anyone know if this is possible?
Yes, it's possible if you use this:
$('#redactor').redactor({
focus: true,
buttonsAdd: ['|', 'button1'],
buttonsCustom: {
button1: {
title: 'Button',
callback: function(buttonName, buttonDOM, buttonObject) { /* … */ },
dropdown: {
alignleft: {
title: lang.align_left,
func: 'alignmentLeft'
},
aligncenter: {
title: lang.align_center,
func: 'alignmentCenter'
}
}
}
}
});