Using expression in ngmodel in angular 1.2 - javascript

I am trying to show checkboxes checked or unchecked based on certain condition. for eg:
$scope.userRoles = {"grants" : [
"Permission",
"View",
"Update",
"Delete"
]}
On the HTML part i have added the following code:
<div ng-repeat="p in userRoles">
<input type="checkbox" ng-model="p.grants.indexOf('Delete') != -1?true:false" ng-change="AddRemovePermission(p,'Delete')" />
</div>
If i use ng-checked instead of ng-model than it works fine, but i will not get 2 way binding with that. Also i know we cant use expressions like above in ng-model.
Can anybody help on how this can be done. The only condition is if user has grants than the checkbox should be checked else not, and when clicked on checkbox it should be changed to checked or unchecked accordingly and gets added in the userRoles object. Cant use directive as well.
Thanks.

The problem is your model. You must send boolean to backend, this can be a solution:
In view:
<div ng-repeat="role in userRoles.grants">
<input type="checkbox" ng-model="role.checked" />
</div>
And in controller:
$scope.userRoles = {"grants" : [
{"permission": "Permission", checked: true },
{"permission": "View", checked: false },
{"permission": "Update", checked: true },
{"permission": "Delete", checked: true }
]}

Related

How do I find a radio button by value to check it with another element - VueJS

