How can we write the condition(s) in If block in Express-Handlebars? - conditional-statements

I am using the Express handlebars and I am stuck at the point to compare the values in IF ELSE block.Is there built in helper? I spent a lot of time to find the solution but I didn't get that. Help would be appreciated

I have fixed this.
Reference:
https://code-maven.com/handlebars-conditionals
Solution:
To make equal '==' condition between two values using Express Helperbars do following steps.
1- Create helpers
hbs.js
module.exports = {
if_eq: function(a, b, opts) {
if (a == b) {
return opts.fn(this);
} else {
return opts.inverse(this);
}
}
}
2- Register these Helpers in app.js file
// Handlebars Helpers
const {
if_eq
} = require('./helpers/hbs'); //path to hbs.js file
// Handlebars Middleware
app.engine('handlebars', exphbs({
helpers: {
if_eq:if_eq
},
defaultLayout: 'main'
}));
3- Use if_eq helper in your HTML code.I am using to check radio button if gender is 'male' and similar to 'female' case.
{{#if_eq idea.gender 'male'}}
Female<input type="radio" class="form-control" name="gender" value="female">
Male <input type="radio" class="form-control" name="gender" value="male" checked>
{{else}}
Female<input type="radio" class="form-control" name="gender" value="female" checked>
Male <input type="radio" class="form-control" name="gender" value="male" >
{{/if_eq}}

Related

Shopify PLUS - additional checkout custom field

I was trying to add additional custom field in the checkout screen and here is my code:
<div class="additional-checkout-fields" style="display:none">
<div class="fieldset fieldset--address-type" data-additional-fields>
<div class="field field--optional field--address-type">
<h2 class="additional-field-title">ADDRESS TYPE</h2>
<div class="field__input-wrapper">
<label>
<input data-backup="Residential" class="input-checkbox" aria-labelledby="error-for-address_type" type="checkbox" name="checkout[Residential]" id="checkout_attributes_Residential" value="Residential" />
<span>Residential</span>
</label>
<label>
<input data-backup="Commercial" class="input-checkbox" aria-labelledby="error-for-address_type" type="checkbox" name="checkout[Commercial]" id="checkout_attributes_Commercial" value="Commercial" />
<span>Commercial</span>
</label>
</div>
</div>
</div>
</div>
<script type="text/javascript">
if (window.jQuery) {
jquery = window.jQuery;
} else if (window.Checkout && window.Checkout.$) {
jquery = window.Checkout.$;
}
jquery(function() {
if (jquery('.section--shipping-address .section__content').length) {
var addType = jquery('.additional-checkout-fields').html();
jquery('.section--shipping-address .section__content').append(addType);
}
});
</script>
It returns the checkout page like this -
The problem is - once I click continue button and comes back to this page again, I don't see the checkbox checked. I feel the values are not being passed or may be something else.
What am I missing?
From the usecase, it looks like you want the user to select the Address Type either Residential or Commercial so a raido button group seems more suitable. I have edited the HTML to create the Radio Button instead of Checkbox. To maintain the state, I have used Session Storage. You may also replace Session Storage with Local Storage if you want to do so. For explanation check code comments.
<div class="additional-checkout-fields" style="display:none">
<div class="fieldset fieldset--address-type" data-additional-fields>
<div class="field field--optional field--address-type">
<h2 class="additional-field-title">ADDRESS TYPE</h2>
<div class="field__input-wrapper">
<label>
<input class="input-radio" aria-label="" type="radio" name="checkout[address_type]" id="checkout_attributes_Residential" value="residential" checked>
<span>Residential</span>
</label>
<label>
<input class="input-radio" aria-label="" type="radio"name="checkout[address_type]" id="checkout_attributes_Commercial" value="commercial">
<span>Commercial</span>
</label>
</div>
</div>
</div>
</div>
JavaScript part
<script type = "text/javascript" >
if (window.jQuery) {
jquery = window.jQuery;
} else if (window.Checkout && window.Checkout.$) {
jquery = window.Checkout.$;
}
jquery(function() {
if (jquery('.section--shipping-address .section__content').length) {
var addType = jquery('.additional-checkout-fields').html();
jquery('.section--shipping-address .section__content').append(addType);
// Get saved data from sessionStorage
let savedAddressType = sessionStorage.getItem('address_type');
// if some value exist in sessionStorage
if (savedAddressType !== null) {
jquery('input[name="checkout[address_type]"][value=' + savedAddressType + ']').prop("checked", true);
}
// Listen to change event on radio button
jquery('input[name="checkout[address_type]"]').change(function() {
if (this.value !== savedAddressType) {
savedAddressType = this.value;
sessionStorage.setItem('address_type', savedAddressType);
}
});
}
});
</script>
You are responsible for managing the state of your added elements. Shopify could care a less about stuff you add, so of course when you flip around between screens, it will be up to you to manage the contents. Use localStorage or a cookie. Works wonders. As a bonus exercise, ensure that your custom field values are assigned to the order when you finish a checkout. You might find all your hard work is for nothing as those value languish in la-la land unless you explicitly add them as order notes or attributes.

Vee-Validate custom errror component with scopes

I wanted to create a custom component to use Vee-Validate scopes to display the error.
Currently for the forms with the scope i am doing in a following ways.
Submit Method:
methods: {
onSubmit(scope) {
console.log(this.$validator)
this.$validator.validateAll().then((result) => {
if (result) {
alert('Form Submitted!');
}
});
}
}
HTML
<label>Name</label>
<input v-model="form_fields.name" data-vv-as="Partner name" data-vv-name="PartnerName" v-validate="'required'" :class="{'input': true, 'is-danger': errors.has('form-partner.PartnerName') }" type="text" class="form-control">
<div v-show="errors.has('form-partner.PartnerName')" class="help is-danger text-red">{{ errors.first('form-partner.PartnerName') }}</div>
which means i have to repeat errors.has('form-partner.PartnerName') multiple times, all over the forms.
I wanted to simplified as below.
<error-form :status="errors" :css-class="'is-danger'" label="Company Name" field="name">
<b-form-input v-validate="'required'" class="form-control" v-model="form_fields.name" name="name" data-vv-as="Company Name"
type="text" />
</error-form>
Similar to the implementation from here! but this is not working with the scopes.
I wanted to have the validation done with scopes. I will pass the scopes to the error-form as a prop like shown below.
///scope here
<error-form :status="errors" :scope='form-registraion' :css-class="'is-danger'" label="Company Name" field="name">
So, how i can check on my error-form component with the scopes? scopes could be mandatory or required.

How to validate a formcontrol with prepopulated data in Angular 5?

I have a form-group. In the form-group, i have a form-array. I have initialized the array with items created from data in the data model with the method as described in angular's documentation on reactive forms, under the section Initialize the secretLairs FormArray. The problem is i need to perform validation.required for each form control in the array. However, since the form-controls already hold values, i do not know how to perform validation.required. The documentation did not go further on how to validate formcontrols in a formarray that are prepopulated.
Here are my source codes:
.html
<!-- list of Questions -->
<div formArrayName="questions">
<!-- <div *ngFor="let que of Questions; let k=index"> -->
<div *ngFor="let question of Ques ; let i=index" [formGroupName]="i" >
<!-- The repeated questions template -->
<h4>{{question.ques}}</h4>
<div style="margin-left: 1em;">
<!-- <div class="form-group">
<label class="center-block">
<input class="form-control" formControlName="ques" >
</label>
</div> -->
<div class="form-group radio" *ngFor="let choice of
question.choices; let j = index">
<input type="radio" formControlName="choices"
class="custom-control-input" [value]="choice.choiceText">
<label>{{choice.choiceText}}</label>
</div>
<br>
<!-- End of the repeated questions template -->
</div>
</div>
</div>
<button type="submit" class="btn btn-danger"
[disabled]="!CheckListForm.valid">Submit</button>
</form>
.ts
export class CheckListFormComponent implements OnInit, OnChanges {
CheckListForm: FormGroup;
Ques: Questions[];
employmenttype = ['Permanent', 'contractor'];
constructor(private fb: FormBuilder,
private checklistservice: ChecklistService) {
this.CreateForm();
}
ngOnInit() {
this.checklistservice.getQuestions(1).subscribe(res =>{ this.Ques =res;
this.setquestions(this.Ques)
});
this.CheckListForm.get('EmploymentType').valueChanges.subscribe(
(EmploymentType: string) => {
if (EmploymentType === 'Permanent') {
this.CheckListForm.get('HRMS').setValidators([Validators.required]);
this.CheckListForm.get('CompanyName')
.setValidators([Validators.nullValidator]);
} else if (EmploymentType === 'contractor') {
this.CheckListForm.get('CompanyName').
setValidators([Validators.required]);
this.CheckListForm.get('HRMS').
setValidators([Validators.nullValidator]);
}
this.CheckListForm.get('HRMS').updateValueAndValidity();
this.CheckListForm.get('CompanyName').updateValueAndValidity();
}
)
}
CreateForm() {
this.CheckListForm = this.fb.group({
name: ['', Validators.required],
EmploymentType: ['', Validators.required],
HRMS: [''],
CompanyName:[''],
questions: this.fb.array([])
})
}
get questions(): FormArray {
return this.CheckListForm.get('questions') as FormArray;
}
setquestions(questions: Questions[]) {
const QuestionsFGs = questions.map(questions => this.fb.group(questions));
const QuestionsFormArray = this.fb.array(QuestionsFGs);
this.CheckListForm.setControl('questions', QuestionsFormArray);
}
As usual, as there is no response from anyone, I will post the answer which i have painstakingly solved.
You cannot validate form-controls through the method i have performed(see my codes). The reason is because the form-controls already hold data and is not empty in the first place. Hence, validation.required will not work.
A solution will be to instead push empty form-controls for each item in the array of the data model.
Validation.required will then work for this case.

v-on:model="form.email" expects a function value, got undefined

Vue.js 2 - I am trying to bind form inputs but I always get the erro message ( on all inputs ..)
v-on:model="form.email" expects a function value, got undefined
<form id="registrationForm">
<div class="form-group">
<input type="email" name="email" id="email" #model="form.email" placeholder="enter your email address">
</div>
<button #click="sendRegistration" type="submit" class="btn btn-primary btn-gradient submit">SEND</button>
</form>
and the script
data: function() {
return {
form: {
...
email: '',
...
}
}
},
methods: {
sendRegistration: function() {
console.log('sending form')
return false
}
},
You're getting some things mixed up. Attributes starting with v-on:, often abbreviated as #, are used to register event listeners on elements. #click="sendRegistration" will for example register the sendRegistration method defined on your Vue instance as a handler for that element's click event.
What you're trying to accomplish has nothing to do with event handling. The attribute you need is called v-model and binds an <input>'s value to a value saved on your Vue instance.
<input type="email" name="email" id="email" #model="form.email">
should be
<input type="email" name="email" id="email" v-model="form.email">

vuejs set a radio button checked if statement is true

I am trying to make a radio button checked using vuejs v-for only if my if-statement is true. Is there a way to use vuejs' v-if/v-else for this type of problem?
in php and html I can achieve this by doing the following:
<input type="radio" <? if(portal.id == currentPortalId) ? 'checked="checked"' : ''?>>
Below is what I have so far using vuejs:
<div v-for="portal in portals">
<input type="radio" id="{{portal.id}}" name="portalSelect"
v-bind:value="{id: portal.id, name: portal.name}"
v-model="newPortalSelect"
v-on:change="showSellers"
v-if="{{portal.id == currentPortalId}}"
checked="checked">
<label for="{{portal.id}}">{{portal.name}}</label>
</div>
I know the v-if statement here is for checking whether to show or hide the input.
Any help would be very much appreciated.
You could bind the checked attribute like this:
<div v-for="portal in portals">
<input type="radio"
id="{{portal.id}}"
name="portalSelect"
v-bind:value="{id: portal.id, name: portal.name}"
v-model="newPortalSelect"
v-on:change="showSellers"
:checked="portal.id == currentPortalId">
<label for="{{portal.id}}">{{portal.name}}</label>
</div>
Simple example: https://jsfiddle.net/b4k6tpj9/
Maybe someone finds this approach helpful:
In template I assign each radio button a value:
<input type="radio" value="1" v-model.number="someProperty">
<input type="radio" value="2" v-model.number="someProperty">
Then in the component I set the value, i.e:
data: function () {
return {
someProperty: 2
}
}
And in this case vue will select the second radio button.
You can follow below option if you can adjust with your logic:
<div class="combination-quantity">
<input type="radio" value="Lost"
v-model="missing_status">
<label for="lost">Lost</label>
<br>
<input type="radio" value="Return Supplier" v-model="missing_status">
<label for="return_supplier">Return Supplier</label>
</div>
Value for missing_status could be "Lost" or "Return Supplier" and based on the value radio option will be get selected automatically.
Below is an example of keeping track of the selected radiobutton, by
applying a value binding to the object (:value="portal") and
applying a v-model binding to the currently selected object (v-model="currentPortal").
The radiobutton will be checked automatically by Vue, when the two match (no :checked binding necessary!).
Vue 3 with composition API
Vue.createApp({
setup() {
const portals = [{
id: 1,
name: "Portal 1"
}, {
id: 2,
name: "Portal 2"
}];
const currentPortal = portals[1];
return {
portals,
currentPortal
}
}
}).mount("#app");
<script src="https://unpkg.com/vue#next"></script>
<div id="app">
<template v-for="portal in portals">
<input
type="radio"
:id="portal.id"
name="portalSelect"
:value="portal"
v-model="currentPortal">
<label :for="portal.id">{{portal.name}}</label>
</template>
</div>
I would like to point out a few options when dealing with radios and vue.js. In general if you need to dynamically bind an attribute value you can use the shorthand binding syntax to bind to and calculate that value. You can bind to data, a computed value or a method and a combination of all three.
new Vue({
el: '#demo',
data() {
return {
checkedData: false,
checkedGroupVModel: "radioVModel3", //some defaul
toggleChecked: false,
recalculateComputed: null
};
},
computed: {
amIChecked() {
let isEven = false;
if (this.recalculateComputed) {
let timeMills = new Date().getMilliseconds();
isEven = timeMills % 2 === 0;
}
return isEven;
}
},
methods: {
onToggle() {
this.toggleChecked = !this.toggleChecked;
return this.toggleChecked;
},
mutateComputedDependentData() {
this.recalculateComputed = {};
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="demo">
<div>
<div>
<span>Simple Radio Group - Only one checked at a time. Bound to data.checkedData</span><br>
<label>Radio 1 - inverse of checkedData = {{!checkedData}}
<input type="radio" name="group1" value="radio1" :checked="!checkedData">
</label><br>
<label>Radio 2 - checkedData = {{checkedData}}
<input type="radio" name="group1" value="radio2" :checked="checkedData">
</label><br>
<span>Understanding checked attribute: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-checked</span>
</div>
<br>
<div>
<span>Simple Radio - Checked bouned to semi-random computed object</span><br>
<label>Radio 1: {{amIChecked}}
<input type="radio" :checked="amIChecked">
</label>
<label>Recalculate Computed Value
<button type="button" #click="mutateComputedDependentData">Click Me Several Times</button>
</label>
</div>
<br>
<div>
<span>Simple Radio Group - v-model bound value = {{checkedGroupVModel}}</span><br>
<label>Simple Radio 1:
<input type="radio" name="vModelGroup" value="radioVModel1" v-model="checkedGroupVModel">
</label><br>
<label>Simple Radio 2:
<input type="radio" name="vModelGroup" value="radioVModel2" v-model="checkedGroupVModel">
</label><br>
<label>Simple Radio 3:
<input type="radio" name="vModelGroup" value="radioVModel3" v-model="checkedGroupVModel">
</label>
</div>
<br>
<div>
<span>Simpe Radio - click handler to toggle data bound to :checked to toggle selection</span><br>
<label>Toggle Radio = {{toggleChecked}}
<input type="radio" :checked="toggleChecked" #click='onToggle()'>
</label>
</div>
</div>
</div>