The application I am working on is based on ExtJS, and what I would like to do is to allow the use to check only one checkbox.
The thing is that my application is very complex, and I don't really know a lot on ExtJS. The checkbox is initialized in a class viewport.js like this :
Ext.define('Viewport', {
extend : 'Ext.container.Viewport',
require : ['A','B'],
frame : true,
layout : 'fit',
items : [{
xtype : 'container',
layout : 'hbox',
margins : "a b c d",
items : [{
margins : "0 0 5 35",
name : 'box1',
inputValue : true,
xtype : 'checkbox',
id : 'box1-box-id',
boxLabel : "BOX 1"
}
,{
margins : "0 0 5 35",
name : 'box2',
inputValue : true,
xtype : 'checkbox',
id : 'box2-box-id',
boxLabel : "BOX 2"
}]
}
})
I don't know how to modify this code to have the user checking only one of these checkboxes. Do I have to add a function in this class?
There are various approaches how to do this, the most straightforward and explicit way to achieve this is to add listeners to the checkboxes:
On the first checkbox definition, add:
listeners: {
change: function(checkbox, newValue) {
if(newValue) { // if this checkbox is changed to "checked" state...
checkbox.nextSibling().setValue(false); // uncheck next checkbox
}
}
}
On the second checkbox definition, add:
listeners: {
change: function(checkbox, newValue) {
if(newValue) { // if this checkbox is changed to "checked" state...
checkbox.previousSibling().setValue(false); // uncheck previous checkbox
}
}
}
Of course this does not scale well if you have more than just a few checkboxes. But then, for more than a few checkboxes this usually is bad UX anyways and you want to rethink your application from a user PoV.
Related
I'm trying to do something, i think, that should be relatively simple with EXT.js 4, but I can not find an answer. I'm trying to create a checkbox with a type of "checkbox" currently when I try it renders it as a type="button"
here is a sample of what I'm doing (I belive this code comes from Sencha itself, but it is what I am trying to do)
THIS CODE
Ext.create('Ext.form.Panel', {
bodyPadding: 10,
width : 300,
title : 'Pizza Order',
items: [{
xtype : 'fieldcontainer',
fieldLabel : 'Toppings',
defaultType: 'checkboxfield',
items: [{
boxLabel : 'Anchovies',
name : 'topping',
inputValue: '1',
id : 'checkbox1'
}, {
boxLabel : 'Artichoke Hearts',
name : 'topping',
inputValue: '2',
checked : true,
id : 'checkbox2'
}, {
boxLabel : 'Bacon',
name : 'topping',
inputValue: '3'
id : 'checkbox3'
}]
}],
bbar: [{
text: 'Select Bacon',
handler: function() {
var checkbox = Ext.getCmp('checkbox3');
checkbox.setValue(true);
}
},
'-',
{
text: 'Select All',
handler: function() {
var checkbox1 = Ext.getCmp('checkbox1'),
checkbox2 = Ext.getCmp('checkbox2'),
checkbox3 = Ext.getCmp('checkbox3');
checkbox1.setValue(true);
checkbox2.setValue(true);
checkbox3.setValue(true);
}
},{
text: 'Deselect All',
handler: function() {
var checkbox1 = Ext.getCmp('checkbox1'),
checkbox2 = Ext.getCmp('checkbox2'),
checkbox3 = Ext.getCmp('checkbox3');
checkbox1.setValue(false);
checkbox2.setValue(false);
checkbox3.setValue(false);
}
}],
renderTo: Ext.getBody()
});
RENDERS
<input type="button" hidefocus="true" autocomplete="off" class="x-form-field x-form-checkbox x-form-cb" id="checkbox1-inputEl" aria-invalid="false" data-errorqtip="">
Notice the type="button"? I nee the type to be a "checkbox"
Let me include the reason, maybe I am approaching this wrong. I am trying to make JAWS reader read the checkbox the way it should. As a type "button" JAWS reader reads it like a button and dose not read the label that goes with the check box.
Hope this makes since, please ask any question you need to and thanks for any help.
Ross
You can do this using config autoEl. Check this fiddle: http://jsfiddle.net/vdazU/3262/
{
xtype: 'component',
autoEl: {
html: '<input type="checkbox" id="checkbox1" name="topping" >Anchovies'
}
If you inspect the DOM, you will be able to see a html input checkbox.
I had the same problem, so almost 2 years later, here's your answer:
You need to include the css! It took me hours to figure this out.
<link rel="stylesheet" href="http://cdn.sencha.com/ext/gpl/4.2.1/packages/ext-theme-gray/build/resources/ext-theme-gray-all.css">
BTW, put a comma after the 3.
inputValue: '3',
I had run your code at my end and its working fine. I am using extjs 6.0.2 and I think what you are seeing is that box that needs to be checked prefix to the label. It always remains as a button only. Even if you use a radiofield, then also it will be type="button" in dom because that box has to handle click event which can be handled by type="button". Can you provide the reason why you need it as type="checkbox"?
I have a simple UI grid with these options:
$scope.transactionGrid = {
enableSorting : true,
enableColumnResize : true,
enableScrollbars : true,
enablePaginationControls : false,
minRowsToShow : 6,
onRegisterApi : function(gridApi) {
$scope.gridEventsApi = gridApi;
}
};
I want to hide rows which have a specific value, deleted: "y".
$scope.transactionGrid.data = [
{ Name: "First", deleted: "y" },
{ Name: "Second", deleted: "y" },
{ Name: "Third", deleted: "n" },
{ Name: "Fourth", deleted: "n" }
];
Without actually changing the data, can it be filtered out from rows?
One way is to adjust the row-repeater-template to check for some row-specific value and make the row show/hide that way.
I created a Plunkr showcasing a possible solution.
First you need to create your row-value-checker-function:
appScopeProvider: {
showRow: function(row) {
return row.deleted !== 'y';
}
},
Then you adjust their template by adding that check to their row-repeater
$templateCache.put('ui-grid/uiGridViewport',
...
ng-if=\"grid.appScope.showRow(row.entity)\"
...
}
I know you specifically said "without actually changing the data", but assigning a filtered dataset to the grid would not change the dataset, just the data for the grid. Also it might be a relevant and valid solution for other cases like this.
I forked CMR's Plunk to demonstrate this: http://plnkr.co/edit/NntwWb?p=preview
The key part is just adding a filter when assigning the dataset:
$scope.gridOptions = {
data: $scope.myData.filter(function(row) {
return row.deleted !== "y";
})
};
You can hide it by creating cell templates and hide it based on row value for every field:
$scope.transactionGrid = {
enableSorting : true,
enableColumnResize : true,
enableScrollbars : true,
enablePaginationControls : false,
minRowsToShow : 6,
onRegisterApi : function(gridApi) {
$scope.gridEventsApi = gridApi;
}
// Column template definitions:
columnDefs: [
{
name: 'Name',
displayName: 'Name',
cellTemplate : '<div ng-if="row.entity.deleted">{{row.entity.Name}}</div>'
}
]
};
I made a Plunk to demonstrate a viable technique to solve this: https://plnkr.co/edit/XQRC45vaiZCySZYkEGrz?p=preview
I have an Ext combo box in a form panel as following.
new Ext.form.ComboBox({
store : routeStore,
displayField : 'rName',
valueField : 'rName',
fieldLabel : 'Select Fixed Route',
id : 'routeCombo',
typeAhead : true,
forceSelection : true,
mode : 'local',
triggerAction : 'all',
selectOnFocus : true,
editable : true,
hidden : false,
disabled : true,
minChars : 1,
hideLabel : true,
width : 210,
emptyText : 'Select Fixed Route'
})
An also I have a label like this.
{
xtype : 'label',
id : 'idTourCode',
text : 'SystemDate',
forId : 'myFieldId',
style : 'marginleft:10px',
//autoWidth : true,
flex : 1
}
Now I need to concatenate the selected value of the combo box to my label text. This label already has a text. What I want is, the selected value of the combo should be concatenate to this label text. All of these things should be happen on a button click.
I've tried to find a solution but no luck. Therefore, please be kind enough to help me to clarify my problem.
Thanx a lot
This is a crude fix.
Add this to your combobox:
listeners: {
change: function(box, newValue)
{
Ext.ComponentQuery.query("#myLabel")[0].setText(newValue)
}
Add this to your label:
itemId: 'myLabel'
You should polish this a bit and find a better to access you combobox than Ext.ComponentQuery, because it is really slow.
I am developing an application in which when submit button is clicked in the form, it should go to a different screen. However it is just printing the results outside of the window and not really going to a new screen. I have hardcoded the store to make sure there is data when I start the application and it still prints it outside of the viewable area.
Here is my Ext.data.Store:
var store = new Ext.data.Store({
model: 'jobSummary',
storeId: 'jobStore',
data : [{title: 'This is test'},
{title: 'This is test2'},
{title: 'This is test3'}]
});
Here is the list that I am using it in:
SearchJobsForm.jobsList = Ext.extend(Ext.Panel, {
dockedItems : [ {
xtype : 'toolbar',
title : 'WTJ',
dock : 'top',
items : [ {
xtype : 'button',
text : 'Back',
ui : 'back',
handler : function() {
//back button controller
},
scope : this
} ]
} ],
items : [ {
xtype : 'list',
emptyText : 'No data available.',
store : 'jobStore',
itemTpl : '<div class="list-item-title">{title}</div>'
+
'<div class="list-item-narrative">{narrative}</div>',
onItemDisclosure : function(record) {
},
grouped : false,
scroll : 'vertical',
fullscreen : true
} ],
initComponent : function() {
SearchJobsForm.jobsList.superclass.initComponent.apply(this, arguments);
}
});
And i am calling this list panel from my submit button handler which is:
var jobsList = new SearchJobsForm.jobsList();
The full code I have pasted on this link for better visibility:
http://pastebin.com/a05AcVWZ
Ok,
SearchJobsForm.form is your main panel, it will contains two components a searchForm (with text/select input) and a panel/list of results.
In the callback, we will hide() the form and show() the results list. This is not a clean code, but the simpliest and kissest one I can get from yours.
First let's instantiate the jobsList
// It has the id ( id: 'jobsListId')
var jobsList = new SearchJobsForm.jobsList();
then you should put all your inputs into a form (xtype : formpanel,
id: 'searchFormId')
And add the resultPanel just after the form
Here is the code
SearchJobsForm.form = Ext.extend(Ext.Panel,{
initComponent: function(){
Ext.apply(this, {
id: 'searchForm',
floating: true,
width: 250,
height: 370,
scroll: 'vertical',
centered: true,
modal: true,
hideOnMaskTap: false,
items: [
{
xtype: 'formpanel', // 1. this is the added formpanel
itemId: 'searchForm',
id: 'searchFormId', // this id is important
items: [
{
xtype: 'textfield',
...
}, {
xtype: 'textfield',
...
},
// all your inputs
]
},
// 2. add here the results panel : jobsList
jobsList
], // the code continues inchanged
dockedItems: [{
...
- Finally we will modify the ajax callback to hide/show the panels. Do not remove one of them, elsewhere you won't be able to reset your form
// here it comes
Ext.util.JSONP.request({
url: "http://"+serverAdd+":"+ port+"/users/searchresults.json",
format: 'json',
callbackKey: 'callback',
params : searchCriteria,
callback: function(data) {
console.log('callback');
// Call your list-filling fonctions here
// jobsList.fill(data);
Ext.getCmp('searchFormId').hide();
Ext.getCmp('jobsListId').show();
},
failure: function ( result) {
console.error('Failed');
}
});
For your next projects, I recommend you to work with classes and namespaces to avoid 1000 lined files ; Ext.ns() is your best friend and will avoid you a lot of headaches.
I have bottom bar added to a panel like this
bbar: [{
xtype : 'button',
text : 'Select Filter By',
itemId : 'filter_by',
arrowAlign : 'right',
menu : [{
text : 'Item Code',
checked : true,
group : 'filter',
itemId : 'item_code'
},{
text : 'Description',
checked : false,
group : 'filter',
itemId : 'description'
}]
}]
how to get the which is checked from these two?
Regards
In this case, they both can be checked or unchecked.
You can give an id to each and then simply do Ext.getCmp('id1').getValue() and Ext.getCmp('id2').getValue() to get the state of each
If you want to use these as a "group", you will have to wrap them in a CheckboxGroup or RadioGroup depending on your requirement.
try this
the idea is just add a listener to each Ext.menu.Menu.
if you are working with your own class, you can make testCheck as one of your method..