Use static value while v-model is changing it - javascript

I need to show 'product.upc' in label tag without change (static, the same value always) while v-model is changing the value by input.
<div class="input-group-prepend">
<label class="input-group-text p-0">#{{ product.upc }}</label>
</div>
<input type="text" class="form-control text-center" v-model="product.upc">

v-model is a two-way binding that will surely update wherever it is being used, so use another variable for your label instead.
For example, on the mounted hook, you can set the initial value of product.upc in another data variable and use that as your label.
On Js side-
data() {
return {
label: null,
product: {
upc: "something",
}
}
},
mounted() {
this.label = product.upc
}
On the template side-
<div class="input-group-prepend">
<label class="input-group-text p-0">#{{ label }}</label>
</div>
<input type="text" class="form-control text-center" v-model="product.upc">

Related

How to use input field value attribute while using formControlName? [Angular]

What I want to achieve: I want pre-populated data in my form and I also want to use formControlName as I want the data too.
My html file -
<div class="container">
<p class="h4 my-5">Add New Result</p>
<div class="row">
<div class="col">
<form (ngSubmit)="editStudent()" [formGroup]="studentEditForm" name="myForm">
<div class="mb-3">
<label for="roll-no" class="form-label">Roll No.</label>
<input type="number" class="form-control" id="roll-no" name="rollno" formControlName="rollno" value="{{student.rollNo}}" placeholder="{{student.rollNo}}" autocomplete="off" required>
</div>
<div class="mb-3">
<label for="name" class="form-label">Name</label>
<input type="text" class="form-control" id="name" name="name" formControlName="name" value={{student.name}} required>
</div>
<div class="mb-3">
<label for="email" class="form-label">Email address</label>
<input type="email" class="form-control" id="email" name="email" formControlName="email" value={{student.email}} required>
</div>
<div class="mb-3">
<label for="score" class="form-label">Score</label>
<input type="number" class="form-control" id="score" name="score" formControlName="score" value={{student.score}} required>
</div>
<button type="submit" class="btn btn-primary" ng-click="submitForm(myForm.$valid)">Submit</button><button type="submit" class="btn btn-dark mx-4">Clear</button>
</form>
</div>
<div class="col"></div>
<div class="col"></div>
</div>
</div>
In Input Tag, I want to use value attribute so I can get a default value but I get Empty fields and I think it is because formControlName is controlling the data in my form. Is there a way to get pre-populated data using value attribute along with formControlName attribute?
Placeholder attribute works fine but I want a default value.
if you want a default value simply initialize the form with values, for example:
form = new FormGroup({
name: new FormControl('defaultNameValue'),
email: new FormControl('defaultEmailValue')
})
You should be doing it in you component instead of using value attribute. While defining the form example
studentEditForm= new FormGroup({
rollNo: new FormControl(this.student.rollNo)
})
or if student data is not available at the time of definition then use formcontrol.setValue after you initialize the student data something like
this.studentEditForm.controls.rollNo.setValue(this.student.rollNo)
Using the value and the CVA (Control Value Accessor: formControlName, formControl, and ngModel) to control the value of the input will override each other each time you change anyone of them.
Instead, it's better to rely only on one of them. If the CVA is used, then you can pass an initial value (default value) to the form-control while defining it:
studentEditForm = new FormGroup({
score: new FormControl(YOUR_INITIAL_VALUE),
});
For more info, check here how Angular passes the value from CVA to the value property when using both of them:
default_value_accessor.ts
Used value and CVA to control value
try this :
studentEditForm = new FormGroup({
score: new FormControl(VALUE),
});

How can I populate input of type text value based on dropdown selection - Angular 5

