Using aurelia variable in html attributes - aurelia

I want to dynamically set the input datetime step granularity using aurelia binding.
In my time.js:
timeStep = "1";
In my time.html:
The following works correctly:
<input type=datetime-local value="2017-01-01T00:00:00" step="1" value.bind="formParameters.timeFrom" >
${timeStep}
However when I try to set the step using my variable - it doesn't seem to work:
<input type=datetime-local value="2017-01-01T00:00:00" step="timeStep" value.bind="formParameters.timeFrom" >
${timeStep}
You can see I have lost the seconds granularity. When I inspect the element, it comes out as:
<input type="datetime-local" value="2017-01-01T00:00:00" step="timeStep" value.bind="formParameters.timeFrom" class="au-target" au-target-id="37">
Where timeStep should be "1".

To bind any HTML attribute to a property in your viewModel - you need to use .bind.
<input type=datetime-local value="2017-01-01T00:00:00" step.bind="timeStep" value.bind="formParameters.timeFrom">
Aurelia will assume anything in a .bind attribute is a property of your viewModel class and bind them accordingly. You can use .bind on any (as far as I know) HTML attribute.

Related

Non V-bind part of the V-Model

As we know v-model is two way binding. Which means it's combination of V-bind and maybe another attribute which I'm looking for and it updates the data. I have a input which it's value is sometimes custom and sometimes should be read from config based on another parameters.
What I need is an input with a v-bind:value/:value and another for update. I know I can do it with #change and a custom method But I'm looking for something easy, Bottom line is I want V-model without doing v-bind ! Thank You
EDIT: I did it with two input using v-if .
<input type="number" class="item-input" v-if="setting.keto_program=='custom'" id="protein_per_kilo" v-model="setting.keto_program_protein_density">
<input type="number" class="item-input" v-else disabled id="protein_per_kilo" :value="config.keto_programs[setting.keto_program].protein_density">
Anyway doing this using just one input feels better. Thanks
May be you can use computed hook.
computed:{
yourVariable(){
return someVariable/computation
}
}
you can use yourVariable inside your code that will act like v-model without doing v-bind.
yourVariable will be updated as soon as the variables of the return statement of this be changed or updated
Edited:
part of v-model for input tag
<input
v-bind:value="variable"
v-on:input="variable = $event.target.value"
>
or
<input
:value="variable"
#input="variable = $event.target.value"
>
found this via
Vue.js—Difference between v-model and v-bind

Pass info between tag helpers?