I apologize for the title being a little hard to understand. I had a hard time explaining it in one line. But here's what I'm trying to do.
I'm developing a screen within my app that supports a barcode gun reader. Barcode guns can only interact with textfields. And then through a text field(hidden) I can pass a custom barcode that instructs the UI to do something. Here is the UI explanation for clarity:
I have a radio button group with 2 options (yes and no)
I have a hidden textfield to accept the barcode gun read
I have a barcode for "yes" and another for "no"
If I scan the "yes" barcode, the radio button option with value = "Yes", should be checked
If I scan the "no" barcode, the radio button option with value = "No", should be checked
I initially thought that by changing the v-model to the correct value, it will do it, but it didn't check it. Likewise, by changing the v-model.value to true or false it will check to its appropriate value. But no cigar.
My idea on how this would work is by (pseudocode)
if querySelector with name ragrouphidden.value = "Yes" then find the option whose value is Yes and option.checked = true
else if querySelector with name ragrouphidden.value = "No" then find the option whose value is No and option.checked = true
The "find" part is what eludes me, or maybe there is an easier way.
Here's some relevant code
Template
<div>
<q-input
class="hidden-field"
v-model="ragrouphidden"
name="ragrouphidden"
#change="raSelectOption()">
</q-input>
<div>
<label class="col-6 text-weight-medium">Mark for Remote Adjudication</label>
<div>
<q-option-group
v-model="ragroup"
:options="raoptions"
#check="raRules($event.target.value)"/>
</div>
</div>
</div>
Script
data() {
return {
ragrouphidden: "",
ragroup: null,
raoptions: [
{
label: "Yes",
value: true
},
{
label: "No",
value: false
}
],
}
},
methods: {
raSelectOption() {
setTimeout(() => {
let hasFocus = document.querySelector("input[name=ragrouphidden]");
hasFocus.focus();
}, 500);
if (
document.querySelector("input[name=ragrouphidden]").value === "*yes*"
) {
this.ragroup.value = true; //this is what I need
} else if (
document.querySelector("input[name=ragrouphidden]").value === "*no*"
) {
this.ragroup.value = false; //This as well
}
},
}
Hopefully it makes sense to you guys. Thanks in advance.
You don't need to use ragroup.value to set the model value here. You can simply do this.ragroup = true; and vue will automatically set the q-option-group selected value for you behind the scene.
A simple demo with dynamic checkbox:
var demo = new Vue({
el: '#demo',
data: {
checked: [],
categories: [{ Id: 1 }, { Id: 2 }]
},
mounted(){ this.checked = [2] }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="demo">
<ul>
<li v-for="c in categories">
<input type="checkbox" :value="c.Id" :id="c.Id" v-model="checked" />
{{c.Id}}
</li>
</ul>
</div>

Hide/Show a checkbox based on json value

I have 4 check boxes and I want to hide/show them based on the value that I am getting in my JSON. I'll get only one name of checkbox in my JSON and only that particular checkbox will be shown to user and it'll be marked as checked. How can I do that? Here is my material checkbox code
<div fxLayout="row wrap" class="py-8" fxLayoutAlign="space-evenly">
<mat-checkbox>Fragile</mat-checkbox>
<mat-checkbox>Flyer</mat-checkbox>
<mat-checkbox>Time Stipulated</mat-checkbox>
<mat-checkbox>Gift Wrapped</mat-checkbox>
</div>
Here is my json
Since I am getting name as flyer so only flyer checkbox will be shown to user as checked while all other will not be shown to user.
Not Cleared with your question. You are using Mat-checkbox without using of JSON file
If your Json will be
SampleJson= [
{
Name: "Fragile",
isActive: true
},
{
Name: "Flyer",
isActive: true
},
{
name: "Time Stipulated",
isActive: true
},
{
name: "Gift Wrapped",
isActive: false
},
]
then modify your html to
<div fxLayout="row wrap" class="py-8" fxLayoutAlign="space-evenly">
<mat-checkbox [(ngModel)]="SampleJson[0].isActive">Fragile</mat-checkbox>
<mat-checkbox [(ngModel)]="SampleJson[1].isActive">Flyer</mat-checkbox>
<mat-checkbox [(ngModel)]="SampleJson[3].isActive">Time Stipulated</mat-checkbox>
<mat-checkbox [(ngModel)]="SampleJson[0].isActive">Gift Wrapped</mat-checkbox>
</div>
Hope it works for you. Happy coding

How to add disabled attribute in input text in vuejs?

I have 2 urls
/register
/register?sponsor=4
The /register route will give me a clean input text in which I can type everything
and the second route will bring a the same input but it has a value of 4 and it's disabled so users cannot modify it.
I managed to get params from router dynamic using vue-router and everything is fine,
but when I visit /register I get the clean input but as soon as I start typing the input will be disabled and I can only type one character.
This what I tried so far,
HTML :
<input :disabled="sponsor ? true : false" v-model="sponsor" id="sponsor" type="number" class="form-control" name="sponsor" value="" required tabindex="14">
Javascript vuejs
<script type="text/javascript">
var router = new VueRouter({
mode: 'history',
routes: []
});
new Vue({
router,
el: '#app',
data () {
return {
cities: [],
city: '',
selectedCountry: '',
sponsor: null
}
},
mounted: function() {
if (this.$route.query.sponsor) {
this.sponsor = this.$route.query.sponsor
console.log(this.sponsor)
}
},
methods: {
onChangeCountry() {
axios.get('http://localhost:8000/api/cities/country/' + this.selectedCountry)
.then(response => this.cities = response.data)
.catch(error => console.log(error))
}
}
});
</script>
disabled is not a Boolean attribute.
The mere presence of the attribute means that the input is disabled.
The only allowed attribute values for disabled are "disabled" and "".
So these three variations are legal to create a disabled input:
<input disabled ... />
or
<input disabled="" ... />
or
<input disabled="disabled" ... />
If you do
<input disabled="false" ... />
that will still disable the input simply because the attribute disabled is on it - on top of being invalid HTML because of an illegal attribute value.
Check it out here:
<input type="text" disabled="false" />
So to solve your problem you need to find a way to not create the attribute on the input in case you don't want to disable it.
Edit: Turns out Vue.js creators have prepared this:
In the case of boolean attributes, where their mere existence implies true, v-bind works a little differently. In this example:
<button v-bind:disabled="isButtonDisabled">Button</button>
If isButtonDisabled has the value of null, undefined, or false, the disabled attribute will not even be included in the rendered element.
https://v2.vuejs.org/v2/guide/syntax.html#Attributes
The problem here is that you are binding the input value to sponsor with v-model="sponsor", so when you star typing, the sponsor get the value and disable the input,
you have to set a flag to know if the value of sponsor comes from the route, and apply the disable logic with that flag. Or directly use the $route.query.sponsor on the :disabled (:disabled="$route.query.sponsor")
<input :disabled="isFromRoute" v-model="sponsor" />
mounted: function() {
if (this.$route.query.sponsor) {
this.sponsor = this.$route.query.sponsor
this.isFromRoute = true //set the flag, make sure to have it in your data section
}
},
Try this one:
<input :disabled="$route.query.sponsor ? true : false" v-model="sponsor" id="sponsor" type="number" class="form-control" name="sponsor" value="" required tabindex="14">

how to add elements into a form by using ng-click?

I have a form that has 4 fields
<form name="form">
Name:
<input type="text" ng-model="edit.name"><br />
age:
<input type="text" ng-model="edit.age"><br />
phone:
<input type="text" ng-model="edit.phone"><br />
address:
<input type="text" ng-model="edit.address"><br />
</form>
And i have an array in the app.js
$scope.statuses = [
{value: 1, text: 'status1'},
{value: 2, text: 'status2'},
{value: 3, text: 'status3'},
{value: 4, text: 'status4'}
];
I am repeating that array in the html and what i want to do is that i want the text to appear in the form when a button such as "edit" is clicked
PLUNKER
So basically as you can see in the plunker when i click on the edit button i want "status1" "status2" "status3" "status4" to appear in the fields that are in the form "name" "age" "phone" and "address"
Your question was a bit unclear, but I think what you want to do is change statuses to the form values.
I create this plunker for you
on your ng-click function. I change the statuses array text (which is shown with ng-repeat in your html) to your forms edit values:
$scope.editFunction = function(edit){
$scope.statuses[0].text=edit.name;
$scope.statuses[1].text=edit.age;
$scope.statuses[2].text=edit.phone;
$scope.statuses[3].text=edit.address;
};
or if you want your array values be in your form just reverse the = in your function like plunker :
but in this case,if you want your empty form to work, you should declare edit before in your controller.
$scope.edit=[];
$scope.editFunction = function(edit){
edit.name=$scope.statuses[0].text;
edit.age=$scope.statuses[1].text;
edit.phone=$scope.statuses[2].text;
edit.address=$scope.statuses[3].text;
};
and so you are using ng-model.there is no need to pass argument to your function, you can use $scope.edit instead of a passing argument in your editFunction

Autoform insert: doc value isn't having any effect

I have this quickForm:
{{> quickForm id="insertFixie" collection="Fixies" type="insert" doc=seedObject}}
Backed up by this schema:
Fixies = new Meteor.Collection('fixies');
Schema.Fixies = new SimpleSchema({
description: {
type: String,
label: "Description",
trim: true,
optional: true
},
cost: {
type: Number,
label: "Cost",
min: 0,
decimal: true
},
product_id: {
type: String,
autoform: {
omit: true
}
},
});
Fixies.attachSchema(Schema.Fixies);
and this seedObject method:
Template.insertFixie.helpers({
seedObject: function () {
console.log({product_id: this._id});
return {product_id: this._id};
}
});
When that console call directly above happens, it's correct and gives something to this effect:
Object {product_id: "1"}
But when I submit the form with something valid (like "stuff" and "100"), I get this error:
insert error:
Error: Product is required {invalidKeys: Array[1],
validationContext: SimpleSchemaValidationContext,
stack: (...),
message: "Product is required"}
stating that the product_id attribute is required and currently has a value of null.
What am I doing wrong? That product_id is a template dependent value, so something like "autoValue" in the schema doesn't seem like the best way to handle it.
The docs seem to clearly state that I'm using things correctly. From the description of the doc attribute of Auto Form:
For an insert form, you can also use this attribute to pass an object
that has default form values set (the same effect as setting a value
attribute on each field within the form).
And from the description of the value attribute of afFieldInput:
value: Set a specific, potentially reactive, value for the input. If
you have also provided a doc attribute on the autoForm or quickForm,
this value will override the value from the doc object.
What am I missing?
Edit
I added an autoValue field to my schema, just to see what pops up:
autoValue: function (doc) {
console.log(doc)
console.log(this.value)
return "1";
}
This allows the form to correctly submit, but with the incorrect hard-coded value of "1" rather than a useful value from the template. The two console logs show this:
:24 Object {description: "stuff", cost: 50}
:25 undefined
It seems my seedObject value isn't available to autoValue.
Do I have to hijack the onSubmit hooks? Do I have to have hidden form inputs with values supplied from the template? What's the fix here?
It turned out to be a hidden input.
I expanded my form to this:
{{#autoForm id="insertFixie" collection="Fixies" type="insert"}}
<fieldset>
{{> afFormGroup name="description" placeholder="schemaLabel" label=false}}
<div class="form-group{{#if afFieldIsInvalid name='cost'}} has-error{{/if}}">
<div class="input-group">
<div class="input-group-addon">$</div>
{{> afFieldInput name="cost" placeholder="schemaLabel" label=false}}
</div>
{{#if afFieldIsInvalid name="cost"}}
<span class="help-block">{{afFieldMessage name="cost"}}</span>
{{/if}}
</div>
{{> afFormGroup name="product_id" type="hidden" value=_id}}
</fieldset>
<button class="btn btn-primary" type="submit">Insert</button>
{{/autoForm}}
Adding an afFormGroup with type="hidden" did exactly the trick.
Although it still seems to me like the doc argument isn't living up to it's promises.

Categories