This is a really strange problem I'm having with an app in Backbone.js. I have different search results which are displayed in an accordion, only one result can be selected at a time.
The model for each result has an attribute, "selected" which represents whether the result is selected or not.
For some reason I'm not able to deselect the match. This is the code that's run on clicks on the result.
I've been looking through it, selected always returns false, and somehow, never gets set to true in this function.
click_header: function (e) {
e.stopPropagation();
var s = this.model.get("selected");
if (s == true) {
this.model.set({ selected: false, expanded:false});
} else {
this.model.set("selected", true, { silent: true });
this.model.set("expanded", true, { silent: true });
}
}
EDIT:
I fixed the problem. A function elsewhere in the program triggered by changes to select was setting select to false on all models.
I fixed the problem. A function elsewhere in the program triggered by changes to select was setting select to false on all models.
Updated Here is a more streamlined approach:
click_header: function (e) {
e.stopPropagation();
var s = this.model.get("selected");
this.model.set({ selected: !s, expanded: !s}, { silent: !s });
}
Related
I have a combo box and I want to throw a message with a fallback logic, in case he selects something, he should get a warning, if he presses okay it executes the logic, if he does not it should be canceled.
<ComboBox id="id1" change="onChange">
<core:Item id="id2" text="A"></core:Item>
<core:Item id="id3" text="B"></core:Item>
<core:Item id="id4" text="C"></core:Item>
</ComboBox>
then I have my messagebox in the onChange function:
onChange: function (oEvent) {
sap.m.MessageBox.show("Are you sure you want to do that?", {
icon: sap.m.MessageBox.Icon.Information,
title: "Info",
actions: [sap.m.MessageBox.Action.YES, sap.m.MessageBox.Action.NO],
defaultAction: sap.m.MessageBox.Action.NO,
onClose: function (sButton) {
if (sButton === sap.m.MessageBox.Action.YES) {
//execute my logic in here => that works
} else {
oEvent.stopPropagation(); //I tried this but this does not work
}
}
});
}
how can I achieve that?
In other words, all I would actually need is to know what the predecessor selection of that combobox was.
I did not find out how to get that out of the oEvent.
the approach is correct (the dialog inside the onChange) but you need some changes.
When SAPUI5 call the onChange method the value is already written inside your control so the oEvent.stopPropagation(); is doing nothing at all.
What you could do is to use the ComboBox method setSelectedItem(null) that should reset the current selection (reverting the user choice).
UPDATE: I've updated the code in order to solve your request.
__selectedItem: null,
onChange: function (oEvent) {
var that = this;
var source = oEvent.getSource();
var selectedItem = oEvent.getSource().getSelectedItem();
MessageBox.show("Are you sure you want to do that?", {
icon: MessageBox.Icon.Information,
title: "Info",
actions: [MessageBox.Action.YES, MessageBox.Action.NO],
defaultAction: MessageBox.Action.NO,
onClose: function (sButton) {
if (sButton === MessageBox.Action.YES) {
//execute my logic in here => that works
that.__selectedItem = selectedItem;
} else {
source.setSelectedItem( that.__selectedItem );
}
}
});
}
Looking at the SAP code on GitHub in InputBase.js, the new value is already written into the property when the event you attach to is fired. My proposal would be saving the selected value in a class variable inside your controller and reverting to this value once the user cancels to achieve your goal.
I decided to go for the following solution, thanks anyway for all the other approaches
onChange: function (oEvent) {
var source = oEvent.getSource();
MessageBox.show("Are you sure you want to do that?", {
icon: MessageBox.Icon.Information,
title: "Info",
actions: [MessageBox.Action.YES, MessageBox.Action.NO],
defaultAction: MessageBox.Action.NO,
onClose: function (sButton) {
if (sButton === MessageBox.Action.YES) {
//execute my logic in here => that works
} else {
var oldSelection = oModel.getProperty(oSource.getBindingContext().getPath() + "/PropertyPath");
switch (oldSelection) {
case "A":
oSource.setSelectedItem(oSource.getItems()[0], true, true);
break;
case "B":
oSource.setSelectedItem(oSource.getItems()[1], true, true);
break;
case "C":
oSource.setSelectedItem(oSource.getItems()[3], true, true);
break;
}
}
}
});
}
I am using ExtJS 2.3. I have 3 comboboxes with following stores.
Here, combo2 and combo3 share same store.
Following are the combo stores-
Combo1 Store:
Vice President
Manager
Employee
Student
Combo2 and Combo3 Store:
Assignments
Meetings
Salary
Now my requirement is, if 'Student' is selected from Combo1, 'Salary' should be filtered out from combo2 and 3 (It should not display 'Salary' option)
I am doing following code on change listener of combo1-
listeners: {
change: function(combo, record, index) {
var combo1Val = combo.value; // Give the selected value correctly
this.filterCombo(combo1Val , combo2);
this.filterCombo(combo1Val , combo3);
}
}
and this is function body
filterCombo: function (combo1Val , combo) {
if (combo1Val == 'Student') {
combo.store.filterBy(function (record) {
return record.get('text') != 'Salary';
});
}
else {
combo.store.clearFilter();
}
}
The problem here is for first time when I select Student from combo1, 'Salary' option disappears from combo2. Then, when I expand combo3, it displays salary option there, and again whwn I click on combo2, again it displays 'salary' option. somehow this filter is not working.
Can anybody tell what I am doing wrong here.
you can try this in combo2
listeners: {
expand: function(combo) {
combo.store.clearFilter();
if (combo1Val == 'Student') {
//filter
}
}
}
Though the answer provided by raghavendra is correct and works well but in the scenario if there are many combos(more than two) that need to be filtered, we have to write expand listener for each combo.
So thought of writing the code in one place that is in combo1 change event.
The problem was somehow after entering the function it was going into else statement i.e. combo.store.clearFilter(); so clearing out the filter.
I have solved my problem by checking the condition in combo1 change event itself instead of inside the function for each combo.
listeners: {
change: function(combo, record, index) {
var combo1Val = combo.value; // Give the selected value correctly
if (combo1Val == 'Student') {
this.filterCombo(combo1Val , combo2);
this.filterCombo(combo1Val , combo3);
}
else {
combo2.store.clearFilter();
combo3.store.clearFilter();
}
}
}
filterCombo: function (combo1Val , combo) {
combo.store.filterBy(function (record) {
return record.get('text') != 'Salary';
});
}
If the user presses the down key while a custom popup is displayed, I would like this down event to be cancelled from the editor and handled manually.
However, if the popup is disactivated, the 'down' key should perform as usual.
For that, I wrote this:
editor.commands.addCommand({
name: 'nav_down.',
bindKey: {win: 'Down', mac: 'Down'},
exec: function(editor) {
if(myPopupIsOpen()) {
// Do whatever I want with the popup.
return false;
} else {
// just leave the key.
return true;
}
readOnly: true
});
Unfortunately, I can return false or true, the result is the same, it always capture the down event, which is annoying. How can I prevent that?
I already tried the following:
Add a key binding to the DOM. But after that, the interaction always happen (i.e. I cannot capture it).
Return false or true as suggested for common events but this does not work here.
EDIT
The solution from #a user works very well.
Instead of the above command, I wrote:
var HashHandler = require("ace/keyboard/hash_handler").HashHandler;
keyboardHandler = new HashHandler();
keyboardHandler.addCommand({
name: 'nav_down.',
bindKey: {win: 'Down', mac: 'Down'},
exec: function(editor) {
if(myPopupIsOpen()) {
// Do whatever I want with the popup.
return true; // CHANGE HERE ! true is when it capture it.
} else {
// just leave the key.
return false; // CHANGE HERE ! false is when I don't capture it.
}
readOnly: true
});
editor.keyBinding.addKeyboardHandler(keyboardHandler);
In the current version ace only keeps one command for each key so your addCommand call removes default binding for down.
You can add new keyboard handler similar to what autocompletion does https://github.com/ajaxorg/ace/blob/v1.1.3/lib/ace/autocomplete.js#L221
var HashHandler = require("ace/keyboard/hash_handler").HashHandler;
keyboardHandler = new HashHandler();
keyboardHandler.addCommand(/*add your command with return false*/)
editor.keyBinding.addKeyboardHandler(keyboardHandler);
I am developing a firefox extension with the Mozilla SDK. The situation is:
I want a toggle/action button to show/hide the extension's panel.
My code:
// the panel
let panel = require("sdk/panel").Panel({
// ...
onHide: handleHide
});
// the button
let button = ToggleButton({
// ...
// will be executed, when user clicks the button
onChange: handleChange
});
// event handlers
function handleChange(state) {
// state.checked is always true
if (???) {
panel.show();
}
}
function handleHide() {
// un-check the button
button.state('window', {checked: false});
}
The problem is, that inside of handleChange, where the toggling logic should be, i can't tell if the panel is supposed to show or hide. In the docs theres an example which uses state.checked, but since this code is run while i am clicking on the button, the state.checked is always true. In the end, the toggling does not work this way, because the panel never gets hidden when clicking the "toggle"-button.
help much appreaciated, i already tried so many things.. mothings works.
thanks in advance!
simply use console.log to see what's inside the state:
{
"disabled": false,
"checked": false,
"label": "the default label",
"icon": "./icon.png",
"id": "show-panel"
}
so we can go on like this:
if(state.checked)
{
myExt.show();
return false;
} else {
myExt.hide();
return false;
}
in older versions you need to return false.
I'm try to return grid data based on the parameter I send, I added new button to my grid :
jq("#grid").navButtonAdd('#pager',
{ caption:"Get Only The Latest Data(Ignores old)",
buttonicon:"ui-icon-plus",
onClickButton: setUniqueValue,
position: "last",
title:"",
cursor: "pointer"
}
);
I have hidden element span with the value false at the initial grid/page load, and I set it to true when this above button is clicked :
function setUniqueValue(){
jq("#unique").text("true");
jq("#grid").trigger("reloadGrid");
}
So I'm sending this value to the server trough postData: {latest : jq("#unique").text()},
But this has always the same initial value false, I mean this has to be possible? Because that is how the search works, its false at the begining then when you click on the query submit its set to true or something like that, anybody knows how to do this?
I can't follow what you exactly want to do, but you should change the definition of latest property of postData to the following:
postData: { latest: function() { return jq("#unique").text(); } }