how to set isDirty() value dynamically in Ext Js
I have form panel which contains textbox, radio buttons and save button. In afterrender function i am setting a value to textbox . after loading the page the isDirty() is returning true, but my requirement is when I click on update button only it should return true.
how I can achieve this.
I tried with trackResetOnLoad= true but its not working.
Fiddle example is
https://fiddle.sencha.com/#fiddle/1d74
Update:-
I need track Change or update after Afterrender function.
You can achieve the same functionality by giving value config to textfield rather than setting anything in afterrender. When you run the below code , you will not get true in isDirty button when you first click it.
Ext.onReady(function() {
var form = new Ext.form.Panel({
itemId:'panelFormID',
trackResetOnLoad: true,
renderTo: Ext.getBody(),
items: [{
xtype: 'textfield'
,name: 'username'
,itemId : 'username'
,fieldLabel: 'username'
, value:'stackoverflow'
},{
xtype: 'textfield'
,name: 'password'
,itemId : 'password'
,fieldLabel: 'password'
}, {
xtype: 'button',
text : 'isDirty' ,handler: function() {
alert(Ext.ComponentQuery.query('#panelFormID')[0].isDirty());
}},
{
xtype: 'button',
text : 'Update' ,
handler: function() {
Ext.ComponentQuery.query('#username')[0].setValue ('resetvalue');
Ext.ComponentQuery.query('#password')[0].setValue ('restpassword');
}
}]
}
})
;
});
You can use form component's setValues method for this purpose. This couldn't change your dirty status while your form's trackResetOnLoad property is true.
In your case you can do it like that;
Ext.ComponentQuery.query('#panelFormID')[0].up('form').getForm().setValues({
username : 'reset value',
password : 'resetpassword'
});
These object properties related with your component's name property. When you miss some field's value it gonna set as empty. so you have to get all of it's value and change your wishes and set again.
Use the below code in your afterrender listener:
var items = Ext.ComponentQuery.query('#panelFormID') [0].getForm().getFields().items,
i = 0,
len = items.length;
for(; i < len; i++) {
var c = items[i];
if(c.mixins && c.mixins.field && typeof c.mixins.field['initValue'] == 'function') {
c.mixins.field.initValue.apply(c);
c.wasDirty = false;
}
}
isDirty() depends upon originalValue of respective component.In afterrender as you set value to field, you also need to set originalValue field.I have added this line in afterrender code:
afterrender :function () {
Ext.ComponentQuery.query('#username')[0].setValue ('stackoverflow');
//new line
Ext.ComponentQuery.query('#username')[0].originalValue='stackoverflow'
Ext.ComponentQuery.query('#panelFormID')[0].trackResetOnLoad = true;
}
Please try using this after setting values (in afterrender function):
Ext.ComponentQuery.query('#panelFormID')[0].form.setValues(Ext.ComponentQuery.query('#panelFormID')[0].form.getValues())
Related
I'm trying to implement a select that calls a function even if the same option is selected twice. Following one of the answers on this thread, I've set the selectedIndex to -1 on focus. However, I'm still not getting the function call when the same option is selected twice.
var scaleSelect = new ComboBox({
id: "scale_select",
style: {width: "150px"},
name: "scale_select",
placeHolder: "Choisir une échelle",
store: scaleStore,
disabled: true,
onFocus: function() {
this.selectedIndex = -1;
console.log(this.selectedIndex); //-1
},
onChange: function(value){
mapScale = value;
window.myMap.setScale(mapScale);
}
}, "scale_select");
scaleSelect.startup();
UPDATE Attempting to set the selected index within onChange still doesn't call the function--wondering if this has to do with the fact that selected index is undefined onChange..
var scaleSelect = new ComboBox({
id: "scale_select",
style: {width: "150px"},
name: "scale_select",
placeHolder: "Choisir une échelle",
store: scaleStore,
disabled: true,
onChange: function(value){
mapScale = value;
window.myMap.setScale(mapScale);
var mySelect = document.getElementById("scale_select");
console.log(this.selectedIndex) //undefined
this.selectedIndex = -1;
mySelect.selectedIndex = -1;
console.log(this.selectedIndex); //-1
console.log(mySelect.selectedIndex); //-1
}
}, "scale_select");
scaleSelect.startup();
I tested every things that i knew with no success. I wondering about the thread that you linked and answers with upvotes! I the reason is that a selected option is not an option any more. But i have a suggestion:
Create your own custom Select
It is only a textbox and a div under that with some links line by line.
So I think the problem is that after you've picked a value in the select, it doesn't lose focus. So your onFocus handler won't get called unless the user actually clicks somewhere else on the page. If she doesn't do that, then the select's value won't fire the onChange if she selects the same value again.
So instead of setting the selected index on focus, why not do it in onChange, after you've handled the change? That way your select will be primed for another selection as soon as you're done treating the current one.
UPDATE
Ok, so looking at the Dojo code, this is the best I could come up with:
var scaleSelect = new ComboBox({
id: "scale_select",
style: {width: "150px"},
name: "scale_select",
placeHolder: "Choisir une échelle",
store: scaleStore,
disabled: true,
onChange: function(value){
if(value) { // the .reset() call below will fire the onChange handler again, but this time with a null value
mapScale = value;
window.myMap.setScale(mapScale);
console.log("Changed to", value, this);
this.reset(); // This is the magic here: reset so you are guaranteed to isseu an "onChange" the next time the user picks something
}
}
}, "scale_select");
scaleSelect.startup();
Note that you need to start the whole thing with no value - or else that initial value won't issue an "onChange" event, and every time you reset the widget, it'll go back to the initial value...
Hope this helps!
I'd created SelectOne component extending TriggerField, setted onTriggerClick to open new Window with Grid there on OK or dblclick mast set triggerfield value like this:
val = {
id: "1234",
text: "Selected value"
}
My problem is, how to return id on getValue() or form submit and text to input field of triggerfield
One way to achieve what you want is to override the rawToValue and getSubmitValue methods of your CustomTrigger and add a custom value to hold the selected information from your grid.
You would define your trigger like this:
Ext.define('Ext.ux.CustomTrigger', {
extend: 'Ext.form.field.Trigger',
alias: 'widget.customtrigger',
config : {
option : null
},
// override rawToValue method
rawToValue: function() {
return this.getOption();
},
// override getSubmitValue method
getSubmitValue : function () {
return this.getOption()
}
// override onTriggerClick
onTriggerClick: function() {
....
}
}
On your grid, the ok button and itemdblclick handlers should use the triggerfield.setOption() method to hold the selected value and use triggerfield.setValue('Selected Value') so your trigger field reads "Selected Value".
Now, when you call triggerfield.getValue() you will get the same value as triggerfield.getOption() but it will display "Selected value"
I created this fiddle: https://fiddle.sencha.com/#fiddle/c1c so you could understand this a little better.
I'm having an issue with a data-bind updating through a custom event that's called when a select element is changed. The idea is that the select element changes which updates the datatype parameter. Then the change event kicks in which updates sliderType which is a boolean and changes to true if a specific value is selected. That all works fine, however the div -data-bind="if: sliderType- does not update on a change, but it works on the page load.
Is there some way to force the page to recheck bindings?
Here is a fragment of the code to give you an idea of my structure.
HTML
<select data-bind="options: Items, optionsText: 'type', value: dataType, optionsCaption: 'Choose Data Item...', event: { change: dataTypeChange }"></select>
<div data-bind="if: sliderType">Here is a message. Astonishing.</div>
JavaScript
dataTypeChange: function() {this.sliderType = (this.dataType._latestValue.id == 6) ? true : false;
ko.observable being used:
{
dataItemId: -1,
name: ko.observable(res.Text),
dataType: ko.observable(res.DataType),
dataTypeChange: function() {
this.sliderType = (this.dataType._latestValue.id == 6) ? true : false;
},
sliderType: sliderActive
}
Stupid mistake on my part, it would help if the data-bind object was an observable
{
dataItemId: -1,
name: ko.observable(res.Text),
dataType: ko.observable(res.DataType),
dataTypeChange: function() {
this.sliderType = (this.dataType._latestValue.id == 6) ? true : false;
},
sliderType: ko.observable(sliderActive)
}
Here's my DataGrid:
// $ is a reference to `this` as it lies in an anonymous function
$.grid = new DataGrid({
store : $.dataStore,
query : {id : "*"},
structure : [
{
noscroll : true,
cells : [{ name : "Recipe", field : 'name', width : '200px' }],
},
{
cells : [
[
{ name : 'ID#', field : 'id', width : '50px'},
{ name : 'Category', field : 'category', width : '100px'},
{ name : 'Status', field : 'status', width : '100px'},
{ name: "Actions", width : '200px', type: dojox.grid.cells._Widget, formatter : $._actionButtons}
]
] // end cells
}
]
}, $.targetNode)
$.grid.startup();
$.grid.on("RowClick", function(e){
console.log(this.getItem(e.rowIndex))
})
And my formatter object for the Actions cell:
_actionButtons : function(){
var _self = this;
var _args = arguments;
this.group = new Pane()
var full = new Button({
label: 'View Full',
style : { fontSize : '80%'},
onClick : function(){
try {
_self.grid.onRowClick.apply(this, arguments)
}catch(e){}
}
});
full._destroyOnRemove = true;
var edit = new Button({
label : 'Edit',
style : {fontSize: '80%'}
});
edit._destroyOnRemove = true;
construct.place(full.domNode, this.group.containerNode)
construct.place(edit.domNode, this.group.containerNode)
return this.group;
}
I'm trying to get access to the event object that would be passed by a normal onRowClick event on the DataGrid. As it sits now this kinda works, but on the on("RowClick"...) block I get multiple logs. Without the try...catch block I get an error as the rowIndex doesn't exist in e, then 2 more logs where it does exist.
This is the 4th or so idea I've had included pub/sub, emit(), etc. I have a feeling that the multiple logs are caused by the bubbling behavior (Button -> Row -> DataGrid or somesuch), but getting the onRowClick's event object to get passed into the Buttons created in the formatter seems impossible.
I just want to access the rowIndex (and other DataGrid-esque properties) from the Button widget's onClick event to process according to the button pressed.
Along the same lines, but here's what I came up with that seems to be working in a direction where what I'm envisioning will happen. Adjusted cell where the buttons will be:
{ name: "Actions", width : '200px', type: dojox.grid.cells._Widget, formatter :
function(){
return $._actionButtons.call($, arguments);
}
}
Adjusted onClick function in the returned Button widget:
_actionButtons : function(){
var _index = arguments[0][1],
_item = this.grid.getItem(_index)
_self = this;
// some code removed
onClick : function(){
console.log(_self.dataStore.getValue(_item, 'name'), "clicked")
}
}
I'll probably end up extending Button to handle this a bit better, but for now, voila!
Sometimes it just helps to write it down and put it out there for your brain to panic and figure out the solution before anyone else does :)
Minor update...
There is the formatterScope parameter for the DataGrid, but it applies to all formatter's and would therefore mess up anything requiring cell scope and not DataGrid scope. The above method allows me to access everything I need.
I have:
dockedItems: [{
xtype: 'toolbar',
store: 'RecordsListStore',
selModel: {
selType: 'cellmodel'
},
and a couple of icons like this:
},{
icon: g_settings.iconUrl + 'view-icon.png',
text: 'View',
itemId: 'view-selected-record-from-grid',
scope: this
},{
This is in my view, and in my controller I have a function which is triggered like this:
'#view-selected-record-from-grid' : {
click: this.onViewRecordClick
}
The problem is that I want to show an alert msg. if the user clicks the button when nothing is selected. In my function I get the info for the selected item (if there is any) like so:
onViewRecordClick: function() {
/**
*Getting the id of the record from the selected row
*/
var id = this.getRecordsListGrid().getSelectionModel().getCurrentPosition().row;
var rec = Ext.data.StoreManager.lookup('RecordsListStore').getAt(id);
rec = rec.data.id;
and after that I call my Ajax request, so between those two parts I want to check the values and if they are undefined (the icon is clicked without selection) to alert the user for this. However if I just try this:
if(id == undefined) { alert('No selection');}
and click the icon when nothing is selected I don't get the alert message but instead get an error in the console that
this.getRecordsListGrid().getSelectionModel().getCurrentPosition().row; is undefined
and that's all. I try some things to bypass this issues because as it seems, the functions stops the time it sees an undefined variable, but still can't find an working solution.
Thanks
Leron
Check if getCurrentPosition() returns undefined.