Ember.js input fields - input

Is it possible to use standard HTML5 input fields in an Ember.js view, or are you forced to use the limited selection of built in fields like Ember.TextField, Ember.CheckBox, Ember.TextArea, and Ember.select? I can't seem to figure out how to bind the input values to the views without using the built in views like:
Input: {{view Ember.TextField valueBinding="objectValue" }}
Specifically, I'm in need of a numeric field. Any suggestions?

EDIT: This is now out of date you can achieve everything above with the following:
{{input value=objectValue type="number" min="2"}}
Outdated answer
You can just specify the type for a TextField
Input: {{view Ember.TextField valueBinding="objectValue" type="number"}}
If you want to access the extra attributes of a number field, you can just subclass Ember.TextField.
App.NumberField = Ember.TextField.extend({
type: 'number',
attributeBindings: ['min', 'max', 'step']
})
Input: {{view App.NumberField valueBinding="objectValue" min="1"}}

#Bradley Priest's answer above is correct, adding type=number does work. I found out however that you need to add some attributes to the Ember.TextField object if you need decimal numbers input or want to specify min/max input values. I just extended Ember.TextField to add some attributes to the field:
//Add a number field
App.NumberField = Ember.TextField.extend({
attributeBindings: ['name', 'min', 'max', 'step']
});
In the template:
{{view App.NumberField type="number" valueBinding="view.myValue" min="0.0" max="1.0" step="0.01" }}
et voile!

Here is my well typed take on it :
App.NumberField = Ember.TextField.extend({
type: 'number',
attributeBindings: ['min', 'max', 'step'],
numericValue: function (key, v) {
if (arguments.length === 1)
return parseFloat(this.get('value'));
else
this.set('value', v !== undefined ? v+'' : '');
}.property('value')
});
I use it that way:
{{view App.NumberField type="number" numericValueBinding="prop" min="0.0" max="1.0" step="0.01" }}
The other systems where propagating strings into number typed fields.

You may also wish to prevent people from typing any old letters in there:
App.NumberField = App.TextField.extend({
type: 'number',
attributeBindings: ['min', 'max', 'step'],
numbericValue : function (key,v) {
if (arguments.length === 1)
return parseFloat(this.get('value'));
else
this.set('value', v !== undefined ? v+'' : '');
}.property('value'),
didInsertElement: function() {
this.$().keypress(function(key) {
if((key.charCode!=46)&&(key.charCode!=45)&&(key.charCode < 48 || key.charCode > 57)) return false;
})
}
})
Credit where its due: I extended nraynaud's answer

