SearchField in SAP UI5 does not render suggestions when "X" is clicked - sapui5

I have implemented a SearchField. When I click on the "X" button, the value gets cleared. Cursor is blinking in the field, but the suggestions do not populate. If I click again in search field still do not populate.
I have to click somewhere else on the page and then again click in the search field again to ensure suggestions populate. How to handle the "X" ?
View.xml
<SearchField class="" suggestionItems="{path:'model>/names'}" id="names"
value="{model>/header/names}" suggest="onSuggest" enableSuggestions="true" width="90%">
<suggestionItems>
<SuggestionItem key="{model>UserId}" text="{order>LastName} , {order>FirstName}"/>
</suggestionItems>
</SearchField>
Controller.js
onSuggest: function (oEvent) {
var value = oEvent.getParameter("suggestValue");
this.oSF = this.getView().byId("name");
this.oSF.getBinding("suggestionItems")
this.oSF.suggest();

Have tried this attachEventOnce('dataReceived') solution?
BTW: using
this.oSF = oEvent.getSource()
instead of
this.oSF = this.getView().byId("name");
will keep you out of trouble with typos (names <=> name) ;-)

Related

React bootstrap typeahead clearButton icon (X) does not appear for a single selection

I have tried selecting clearButton prop for a single selection input. However it does not work as expected. The clear (x) icon does not appear with a default selected input. It appears only once there is an event change, that is if I select some other input. My problem is that removing the input manually does not trigger a change in the selected value. Any pointers would be appreciated.
<Typeahead
clearButton
defaultInputValue={props.city}
options={props.cityOptions}
onChange={(selected) => handleCityFieldChange(selected[0], props)}
placeholder="Choose a city"
/>
Here's the handleCityFieldChange function:
handleCityFieldChange = (selected, props) => {
const newFieldValues = Object.assign({}, props.fieldValues, {"city": selected});
props.onChange(newFieldValues);
};
Use defaultSelected, not defaultInputValue:
<Typeahead
clearButton
defaultSelected={props.city}
options={props.cityOptions}
onChange={(selected) => handleCityFieldChange(selected[0], props)}
placeholder="Choose a city"
/>
The clear button only appears when there is a selection. defaultInputValue sets the value of the input, without actually selecting an option, which is why you weren't seeing the button.
Note: defaultSelected expects an array, so if props.city is an object, you'll need to pass [props.city].

How can I write some javascript to click this "continue" button?

<span id="continue" class="a-button a-button-span12 a-button-primary"><span class="a-button-inner"><input id="continue" tabindex="5" class="a-button-input" type="submit" aria-labelledby="continue-announce"><span id="continue-announce" class="a-button-text" aria-hidden="true">
Continue
</span></span></span>
Above the the HTML from part of a page, which has a 'Continue' button that i'm trying to click, using my script.
So, writing in Javascript, i'm trying to click this button. But nothing I have tried works.
My attempted answer is:
function() {
var goButton = document.getElementById("continue");
goButton.click();},
Why doesn't it work? Help me, please !
You have set the ID of both the span and the input field to "continue". ID's should be unique for a single element. When I enter your code in the browser's console it returns the following:
> var goButton = document.getElementById("continue");
< undefined
> goButton.valueOf()
< <span id="continue" class="a-button a-button-span12 a-button-primary">
You can see the span is the element being selected instead of the input submit button. You should rename either of the 2 elements so both have a unique ID and use that in your script.
Edit: OP mentioned the HTML can not be changed so instead of fixing the use of a not-unique ID this Javascript can be used:
function() {
var continueSpan = document.getElementById("continue");
var goButton = continueSpan.firstElementChild.firstElementChild;
goButton.click();}

Combobox in sap.ui.table.Table

