ExtJS not able to set value for timefield component - javascript

I've been trying to find an approach on how to fix the issue I have, but I could not find it in Google nor S.O, that's why I'm posting this question.
I have two components of type: timefield that are represented in this piece of code:
{
xtype: 'timefield',
format: 'H:i',
increment: 30,
name: 'shiftStartTime',
itemId: 'shiftStartTime',
fieldLabel: 'Shift Start Time',
required: true,
value: '00:00'
}, {
xtype: 'timefield',
format: 'H:i',
increment: 30,
name: 'shiftEndTime',
itemId: 'shiftEndTime',
fieldLabel: 'Shift End Time',
required: true,
value: '00:00'
},
What I'm doing is easy, actually, I'm trying to set a value for the fields based on an entity that comes from server. I already managed to retrieve the entity which has two fields: 'hour' and 'minute', I want to set the concatenated value to both components, but for some reason, it always display blank. Here's the piece of code I implemented in order to set the value:
setPreEnteredTimes: function(userProfileItem) {
var me = this,
shiftStartTimeComp = me.getItem('shiftStartTime'),
shiftEndTimeComp = me.getItem('shiftEndTime'),
hh = userProfileItem.get('hour'),
mm = userProfileItem.get('minute');
var displayStr = hh + ':' + mm;
shiftStartTimeComp.setValue(displayStr);
shiftEndTimeComp.setValue(displayStr);
},
I've already tried even creating a new Date and using Ext.Date.format() using H:i but not working, the timefield is always displaying blank.
Version of ExtJS is 4.2.3
Thanks in advance.

There is nothing wrong with timefields and .setValue(). I'm sure that you will get an error like me.getItem(...) is not a function on the console. Here is a fiddle with an example: https://fiddle.sencha.com/#fiddle/17al
Replace me.getItem() with a component query like this (included in fiddle):
var shiftStartTimeComp = Ext.ComponentQuery.query('timefield[name="shiftStartTime"]', me)[0];

Related

Extjs 6 combobox values and display values not displaying correctly when setting values dynamically per row

Oof that was a long title.
In my current project I have a grid that holds a set of workshop records. For each of these workshops there is a set of rates that apply specifically to the given workshop.
My goal is to display a combobox for each row that shows the rates specific to that work shop.
I've got a prototype that works for the most part up on sencha fiddle, but there's something off about how the selection values are being created:
Ext.define('Rates',{
extend: 'Ext.data.Store',
storeId: 'rates',
fields: [
'rateArray'
],
data:[
{
workshop: 'test workshop 1',
rateArray: {
rate1: {show: "yes", rate: "105", description: "Standard Registration"},
rate3: {show: "Yes", rate: "125", description: "Non-Member Rate"},
rate4: {show: "yes", rate: "44", description: "Price for SK tester"}
}
},
{
workshop: 'test workshop 2',
rateArray: {
rate1: {show: "yes", rate: "10", description: "Standard Registration"},
rate2: {show: "yes", rate: "25", description: "Non-Member Registration"}
}
}
]
});
Ext.define('MyGrid',{
extend: 'Ext.grid.Panel',
title: 'test combo box with unique values per row',
renderTo: Ext.getBody(),
columns:[
{
xtype: 'gridcolumn',
text: 'Name',
dataIndex: 'workshop',
flex: 1
},
{
xtype: 'widgetcolumn',
text: 'Price',
width: 200,
widget:{
xtype: 'combo',
store: [
// ['test','worked']
]
},
onWidgetAttach: function (column, widget, record){
var selections = [];
Ext.Object.each(record.get('rateArray'), function (rate, value, obj){
var desc = Ext.String.format("${0}: {1}", value.rate, value.description);
// according to the docs section on combobox stores that use 2 dimensional arrays
// I would think pushing it this way would make the display value of the combobox
// the description and the value stored the rate.
selections.push([rate, desc]);
});
console.log(selections);
widget.getStore().add(selections);
}
}
]
});
Ext.application({
name : 'Fiddle',
launch : function() {
var store = Ext.create('Rates');
Ext.create('MyGrid',{store: store});
}
});
In the grid widget that I'm using for the combobox I'm using the onWidgetAttach method to inspect the current row's record, assemble the rate data from the record into 2 dimensional array, and then setting that to the widget's store.
When I look at the sencha docs section on using a 2 dimensional array as the store, it states:
For a multi-dimensional array, the value in index 0 of each item will be assumed to be the combo valueField, while the value at index 1 is assumed to be the combo displayField.
Given that, I would expect the combo box to show the assembled description (e.g.
"$150: Standard Registration") and use the object key as the actual stored value (e.g. "rate1").
What I'm actually seeing is that the display value is the rate and I'm not sure how sencha generates the combobox selections to see how the selection is being rendered out.
Is my assumption about how the 2-dimensionally array gets converted to the store wrong?
Well, your question is suffering from the XY problem. Because what you really want to do is the following:
You want to create a decent store for your combo, using a well-defined model with the meaningful column names you already have in "rateArray", then you define displayField and valueField accordingly, and in onWidgetAttach, just stuff the "rateArray" object into that store using setData.
Sth. along the lines of
xtype: 'widgetcolumn',
text: 'Price',
width: 200,
widget:{
xtype: 'combo',
store: Ext.create('Ext.data.Store',{
fields:['rate','description','show']
filters:[{property:'show',value:"yes"}]
}),
displayField:'description',
valueField:'rate',
onWidgetAttach: function (column, widget, record){
widget.getStore().setData(record.get("rateArray"));
}
},