I am writing a set of tag helpers that target, for example, <form> and <input> elements. I want to add a custom attribute to the <form> element, and retrieve the value of that attribute in the contained <input> element. So, if my HTML looks like this:
<form xx-value='123'>
<input asp-for='Something' />
</form>
then in my InputTagHelper I would want to retrieve the value 123 that was specified for the xx-value attribute.
Is there a designed-in way to pass data like this between tag helpers?
Consider the case where I have this markup:
<form xx-value='123'>
<input asp-for='Something' />
</form>
<form>
<input asp-for='SomethingElse' />
</form>
In this case, the first invocation of the InputTagHelper would get the value 123. But the second invocation of the InputTagHelper would get a value of 0 since its parent <form> tag didn't specify the magic xxx-value attribute.
The simple answer (which doesn't work for <form> and <input> tags - see blow) is for the "parent" tag helper to store the value in the context.Items dictionary and for the "child" tag helper(s) to retrieve the value from that same dictionary. A Google search for "child tag helper" yields many examples of this scheme.
The problem with this answer (in the context of the OP) is that, for some reason, the <form> tag helper executes after its child <input> tag helper. So, rather than receiving the value from the parent FormTagHelper, the InputTagHelper discovers that the context.Items dictionary is empty.
I created this SO post to ask about that weird behavior.

Problems with custom renderer and validation triggered in custom elements

I'm using aurelia-validation#1.0.0-beta.1.0.1.
My scenario is:
I've got a form which has a validation controller and validation rules
There is a containerless custom element in the form which wraps a password input, and exposes the current password as a bindable property
The validate binding behavior is used on the form's binding to this custom element property
The custom element also raises the blur event, so that the validation binding is triggered when the wrapped password input loses focus
The validation lifecycle is working as expected.
The problem I'm running into is with the custom renderer I'm using, which currently assumes the element it receives is the actual DOM input element so that a class can be applied to the input, and a sibling error element can be injected next to it, but here it's receiving the custom element that wraps the input, which can't be handled in the same manner because it's just a comment node in the DOM.
Is there a strategy or API in aurelia-validation that could solve this sort of problem? I'm stumped, and can't find much out there on working with custom elements within validation.
EDIT:
Here is the custom element template:
<template>
<div class="input-group -password">
<div class="input-toggle-wrapper">
<label for="password" class="-hidden" t="fields_Password"></label>
<input
id="password"
type="${isPasswordVisible ? 'text' : 'password'}"
value.bind="password"
t="[placeholder]fields_Password"
maxlength="20"
focus.trigger="onInputFocus()"
blur.trigger="onInputBlur()" />
<div
class="toggle ${isPasswordVisible ? '-show' : ''}"
click.delegate="onToggleClick($event)"
mousedown.delegate="onToggleMouseDown($event)"></div>
</div>
</div>
</template>
I made it containerless because I don't want <password-box> emitted into the DOM as an outer element, as that breaks the current CSS rules for layout (and I don't want to change the CSS).
However if the custom element is containerless then I don't know how to access the first div inside the template using DOM navigation from the comment node that represents the custom element in the DOM.
Unfortunately, Aurelia team has identified this issue and (at least as of now) said they won't fix it. https://github.com/aurelia/templating/issues/140
There is a hacky workaround for the issue as follows:
if(element.nodeType === 8) {
element = this.getPreviusElementSibling(element)
}
If you add that within your render method for your renderer, it should work. Again, hacky, but it gets the job done in lieu of an official fix from the AU team.

How to specify two-way bindable property in HTML-only custom element (Aurelia)

I have created an HTML-only custom element to represent an input and all the DOM structure that does with it.
I have set up bindable properties on the template to supply values into the element. However, I don't see a way to specify that a bindable should be two-way.
the element:
<template bindable="label,name,placeholder,value">
<div class="form-group">
<label class="control-label col-sm-2" for.bind="name">${label}</label>
<div class="col-sm-7 col-md-6">
<input class="form-control" id.bind="name" placeholder.bind="placeholder" value.bind="value" />
</div>
</div>
</template>
I know I can specify two-way binding each time the element is used (e.g. <my-element value.bind="firstName & twoWay"></my-element>, but I want to set the default without having to create and maintain a separate class (i.e. I like html-only element for this case).
Is this possible?
I don't think that's possible in a simple way. I mean, you could figure out how to override the default behaviour somehow ([source], [source]), but it's likely that you would end up with several more classes to maintain.
Documentation is clear about that:
You can even have bindable properties on your HTML Only Custom Element. These properties default to one-way databinding, but you can't change the default, though you are still free to explicitly set the binding direction when you bind to the Custom Element.
In my opinion, using .two-way explicit binding is your simplest option here.
<my-element value.two-way="firstName"></my-element>

default radio input checked attribute not working with can-value

Using can 2.2 : I'm having trouble getting a radio input field to be checked by default when also using the can-value attribute.
The relevant part of the stache template looks like this:
<input type="radio" name="visibility" value="corporate" can-value="reportData.visibility" checked="checked"/>
The relevant part of my viewModel looks like this:
can.Map.extend({
reportData = {
visibility: 'corporate',
}
});
I want the input value to be live-bound to my view model. According to the can 2.2 docs, I can use the can-value attribute on an input to reference a property on my view model and keep it in sync with the value of the input's value. My problem is the checked="checked" doesn't result in the input being checked by default, though the value on the input item (corporate) is being correctly live-bound. If I remove the can-value attribute, the check appears by default. How can I get both live-binding and a checked input by default with the help of can-value?