I want to set values in a Combobox in the table: It does not show me the values ? Here is the code:
View:
<Column width="10rem">
<m:Label text="{i18n>Status}" />
<template>
<m:ComboBox items="{items>/Status}"
templateShareable="true">
<m:items>
<core:Item text="{Name}" />
</m:items>
</m:ComboBox>
</template>
</Column>
Controller: This is the parameterset.
success : function(oData, oResponse) {
// create JSON model
var oODataJSONModel = new sap.ui.model.json.JSONModel();
var child1 = [];
child1.push({Name:"S"});
child1.push({Name:"E"});
oData.Status = child1;
oODataJSONModel.setData(oData);
oView.setModel(oODataJSONModel, "items");
Thanks for helping!
You're missing alias for model in property binding of Item.
<core:Item text="{items>Name}" />
If you want to read the value of the combobox when it changes you can do the following. First in the XML, set the property selectionChange="nameOfYourFunction" in the combobox element. Whenever the user clicks on a different item, nameOfYourFunction() will execute. Here in this function you can check for the value.
nameOfYourFunction : function(){
//Do whatever you want to do here when user changes value of combo
this.getView().byId("combobox_id_here").getValue(); // returns text inside combobox
}
You might have to play around with the function and see when exactly it gets called. I have done a little with it and sometimes it gets called twice. I think once when the Combobox's text is a value in the list and then it gets called again when you leave focus of the combobox. Getting called twice probably won't affect your code though, depends on what you do in your function.

How do I know when the user has selected all rows in a sap.m.Table

I am using a sap.m.Table which is bound to an OData model. I have set growing="true" and growingScrollToLoad="true". This way the UI only fetches 20 rows at a time as the user scrolls down. I am also using the table in multi selection mode, so the user can select some (or all rows using the "select all" checkbox). All this is working as expected.
I am now adding an export to Excel functionality, and I see that when the user selects the "select all" checkbox, only the rows that are on the client are selected. So for example, if the user doesnt scroll after the data is fetched, only the first 20 rows are selected even if there are a hundred records in the back end. My plan is to get all data from the backend and export it to a spreadsheet if the "select all" is checked, if not just export the selected rows. Question is how do I know when the select all is checked? I havent found an API that gives me this information. Is there a better way of achieving this? I would love to hear your thoughts.
Thanks.
You can add a selection event listener on your table:
<Table selectionChange=".onSelectionChange">
The parameter selectAll will be true if the header checkbox is checked, undefined otherwise.
onSelectionChanged: function(event) {
var selectAll = event.getParamerter("selectAll") === true;
}
You can define combobox in the xml:
<ComboBox id="comboBoxSelectAll">
<core:Item id="sellectAll" text="Select all" key="All" />
<core:Item id="sellectNotAll" text="Select not all" key="notAll" />
</ComboBox>
You can register combo box event handler in the controller:
var comboBoxSelectAll = this.getView().byId("comboBoxSelectAll");
comboBoxPerc.attachSelectionChange(this.comboBoxSelectAllchanged, this);
And handle event in the controller:
comboBoxSelectAllchanged: function(oEvent){
var key = oEvent.getParameters().selectedItem.getKey();
if (key === "selectAll"){
//save all data
}
else{
//save just loaded data
}
}
I hope this is what you are looking for, if not feel free to ask.
EDITED 10:10 130117:
Sorry now I see you are using Check Box, so in the xml:
<VBox>
<CheckBox id="checkBoxAll" text="Select all"/>
</VBox>
And in the function where you save data you use Check Box method getSelected:
var oCheckBoxAll = this.getView().byId("checkBoxAll");
var bIsSelected = oCheckBoxAll.getSelected();
if(bIsSelected === true){
//save all data
}
EDITED 10:14 130117:
Here is working example in jsbin.
The selectionChange event fired by the table has a listItems parameter. If the length is more than 1, then the select all button was pressed. To determine whether all rows were selected or deselected, you can check the selected parameter of the same event.
onSelectionChanged: function(oEvent) {
//this will return true if more than 1 item was selected
var bSelectAll = oEvent.getParameter("listItems").length > 1
//this will return true if the rows were selected, false if they were deselected
var bSelected = oEvent.getParameter("selected");
if (bSelectAll && bSelected) {
//make a call to the backend to get all data
}
}
You can also check the number of selected items vs the number of items in the table. oTable.getItems().length will indicate how many items are currently in the table. Comparing the number of items in the table vs the number of selected items, will tell you if all are selected.
var bAll = oTable.getSelectedItems().length === oTable.getItems().length;
For further validation, you can use the $count function of your oData service to find the total number of items in the backend, and then compare that with your table data.
var total;
oModel.read("/EntitySet/$count", {
success: function(response) {
total = response;
}
}
The table also has a growingFinished event you can use to determine if all rows have been retrieved from the backend or not.

Angular -- data-binding for a form that grows

I'm trying to create a form with data-binding that the user can add items to; they can click a button to add another text field (in this example it's the "plus" button). Here's a screenshot:
I've got things working now so more list items appear when the user clicks the button, but I can't find a clean and simple solution for how to let each form-element bind to a separate instruction in the model (theoretically in some sort of array in $scope.form). So right now, every instruction text area always contains the same text (as expected, which is the problem).
Here's my view code (in jade, but should be readable):
ol
li( ng-repeat='instruction in form.instructions' )
input( name='instruction[]' type='text' ng-model='form.instructions.text' )
| <br>
input( type='button' value='+' ng-click='addInstr()' )
Here's my controller code.
formControllers.controller('new-instruction-set-ctrl', function ($scope, $http) {
$scope.form = $scope.form || {};
$scope.form.instructions = [{}];
$scope.addInstr = function() {
$scope.form.instructions.push({});
};
});
This finally worked for me. See live demo in Plunker.
View:
li( ng-repeat='instruction in form.instructions' )
input( name='instruction[]' type='text' ng-model='form.instructions[$index].text')
I didn't have to change my controller at all.
$index is automatically provided by ng-repeat.