understanding store in ExtJS

I am new to ExtJS and I find documentation confusing, I need to get the first data from store, which I get from the report. How to do it correctly?
this.divisionList = new ....SimplestReportCombo({
fieldLabel: "Division",
allowBlank: false,
valueField: 'KEY',
displayField: store.load.get(0),
width: 200,
reportID: 'USER_ACCESS',
store : new Ext.data.ArrayStore({
fields: [{name: 'KEY'}],
data: [{name: 'VALUE'}]
}
)
});
Javascript Stores mostly resembles RDBMS tables. They have in memomy storage and they are helpful to perform various grid level operation like sorting , paging , shuffling , editing etc.
Lets come to your code now,
You dont need to load store get its elements.If you requirement is only to select 1st ellement from store then you can do that using getAt function like below:
this.divisionList = new ....SimplestReportCombo({
fieldLabel: "Division",
allowBlank: false,
valueField: 'KEY',
displayField: store.getAt(0),
width: 200,
reportID: 'USER_ACCESS',
store : new Ext.data.ArrayStore({
fields: [{name: 'KEY'}],
data: [{name: 'VALUE'}]
}
)
});
or else you can also use following store method if you want to render mere 1st element:
store.first()

Programmatically Set Constructor Parameters in Javascript

I am trying to interact with a javascript api (bare in mind I have never done this before). An example of what I am attempting to work with is here:
SearchSpring.Catalog.init({
leaveInitialResults : true,
facets : '.leftNav',
results : '#results',
result_layout: 'list',
results_per_page : 12,
layout: 'top',
loadCSS: false,
filters: {
color: ['Blue']
},
backgroundFilters: {
category: ['Shirt', 'Shoes'],
department: ['Mens']
},
maxFacets: 5,
maxFacetOptions: 10,
sortText: 'Sort By ',
sortType: 'dropdown',
filterText: 'Refine Search Results',
previousText: 'Previous',
scrollType: 'scroll',
scrollTo: 'body',
backgroundSortField: 'price',
backgroundSortDir: 'desc',
compareText: 'Compare Items',
summaryText: 'Current Filters',
showSummary: true,
subSearchText: 'Subsearch:',
showSubSearch: true,
forwardSingle: false,
afterResultsChange: function() { $('.pagination').hide(); },
filterData: function(data) { console.debug(data); }
});
In the example I want to add a "backgroundFilter" to this with a value:
var cat="MyNewCategory";
cat.value="ANewValue;
How would I add this category and value to the backgroundFilters: listed above?
This is a very common framework initialization pattern when working with frameworks.
Your example code is passing a JavaScript Object {} as a parameter into a function () that is called init.
Taking out all definitions the pattern looks like this:
SomeFramework.frameworkFunction({});
In the above code the {} is an empty object used for initialization. There are two ways that you can work with that object in practice.
Regarding your first code snippet, you can add code into that 'object literal'.
backgroundFilters: {
category: ['Shirt', 'Shoes'],
department: ['Mens'],
cat: ['My value']
},
Notice the added comma, this is an important tripping point. This may or may not fit your needs, depending on a few factors.
Regarding your second code snippet, you can apply members to JavaScript objects at runtime. What I mean is, your var cat can be added to the anonymous object-literal that is being passed in. Hard to say, but a simple concept. Here is how:
//Say this is initialized in some separate way. //There is a bug here I'll describe later.
var cat="MyNewCategory";
cat.value="ANewValue";
//Extract and name the initialization object. It is verbatim at this point.
var initObject = {
leaveInitialResults : true,
facets : '.leftNav',
results : '#results',
result_layout: 'list',
results_per_page : 12,
layout: 'top',
loadCSS: false,
filters: {
color: ['Blue']
},
backgroundFilters: {
category: ['Shirt', 'Shoes'],
department: ['Mens']
},
maxFacets: 5,
maxFacetOptions: 10,
sortText: 'Sort By ',
sortType: 'dropdown',
filterText: 'Refine Search Results',
previousText: 'Previous',
scrollType: 'scroll',
scrollTo: 'body',
backgroundSortField: 'price',
backgroundSortDir: 'desc',
compareText: 'Compare Items',
summaryText: 'Current Filters',
showSummary: true,
subSearchText: 'Subsearch:',
showSubSearch: true,
forwardSingle: false,
afterResultsChange: function() { $('.pagination').hide(); },
filterData: function(data) { console.debug(data); }
};
//Now we can add variables (and functions) dynamically at runtime.
initObject.cat = cat;
//And pass them into the framework initialization in a separated way.
SearchSpring.Catalog.init(initObject);
Now for the bug. I don't know the solution because I do not know what it is intended to do, but I can point out what is potentially incorrect.
var cat="MyNewCategory";
cat.value="ANewValue;
This code is: 1 creating a String Object called cat. 2 changing the value to a new string.
I do not think this is what you really want.
To add a new backgroundFilter, in the separated way above, it would be:
initObject.backgroundFilters.cat = ['A', 'B'];
//Line above would give you this type of definition within the initObject (at runtime):
backgroundFilters: {
category: ['Shirt', 'Shoes'],
department: ['Mens'],
cat: ['A','B']
},
For this to work it will depend on what the framework is expecting regarding backgroundFilters.
Hope that helps.
All the best!
Nash
I don't quite understand - do you want to have the backgroundFilters categories as structured objects rather than plain strings? If you are in control of the entire API, you can do something like
...
backgroundFilters: {
category: [
new SearchSpring.Catalog.Category("Shirt"),
new SearchSpring.Catalog.Category("Shoes"),
new SearchSpring.Catalog.Category("MyNewCategory", "ANewValue")
],
department: 'Mens'
}
...

