HTML Form to ExtJS Form - forms

I have an html form in which the fields are extremely scattered. The page has been created using html table - rowspan and colspan combinations.
I need to convert this form to ExtJS and display it in a window.
After carrying out some research, I feel that table layout could be best choice for positioning the fields. But there are few issues which I have been facing as following:
If I give rowspan or colspan as 2 or more, then also the fields don't increase in size to occupy the availabe space and remain confined to single column.
If I resize the window, then the table doesn't resize (though, the form does as the tbar present at the top expand to occupy the complete space).
I have used the layout as 'fit' for window and layout as 'table' for the form.
I have also tried using 'anchor' layout for form and then having a fieldset with table layout, but the positioning didn't work.
Could someone please throw some light on this. Following is a basic code snippet I am using:
var form = Ext.create('Ext.form.Panel', {
url:'voyage_berth_monitoring.php',
fieldDefaults: {
labelAlign: 'right'
},
layout:{
type:'table',
columns:3
},
defaults:{
anchor:'100%'
},
tbar:[
{
xtype:'button',
text:'Clear'
},
{
xtype:'button',
text:'Delete'
},
{
xtype:'tbfill'
},
{
xtype:'button',
text:'Save'
},
{
xtype:'button',
text:'Exit'
}
],
items: [
{
fieldLabel:'item',
xtype:'textfield'
},
{
fieldLabel:'item',
xtype:'textfield',
colspan:2
},
{
fieldLabel:'item',
xtype:'textfield'
},
{
fieldLabel:'item',
xtype:'textfield'
},
{
fieldLabel:'item',
xtype:'textfield'
}
]
});
var win = Ext.create('Ext.window.Window', {
title: 'Window',
closable: true,
closeAction:'hide',
minimizable:true,
maximizable:true,
height:350,
width:750,
layout:'fit',
autoScroll:true,
items: form
});
win.show();

Basicly i had the same problem with the layout table, couldn't find any way to span my displayfields to the length of the td, and also the same issue with the 2 columns field.
The solution i prefered was to extend the table layout and give it that flexibility
Ext.define('Extended.TableLayout', {
alias:'layout.extendedTable',
extend: 'Ext.layout.container.Table',
type: 'extendedTable',
columns: 2,
rightMargin: 20,
tableAttrs:{
width: '100%'
},
tdAttrs:{
width:'50%'
},
itemCls:'x-table-cell',
renderItems: function(items) {
var totalWidth = this.getLayoutTargetSize().width,
len = items.length,
i, item, colNr;
for (i = 0; i < len; i++) {
item = items[i];
colNr = this.columns;
if ((colNr > 1) && Ext.isNumber(item.colspan)) {
colNr = colNr - item.colspan + 1;
}
item.width = Math.floor(totalWidth/colNr) - this.rightMargin;
}
this.callParent(arguments);
}
});
Using the extendedTable layout i get the desired look

One alternative it to serialize your HTML form data as JSON and load it into an EXT store. Once it's in a store, EXT will happily do whatever you want with it.

Related

Is it possible to display multiple icons in a single AG Grid cell and then be able to filter rows on each individual icon?

enter image description here
So would I be able to display multiple icons here and if so would the user be able to filter the grid rows to display rows that feature each icon (alone and as part of a group) by selecting each icon in the filter?
And could users tap the icons to open a detail grid?
Thanks in advance
Please see this sample which implements your use case: https://plnkr.co/edit/kEDrnyfBkoFoxFGB
You can display multiple icons on a row by using cellRenderers, first you have to provide it to the grid:
columnDefs: [
// group cell renderer needed for expand / collapse icons
{
field: 'name',
minWidth: 300,
cellRenderer: 'agGroupCellRenderer',
cellRendererParams: {
innerRenderer: 'iconRenderer',
},
},
],
components: {
iconRenderer: IconCellRenderer,
},
};
Here is the Cell Renderer Component:
class IconCellRenderer {
init(params) {
this.params = params;
this.eGui = document.createElement('div');
this.eFilterButton = document.createElement('button');
this.eExpandButton = document.createElement('button');
this.eText = document.createElement('span');
this.eText.textContent = params.value;
this.eFilterButton.textContent = 'filter';
this.eExpandButton.textContent = 'expand';
this.eGui.appendChild(this.eText);
this.eGui.appendChild(this.eFilterButton);
this.eGui.appendChild(this.eExpandButton);
this.eFilterButton.addEventListener('click', this.filterOnClick.bind(this));
this.eExpandButton.addEventListener('click', this.expandOnClick.bind(this));
}
getGui() {
return this.eGui;
}
expandOnClick(ev) {
const isExpanded = this.params.node.expanded;
this.params.node.setExpanded(!isExpanded)
}
filterOnClick(ev) {
const value = this.params.value;
this.params.api.setFilterModel({
name: { values: [value] },
});
}
}
The key here is that we can expand a row by calling api.setExpanded(true) on a node. And we can filter on the grid by calling api.setFilterModel(filterModel)

