How to use focus() on QButton (<q-btn>)? - vuejs3

I have a form developed in Quasar + Vue 3, and would like to programmatically set focus on the Submit button so that the user can press ENTER to submit.
<q-btn ref="btn" />
I thought using refs would work:
this.$refs.btn.focus()
But I'm getting TypeError: this.$refs.btn.focus is not a function.
How do I set focus on QButton?

Retrieve the native DOM element by using $el and set focus() on that:
this.$refs.btn.$el.focus()
Some Quasar component have built-in focus() methods, like QInput and QSelect, but QButton does not.
However, since the QButton component (<q-btn>) simply renders a <button> element as its root element, we can use Vue's $el to retrieve it from the component instance (via $refs
), and then call the native JS function focus() on that :)

Related

Dialog not displaying propagated model data

In my UI5 application, I have an i18n.properties file with keys and values:
#XMSG:
qty=Quantity
And I'm using this property value in a dialog box as title
onUpdateDialog: function() {
var that = this;
var dialog = new Dialog({
title: "{i18n>qty}",
// ...,
});
dialog.open();
},
But when I run my application, the dialog box title is not getting displayed:
When I use text values from i18n property file somewhere else it's getting displayed.
ManagedObjects, that are created by the application code imperatively outside of the framework-managed features (Such creating an instance of sap.m.Dialog in a Controller code without using the API loadFragment), have to be added to the model delegation chain manually in order to make use of the propagated models.
In order to do so, add the created instance to the parent's <dependents> aggregation. E.g.:
this.getView().addDependent(myDialog); // myDialog is now aware of the "i18n" model
From API Reference:
Special aggregation dependents is connected to the lifecycle management and databinding, but not rendered automatically and can be used for popups or other dependent controls or elements. This allows the definition of popup controls in declarative views and enables propagation of model and context information to them.
In order to use texts in the controller you need to fetch the text first, like so:
this.getOwnerComponent().getModel("i18n").getResourceBundle().getText("qty")
this will be the dialog inside the dialog, so declare a that before the dialog and change this to that..
var that = this;
that.getOwnerComponent().getModel("i18n").getResourceBundle().getText("qty")
Hope this solves your issue..
At the point of opening the Dialog, it doesn't know the i18n model. You need to provide the model to the dialog by calling dialog.setModel(this.getModel('i18n'), 'i18n') before opening the dialog.

Angular2 Custom Component with bindable property - how to [(value)] without #Output in custom component?

I have a custom component with an input property as follows:
export class MyComponent{
#Input() value:number;
}
So that I can plop one on a parent component:
<my-component [(value)]="someValueAtParentComponent"></my-component>
Note that I did not provide #Component decorator and the class for the parent component because I don't think those are relevant.
Now, things happen internally in MyComponent that can change the value of value.
From inside MyComponent's template, I display {{value}}, and it displays the correct value throughout its lifetime.
From the parent component's template, I display {{someValueAtParentComponent}}, but it doesn't update with MyComponent's value. I thought [(value)] will automatically do the job, but I guess not.
I don't want to create an #Output event on MyComponent for the parent component to handle the event where it would set someValueAtParentComponent explicitly.
I believe Angular wants to emit an event for a parent component to handle, but that seems very tedious. Is there something we can do in our own components so that we may use the syntactic sugar [(value)] instead of [value]="..." (onValueChanged)="onValueChangedHandler($event)"?

Meteor JS Template rendered function called before template is rendered?

I'm trying to use the Buttonset widget in JQuery UI. I've got the package loaded and my template renders the radio buttons fine. I have a "rendered" function to call the JQ UI routine to setup the buttonset:
Template.teamList.rendered = function () {
$("#buttonsetID").buttonset();
}
But it looks like the rendered function is being called before the template is rendered! I stick a console.log in the function and it prints out to the console before there's anything on the screen. So none of the radio buttons are set up, therefore the .buttonset() call does nothing. If I make that call in the console after the page is rendered, JQuery UI does the right thing and my button set appears.
Isn't the .rendered function supposed to be called after everything's set up? Am I doing something wrong?
Thanks!
edit:
As an example, the same thing is seen in the leaderboard example.
If you add:
Template.leaderboard.rendered = function() {
alert($('.player').length);
}
When the page is displayed, it will show 0. This makes it difficult to access the DOM items if you need to add some JQuery events or, in this case, a JQuery UI element.
rendered only works for elements which will appear in the DOM the very first time the template is added to the page. Assume that subscription data takes infinitely long to arrive, then look at the template and see which elements would appear in the default state.
Using the leaderboard example, we can't assume that players are available when the leaderboard template renders (it depends on a subscription). To target a player, you should use the rendered callback on the player template.
It's hard to generalize a strategy for when to apply jQuery plugins, but here are some ideas:
Use the rendered callback if the element will always be added in the default state (e.g. the element is hard-coded and doesn't depend on a conditional).
Use the rendered callback of the most specific child template to target that child (e.g. the player template from above).
Consider using an event handler callback to target the element if it's appearance depends on an event (e.g. a button click).
Consider using a template autorun callback to target the element if it's appearance depends on reactive state. See this question for an example.

Meteor template elements lose style during (re)render

I have a template that has a some text updated reactively once every second.
I also have a button, that when clicked, gets it's style changed to display a disabled button - this works fine but as soon as the template re-renders due to the condition above then the button reverts back to it's original style. It is almost as if the entire template is rendering from scratch (template.render is fired every second).
Is this normal? do I need to control the style via a reactive {{btnstyle}} type mechanism?
Yes, the typical way to do this is to set the style via a class that is set by a template helper function. For disabling button/input elements, you can just use the disabled attribute instead of class:
<button type="button" {{#if buttonDisabled}}disabled{{/if}}>Button Text</button>
or
<input type="button" value="Button Text" {{#if buttonDisabled}}disabled{{/if}} />
and then do:
Template.yourFormTemplate.buttonDisabled = function() {
// return true or false depending on if the button should be disabled
};
The problem is that when Meteor re-renders your template, the element which you set the style of is actually getting replaced with a new one. Note that the Meteor team is currently working on a new templating engine that works on a more fine-grained level, so that elements don't necessarily get replaced like that. You can try your current code with the preview release of the new templating engine with this command:
meteor --release shark-1-29-2014-e
or
mrt --release shark-1-29-2014-e
However, it is still generally recommended to style elements via the class attribute, set with a template helper. This is a more declarative, template-driven approach that just fits better with the "Meteor way" to do things, rather than the imperative approach of setting the style directly from your JavaScript. It also helps with separating concerns, by allowing your CSS to control the actual style.

Is there a way for MVC Partial View retrieved using jQuery to keep UI CSS Styling?

I have an MVC 2 project, consisting of a MasterPageView a child View called Index and a number of PartialViews. The PartialViews are loaded into the Index View using the jQuery Ajax method $.get(....).
My problem is that I am styling the buttons using jQuery UI like:
$('button').button();
but I find that I need to do this on every PartialView. What I would like to do is define
this once in the MasterPageView, but if I do this the styling is lost. I'm guessing this
is because the styling is applied before the DOM is loaded, is this correct? Is there any
way to implement this i.e. just define it on the MasterPageView?
Thanks for the help !
This wont work when objects are added to the DOM after the initial load. In those cases you should go for the new .live() syntax in jQuery :
$("button").live("load", function(){
$(this).button();
});
It listens for new objects being added to the DOM and attaches an eventhandler to it..
Hope that helps!

Resources