ExtJS Forms > .getFieldValues() function doesn't return any value for "timefield" xtype

I am using ExtJS Forms.
My form code is as follows:
Ext.create('Ext.form.Panel', {
width: 600,
layout: 'anchor',
defaultType: 'textfield',
items: [{
fieldLabel: "Specimen",
name: "Specimen"
}, {
.
.
.
}, {
fieldLabel: "Time Stamp",
name: "timestamp",
xtype: "timefield",
allowBlank: false
}],
buttons: [{
text: 'Save',
handler: function() {
var form = this.up('form').getForm();
var fieldValuePair = form.getFieldValues();
}
}],
renderTo: "ui"
});
For some special purpose, I want to get the id/value pairs in json format, which I have acheived using the .getFieldValues() function.
The problem is, when I press the "Save" button, the "fieldValuePair" variable in the handler function correctly gets all the values in json format except for the fields that have the "timefield" or "datefield" xtypes.
I have searched the web, but didn't come across any solution.
Any idea what may be the problem...?
Try with:
handler: function () {
var form = this.up('form').getForm();
var formValues = form.getValues(); // instead getFieldValues
console.log(formValues);
}
this way it returns:
date "12:30 AM"
and not:
date
Date {Tue Jan 01 2008 00:15:00 GMT+0100 (Central European Standard Time)} // this being another object
cheers!