How to apply CSS to sap.m.table row based on the data in one of the cell in that row

I am working with sap.m.table. I have requirement to apply or change the background color for some of the rows based on the data in one of the column in those rows in table.
I am using the following code but it is not working
created the CSSfile: test.css
<style type="text/css">
.Total {
background-color: LightSteelBlue !important;
}
</style>
The above CSS file declare in Component.js like the following way ( correct me if this not right way to make the css file available to access in whole ui5 project.
"resources": {
"css": [
{
"uri": "css/test.css"
}
]
}
In Controller.i have defined the following method to apply the style sheet for the particular rows alone in table.
rowColours: function() {
var oController = this;
console.log("rowColours() --> Start ");
var oTable = this.oView.byId("tblAllocation");
var rows = oTable.getItems().length; //number of rows on tab
//start index
var row;
var cells = [];
var oCell = null;
for (i = 0; i < oTable.getItems().length; i++) {
//console.log("rowColours() :: row--> "+row);
//actualRow = oTable.getItems(); //content
if (i == 0) {
row = oTable.getItems()[i];
cells = cells.concat(oTable.getItems()[i].getCells());
//getting the cell id
oCell = cells[2];
oCell = oCell.toString().substring(29, oCell.length);
otemp = this.getView().byId(oCell).getText();
if (otemp.toString() == "TotalAllocation") {
oTable.getItems()[i].$().taggleClass("grandTotal");
}
}
}
console.log("rowColours() --> end ");
}
In the above method. I am checking the cell2 data ( in table cell 2 i was using the Textview control to display the data. when call this method to get the data in that cell. I am getting the following error.
otemp = this.getView().byId(oCell).getText());
error:
Uncaught TypeError: Cannot read property 'getText' of undefined
is the following code is possible to change the row bg color.
if (otemp.toString() == "TotalAllocation") {
oTable.getItems()[i].$().taggleClass("Total");
}
Please let me know how to change the bg color or applying the style for the perticular row in sap.m.table
Thanks
The approach your following is not right. Better you can use a formatter.
Example:
var oTable = new sap.m.Table({
columns: [
new sap.m.Column({
header: new sap.m.Label({
text: "Name"
}),
}),
],
items: {
path: 'modelList>/',
template: new sap.m.ColumnListItem({
cells: [
new sap.m.Text({
//formatter to the text property on sap.m.Text control.
text: {
parts: [{
"path": "modelList>Name"
}],
formatter: function(name) {
if (name == "TotalAllocation") {
// use this.getParent().. until u get the row. like this below and add class.
this.getParent().getParent().addStyleClass("Total");
}
}
}
})
]
})
}
});

Knockout.js - Reload a dropdown with new options using the value of another drop down

I've seen similar things, where people have wanted to do this in ASP .NET, generic JavaScript, PHP, etc., but now here we have KnockOut that throws a wrench in things, since its fields are already rendered dynamically. Now here I go wanting to rewrite a dropdown when another is changed... dynamic loading on top of dynamic loading, all in old-fashioned cascading style....
I have a dropdown, "ourTypes", I've called it, that when changed, should re-write the options of the "slots" dropdown to its left. I have a .subscribe() function that creates new options based on a limit I get from the "ourTypes" value. All well and good, but how do we make the dropdown actually reflect those new values?
HTML:
<select data-bind="options: $root.slots, optionsValue: 'Value', optionsText: 'Text', value: $data.SlotPosition"></select>
<select data-bind="options: $root.ourTypes, optionsValue: 'ID', optionsText: 'Name', value: $data.OurTypeId"></select>
JavaScript:
var slots = [
{ Text: "1", Value: "1" },
{ Text: "2", Value: "2" },
{ Text: "3", Value: "3" }
];
var ourTypes = [
{ ID:"1", Name:"None", Limit:0 },
{ ID:"2", Name:"Fruits", Limit:5 },
{ ID:"3", Name:"Vegetables", Limit:5 },
{ ID:"4", Name:"Meats", Limit:2 }
];
var dataList = [
{ SlotPosition: "1", OurTypeId: 4 },
{ SlotPosition: "2", OurTypeId: 2 },
{ SlotPosition: "3", OurTypeId: 3 }
];
var myViewModel = new MyViewModel(dataList);
ko.applyBindings(myViewModel);
function MyViewModel(dataList) {
var self = this;
self.slots = slots;
self.ourTypes = ourTypes;
self.OurTypeId = ko.observable(dataList.OurTypeId);
self.SlotPosition = ko.observable(dataList.SlotPosition);
self.OurTypeId.subscribe(function() {
if (!ko.isObservable(self.SlotPosition))
self.SlotPosition = ko.observable("1");
// Get our new limit based on value
var limit = ko.utils.arrayFirst(ourTypes, function(type) {
return type.ID == self.OurTypeId();
}).Limit;
// Build options here
self.slots.length = 0;
self.slots.push({Text:"",Value:""});
for (var i=1; i < limit+1; i++) {
self.slots.push({Text:i, Value:i});
}
// What else do I do here to make the dropdown refresh
// with the new values?
});
}
Fiddle: http://jsfiddle.net/navyjax2/Lspwc4n4/
Well just made small changes in you code
View Model:
self.slots = ko.observableArray(slots); //should make it observable
self.ourTypes = ko.observableArray(ourTypes);
self.OurTypeId = ko.observable(dataList[0].OurTypeId); // initial value setting
self.SlotPosition = ko.observable(dataList.SlotPosition);
//Inside subscribe
self.slots([]); // clearing before filling new values
Working fiddle here

ExtJs 4.2 Paging toolbar - Disable invalid page message

I have set up a paging toolbar for my grid. If I put an invalid number in the text field for page numbers, an error message/quicktip is displayed. I want to disable it. I have gone through all the configs, but couldn't find one. Is there a way to do this?
Try here!
Try adding a 0 in the text input for the paging toolbar, and keep pointing at it with the mouse. The tooltip will pop out.
You need to override the getPagingItems function for this:
xtype: 'gridpanel',
(...),
dockedItems: [{
xtype: 'pagingtoolbar',
(...),
getPagingItems: function() {
var me = this;
var pagingItems = me.self.prototype.getPagingItems.apply(me, arguments);
for (var i in pagingItems) {
var pagingItem = pagingItems[i];
if (pagingItem != null && pagingItem.itemId == 'inputItem') {
pagingItem.preventMark = true;
break;
}
}
return pagingItems;
}
}]

Dynamic Carousel Content does not show

I have been working on this for a number of days now, but my limited JS knowledge seems to hurt me.
I am creating a dynamic Ext.Carousel component in my ST2 application, which is based on the contents of a Store file.
That all works fine, but I will show the code anyway, so that nothing is left to imagination:
Ext.getStore('DeviceStore').load(
function(i) {
Ext.each(i, function(i) {
if (i._data.name == 'Audio Ring') {
var carousel = Ext.ComponentManager.get('speakerCarousel');
var items = [];
Ext.each(i.raw.speakers, function(speaker) {
items.push({
sci: Ext.create('SmartCore.view.SpeakerCarouselItem', {
speakerId: speaker.speakerid,
speakerName: speaker.speakername,
speakerEnabled: speaker.speakerenabled
})
});
});
carousel.setItems(items);
}
});
})
Now, this adds me the appropriate number of items to the carousel. They display, but without the content I specified:
This is the Carousel itself:
Ext.define('SmartCore.view.SpeakerCarousel', {
extend: 'Ext.Carousel',
xtype: 'speakerCarousel',
config: {
id: 'speakerCarousel',
layout: 'fit',
listeners: {
activeitemchange: function(carousel, item) {
console.log(item);
}
}
}
});
This is the item class, that I want to fill the data from the store into:
Ext.define("SmartCore.view.SpeakerCarouselItem", {
extend: Ext.Panel,
xtype: 'speakerCarouselItem',
config: {
title:'SpeakerCarouselItem',
styleHtmlContent: true,
layout: 'fit'
},
constructor : function(param) {
this.callParent(param);
this.add(
{
layout: 'panel',
style: 'background-color: #759E60;',
html: 'hello'
}
)
}
});
Again, the right number of items shows in the carousel (11), but the content is not visible, nor is the background colour changed.
When I check the console.log(item) in the browser, the items show as innerItems inside the carousel object.
Any help is greatly appreciated!!
Well, I fixed it myself, or better, I found a workaround that seems to be what I want.
I ended up ditching the constructor all together.
Instead I overwrote the apply method for the 'speakerName' key-value pair.
From there, I can use:
this._items.items[0]._items.items[i].setWhatever(...)
to set the content inside the item.
If anyone knows the "real" way to do this, I would still greatly appreciate input!