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.
Related
So I have the following select2:
productFamilySelect.select2({
tags: true
});
By default the name of the associated select element is product_family_id, so is there a way to change the name of the input to lets say product_family_name, if selected value if one that user entered? This is so, that I could in the backend for sure distinguish between an already existing value, and one that user thought of. Checking by id in the database does not really suit, as this value could actually be numeric in on itself.
After some digging into select2 custom events I found a way:
firstly add createTag callback like so:
productFamilySelect.select2({
tags: true,
createTag: function (params) {
var term = $.trim(params.term);
if (term === '') {
return null;
}
return {
id: term,
text: term,
newTag: true
}
}
});
Then, add the following listener:
productFamilySelect.on('select2:select', function (e) {
if (e.params.data.newTag === true) {
$(this).attr('name', 'product_family_name');
} else {
$(this).attr('name', 'product_family_id');
}
});
Seems a bit hacky, since it is outside the config of the actual select2 config, but well it dos the job :)
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())
I have set up the following select for changing semesters on page. When the select detects a change, the changeSemesters function is fired, which runs an AJAX that replaces the current data on the page with data specific to the selected semester.
View
<select data-bind="options: semestersArr, optionsText: 'name', optionsValue: 'id', value: selectedSemester, event: { change: changeSemesters }"></select>
ViewModel
this.selectedSemester = ko.observable();
//runs on page load
var getSemesters = function() {
var self = this, current;
return $.get('api/semesters', function(data) {
self.semestersArr(ko.utils.arrayMap(data.semesters, function(semester) {
if (semester.current) current = semester.id;
return new Model.Semester(semester);
}));
self.selectedSemester(current);
});
};
var changeSemesters = function() {
// run ajax to get new data
};
The problem is that the change event in the select fires the changeSemester function when the page loads and sets the default value. Is there a way to avoid that without the use of a button?
Generally what you want to do in these scenarios is to use a manual subscription, so that you can react to the observable changing rather than the change event. Observables will only notify when their value actually changes.
So, you would do:
this.selectedSemester.subscribe(changeSemesters, this);
If selectedSemester is still changing as a result of getting bound, then you can initialize it to the default value.
this.selectedSemester = ko.observable(someDefaultValue);
I have a select control bound to a Knockout observable array:
<select data-bind="event: { change: selectedProductOfferingChange }, options: $parent.productTypes, optionsText: 'text', optionsCaption: '-- Select --', value: selectedProductType, enable: !isReadOnly()"></select>
When the selection is changed, I want to run some code, perhaps make an AJAX call. If the change is not allowed, I want to cancel the change and display a modal dialog. I can't subscribe to the property as that will fire after the change has taken place. I would need the new value to determine if the change should be cancelled or not.
I tried the following in the viewmodel but the change is not cancelled though the property (selectedProductOffering) on the viewmodel is not updated:
self.selectedProductOfferingChange = function (data, event) {
event.stopImmediatePropagation();
return false;
};
Could I use the "beforeChange" option with subscribe?
self.selectedProductType.subscribe(function (previous) {
}, self, "beforeChange");
Can the change be cancelled here?
After some thought, here's what I came up with:
self.selectedProductOfferingChange = function (data, e) {
// Do any checking here
if (confirm("OK to make this change ?")) { return; }
// This stops the viewmodel property from being updated
e.stopImmediatePropagation();
// Since the viewmodel property hasn't changed, force the view to update
self.selectedProductType.valueHasMutated();
};
The problem with this code is that it doesn't give you access to the new value. A computed will solve this issue:
<select data-bind="options: $parent.productTypes, optionsText: 'text', optionsCaption: '-- Select --', value: computedSelectedProductType, enable: !isReadOnly()"></select>
self.computedSelectedProductType = ko.computed({
read: function () {
return self.selectedProductType();
},
write: function (value) {
// Do any checks here. If you want to revert to the previous
// value, don't call the following but do call:
// self.selectedProductType.valueHasMutated()
self.selectedProductType(value);
},
owner: self
});
I have a checkbox that I would like to trigger a simple 'select all' functionality. The problem is that I can't figure out how to connect the checkbox's action to an action in my controller so that I can actually update the records.
App.LanguagesController = Ember.ArrayController.extend({
actions: {
toggleAllVisibility: function() {
var newVisibility = !this.get('allAreVisible');
var needingVisibilityChange = this.filterBy('visible', !newVisibility);
needingVisibilityChange.setEach('visible', newVisibility);
}
},
allAreVisible: function(param) {
return this.filterBy('visible', false).get('length') === 0;
}.property('#each.visible'),
});
In my template, I have the following input helper
{{input type='checkbox' checked=allAreVisible}}
This properly updates the checkbox when I change the elements manually (i.e. if all of them are selected, then checkbox updates), but no actions fire when I toggle the checkbox.
It looks like in older versions of Ember.js I could simply add an action parameter to the input helper but that doesn't work anymore. I'm assuming I need to setup something that observes when the computed property attempts to change, but I couldn't find anything in the docs or other help.
I also tried extending checkbox to send the click event:
App.AllLanguagesCheckbox = Ember.Checkbox.extend(Ember.ViewTargetActionSupport, {
click: function() {
this.triggerAction({
action: 'toggleAllVisibility'
});
}
});
And then loaded that in my template with
{{view App.AllLanguagesCheckbox checkedBinding=allAreVisible}}
That allows the checkbox to trigger the action, but does not update based on the computed property in the controller.
I feel like I'm missing something obvious here.
EDIT
Based on kingpin2k's answer below, here's the working controller code:
App.LanguagesController = Ember.ArrayController.extend({
toggleAllVisibility: function() {
var newVisibility = !this.get('controller').get('allAreVisible');
var needingVisibilityChange = this.get('controller').filterBy('visible', !newVisibility);
needingVisibilityChange.setEach('visible', newVisibility);
},
allAreVisible: function(param) {
return this.filterBy('visible', false).get('length') === 0;
}.property('#each.visible'),
});
It's not called with the normal scope so you have to explicitly go through the controller to get the model array, but it works as expected now.
Here's the accompanying input helper:
{{input type='checkbox' checked=allAreVisible change=toggleAllVisibility}}
The problem is your checkbox is connected to a computed property, the computation should derive the value (aka you shouldn't be setting it), which is what would be happening when someone tries to check.
_allAreVisible:false,
allAreVisible: function(param) {
if(this.filterBy('visible', false).get('length') === 0){
// set to true;
// else set to false
}.observes('#each.visible'),
http://emberjs.jsbin.com/abODIKoj/1/edit