ExtJS - Post date values as Unix timestamp

I use an editorgrid to edit elements from a JsonStore. The JsonStore uses a HttpProxy to update the backend database.
My problem is that the backend API expects fromTs and toTs to be Unix timestamps, but when a record is updated, the resulting http post contains a date formatted like this: Wed Oct 20 00:00:00 UTC+0200 2010
I've searched the API documentation for a parameter to control the post format, but I've not been able to find anything. Is there a simple way to do this?
myJsonStore = new Ext.data.JsonStore({
autoLoad: true,
autoSave: true,
proxy: new Ext.data.HttpProxy({
api: {
create: '/create/',
read: '/read/',
update: '/update/',
destroy:'/destroy/'
}
}),
writer: new Ext.data.JsonWriter({
encode: true,
writeAllFields: true
}),
idProperty: 'id',
fields: [
{name: 'id', type: 'int'},
{name: 'fromTs', type: 'date', dateFormat:'timestamp'},
{name: 'toTs', type: 'date', dateFormat:'timestamp'}
]
});
The editorgrid is configured like this:
{
xtype: 'editorgrid',
clicksToEdit: 1,
columns: [
{header: "Id", dataIndex: 'id', editable: false},
{header: "From", dataIndex: 'fromTs', editor: new Ext.form.DateField({format: 'd.m.Y', startDay: 1}), xtype: 'datecolumn', format: 'd.m.Y'},
{header: "To", dataIndex: 'toTs', editor: new Ext.form.DateField({format: 'd.m.Y', startDay: 1}), xtype: 'datecolumn', format: 'd.m.Y'}
],
store: myJsonStore
}
I know this case is old, but I found a solution to this problem that I never came around to post here.
I added a listener to the proxy's beforewrite event, and manipulated the post params there
proxy: new Ext.data.HttpProxy({
api: {
create: '/create/',
read: '/read/',
update: '/update/',
destroy:'/destroy/'
},
listeners: {
beforewrite: function(proxy, action, record, params) {
var fromTs = record.data.fromTs;
var toTs = record.data.toTs;
if(record.data.fromTs) record.data.fromTs = fromTs.format('U');
if(record.data.toTs) record.data.toTs = toTs.format('U');
// Update record to be sent
// root = store.reader.root
params.root = Ext.util.JSON.encode(record.data);
// Restore record
record.data.fromTs = fromTs;
record.data.toTs = toTs;
}
}
})
You might be able to hook into the validateedit event or afteredit event of your EditorGridPanel and convert the user-entered-value back into a timestamp using a Date parsing method. I'm guessing that EditorGridPanel is updating the records in the store verbatim without converting them back into timestamps, so you have to do that manually. So I'm thinking maybe something like:
grid.on('validateedit', function(event) {
if (isDateColumn(column)) {
event.record.data[event.field] = dateToTimestamp(event.value);
}
}
The problem is that the JsonWriter does not respect the dateFormat field used in your JsonReader. This post describes the issue along with some code that will address it. You can find it here.

Categories