diff --git a/app/components/erf-html-input.js b/app/components/erf-html-input.js
new file mode 100644
index 0000000000..407f6e456a
--- /dev/null
+++ b/app/components/erf-html-input.js
@@ -0,0 +1,15 @@
+import HTMLInput from 'ember-rapid-forms/components/html-input';
+import layout from '../templates/components/html-input';
+
+export default HTMLInput.extend({
+ layout,
+ actions: {
+ update(value) {
+ let sanitize = this.get('mainComponent.sanitize');
+ if (sanitize && sanitize.call) {
+ value = sanitize(value);
+ }
+ this.set('selectedValue', value);
+ }
+ }
+});
diff --git a/app/components/number-input.js b/app/components/number-input.js
new file mode 100644
index 0000000000..dc47e74d8a
--- /dev/null
+++ b/app/components/number-input.js
@@ -0,0 +1,13 @@
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+ sanitizeFunction(value) {
+ return value.replace(new RegExp(/([^0-9|.]+)/g), '');
+ },
+ tagName: '',
+ actions: {
+ sanitize(value) {
+ return this.get('sanitizeFunction')(value);
+ }
+ }
+});
diff --git a/app/initializers/i18n.js b/app/initializers/i18n.js
index 3f727d9ec2..33056b782b 100644
--- a/app/initializers/i18n.js
+++ b/app/initializers/i18n.js
@@ -9,4 +9,4 @@ export default {
app.inject('mixin', 'i18n', 'service:i18n');
app.inject('model', 'i18n', 'service:i18n');
}
-};
\ No newline at end of file
+};
diff --git a/app/inventory/adjust/template.hbs b/app/inventory/adjust/template.hbs
index 8effad70b3..e6e8bcd0e8 100644
--- a/app/inventory/adjust/template.hbs
+++ b/app/inventory/adjust/template.hbs
@@ -21,7 +21,7 @@
property="transactionType" content=adjustmentTypes
optionValuePath="type" optionLabelPath="name"
}}
- {{em-input property="adjustmentQuantity" label=(t 'labels.quantity') class="col-sm-3 required"}}
+ {{number-input property="adjustmentQuantity" label=(t 'labels.quantity') class="col-sm-3 required"}}
{{em-text label=(t 'inventory.labels.reason') property="reason" rows=3}}
diff --git a/app/inventory/batch/template.hbs b/app/inventory/batch/template.hbs
index 936fe62f66..07d1f59502 100755
--- a/app/inventory/batch/template.hbs
+++ b/app/inventory/batch/template.hbs
@@ -29,14 +29,14 @@
selection=selectedInventoryItem
showQuantity=false
}}
- {{em-input property="quantity" label=(t 'labels.quantity') class="col-sm-2 required test-inv-quantity"}}
+ {{number-input property="quantity" label=(t 'labels.quantity') class="col-sm-2 required test-inv-quantity"}}
- {{em-input property="purchaseCost" label=(t 'inventory.labels.purchaseCost') class="col-sm-2 required test-inv-cost"}}
+ {{number-input property="purchaseCost" label=(t 'inventory.labels.purchaseCost') class="col-sm-2 required test-inv-cost"}}
{{em-input property="vendorItemNo" label=(t 'inventory.labels.vendorItemNumber') class="col-sm-4"}}
diff --git a/app/inventory/request/template.hbs b/app/inventory/request/template.hbs
index 1094f61ebf..fe18c50b58 100755
--- a/app/inventory/request/template.hbs
+++ b/app/inventory/request/template.hbs
@@ -22,7 +22,8 @@
content=inventoryList
selection=selectedInventoryItem
}}
- {{em-input property="quantity" label=quantityLabel class="col-sm-3 test-inv-quantity"}}
+
+ {{number-input property="quantity" label=quantityLabel class="col-sm-3 test-inv-quantity"}}
- {{em-input property="quantity" label=quantityLabel class=quantityClass }}
+ {{number-input property="quantity" label=quantityLabel class=quantityClass }}
{{em-input property="refills" label=(t 'medication.labels.refills') class="col-xs-3"}}
{{#unless model.hideFulfillRequest}}
diff --git a/app/patients/socialwork/expense/template.hbs b/app/patients/socialwork/expense/template.hbs
index 2d78dc7d98..3e1d5081c2 100644
--- a/app/patients/socialwork/expense/template.hbs
+++ b/app/patients/socialwork/expense/template.hbs
@@ -11,6 +11,6 @@
prompt=" "
}}
{{em-input label=(t 'patients.labels.sources') property="sources"}}
- {{em-input label=(t 'patients.labels.cost') property="cost" class="required"}}
+ {{number-input label=(t 'patients.labels.cost') property="cost" class="required"}}
{{/em-form}}
{{/modal-dialog}}
diff --git a/app/patients/socialwork/family-info/template.hbs b/app/patients/socialwork/family-info/template.hbs
index 06d1bac36e..9f2a717625 100644
--- a/app/patients/socialwork/family-info/template.hbs
+++ b/app/patients/socialwork/family-info/template.hbs
@@ -19,7 +19,7 @@
{{em-input label=(t labels.occupation)property="occupation" class="col-xs-6"}}
- {{em-input label=(t labels.income) property="income" class="col-xs-6"}}
+ {{number-input label=(t labels.income) property="income" class="col-xs-6"}}
{{em-input label=(t labels.insurance) property="insurance" class="col-xs-6"}}
{{/em-form}}
diff --git a/app/pricing/edit/template.hbs b/app/pricing/edit/template.hbs
index 4c4011cd92..3f2dcc8b45 100644
--- a/app/pricing/edit/template.hbs
+++ b/app/pricing/edit/template.hbs
@@ -2,7 +2,7 @@
{{#em-form model=model submitButton=false }}
{{em-input label=(t 'labels.name') property="name" class="required price-name"}}
- {{em-input label=(t 'labels.price') property="price" class="required col-xs-2 price-amount"}}
+ {{number-input label=(t 'labels.price') property="price" class="required col-xs-2 price-amount"}}
{{select-or-typeahead property="expenseAccount" label=(t 'labels.department') list=expenseAccountList selection=model.expenseAccount className="col-xs-4 price-department"}}
diff --git a/app/pricing/override/template.hbs b/app/pricing/override/template.hbs
index cfa473714c..80d4045848 100644
--- a/app/pricing/override/template.hbs
+++ b/app/pricing/override/template.hbs
@@ -12,6 +12,6 @@
class="required pricing-profile"
prompt=" "
}}
- {{em-input label=(t 'labels.price') property="price" class="required pricing-override-price"}}
+ {{number-input label=(t 'labels.price') property="price" class="required pricing-override-price"}}
{{/em-form}}
{{/modal-dialog}}
diff --git a/app/pricing/profiles/edit/template.hbs b/app/pricing/profiles/edit/template.hbs
index 57bbfbbcac..6b61c9a26b 100644
--- a/app/pricing/profiles/edit/template.hbs
+++ b/app/pricing/profiles/edit/template.hbs
@@ -5,7 +5,7 @@
updateButtonText=updateButtonText }}
{{#em-form model=model submitButton=false }}
{{em-input property="name" label="Name" class="required pricing-profile-name"}}
- {{em-input property="discountPercentage" label="Discount Percentage" class="pricing-profile-percentage"}}
- {{em-input property="discountAmount" label="Discount Amount" class="pricing-profile-discount"}}
+ {{number-input property="discountPercentage" label="Discount Percentage" class="pricing-profile-percentage"}}
+ {{number-input property="discountAmount" label="Discount Amount" class="pricing-profile-discount"}}
{{/em-form}}
{{/modal-dialog}}
diff --git a/app/procedures/charge/template.hbs b/app/procedures/charge/template.hbs
index 1062880ac6..0a1f422423 100644
--- a/app/procedures/charge/template.hbs
+++ b/app/procedures/charge/template.hbs
@@ -7,7 +7,7 @@
{{#em-form model=model submitButton=false }}
{{pricing-typeahead property="itemName" label=(t 'inventory.labels.item') content=pricingList selection=selectedItem class="required charge-item-name"}}
- {{em-input label=(t 'labels.quantity') property="quantity" class="col-xs-3 required"}}
+ {{number-input label=(t 'labels.quantity') property="quantity" class="col-xs-3 required"}}
{{date-picker property="dateCharged" label="Date Charged" class="col-xs-4 required"}}
{{/em-form}}
diff --git a/app/templates/components/html-input.hbs b/app/templates/components/html-input.hbs
new file mode 100644
index 0000000000..b408151204
--- /dev/null
+++ b/app/templates/components/html-input.hbs
@@ -0,0 +1,17 @@
+{{input
+ type=mainComponent.type
+
+ placeholder=mainComponent.placeholder
+ value=(readonly selectedValue)
+ name=mainComponent.name
+ disabled=mainComponent.disabled
+ class=(concat "form-control " mainComponent.elementClass)
+ id=mainComponent.id
+ required=mainComponent.required
+ title=mainComponent.title
+ pattern=mainComponent.pattern
+ autofocus=mainComponent.autofocus
+ readonly=mainComponent.readonly
+ autoresize=mainComponent.autoresize
+ input=(action "update" value="target.value")
+}}
diff --git a/app/templates/components/number-input.hbs b/app/templates/components/number-input.hbs
new file mode 100644
index 0000000000..a688d31bd3
--- /dev/null
+++ b/app/templates/components/number-input.hbs
@@ -0,0 +1 @@
+{{em-input property=property label=label class=class sanitize=(action 'sanitize')}}
diff --git a/app/templates/inv-purchase.hbs b/app/templates/inv-purchase.hbs
index 0b0efd9793..2befeecf07 100644
--- a/app/templates/inv-purchase.hbs
+++ b/app/templates/inv-purchase.hbs
@@ -11,7 +11,7 @@
{{/if}}
- {{em-input property="purchaseCost" label=(t 'inventory.labels.purchaseCost') class="required col-sm-4 test-inv-cost"}}
+ {{number-input property="purchaseCost" label=(t 'inventory.labels.purchaseCost') class="required col-sm-4 test-inv-cost"}}
{{em-input property="lotNumber" label=(t 'inventory.labels.serialNumber') class="col-sm-4"}}
diff --git a/app/visits/vitals/edit/template.hbs b/app/visits/vitals/edit/template.hbs
index f599584d51..acbcf6562a 100644
--- a/app/visits/vitals/edit/template.hbs
+++ b/app/visits/vitals/edit/template.hbs
@@ -9,7 +9,7 @@
{{date-picker property="dateRecorded" label=(t "vitals.labels.dateRecorded") class="col-sm-6" format="l h:mm A" showTime=true }}
- {{em-input class="col-sm-3 required temperature-text" property="temperature" label=temperatureLabel }}
+ {{number-input class="col-sm-3 required temperature-text" property="temperature" label=temperatureLabel }}
{{em-input class="col-sm-3 weight-text" property="weight" label=(t "vitals.labels.weight")}}
@@ -20,8 +20,8 @@
{{em-input class="col-sm-3 required dbp-text" property="dbp" label=(t "vitals.labels.dbp")}}
- {{em-input class="col-sm-3 required heart-rate-text" property="heartRate" label=(t "vitals.labels.heartRate")}}
- {{em-input class="col-sm-3 required respiratory-rate-text" property="respiratoryRate" label=(t "vitals.labels.respiratoryRate")}}
+ {{number-input class="col-sm-3 required heart-rate-text" property="heartRate" label=(t "vitals.labels.heartRate")}}
+ {{number-input class="col-sm-3 required respiratory-rate-text" property="respiratoryRate" label=(t "vitals.labels.respiratoryRate")}}
{{/em-form}}
{{/modal-dialog}}
diff --git a/tests/integration/components/number-input-test.js b/tests/integration/components/number-input-test.js
new file mode 100644
index 0000000000..cadc1d3c36
--- /dev/null
+++ b/tests/integration/components/number-input-test.js
@@ -0,0 +1,44 @@
+import { moduleForComponent, test } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+import Ember from 'ember';
+
+moduleForComponent('number-input', 'Integration | Component | number input', {
+ integration: true
+});
+
+test('the number-input renders', function(assert) {
+ assert.expect(2);
+
+ this.render(hbs`
+ {{#em-form model=model}}
+ {{number-input property='petType' label='Pet Type' class='test-number-input'}}
+ {{/em-form}}
+ `);
+
+ assert.equal(this.$('label').text().trim(), 'Pet Type', 'it renders the label');
+ assert.ok(Ember.isPresent(this.$('.test-number-input')), 'it renders the input field');
+});
+
+test('the number input sanitizes the data', function(assert) {
+ assert.expect(1);
+
+ this.set('model', Ember.Object.create({ petType: 'cats' }));
+
+ this.set('sanitizeFunction', (value) => {
+ assert.equal(value, 'dragons', 'it passes the value to the sanitize function');
+ });
+
+ this.render(hbs`
+ {{#em-form model=model}}
+ {{number-input
+ property='petType'
+ sanitizeFunction=sanitizeFunction
+ label='Pet Type'
+ class='test-number-input'}}
+ {{/em-form}}
+ `);
+
+ this.$('input').eq(0).val('dragons');
+ this.$('input').trigger('input');
+ this.$('input').trigger('change');
+});