I'm fetching products from database, they are populating my dropdown.
I have ability to choose a product from dropdown, that product contains unit of measure (liter, kilo, oz etc). So basically when I choose a product from a dropdown I would like to display unit of measure in control below dropdown, like in example above.
Here is my html:
<div class="form-horizontal" action="">
<div class="form-group">
<label class="control-label dash-control-label col-sm-3">Title:</label>
<div class="col-sm-6">
<select class="form-control dash-form-control select2" style="width: 100%;">
<option selected disabled>Search...</option>
<option *ngFor="let ingredient of ingredients;" [value]="ingredient.id">{{ingredient.title}}</option>
</select>
</div>
<div class="col-sm-3">
<button type="button"
class="btn main-content-button mini-add-button"
data-toggle="modal"
data-target="#modal-3">
<i class="fas fa-plus"></i>
</button>
</div>
</div>
<!--Unit of measure-->
<div class="form-group">
<label class="control-label dash-control-label col-sm-3" for="user-lastname">Unit of measure:</label>
<div class="col-sm-4">
<input type="text" class="form-control dash-form-control read-only" placeholder="" value="Liter (L)" readonly>
</div>
</div>
<!--Quantity-->
<div class="form-group">
<label class="control-label dash-control-label col-sm-3" for="user-password">Quantity:</label>
<div class="col-sm-4">
<input type="text" class="form-control dash-form-control" id="user-password" placeholder="">
</div>
</div>
</div><!--End of form horizontal-->
So basically in my input which holds Unit of measure I would like to get unit of measure of selected product and display it there, it's just read only field :)
And here is my typescript code where I'm getting product from DB:
export class ProductIngredientNewComponent implements OnInit {
#Input() ProductId: string;
// Array that will holds all Products which represent ingredients
ingredients: Product[];
id: string;
constructor(public _productsService: ProductService) {
}
ngOnInit() {
// Here I'm getting values from DB and this values are source to dropdown
this._productsService.getAll().subscribe(ing => this.ingredients = ing);
}
}
Do I need to attach event when value in dropdown is selected, to manually set value to some property in typescript and display it in unit of measure, of there is some another more nice and more angular way?
Thanks guys
Cheers
Can you try using the following code and check if your problem is solved. I had the same situation just I had radio buttons in my case. Idea is save your object in value of Option. and assign a model to it which will contain the selected value from select box and bind the same ngmodel to your input.
Hoping it to work for you!
<div class="col-sm-6">
<select class="form-control dash-form-control select2" style="width: 100%;" [(ngModel)]="ingredient.title">
<option selected disabled>Search...</option>
<option *ngFor="let ingredient of ingredients;" [value]="ingredient">{{ingredient.title}}</option>
</select>
</div>
<input type="text" class="form-control dash-form-control read-only" placeholder="" value="Liter (L)" readonly [(ngModel)]="ingredient.title">
With Angular you have the possibility to use the two-way data binding for the selected dropdown item. First declare a property which holds the selected item in the component:
export class ProductIngredientNewComponent implements OnInit {
selectedIngredient: Product;
/* */
}
Then add the ngModel directive to your dropdown and also change the value to be the ingredient itself, instead of ingredient.id:
<select [(ngModel)]="selectedIngredient">
<option selected disabled>Search...</option>
<option *ngFor="let ingredient of ingredients;" [value]="ingredient">
{{ingredient.title}}
</option>
</select>
Then you can easily display the unit in the input field. I also added a check to avoid errors, when the selectedIngredient is not set.
<input type="text" placeholder="Unit" [value]="selectedIngredient && selectedIngredient.unitOfMeasure" readonly>

Adding a new component instance in Vue via a button click returning error

Just to preface this whole thing-- I'm not even sure that the way I'm going about this is the most correct way to do it. Basically, I need to add an instance of a Vue component when the user clicks a button, expanding. I used this discussion in the vue.js forum to help. Unfortunately, triggering this insert function via a button click is not working. Console is showing an "addNewStop is not defined at HTMLButtonElement.onclick" error.
The HTML in my template:
<div id="newCont"></div>
<button type="button" class="btn-primary" id="addStop" onclick="addNewStop()">Add Stop</button>
The script I'm calling:
import Stops from '#/components/Stops'
const ComponentCtor = Vue.extend(Stops)
const componentInstance = new ComponentCtor({})
function addNewStop() {
componentInstance.$mount('#newCont')
}
I will freely admit that I wasn't sure how to go about doing this in the first place, and have found surprisingly little information about how to insert new component instances. If there are other, better options I should be exploring beyond this, please let me know!
Edit:
Stops is actually a template containing form inputs, allowing the user to specify a delivery stop along a truck route. Here is its template:
<template>
<div class="stops">
<h4>Delivery</h4>
<div class="form-group">
<label for="shipName">Shipper Name</label>
<vue-simple-suggest
:list="simpleSuggestionList"
:filter-by-query="true" id="shipName" placeholder="Start typing a name" autocomplete="autofill-myself"></vue-simple-suggest>
</div>
<div class="form-group">
<label for="locationPickup">Location</label>
<vue-simple-suggest
:list="simpleSuggestionList"
:filter-by-query="true" id="locationPickup" placeholder="Start typing an address" autocomplete="custom-addresses"></vue-simple-suggest>
</div>
<div class="form-group row">
<label>Date</label>
<flat-pickr
:config="dateConfig"
class="form-control"
placeholder="Select date"
name="date" id="date1"></flat-pickr>
</div>
<div class="row">
<div class="form-group col left">
<label>Time</label>
<flat-pickr
:config="timeConfig"
class="form-control"
placeholder="Select time"
name="time1" id="time1"></flat-pickr>
</div>
<div class="form-group col right">
<label v-show="pickupChecked">Time 2</label>
<flat-pickr
:config="timeConfig"
class="form-control"
placeholder="Select time"
name="time2" v-show="pickupChecked" id="time2"></flat-pickr>
</div>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" v-model="pickupChecked" id="apptCheck1" >
<label class="form-check-label" for="apptCheck1">
Time range?
</label>
</div>
<div class="form-group row">
<label for="userAboutMe">Location notes:</label>
<textarea class="form-control" id="userAboutMe" rows="3" placeholder="Is there any information about the location that the driver should know?"></textarea>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="defaultCheck1">
<label class="form-check-label" for="defaultCheck1">
Save location notes for this place?
</label>
</div>
</div>
</div>
</template>
In most cases, trying to manipulate the DOM directly (e.g. by adding a component) is a sign that you're not using Vue.js as it was intended. Vue is data-driven, which means that your code should simply update the data, leaving the DOM manipulation to Vue itself. Your question doesn't provide enough details for a specific solution, but there are a couple of general approaches that might work.
If you have a number of Stop components in the DOM, and clicking on the button simply adds another, then use v-for to render the stops from data, and have the button click handler simply add another entry in the data array.
<template>
<form>
<fieldset v-for="(stop, index) in stops" :key="index">
<stop v-bind="whatever"/>
</fieldset>
<button #click="onClick">Add one</button>
</form>
</template>
<script>
export default {
data() {
return {
stops: []
};
},
methods: {
onClick() {
this.stops.push(/* whatever */)'
}
},
components {
Stop
}
};
</script>

