I am using enyojs 2.4 and the moonstone library.
What does "can't spot in frozen mode" mean ?
I have two inputs :
{kind: "moon.InputDecorator", name: "emaildec", spotlight: true, defaultSpotlightLeft : "emaildec", components: [
{kind: "moon.Input", name: "username",placeholder: "e-mail address", onchange: "nameChanged", value:"",classes: "input-style"} //,spotlight: true
]
},
{tag: "br"},
{kind: "moon.InputDecorator", name: "pwddec" , spotlight: true, defaultSpotlightLeft : "pwddec", components: [
{kind: "moon.Input", name: "userpwd",type:"password", placeholder: "ameba password", onchange: "passwordChanged", value: "",classes: "input-style"} //,spotlight: true
]
}
This console error is thrown when I attempt to set focus on the password input :
enyo.Spotlight.spot(this.$.userpwd);
What I want to happen is:
user fills in first input using onscreen keyboard
user then navigates to enter button on onscreen keyboard and presses ok/enter on remote control
focus is set to second input.
The moon.InputDecorator will automatically unfreeze Spotlight upon a blur event (from the moon.Input), whereupon you could call enyo.Spotlight.spot(). moon.Input will automatically blur itself when it detects the Enter key being pressed, but only if the dismissOnEnter flag is set to true on moon.Input. It sounds like you might actually want to call focus on the desired moon.Input (instead of spotting, as that will just display the Spotlight hovered state on the moon.InputDecorator and not actually spot it), something like this (http://jsfiddle.net/aarontam/nxp8x7ku/):
enyo.create({
handlers: {
onblur: 'blurHandler'
},
components: [{
kind: "moon.InputDecorator",
name: "emaildec",
spotlight: true,
defaultSpotlightLeft: "emaildec",
components: [{
kind: "moon.Input",
name: "username",
placeholder: "e-mail address",
onchange: "nameChanged",
value: "",
classes: "input-style",
dismissOnEnter: true,
} //,spotlight: true
]
}, {
tag: "br"
}, {
kind: "moon.InputDecorator",
name: "pwddec",
spotlight: true,
defaultSpotlightLeft: "pwddec",
components: [{
kind: "moon.Input",
name: "userpwd",
type: "password",
placeholder: "ameba password",
onchange: "passwordChanged",
value: "",
classes: "input-style"
} //,spotlight: true
]
}],
blurHandler: function (sender, event) {
if (event.originator === this.$.username) {
this.$.userpwd.focus();
}
}
}).renderInto(document.body);
I'm not exactly sure of the "why", but looking at Spotlight source, it looks like when a control gets spotted, frozen mode is turned on. Now, I would guess it should get turned off when you try to spot a new one, but it doesn't do that.
You could try: enyo.Spotlight.unfreeze(); and then set the spot on your second control, but I haven't tested it to see if there are unintended side effects.
As per #dmikeyanderson on the enyo forum:
It means that the spotlight has been frozen on a control, and until
unfrozen the spotlight can't move. There doesn't seem anything wrong
with your components, do you have more code to share?
As per #aarontam on the enyo forum:
Hi #Fabii23, the moon.InputDecorator will automatically unfreeze
Spotlight upon a blur event (from the moon.Input), whereupon you could
call enyo.Spotlight.spot(). moon.Input will automatically blur itself
when it detects the Enter key being pressed, but only if the
dismissOnEnter flag is set to true on moon.Input. It sounds like you
might actually want to call focus on the desired moon.Input (instead
of spotting, as that will just display the Spotlight hovered state on
the moon.InputDecorator and not actually spot it), something like this
(based off of the fiddle from #dmikeyanderson)
Related
I'm making an admin dashboard and I need to ask for data (for example when creating or updating data) a lot. I am already using vue-sweetalert2 which made me aware of how easy it is to use this.$swal.fire().then()...
I was wondering, how would I go about making my own kind of thing like that (without using TypeScript)?
let reply = await this.$ask(fields)
alert("You entered: " + reply.yourname.answer)
Then in the component that I load in on every page, I would have a modal which takes the fields and allows for user input. When a user clicked submit or exited the modal, it needs to return a / the value(s).
I'm thinking of using it this way:
// Ask for new team name & description
let modalResult = await this.$ask({
fields: [
{
title: "Team name",
placeholder: "Give youre team a name!",
key: "teamName",
type: "text"
}, {
title: "Team description",
placeholder: "What's your team about?",
key: "teamDescription",
type: "text"
}
],
modal: {
variant: "primary",
icon: null,
title: "Make a new team",
confirmButtonText: "Create team",
cancelButtonText: "Cancel"
}
});
console.log("Team name: " + modalResult.data.teamName);
console.log("Team description: " + modalResult.data.teamDescription);
However, I honestly have no idea how I'd go about making this possible. What I've thought of:
Mixins: Of what I've learnt so far, I don't know how to put a template file in it. (so a .vue file, only a .js file).
Here's a screenshot of :
what I'm trying to say
Thanks in advance! :-)
When you're setting up your vue instance (usually in main.js), you can put your method on as a prototype
Vue.prototype.$ask= (your function or your object);
Here's some vuejs docs on the subject
https://v2.vuejs.org/v2/cookbook/adding-instance-properties.html
I`m creating bot for MS Teams and using JS Microsoft Bot Framework V4 SDK.
In my work, I use search message extension and to work with it, I implemented the onSelectItem method that returns a adaptive card. I will give an example of the code below.
return Promise.resolve({
type: "result",
attachmentLayout: "list",
attachments: [CardFactory.heroCard(
`${file.name}`,
`${text}`,
undefined,
CardFactory.actions([
{
type: "openUrl",
title: "Open",
value: `${openLink}`
},
{
type: "openUrl",
title: "Download",
value: `${downloadLink}`
},
]),
)]
});
Where I pass undefined, this should be the path to the picture, but in my implementation I don't need it. So and this code works great in the browser and on the desktop version here is a screenshot
however, on the mobile version, I get the following result
this is absolutely not the right card, it has no content or buttons
I think I found the answer myself. When the message extension search is triggered, the onQuery method is called and suppose you made a query and received an array of values that you want to display. And here, in the same method, iterating over the array, you must draw two cards at once. For example
files.forEach((file: IDocumentInfo): void => {
const card: any = CardFactory.heroCard(
cutString(file.name, LIMIT),
text,
undefined,
[
{
type: "openUrl",
title: "Open",
value: "", // some value
},
{
type: "openUrl",
title: "Download",
value: "" //some value,
},
]
);
const preview: any = {
contentType: "application/vnd.microsoft.card.thumbnail",
content: {
title: `${cutString(file.name, LIMIT)}`,
text: "", // some text
}
};
And here the variable preview in my case will respond to a small view of information after the search and the variable card will be responsible for the view after selection. And after the card is selected, the onSelectItem method is triggered, which I need to get more information about the document
It turns out that the adaptive heroCard is not to blame here, the onSelectItem method is not called in the mobile application, or I am doing something wrong
I have different groups of words on a single page, let's say nouns verbs and adjectives. The way to describe each group is with its 'part-of-speech'. This 'part-of-speech' is being printed inside a little box. So you have the 'part-of-speech' of the group, noun, in the little box, and I want to achieve that when I click on that box I hide verbs and adjectives. If I were to click on verb I would hide nouns and adjetives, and so on. Right now the 'part-of-speech' of each group is being passed in as a prop.
The problem is that I'd like to compare parts of speech that exist on the current page with the clicked part of speech, but I cannot manage to differentiate it.
In my template I've got:
<div class="part-of-speech">
<p class="pos">{{ pos }}</p>
</div>
and this { pos } is coming from my props
props: {
pos: {
type: String,
required: false,
default: "na"
}
},
mounted() {
console.log(this.pos)
}
This gives me all the parts-of-speech that are being printed on the page (take into account that this is a child-component of something else and these groups of words are printing as many times as there are groups). So I though that adding a method to detect the clicked part-of-speech would help.
<div class="part-of-speech" #click="handleSelectedPos(pos)">
<p class="pos">{{ pos }}</p>
</div>
props: {
pos: {
type: String,
required: false,
default: "na"
}
},
methods: {
handleSelectedPos(pos) {
console.log(pos);
console.log(this.pos);
}
}
When I click on the current item, I get the current part-of-speech, and as you can see this.pos in this context is no longer the list of parts-of-speech that are on the page but it has become the currently clicked part-of-speech. My idea was to make the comparison somehow between pos and this.pos, but they are now identical.
How to make the comparison to say: If there are parts-of-speech that are not equal to the one currently clicked, take some action (add a class or wtv) to hide the element.
If I understand well, what you would like to achieve, then some of the events shouldn't be handled by the subcomponents, but by the parent component.
Vue.component('partOfSpeech', {
props: ['pos', 'text'],
template: `<div :class="pos" #click='emitEvent'>{{text}}</div>`,
methods: {
emitEvent() {
this.$emit('emitpos', this.pos)
}
}
})
new Vue({
el: '#app',
data: {
words: [{
pos: 'noun',
text: 'noun1',
compare: false
},
{
pos: 'verb',
text: 'verb1',
compare: false
},
{
pos: 'adjective',
text: 'adjective1',
compare: false
},
{
pos: 'noun',
text: 'noun2',
compare: false
},
{
pos: 'verb',
text: 'verb2',
compare: false
},
{
pos: 'adjective',
text: 'adjective2',
compare: false
},
{
pos: 'verb',
text: 'verb3',
compare: false
},
{
pos: 'noun',
text: 'noun3',
compare: false
},
{
pos: 'adjective',
text: 'adjective1',
compare: false
},
]
},
methods: {
filterWords(val) {
this.words.forEach(e => {
if (e.pos === val) {
e.compare = true
} else {
e.compare = false
}
})
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<part-of-speech :key="i" v-for="(word, i) in words" :pos="word.pos" :text="word.text" v-on:emitpos="filterWords" :style="{ color: !word.compare ? 'black' : 'red'}" />
</div>
In the snippet above you can see that every
data is passed down to the child component as prop (except for compare - that's not needed there)
a click event is set up on each of the child components, that (#click) $emit() an event and their prop back to the parent
the parent has a v-on: for the event emitted, and executes a function on ALL the parts of speech (words in my app; the function colors words red that have the same pos as the clicked one).
MORE INFO
The problem is that sibling elements do not know anything about each other: they’re not supposed to share any information with each other.
A component can share its own unique state information with sibling components either via their common parent (by emitting an event (with a data payload)) or by using some form of state management solution (event bus or Vuex store are the most common in Vue - the latter is for serious cases, the former is for occasions that require more than simple event emitting, but doesn’t require anything really complicated).
Custom events in Vue: https://v2.vuejs.org/v2/guide/components-custom-events.html
Event bus: https://alligator.io/vuejs/global-event-bus/
Vuex state management: https://vuex.vuejs.org/
I use Keystone JS Types.Url type of field to show clickable (by link) field of object in the generated admin UI:
Message.add({
uId: { type: String, initial: true, required: true },
title: { type: String, initial: true, required: true },
stat: { type: Types.Url, default: '', required: false, label: 'Statistics' }
})
Message.schema.add({ status: mongoose.Schema.Types.Mixed })
Message.schema.pre('save', function (next) {
this.stat = 'link_to_config'
next()
})
Message.defaultColumns = 'uId, stat'
Message.register()
Field 'stat' is shown correctly by <a href=""> in the generated admin UI.
Problem:
Field 'stat' is not opened with a click, but the link is changed in the browser's address bar correctly or it can be opened by using ctrl + click
Is it a bug or I do something wrong?
The URL type is not meant to appear as a URL in the Admin panel. It's meant to provide validation and formatting for items to be stored as URLs; they have no function as clickable links within the Admin panel at all.
Source: http://keystonejs.netlify.com/api/field/url/
I recently posted about getting a combobox into the settings of a Rally app, now I'm trying to figure out how checkboxes work in settings. I assumed they would work similarly [ish] but for some reason it's not [hence why i'm on this site again].
My checkbox field and getSettingsField function look like this right now:
getSettingsFields: function() {
return [
{
xtype: 'fieldcontainer',
defaultType: 'checkboxfield',
items: [
{
name: 'box1',
boxLabel: 'Box 1:',
inputValue: true,
value: true,
id: 'boxone'
}
]
}
];
}
At the top of my app I also have the following default settings set:
config: {
defaultSettings: {
box1: true
}
},
I console.log()'d the setting for that checkbox inside the launch function and found that the setting starts at "true" but the checkbox is not originally checked. When I check the box and save the settings, the setting stays at "true" and again unchecks when i go back to the settings tab. This would all be okay, but when I save the settings with the box unchecked, the setting still stays as "true".
I tried changing the defaultSetting to false just for testing, but again I only got a "true" setting field for box1. My logging line, console.log('Setting: ' + this.getSettings()); is what is showing me the current value for each setting each time the app is loaded & each time the settings are changed.
The goal is to get the checkbox setting to read correctly [true / false or whatever syntax the settings come in] at the beginning of the app so a grid can be filtered later. Does someone know what I'm doing wrong?
So apparently the settings tab is returning a string, so "true" is returned from the inputValue, not the boolean true value. Also, the value setting is messing things up, so here's what I ended up using:
config: {
defaultSettings: {
boxes: "check"
}
},
...
getSettingsFields: function() {
return [
{
xtype: 'fieldcontainer',
defaultType: 'checkboxfield',
items: [
{
name: 'boxes',
boxLabel: 'Box 1:',
inputValue: "one",
checked: this.getSettings().boxes.split(',').indexOf('one') > -1,
id: 'boxone'
},
{
name: 'boxes',
boxLabel: 'Box 2:',
inputValue: "two",
checked: this.getSettings().boxes.split(',').indexOf('two') > -1,
id: 'boxtwo'
}
]
}
];
}
I learned that the 'name' field is a generic field that should apply to all checkboxes that are related to each other in the settings panel. The 'inputValue' field is the returned string to the settings field, and each returns to a string in this.getSettings().boxes.
I wanted to keep the boxes to remember if they were checked before, so that's where the line checked: this.getSettings().boxes.split(',').indexOf('one') > -1 comes from. If the string 'one' is in the settings, that means the index will be larger than one, so checked will be true and therefore the box will be checked next time someone opens the settings menu.