How can I select from a set of fixed values? - bixby

If my capsule has a requirement to allow a user to select from a set of fixed values represented by an enum, how can I do that in Bixby?

We are going to represent the fixed values as an enum
enum (FixedValue) {
symbol (ONE)
symbol (TWO)
symbol (THREE)
symbol (FOUR)
}
The Action file will look like this
action (GetFixedValue) {
type(Search)
description (Allow user to choose a value from the set of fixed values)
collect{
input (fixedValue) {
type (FixedValue)
min (Required) max (One)
prompt-behavior (AlwaysElicitation)
default-init {
intent {
goal: FixedValue
value-set {FixedValue {FixedValue(ONE) FixedValue(TWO) FixedValue(THREE) FixedValue(FOUR) }}
}
}
}
} output (FixedValue)
}
The Javascript file for this action is as follows:
module.exports.function = function GetFixedValue (fixedValue) {
return JSON.stringify(fixedValue)
}

Related

Bixby: want to display two form element text-input in one input form view

I want to build an input form using text-input, in which I want to display multiple text fields in one form.
Making a single view having multiple text fields not providing the output.
So, would it possible to write multiple text-input in a single form or not.
Below is my code which I am trying to implement:
Action:
action (CardDetails) {
type(Search)
collect{
input (creditCard) {
type (CreditCard)
min (Required)
}
input (cvv) {
type (Cvv)
min (Required)
}
}
output (getCardInfo)
}
Structure:
structure (getCardInfo){
property (creditCard) {
type (CreditCard)
min (Optional)
}
property (cvv) {
type (Cvv)
min (Optional)
}
}
Input View:
input-view {
match {
CreditCard (creditCard) {
to-input: CardDetails
}
}
message {
template ("Enter Card Details")
}
render {
form {
elements {
text-input {
id (creditCard)
label (Credit Card)
type (CreditCard)
max-length (20)
value ("#{raw(creditCard)}")
}
text-input {
id (cvv)
label (cvv)
type (Cvv)
max-length (4)
}
}
on-submit {
goal: CardDetails
value: viv.core.FormElement(creditCard)
value: viv.core.FormElement(cvv)
}
submit-button (Ok)
}
}
}
Result View :
result-view {
match: getCardInfo(res){
from-output : CardDetails
}
message{
template ("Here are the details")
}
}
Unable to display result view. Showing I need CVV details to continue.
Any Help on this, Please
I am sure there are other ways, but the easiest way I could think of is to do input-view on the structure. Also it might be just personal style, but I would recommend change the naming, actions should start with something like Get or Create, not the structure name.
input-view {
match: StructCard(this)
message: template ("Give me your card")
render {
form {
elements {
text-input {
id (aaa)
label("Card Number")
type (TextCardNumber)
value("Costco Citi")
}
text-input {
id (bbb)
label("Card CVV")
type (TextCardCvv)
value("No WAY")
}
}
on-submit {
goal: StructCard
value: StructCard {
cardNumber: viv.core.FormElement(aaa)
cardCvv: viv.core.FormElement(bbb)
}
}
}
}
}
There are other minor but subtle changes to the action, check the complete example on GitHub. Utterance "tell me your card".
Here is the input-view
Here is the result-view

Bixby : Display form element slider along with other information

