I need to create an action sheet or some other kind of alert which displays options to a user and saves the option they clicked in a variable. However, the options displayed to the user need to be retrieved from Firestore and are different for each user (each user also may have a different number of options).
I’ve been able to display these options in an action sheet, but I’m struggling to get the value of the option they clicked.
Below is my code for the function so far. The list of options retrieved from Firestore is saved in an array called ‘options’.
categorizeProblem(){
this.action = this.actionCtrl.create({
title: "What sort of problem did this student have?",
})
this.options.forEach(option => {
var button = {
text: option,
value: //option name
handler: (data)=> {
//Need to get the value/name of the option clicked and save this in a variable
}
}
this.action.addButton(button);
})
this.action.present();
}
I would really appreciate if someone could help me with this or suggest an alternate way to do this.
Thanks in advance!
You can use the text property as your identifier. And then your handler should use the old function syntax so you will have the value of handler's this.
Might sound confusing but here's the code, that should demonstrate my point clearly.
presentActionSheet() {
var self = this;
let options = [
"Option1",
"Option2",
"Option3"
];
let actionSheet = this.actionSheetCtrl.create({
title: 'Categories',
});
options.forEach(option => {
actionSheet.addButton({
text: option,
handler: function() {
self.selectedOption = this.text;
}
})
});
actionSheet.present();
}
Here's the running code.
Related
I'm new to Protractor.
I'm trying to select a button based on the button title. I want to make this into a function, and pass the button title in as a parameter.
This is the hard-coded version which works:
it('I click on a button based on the button title', async function() {
let button = element(by.css('button[title=example_button_title]'));
await button.click();
});
I created a global variable and a function to try and replace this, where 'buttonTitle' is the parameter I'm passing into the function:
Variable:
let dynamicButton = buttonTitle => { return element(by.css("'button[title=" + buttonTitle + "]'")) };
Function:
this.selectDynamicButton = async function(buttonTitle) {
await browser.waitForAngularEnabled(false);
await dynamicButton(buttonTitle).click();
};
When I try this I get the following error:
Failed: invalid selector: An invalid or illegal selector was specified
Apologies if there appear to be basic errors here, I am still learning. I appreciate any help that anyone can give me. Thanks.
You can add a custom locator using protractors addLocator functionality. (this is actually a very similar use case to the example listed in the link)
This would look like the following:
onPrepare: function () {
by.addLocator('buttonTitle', function (titleText, opt_parentElement) {
// This function will be serialized as a string and will execute in the
// browser. The first argument is the text for the button. The second
// argument is the parent element, if any.
const using = opt_parentElement || document;
const matchingButtons = using.querySelectorAll(`button[title="${titleText}"]`);
let result = undefined;
if (matchingButtons.length === 0) {
result = null;
} else if (matchingButtons.length === 1) {
result = matchingButtons[0];
} else {
result = matchingButtons;
}
return result;
});
}
This is called like
const firstMatchingButton = element(by.buttonTitle('example_button_title'));
const allMatchingButtons = element.all(by.buttonTitle('example_button_title'));
I had to edit this code before posting so let me know if this does not work. My work here is largely based off this previous answer
let dynamicButton = buttonTitle => { return element(by.css('button[title=${buttonTitle} ]')) };
Use template literals instead of string concatenation with +.
Protractor already has a built in locator which allows you to get a button using the text. I think you are looking at something like that. See the element(by.buttonText('text of button')) locator.
For more reference see here.
I want to display to the user an input with some options, but the user can answer a new one.
Using showQuickPick I can show some options, but if the user answer a different option the return is undefined.
It's possible to do what I want?
I have already think about create a New option and then show an InputBox to the user, but I don't want that the user need to answer two questions.
I have used a solution where I inject the user input in the list of items.
It works pretty well:
const choices = ['a', 'b']
async function getUserSelectdValue() {
return new Promise((resolve) => {
const quickPick = window.createQuickPick();
quickPick.items = choices.map(choice => ({ label: choice }));
quickPick.title = 'Choose your favorite value:'
quickPick.onDidChangeValue(() => {
// INJECT user values into proposed values
if (!choices.includes(quickPick.value)) quickPick.items = [quickPick.value, ...choices].map(label => ({ label }))
})
quickPick.onDidAccept(() => {
const selection = quickPick.activeItems[0]
resolve(selection.label)
quickPick.hide()
})
quickPick.show();
})
}
Please let me know if you need further explanations
It sounds like you might be interested in the approach taken in this issue?
https://github.com/microsoft/vscode/issues/89601
I am trying to make working sheets for my work. In Google scripts, I've created "Custom Menu" for my sheet wich is sending email correctly. But now I want to get value from the specific cell and check if it is below, for example, 2, send an email with that value. For now, I have this:
function onOpen() {
var ui = SpreadsheetApp.getUi();
// Or DocumentApp or FormApp.
ui.createMenu('Custom Menu')
.addItem('First item', 'menuItem1')
.addSeparator()
.addToUi();
}
function menuItem1() {
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.alert('You clicked the first menu item!');
if( 'A1' > 3){
MailApp.sendEmail('luk...#gmail.pl', 'subject', 'message');
}
}
I don't know how to get this value from this cell. This 'If" is just an example of what I am trying to do, I know it is not working. Thank you in advance for any kind of help.
First, You need to find the sheet:
var sheet = SpreadsheetApp.getActiveSheet();
Then, you need to specify a cell range and get the value(s):
var value = sheet.getRange("A1").getValue();
You can browse the API for more functions here: https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app
The click seems to fire the event and set the cookies but pressing enter to submit doesn't set the cookies and instead the page redirects without the cookies.
function locationAuto() {
$('.search-location').focus(function () {
autocomplete = new google.maps.places.Autocomplete(this);
searchbox = this;
google.maps.event.addListener(autocomplete, 'place_changed', function () {
var thisplace = autocomplete.getPlace();
if (thisplace.geometry.location != null) {
$.cookie.raw = true;
$.cookie('location', searchbox.value, { expires: 1 });
$.cookie('geo', thisplace.geometry.location, { expires: 1 });
}
});
});
The .search-location is a class on multiple textboxes.
There is a submit button that takes the values from the cookies and redirects (server side)
Adapted from Jonathan Caulfield's answer:
$('.search-location').keypress(function(e) {
if (e.which == 13) {
google.maps.event.trigger(autocomplete, 'place_changed');
return false;
}
});
I've encountered this problem as well, and came up with a good solution. In my website I wanted to save the autocomplete.getPlace().formatted_address in a hidden input prior to submission. This worked as expected when clicking the form's submit button, but not when pressing the Enter key on the selection in the autocomplete's dropdown menu. My solution was as follows:
$(document).ready(function() {
// Empty the value on page load
$("#formattedAddress").val("");
// variable to indicate whether or not enter has been pressed on the input
var enterPressedInForm = false;
var input = document.getElementById("inputName");
var options = {
componentRestrictions: {country: 'uk'}
};
autocomplete = new google.maps.places.Autocomplete(input, options);
$("#formName").submit(function(e) {
// Only submit the form if information has been stored in our hidden input
return $("#formattedAddress").val().length > 0;
});
$("#inputName").bind("keypress", function(e) {
if(e.keyCode == 13) {
// Note that simply triggering the 'place_changed' event in here would not suffice, as this would just create an object with the name as typed in the input field, and no other information, as that has still not been retrieved at this point.
// We change this variable to indicate that enter has been pressed in our input field
enterPressedInForm = true;
}
});
// This event seems to fire twice when pressing enter on a search result. The first time getPlace() is undefined, and the next time it has the data. This is why the following logic has been added.
google.maps.event.addListener(autocomplete, 'place_changed', function () {
// If getPlace() is not undefined (so if it exists), store the formatted_address (or whatever data is relevant to you) in the hidden input.
if(autocomplete.getPlace() !== undefined) {
$("#formattedAddress").val(autocomplete.getPlace().formatted_address);
}
// If enter has been pressed, submit the form.
if(enterPressedInForm) {
$("#formName").submit();
}
});
});
This solution seems to work well.
Both of the above responses are good answers for the general question of firing a question when the user presses "enter." However - I ran into a more specific problem when using Google Places Autocomplete, which might have been part of the OP's problem. For the place_changed event to do anything useful, the user needs to have selected one of the autocomplete options. If you just trigger 'place_changed', the if () block is skipped and the cookie isn't set.
There's a very good answer to the second part of the question here:
https://stackoverflow.com/a/11703018/1314762
NOTE: amirnissim's answer, not the chosen answer, is the one to use for reasons you'll run into if you have more than one autocomplete input on the same page.
Maybe not the most user friendly solution but you could use JQuery to disable the enter key press.
Something like this...
$('.search-location').keypress(function(e) {
if (e.which == 13) {
return false;
}
});
I am using auto suggest v.2.1.3 from brandspankingnew.
I have a form with two radio button and a text field and would like to know how to make the auto suggest script pointing to a different php file if one of the radio button is checked.
I tried this but it doesnt work, its always point to the same php file even if second button is checked
Could you please assist?
Many thanks in advance.
My code is as follows:
function targetvalue()
{
for (i=0;i
/>Business Street
var options = {
script:"autosuggest.php?json=true&limit=6&",
varname:"input",
json:true,
shownoresults:false,
maxresults:10,
callback: function (obj) { document.getElementById('name').value = obj.id; }
};
var as_json = new bsn.AutoSuggest('business', options);
var options_xml = {
script: function (input) { return "autosuggest.php?input="+input+"&testid="+document.getElementById('testid').value; },
varname:"input"
};
var as_xml = new bsn.AutoSuggest('business', options_xml);
As for me, the easiest solution is to pass the the button state to the one script eg only one script but can return different results depending on button state. Otherwise you need to rewrite options each time someone clicks on the radio button. The second solution an lead to unpredictable behavior of auto suggest component.
Sample script:
var selectedValue = getRadioSelectedValue("radioGroupName");
var options_xml = { script: function (input) { return "autosuggest.php?input="+input+"&testid="+document.getElementById('testid').value+"&mode="+selectedValue; },
Write getRadioSelectedValue by yourself to get selected radio button value or set some flag on click. Mode param in GET request will indicates the state of the button, so you can return proper response.