This is how I would do this now (currently Ember 1.6-beta5) using components (using the ideas from #nraynaud & #nont):
App.NumberFieldComponent = Ember.TextField.extend
tagName: "input"
type: "number"
numericValue: ((key, value) ->
if arguments.length is 1
parseFloat #get "value"
else
#set "value", (if value isnt undefined then "#{value}" else "")
).property "value"
didInsertElement: ->
#$().keypress (key) ->
false if (key.charCode isnt 46) and (key.charCode isnt 45) and (key.charCode < 48 or key.charCode > 57)
Then, to include it in a template:
number-field numericValue=someProperty

Related

vuejs pass extra parameter to function

Is it possible within Quasar Form rules to pass extra parameter?
This had to do with the following template code:
<q-field outlined v-else-if="prop.component === 'checkbox'"
class="q-gutter-sm"
v-model="dataRef[key]"
:label="prop.label"
:rules="[isCheckLimit]"
>
<q-option-group
style="margin-top:20px;"
:options="prop.options"
type="checkbox"
v-model="dataRef[key]"
/>
</q-field>
The function:
const isCheckLimit = (v) => {
return v.length > 2 || t('checked-to-much')
}
I want that number 2 to be dynamic instead of static, is it possible to pass for example a number to that function? I cant find any clear information about that?
Thank you in advance.
You have to define your rule as function in your rules array, first lets update your validation function to accept second argument, I will also set it to default value of 2:
const isCheckLimit = (v, minLength = 2) => {
return v.length > minLength || t('checked-to-much');
};
Now if you use this for your rules:
:rules="[(value) => isCheckLimit(value, 4)]"
Your validation function will use 4 for minLength instead of default 2.
Original way will also work:
:rules="[isCheckLimit]"
But will use the default value of 2 for minLength

q-input has value then only Rules will apply

If q-input has value != '' then only i want to apply the Rules like required 8 number maximum. In the below code it gives me the required input error even it's null.
<q-input
filled
name="landline"
label="Landline Phone Number"
v-model="user.landline"
placeholder="Landline Phone Number"
ref="landlinePhoneNumber"
type="number"
:maxlength="8"
:rules="[val => val!='' && val.length > 7 || 'Landline Required 8 digit']"
/>
Try to add prop lazy-rules.
By default, it's set to 'ondemand', which means that validation will be triggered only when the component’s validate() method is manually called or when the wrapper QForm submits itself. More info
You have to return true when the field is null first, then validate only if it's not null. Also, add the prop lazy-rules so that it only validates when the form field loses focus.
Here is how I did it in Vue 3, using composable and TypeScript. The form field component:
<q-input
class="q-mt-md"
filled
v-model="id_number"
label="ID Number "
type="text"
hint="Optional/Leave blank if not available"
lazy-rules
:rules="[(val) => isNumberBlankOrValid(val) || 'Invalid ID Number']"
/>
The method isNumberBlankOrValid called from the field above:
const isNumberBlankOrValid = (val: string) => {
if (val.length === 0) {
return true
}
return isValidNumber(val)
}
The isValidNumber for other fields that must be filled:
const isValidNumber = (val: string) => val && isNumeric(val)
The isNumeric method is a simple regex for validating numbers:
const isNumeric = (value: string) => {
return /^\d+$/.test(value)
}

How to validate multiple user inputs within just one popup using Vue-SweetAlert2

As a coding training, right now I'm making a web page where you can click a "Create" button, which triggers a popup, where you are supposed to fill in 6 data inputs, whose input style varies like text, select etc. (See the code and the attached image below)
<template>
<v-btn class="create-button" color="yellow" #click="alertDisplay">Create</v-btn>
<br/>
<p>Test result of createCustomer: {{ createdCustomer }}</p>
</div>
</template>
<script>
export default {
data() {
return {
createdCustomer: null
}
},
methods: {
alertDisplay() {
const {value: formValues} = await this.$swal.fire({
title: 'Create private customer',
html: '<input id="swal-input1" class="swal2-input" placeholder="Customer Number">' +
'<select id="swal-input2" class="swal2-input"> <option value="fi_FI">fi_FI</option> <option value="sv_SE">sv_SE</option> </select>'
+
'<input id="swal-input3" class="swal2-input" placeholder="regNo">' +
'<input id="swal-input4" class="swal2-input" placeholder="Address">' +
'<input id="swal-input5" class="swal2-input" placeholder="First Name">' +
'<input id="swal-input6" class="swal2-input" placeholder="Last Name">'
,
focusConfirm: false,
preConfirm: () => {
return [
document.getElementById('swal-input1').value,
document.getElementById('swal-input2').value,
document.getElementById('swal-input3').value,
document.getElementById('swal-input4').value,
document.getElementById('swal-input5').value,
document.getElementById('swal-input6').value
]
}
})
if (formValues) {
this.createdCustomer = this.$swal.fire(JSON.stringify(formValues));
console.log(this.createdCustomer);
}
}
}
}
</script>
Technically, it's working. The popup shows up when the "create" button is clicked, and you can fill in all the 6 blanks and click the "OK" button as well. But I want to add some functionalities that check if the user inputs are valid, I mean things like
address should be within 50 characters
firstName should be within 20 characters
customerNumber should include both alphabets and numbers
and so on.
If it were C or Java, I could probably do something like
if(length <= 50){
// proceed
} else {
// warn the user that the string is too long
}
, but when it comes to validating multiple inputs within a single popup using Vue-SweetAlert2, I'm not sure how to do it, and I haven't been able to find any page that explains detailed enough.
If it were just a single input, maybe you could use inputValidor like this
const {value: ipAddress} = await Swal.fire({
title: 'Enter an IP address',
input: 'text',
inputValue: inputValue,
showCancelButton: true,
inputValidator: (value) => {
if (!value) {
return 'You need to write something!'
}
}
})
if (ipAddress) {
Swal.fire(`Your IP address is ${ipAddress}`)
}
, but this example only involves "one input". Plus, what this checks is just "whether an IP address has been given or not" (, which means whether there is a value or not, and it doesn't really check if the length of the IP address is correct and / or whether the input string consists of numbers / alphabets).
On the other hand, what I'm trying to do is to "restrict multiple input values (such as the length of the string etc)" "within a single popup". Any idea how I am supposed to do this?
Unfortunately the HTML tags to restrict inputs (e.g. required, pattern, etc.) do not work (see this issues),
so I find two work around.
Using preConfirm as in the linked issues
You could use preConfirm and if/else statement with Regex to check your requirement, if they are not satisfied you could use Swal.showValidationMessage(error).
const{value:formValue} = await Swal.fire({
title: "Some multiple input",
html:
<input id="swal-input1" class="swal-input1" placeholder="name"> +
<input id="swal-input2" class="swal-input2" placeholder="phone">,
preConfirm: () => {
if($("#swal-input1").val() !== "Joe"){
Swal.showValidationMessage("your name must be Joe");
} else if (!('[0-9]+'.test($("#swal-input2").val())){
Swal.showValidationMessage("your phone must contain some numbers");
}
}
});
Using Bootstrap
In this way Bootstrap does the check at the validation, you need to include class="form-control" in your input class and change a little your html code.
If some conditions fails, the browser shows a validation message for each fields, in the order they are in the html code.
const {value: formValue} = await Swal.fire({
title: 'Some multiple inputs',
html:
'<form id="multiple-inputs">' +
'<div class="form-group">' +
'<input type="text" class="form-control swal-input1" id="swal-input1" min=2 max=4 required>' +
'</div>' +
'<div class="form-group">' +
'<input type="text" class="form-control swal-input2" id="swal-input2" placeholder="Name" pattern="[A-Za-z]" required>' +
'</div>' +
'</form>',
});
I have tried both the solution, actually only with Bootstrap3 but it should work also with the latest release.

Angular Translate default translate value while using filter

Is there any way to provide the translate-default value while using the filter instead of directive?
e.g:
How to achieve the same results as this
<h3 translate="TEST" translate-default="Not present"></h3>
with filter format
{{ 'TEST' | translate }}
How do i put the "translate-default" attribute when using the translate filter?
What i need to do is show the original text if the key is not present.
I have created a wrapping filter for that purpose:
.filter('txf', ['$translate', ($translate: angular.translate.ITranslateService) => {
return (input: string, stringIfNotAvailable: string = '') => {
const translation = $translate.instant(input);
return translation === input ? stringIfNotAvailable : translation;
};
}]);

MVC 4 WebGrid Checkbox in a column with Condition

I'm trying to add a new column to a .Net MVC WebGrid that includes a checkbox that is there if a specific condition is met and not there if the condition is false.
The below code works to correctly display X or Y (placeholder):
grid.Column("ID", header: "",
style: "labelcolumn",
format: (item) => item.ID != null ? "X" : "Y"),
I can't seem to get the syntax right to include the checkbox instead of X.
grid.Column("ID", header: "",
style: "labelcolumn",
format: (item) => item.ID != null ? #<text><input class="check-box" id="cbSelectedBranch" name="cbSelectedBranch" type="checkbox" value="#item.ID" /></text> : "Y"),
On this second snippet, the "(item)" variable causes this error:
CS0136: A local variable named 'item' cannot be declared in this scope
because it would give a different meaning to 'item', which is already
used in a 'parent or current' scope to denote something else
Adding the # when using the if null condition seems to cause item to throw this error. The below code, without the conditional, works correctly:
grid.Column(header: "",
style: "labelcolumn",
format: #<text><input class="check-box" id="cbSelectedBranch" name="cbSelectedBranch" type="checkbox" value="#item.ID" /></text>),
Any idea how I can make this work with a conditional and checkbox input?
try like this:
format: (item) => item.ID != null ? Html.Raw("<input class='check-box' id='cbSelectedBranch' name='cbSelectedBranch' type='checkbox' value='#item.ID' />") : "Y")