We have to implement a ticket booking system in our capsule, where we need selectbox to select tickets. But I didn't get a selectbox in Bixby. so, I am using slider to select. On that I have to display event with input form element slider. But, unable to display js details and slider on one page.
Link: https://bixbydevelopers.com/dev/docs/reference/type/input-view.render.form.elements.slider
Action :
action (Book) {
type(Search)
collect {
input (rating) {
type (Rating)
min (Required) max (One)
}
input (event) {
type (Event)
min (Optional) max (One)
}
}
output (OrderBooking)
}
Structure :
structure (OrderBooking){
property (event) {
type (Event)
min (Optional)
max (One)
}
property (rating){
type (Rating)
min (Required)
max (One)
}
}
View:
input-view {
match {
OrderBooking (rating)
}
render {
form {
elements {
slider {
id (rating)
min-value (0)
max-value (10)
min-label (0 - Lowest)
max-label (10 - Highest)
step (1)
type (Rating)
}
}
on-submit {
goal: Rating
value: viv.core.FormElement(rating)
}
}
if (exists(rating.ticketName)){
selection-of (rating) {
navigation-mode {
read-many {
page-size (3)
page-content{
underflow-statement (This is the final set)
item-selection-question {
if(exists(rating.ticketName)){
template ("Here are a few suggestions for the events.")
}else{
template (Which one would you like)
}
}
overflow-statement (That's all I have)
}
}
}
has-details (false)
where-each (item) {
layout-macro (book-type-summary) {
param (singlebook) {
expression (item)
}
}
}
}
}
}
}
Layout:
layout-macro-def(book-type-summary) {
params {
param (singlebook) {
type (OrderBooking)
min (Required)
max (One)
}
}
content {
compound-card {
content {
paragraph {
value {
if (exists(singlebook.event)){
template ("#{value(singlebook.event)}")
}
}
style (Detail_M)
}
}
}
}
}
There are two points to this question:
It looks like you would like to display additional information in the input-view. Currently this is not possible. You cannot add content that does not fit in the form you want to present to the user.
Instead of a slider, perhaps it would be better for you to use selection-of (documentation)

Match multiple concept

Wish to show my input view, with a message vary from time, and showing content based on another variable.
This is my input-view
input-view{
match{
userWantToHear(this){
from-output:getStart //action to get list of selection
}
}
message{
switch (this){//should be another value which is (timePeriod)
case ("M"){
template-macro (morning-template)
}
case ("A"){
template-macro (afternoon-template)
}
case ("N"){
template-macro (night-template)
}
default{
template-macro (normal-template)
}
}
}
render{
selection-of (this){ //this should be (userWantToHear)
where-each (one){
spoken-summary{
template ("#{value(one)}")
}
cell-card{
slot2{
content{
primary{
template ("#{value(one)}")
}
}
}
}
}
}
}
}
So what my thought is, create a structure to contain both of them.
structure (menu) {
description (__DESCRIPTION__)
property (timeperiod){
type (timePeriod)
min (Required) max (One)
}
property (whatuserwant) {
type (userWantToHear)
min (Required) max (One)
}
}
And i also create a action to get them.
action (getMenu) {
type(Search)
collect{
input (timeperiod){
type (timePeriod)
min (Required) max (One)
default-init{
intent{
goal: getTime
}
}
}
input (whatuserwant){
type (userWantToHear)
min (Required) max (One)
default-init{
intent{
goal: getStart
}
}
}
}
output (menu)
}
The result from the input-view will be pass into the action below, which is userWantToHear
action (getNews) {
type (Search)
description (__DESCRIPTION__)
collect {
input (whatuserwant){
type (userWantToHear)
min (Required) max (One)
default-init{
intent{
goal: getMenu
}
}
}
}
output (newsAudio)
}
So i wonder how the input view is gonna accept the structure and access the property inside it for each section, and get back the input i want? Currently from my side, it's able to get the selection, but the message doesn't change according to "timePeriod" where i believe it doesn't pass in into the input view yet.
I think there are two questions here in your post.
How do I render different views? Answer: use if-else or switch statement to select template macros.
How to I access concept not in match Type(this)? Answer: use complicated match pattern that link these concept through an action. Consider the following code block.
match: IntAge(this) {
to-input: GetStructPerson (action)
}
message {
template ("Enter age of #{value(action.name)}")
}
You can read more and download sample capsule in Bixby Developer Center

Not sure how to update a struct with new information

A question concerning Bixby Studio.
I am trying to figure out how to accept text-input from the user.
I have a Filter struct with some fields such as SearchField, Genre, Platforms (Gaming consoles), and Themes (A few other entries)
By default, all of these are optional, especially with the search field. However, i would like for the user to be able to visibly see what filters are enabled, and be able to select and change their values (This values can be overwritten by NLP training, but I can't figure out how to disable the field.)
I created a result view for my filters and I've setup input-cells for selecting a specific field to modify. (In this case, SearchField.). I have been successful in redirecting to an input-view, but it seems that no matter what text I put in here, it does not save or apply to my filter.
Looking for some insight into the problem and willing to provide more information as needed.
Some of the things that I have tried in the past, seem to want take the existing context "SearchField" within the filters (which might not exist) and apply it to the new "search field". However, this doesn't work and seems to create a loop.
I've also tried to set the prompt-behavior (AlwaysSelection) in the action model for SetSearchField, but it appears to do nothing.
// Result View for Filters
result-view {
match {
Filter(this)
}
message {
template (Active Filters){
speech (Would you like to change any filters?)
}
}
render {
layout-macro (filter-details) {
param (filter) {
expression (this)
}
}
}
}
// Layout Macro
layout-macro-def(filter-details) {
params {
param (filter) {
type (Filter)
min (Required)
max (One)
}
}
content {
section {
title (Filters)
content {
input-cell {
label (Search Name)
value ("#{value(filter.name)}")
on-click {
intent {
goal: SetSearchField // <-------- Field in question
}
}
}
}
}
}
}
// Input-view for SearchField
input-view {
match {
SearchField(searchField)
}
render {
form {
elements {
text-input {
id (val)
type (SearchField)
required (true)
}
}
on-submit {
goal:SearchField
}
}
}
}
// SetSearchField action
action (SetSearchField) {
description (Sets the name in a search filter)
type (Fetch)
collect {
input (newSearchField) {
type (SearchField)
min (Required)
prompt-behavior (AlwaysSelection)
}
}
output (SearchField)
}
// SetSearchField endpoint
action-endpoint (SetSearchField) {
accepted-inputs (newSearchField)
local-endpoint ("filters/SetSearchField.js")
}
// .js file
module.exports.function = function setName (newSearchField) {
return newSearchField
}
I discovered there is a special way in accessing input form elements for input-views.
Collect input through the form -> elements, then reference them using the viv.core.FormElement(id)
input-view {
match {
SearchField(searchField)
}
render {
form {
on-submit {
goal: SearchField
value: viv.core.FormElement(text)
}
elements {
text-input {
id (text)
type (SearchField)
label (Search for: )
value("#{raw(searchField)}")
}
}
}
}
}

Can I make an optional input required, if another optional input is present?

I'm writing an action that is collecting three inputs. The first is required, but the second and third are optional. Because the second and third options are of similar Types, sometimes the third type is filled while the second is left unfilled.
i.e., I want to pass in a book, or book + page, or book + page + line number
I can obviously handle this by making multiple (nearly identical) actions, or in the endpoint itself, but is it possible to make a single actions input's dependency determined by the presence of another input?
Action currently looks something like...
collect {
input (book) {
type (String)
min (Required) max (One)
}
input (page) {
type (Integer)
min (Optional) max (One)
}
input (line) {
type (Integer)
min (Optional) max (One)
}
}
Given your use case, it would make sense to use default-init in the following way:
collect {
input (book) {
type (String)
min (Required) max (One)
}
input (page) {
type (Integer)
min (Optional) max (One)
default-init {
if (!exists(page)) {
intent {
goal: YOUR ACTION HERE
value: Integer (1)
}
}
}
}
input (line) {
type (Integer)
min (Optional) max (One)
default-init {
if (!exists(line)) {
intent {
goal: YOUR ACTION HERE
value: Integer (1)
}
}
}
}
}
This would allow for the page and line numbers to default to 1 if they have not been provided by the user.
Looks like the best option (and only I've been able to find so far) is to create modify the original, then add a second. Finally, add a new action-endpoint to endpoints.
ReadBook removes the optional Line
action (ReadBook) {
description ("Read a page from a book (first if page isn't provided)."")
type (Calculation)
collect {
input (book) {
type (Book)
min (Required) max (One)
}
input (page) {
type (PageNum)
min (Optional) max (One)
}
}
output (Passage)
}
ReadBookLine makes all inputs required
action (ReadBookLine) {
description (Read a line from a book.)
type (Calculation)
collect {
input (book) {
type (Book)
min (Required) max (One)
}
input (page) {
type (PageNum)
min (Required) max (One)
}
input (line) {
type (LineNum)
min (Required) max (One)
}
}
output (Passage)
}
Endpoints
endpoints {
action-endpoint (ReadBook) {
accepted-inputs (book, page)
remote-endpoint ("https://.../read_book) {
method (POST)
}
}
action-endpoint (ReadBookLine) {
accepted-inputs (book, page, line)
remote-endpoint ("https://.../read_book") {
method (POST)
}
}
}
}

Resources