I am having trouble making a select required in ExtJS.
I tried with allowBlank: false, even afterredner methods but nothing works, I can submit the form with no value in that select.
The code to generate the field is as follows:
OldType: function () {
return {
xtype: 'xEasyGridCombo',
allowBlank: false,
required: true,
valueField: 'fe_code',
displayField: 'fe_name',
dropPanelConfig: {
width: 480,
height: 200
},
searchFieldList: ['fe_code', 'fe_name'],
gridConfig: {
table: 'type_store',
idColumn: 'fe_id',
hasBottomBar: true,
rowLimit: 40,
tools: [],
conditions: [],
forceColumns: ['fe_code', 'fe_name'],
forceSelectFieldsQuery: ' DISTINCT fe_code, CONCAT(fe_name, \'[\', fe_code, \']\') fe_name ',
xColumns: [],
storeBaseParams: {}
},
listeners: {
afterrender: function () {
let oGrid,
sDivision = this.findParentByType('panel').find('KeyNr1', 'Divsion')[0].getValue();
// making sure the grid is rendered
this.getGridList();
oGrid = this.gridList.findByType('uxgrid')[0];
oGrid.store.baseParams.filter = Ext.util.JSON.encode([{
"field": "fe_tip",
"value": (sDivision === '02') ? 'F-GAZ' : 'F-ELEC'
}]);
//store from server try
oGrid.store.reload();
}
}
};
},
What am I doing wrong ? I can't even make it have a default value.
Thanks in advance and happy Holidays !
In the modern toolkit, the formpanel has a beforesubmit event. you can check if the value is selected or not. If you return a false from this event the form will not be submitted.
in the classic toolkit the event is beforeaction.
I have function for creating/rendering input fields but i don't know how to add tool tip on it in EXTjs6
this is my function:
createInputField: function(value, fieldsMarginBottom, readonly) {
var fieldStyle = this.getFieldStyle(readonly);
var nameField = Ext.create('Ext.form.field.Text', {
name: 'name',
readOnly: true,
hideLabel: true,
value: value,
width: this.fieldWidth,
style: {
marginBottom: fieldsMarginBottom + 'px'
},
//My try which is not working
tooltip: {
trackMouse: true,
width: 140,
renderer: function(tip, item){
tip.setTitle('name');
tip.update('Count: ');
}
},
fieldStyle: fieldStyle
});
return nameField;
}
I hope you guys can help me. If you need any additional informations, please let me know and I'll provide. Thank you
As can be seen in the textfield docs, fields do not have a way to add a tooltip to their configuration, so you would have to create the tooltip manually.
If you look at the docs for Ext.tip.ToolTip how to do that, you may find a small example, where you just have to change the target as per the target configuration description:
var tip = Ext.create('Ext.tip.ToolTip', {
target: nameField.getEl(),
html: 'Press this button to clear the form'
});
Above answer is correct. Here is example of generic function which you write once and use wherever you required in project by using using attributes.
addToolTip : function (id, msg) {
new Ext.ToolTip({
target : id,
dismissDelay : 0,
anchor : 'right',
html : msg
});
};
I am trying to add a hidden field for the user registration. The problem is not with the field itself but with its value. I want to parse it a default value. This is my code:
Accounts.ui.config({
requestPermissions: {},
extraSignupFields: [{
fieldName: 'name',
fieldLabel: 'Name',
inputType: 'text',
visible: true,
validate: function(value, errorFunction) {
if (!value) {
errorFunction("Please write your first name");
return false;
} else {
return true;
}
}
},{
fieldName: 'status',
fieldLabel: 'Status',
inputType: 'text',
value: 'somevalue',
visible: false,
}]
});
I want to add the value to the field 'status'.
Actually, I found the answer. The option is the following code in the
server folder:
Accounts.onCreateUser(function(options, user) {
if (options.profile) {
user.profile = options.profile;
}
user.profile.status = "sth";
return user;
});
Looking at the implementation of signup in that package, there is no way to set a default value. The code just creates an object in signup() and grabs whatever existing values from the form that it can.
The code
Ext.onReady(
function() {
Ext.QuickTips.init();
Ext.namespace('TimeTracker');
TimeTracker.dataStore = new Ext.data.JsonStore(
{
root: 'timecardEntries',
url: 'php/scripts/timecardEntry.script.php',
storeId: 'timesheet',
autoLoad: true,
autoSave: true,
writer: new Ext.data.JsonWriter(
{
encode: true
}
),
fields: [
{name: 'id', type: 'integer'},
{name: 'user_id', type: 'integer'},
{name: 'ticket_id', type: 'integer'},
{name: 'description', type: 'string'},
{name: 'start_time', type: 'date', dateFormat: 'Y-m-d H:i:s'},
{name: 'stop_time', type: 'date', dateFormat: 'Y-m-d H:i:s'},
{name: 'client_id', type: 'integer'},
{name: 'is_billable', type: 'integer'}
]
}
);
TimeTracker.timeEntryGrid = new Ext.grid.EditorGridPanel(
{
renderTo: Ext.getBody(),
store: TimeTracker.dataStore,
autoFit: true,
height: 500,
title: 'Timesheet Entries',
tbar: [
{
xtype: 'button',
text: 'Add Record',
iconCls: 'silk-add',
handler: function() {
var timecardEntry = TimeTracker.timeEntryGrid.getStore().recordType;
var tce = new timecardEntry(
{
description: 'New Timesheet Entry',
start_time: new Date().format('m/d/Y H:i:s'),
is_billable: 0
}
)
TimeTracker.timeEntryGrid.stopEditing();
var newRow = TimeTracker.dataStore.getCount();
TimeTracker.dataStore.insert(newRow, tce);
TimeTracker.timeEntryGrid.startEditing(newRow, 0);
}
}
],
view: new Ext.grid.GridView(
{
autoFill: true
}
),
colModel: new Ext.grid.ColumnModel(
{
defaults: {
sortable: true,
editable: true
},
columns: [
{
id: 'ticket_number',
header: 'Ticket #',
dataIndex: 'ticket_number',
editor: new Ext.form.TextField({allowBlank: true}),
renderer: function(value) {
return (!value) ? 'N/A' : value;
}
},
{
id: 'description',
header: 'Description',
dataIndex: 'description',
editor: new Ext.form.TextField({allowBlank: false})
},
{
id: 'start_time',
header: 'Start',
dataIndex: 'start_time',
renderer: Ext.util.Format.dateRenderer('m/d/Y h:i A'),
editor: new Ext.form.DateField({allowBlank: false})
},
{
id: 'stop_time',
header: 'Stop',
dataIndex: 'stop_time',
renderer: Ext.util.Format.dateRenderer('m/d/Y h:i A'),
editor: new Ext.form.DateField({allowBlank: false})
},
{
id: 'client',
header: 'Client',
dataIndex: 'client_id',
renderer: function(value) {
return (!value) ? 'N/A' : value;
}
},
{
id: 'billable',
header: 'Billable',
dataIndex: 'is_billable',
renderer: function(value) {
return (!value) ? 'No' : 'Yes';
}
},
{
id: 'actions',
header: null,
xtype: 'actioncolumn',
items: [
{
icon: 'assets/images/silk_icons/page_copy.png',
iconCls: 'action_icon',
handler: function(grid, rowIndex, columnIndex) {
// THE PROBLEM STARTS HERE
grid.stopEditing();
var newRow = TimeTracker.dataStore.getCount();
recordClone = grid.store.getAt(rowIndex);
recordClone.data.start_time = new Date().format('Y-m-d H:i:s');
grid.store.insert(newRow, recordClone);
grid.startEditing(newRow, 0);
}
},
{
icon: 'assets/images/silk_icons/page_delete.png',
handler: function(grid, rowIndex, columnIndex) {
alert('called');
}
}
]
}
]
}
)
}
);
}
);
The Goal
When the user clicks the 'copy' button, that store record is stored into memory, its 'start_time' is set to the current date and time, and it is re-inserted into the store as a new record
The Current Result
I receive the following JS error: Uncaught TypeError: Cannot read property 'data' of undefined
My Question(s)
For starters, I'm not even sure if I'm grabbing the currently selected row's data record properly. Second, I have no idea what the error message I'm getting means.
Any help is, as always, highly appreciated.
Thanks.
Update 1
After some tweaking, here's what I came up with (this modified code for the copy button handler)
{
id: 'actions',
header: null,
xtype: 'actioncolumn',
items: [
{
icon: 'assets/images/silk_icons/page_copy.png',
iconCls: 'action_icon',
handler: function(grid, rowIndex, columnIndex) {
grid.stopEditing();
var newRow = TimeTracker.dataStore.getCount();
var currentRecord = grid.store.getAt(rowIndex);
var timecardEntry = grid.store.recordType;
tce = new timecardEntry(currentRecord.data);
tce.data.start_time = new Date().format('Y-m-d H:i:s');
grid.store.insert(newRow, tce);
}
},
{
icon: 'assets/images/silk_icons/page_delete.png',
handler: function(grid, rowIndex, columnIndex) {
alert('called');
}
}
]
}
Here's what I'm doing:
Stop editing the grid
Get the number of records currently in the store
Grab the currently selected record and store it in memory
Grab the record type from the store
Make a new instance of the store record type, and pass in the data object from the selected record. The data object is equivalent to the object literal if you were making a new record by hand (see my original 'add button' code for details)
Alter the start_time value of the new object that was created to today's date and time
Insert record into grid
Happy time!
Please critique this code and let me know if there's a better way to do it. Thanks!
Update 2:
handler: function(grid, rowIndex, columnIndex) {
grid.stopEditing();
var recordClone = grid.store.getAt(rowIndex).copy();
Ext.data.Record.id(recordClone);
if(recordClone) {
grid.store.add(recordClone);
}
}
I updated the code to use the copy and add methods and it does work. However, when I call the add() method I get a 'e is undefined error' but when I refresh the page, the record is inserted despite the error message. Ideas?
Looks to me like it's not constructing the tce object correctly. This line is where you should set your breakpoint:
tce = new timecardEntry(currentRecord.data);
It seems like it's successfully constructing a timecardEntry that somehow isn't a proper record. Having a poke at just what it is constructing may help.
If it's not apparent from poking at it that way why it's up the spout, try doing it like this, like #timdev suggests:
var store = grid.store,
currentRecord = store.getAt(rowIndex),
tce;
tce = currentRecord.copy();
tce.set('start_time', new Date().format('Y-m-d H:i:s'));
if (tce) {
store.add(tce);
}
(You should be able to call grid.store.add(tce) instead of insert as you're inserting at the end.)
Really well-written question. Good bit of relevant code, and nice explanation of what you're stuck on. Unfortunately, I don't see anything that stands out.
Your script looks mostly right. You're close to being where you need to be.
Below is an answer that I just typed out, and then reread your question (and code), and thought a little better of. You probably know this stuff already, but it's here for anyone else. It's also relevant, because I don't see any errors in the relevant part of what you did, so you probably blew it somewhere else. The questions are: where and how?
Hopefully someone less exhausted than i am will come along and find the obvious problem, in the meantime, here's my scrawl about how to debug in Ext and why:
You've left something important out, or overlooked it. That error message you mentioned: Uncaught TypeError: Cannot read property 'data' of undefined -- where is that happening? It looks like it's not happening in the code you posted, it might very well be happening down in the bowels of ExtJS.
So, fire up FireBug, and turn on the "break on error" feature. Make your error happen, and start looking at the "stack" pane over on the right (usually). The stack will show you how you got to where you are.
Unless I'm missing something (and since I'm just running your code in my head, I very well may be), there's probably something misconfigured elsewhere that's causing your bug.
But as with any program (and especially with ExtJS, in my experience), the debugger is your friend.
Do this:
Use the -debug version of ext-base.js and ext-all.js (until it all works)
Use firebug, and "break on errors"
Learn to use the debugger to step through code, and to watch the data you're operating on.
Don't give up when you find yourself deep in the bowels of ExtJS. If you try, you'll start to get a sense of WTF is going on, and even if you don't understand it all, it will start to give you hints about where you screwed up.
I've got a script that generates a form panel:
var form = new Ext.FormPanel({
id: 'form-exploit-zombie-' + zombie_ip,
formId: 'form-exploit-zombie-' + zombie_ip,
border: false,
labelWidth: 75,
formBind: true,
defaultType: 'textfield',
url: '/ui/modules/exploit/new',
autoHeight: true,
buttons: [{
text: 'Execute exploit',
handler: function () {
var form = Ext.getCmp('form-exploit-zombie-' + zombie_ip);
form.getForm().submit({
waitMsg: 'Running exploit ...',
success: function () {
Ext.beef.msg('Yeh!', 'Exploit sent to the zombie.')
},
failure: function () {
Ext.beef.msg('Ehhh!', 'An error occured while trying to send the exploit.')
}
});
}
}]
});
that same scripts then retrieves a json file from my server which defines how many input fields that form should contain. The script then adds those fields to the form:
Ext.each(inputs, function(input) {
var input_name;
var input_type = 'TextField';
var input_definition = new Array();
if(typeof input == 'string') {
input_name = input;
var field = new Ext.form.TextField({
id: 'form-zombie-'+zombie_ip+'-field-'+input_name,
fieldLabel: input_name,
name: 'txt_'+input_name,
width: 175,
allowBlank:false
});
form.add(field);
}
else if(typeof input == 'object') {
//input_name = array_key(input);
for(definition in input) {
if(typeof definition == 'string') {
}
}
} else {
return;
}
});
Finally, the form is added to the appropriate panel in my interface:
panel.add(form);
panel.doLayout();
The problem I have is: when I submit the form by clicking on the button, the http request sent to my server does not contain the fields added to the form. In other words, I'm not posting those fields to the server.
Anyone knows why and how I could fix that?
Your problem is here:
id: 'form-exploit-zombie-'+zombie_ip,
formId: 'form-exploit-zombie-'+zombie_ip,
what you are doing is that you are setting the id attribute of the form panel and the id attribute of the form (form tag) to the same value. Which means that you have two elements with the same id and that is wrong.
Just remove this line
formId: 'form-exploit-zombie-'+zombie_ip,
and you should be fine.
Did you check the HTTP Request parameter for the form values?
If you server side is in PHP, what do you get from response by passing any field name? For example, if one of your input name was "xyz" what do you get by
$_POST[ 'txt_xyz' ]