label and value overlapping in material design with bootstrap

I'm using mdb in my ember app. I'm generating dynamic value for the input field. In the UI value and label are getting overlapped. How to deal with it?
<div class="md-form">
<i class="fa fa-user-o prefix grey-text iconSize"></i>
{{input type="text" id="firstName" class="form-control" value=model.firstName}}
<label for="firstName">First Name<i class="mandatoryIcon">*</i></label>
</div>
Try this:
didInsertElement() {
this._super(...arguments);
if (this.get('model.firstName') !== null) {
Ember.$('firstName').focus();
}
}
You can always use the autofocus attribute as well
{{input type="text" id="firstName" class="form-control" value=model.firstName autofocus=true}}

Data binding stops when adding default value to field in ng-repeat

I am re-asking the question because I left out vital info previously.
I have a date model which changes the values of an input based on this: AngularJS: How to set default value to ng-model="searchText"?.
<div class="modal-body">
<div style="display:inline-block; margin-bottom:20px;">
<h3 style="float:left;">Set All Dates: </h3>
<span style="padding-top:15px; padding-left:7px;" class="input-group date">
<input id="setAllEffectiveDates" type="text" data-ng-model="date" value="" class="form-control input-sm">
<span class="input-group-addon"><i class="glyphicon glyphicon-th"></i></span>
</span>
</div>
<table class="table table-bordered">
<tbody data-ng-repeat="(associatedContract,ndc) in ndcs">
<tr>
<td>
<div class="input-group date updateIt">
<input id="effectiveDate" type="text" data-ng-model="date" class="form-control input-sm">
<span class="input-group-addon"><i class="glyphicon glyphicon-th"></i></span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
The above works as intended, when I select a date all of the inputs change to that selected date.
My problem is that I want to add a default value to the fields. This value is a variable that is being iterated through here: <tbody data-ng-repeat="(associatedContract,ndc) in ndcs">.
<input id="effectiveDate" type="text" data-ng-model="date" ng-init="date=ndc.value" class="form-control input-sm">
Adding ng-init="date=ndc.value" does add a default value coming from the controller as expected. But it removes the data binding. The field no longer updates when changing the the input id="setAllEffectiveDates".
How can I have the default values but also have the data binding working?
edit:
updated function I added ng-change:
<input id="setAllEffectiveDates" ng-change="updateEffectiveDates(date)" type="text" data-ng-model="date" value="" class="form-control input-sm">
and then made a function:
$scope.updateEffectiveDates = function (date) {
angular.forEach($scope.ndcs, function (ndc) {
ndc.value = date;
});
console.log($scope.ndcs);
};
THis looks like it updates the model but not the fields on the page.
I suspect that ng-init is creating a new date variable on each new scope created by ng-repeat, so it won't be binding from your controller anymore. If you only need one date, try setting it to an object that exists in your controller:
Controller:
$scope.obj = {
date: null
};
View:
<input ng-init="obj.date=ndc.value">
Edit: Just bind to the date that you already have on each array element:
data-ng-model="ndc.date" ng-change="setOtherDates()"
Final answer:
<input id="setAllEffectiveDates" ng-change="updateEffectiveDates(date)" type="text" data-ng-model="date" value="" class="form-control input-sm">
then:
<input id="effectiveDate" type="text" data-ng-model="ndc.value" class="form-control input-sm">
with function:
$scope.updateEffectiveDates = function (date) {
angular.forEach($scope.ndcs, function (ndc) {
ndc.value = date;
});
console.log($scope.ndcs);
};

Categories

Resources