Can we append a dynamic value to v-if condition - vue.js

Based on the index value need the if condition to dynamically change and show the contents based on that.
Have 3 dropdown and when a certain value is selected from the drop down the 4 text fields need to be shown.
When I select a value from the first dropdown and meets the v-if condition then the 4 text fields are shown and when I go and select another option from the dropdown which also meets the if criteria the text fields are shown under the 2nd dropdown but fields under the 1st dropdown goes off.
<template>
<tr
v-if="(rowIndex == index && isCtlRail)"
:id="'ctlRail_'+items.id"
style="line-height:2em;"
>
<td
style="text-align:left; vertical-align:top;font-size:9pt;"
colspan="4"
>
Length:
<br>
Left Cut:
<br>
Right Cut:
<br>
Rotate 90°:
<br>
</td>
<td>
<input
id="bap_productLen"
v-model="length"
type="number"
inputmode="numeric"
value="20"
maxlength="4"
min="20"
max="5000"
>
<br>
<select
id="leftCut"
v-model="leftCutSelected"
name="leftCut"
style="font-size:10pt;"
>
<option value="45">
45°
</option>
<option value="90">
90°
</option>
</select>
<br>
<select
id="rightCut"
v-model="rightCutSelected"
name="rightCut"
style="font-size:10pt;"
>
<option value="45">
45°
</option>
<option value="90">
90°
</option>
<option value="135">
135°
</option>
</select>
<br>
<input
v-model="rotate"
type="checkbox"
:disabled="!rotateFlag"
>
</td>
</tr>
</template>
The above is the code for the 4 text fields to be shown. In the v-if condition , isCtlRail I am setting it as true when the index is 0 or 1 or 2 based on the condition check in the method. Similarly for rowIndex as well.
Tried setting dynamic value to if but condition did not work.
For eg:-
v-if="(rowIndex_+index == index && isCtlRail_+index == index)"
so that it will be specific to that particular row but did not work , always the text fields where shown under all the 3 dropdowns.
Please let me know how to proceed further.
Below is the method where I am setting the values for rowIndex
readOrdAttribute : function(value) {
console.log("Inside the readOrdAttribute function");
if(this.orderingAttribute !== undefined && this.orderingAttribute.isCTLCable === 'true')
this.isCtlCable = true;
else
this.isCtlCable = false;
if(this.orderingAttribute !== undefined && this.orderingAttribute.isCTLRail === 'true'){
//this.isCtlRail = true;
console.log("the ctrail shape is...rectangular...." + this.orderingAttribute.rail_shape);
this.railShape = this.orderingAttribute.rail_shape;
if (value === 'showDiv_1'){
//this.isCtlRail_0 = true;
this.isCtlRail_0 = '0';
this.rowIndex = '0';
this.rowIndex_0 = '0';
this.isCtlRail = true;
}
else if (value === 'showDiv_2'){
//this.isCtlRail_1 = true;
this.isCtlRail_1 = '1';
this.rowIndex = '1';
this.rowIndex_1 = '1';
this.isCtlRail = true;
console.log("value of isCtlRail_1 is " + this.isCtlRail_1 +"and rowIndex_1 is " +this.rowIndex_1);
}
else {
//this.isCtlRail_2 = true;
this.isCtlRail_2 = '2';
this.rowIndex = '2';
this.rowIndex_2 = '2';
this.isCtlRail = true;
}
}
else{
if (value === 'showDiv_1'){
console.log("value === 'showDiv_1'");
this.isCtlRail_0 = '';
this.rowIndex_0 = '';
}
else if (value === 'showDiv_2'){
console.log("value === 'showDiv_2'");
this.isCtlRail_1 = '';
this.rowIndex_1 = '';
}
else {
console.log("value === 'showDiv_3'");
this.isCtlRail_2 = '';
this.rowIndex_2 = '';
}
}
},

Related

Dynamic Rendering with V-If

I am creating a form and I want to show certain fields only when a certain button is pressed, but take those fields away and show other fields when another button is pressed.
I am new to vue (and coding), but I think I'm wanting to use v-if, but I can't seem to return the values back to the v-if field.
If the type MAGAZINE is selected, then a method sets the typeIsMagazine to TRUE and the other typeselectors to FALSE. I would expect that once typeIsMagazine is set to true, then the v-if would be triggered and the form fields will be shown.
The method is being triggered, and I am testing it with console.log so I know the if functions are working. I just don't think it's being returned to v-if.
<template>
<form #submit.prevent="handleSubmit">
<label class="main">Type:</label>
<div class="type-row">
<div class="sub-column">
<div
class="sub"
#click="updateType('auto_stories')"
:class="{ selected: type === 'auto_stories' }"
>
Book
</div>
</div>
<div class="sub-column">
<div
class="sub"
#click="updateType('article')"
:class="{ selected: type === 'article' }"
>
Article
</div>
</div>
<div class="sub-column">
<div
class="sub"
#click="updateType('website')"
:class="{ selected: type === 'website' }"
>
Website
</div>
</div>
</div>
<template v-if="typeIsWebsite">
<label class="main">Website:</label>
<input type="text" class="text" v-model="url" required />
</template>
<template v-if="typeIsArticle">
<label class="main">Magazine:</label>
<input type="text" class="text" v-model="magazine" required />
</template>
<button class="form">Add Entry</button>
</form>
</template>
<script>
export default {
data() {
return {
typeIsWebsite: false,
typeIsArticle: false,
typeIsBook: false,
};
},
methods: {
updateType(typeSelect) {
this.type = typeSelect;
let typeIsWebsite = false;
let typeIsBook = false;
let typeIsArticle = false;
if (typeSelect === "website") {
typeIsWebsite = true;
typeIsArticle = false;
typeIsBook = false;
} else if (typeSelect === "article") {
typeIsWebsite = false;
typeIsArticle = true;
typeIsBook = false;
} else if (typeSelect === "auto_stories") {
typeIsWebsite = false;
typeIsArticle = false;
typeIsBook = true;
}
return typeIsWebsite, typeIsArticle, typeIsBook;
},
In updateType, your variables typeIsWebsite, typeIsBook, etc are declared as local variables using let. Thus, when you do the if, you are updating local variables, not your component's instance variables.
To fix, remove the typeIsX variable declarations in updateType, and use this.typeIsX to refer to each variable.
Like so:
updateType(typeSelect) {
this.type = typeSelect;
if (typeSelect === "website") {
this.typeIsWebsite = true;
this.typeIsArticle = false;
this.typeIsBook = false;
} else if (typeSelect === "article") {
this.typeIsWebsite = false;
this.typeIsArticle = true;
this.typeIsBook = false;
} else if (typeSelect === "auto_stories") {
this.typeIsWebsite = false;
this.typeIsArticle = false;
this.typeIsBook = true;
}
}
Finally, the function doesn't need to return anything.
As an extra advice, note that this is really verbose code and at least in your use case you don't need all the flags. Just keeping the current type as a string and then comparing against that would be enough. For example:
this.typeIsWebsite is equivalent to this.type === 'website'.
Remember: less code means less errors!

Infinite loop warning in vue table rendering

I tried calling a function while rendering a table, and based on condition in the function i assigned that value and displayed it using string interpolation, but i am getting infinite loop error.
Below is url for code
jsfiddle.net/amit_bhadale/5kct0au1/2/
Below is function
checkData(day, time){
let that = this
let result = this.serverData.some(a=>{
if(a.Day === day && a.Time === time){
that.cellId = a.id
// This is giving infinite loop error
// if i chnage it to this then it works
// that.cellId = 'Some normal string'
}
return (a.Day === day && a.Time === time)
})
return result
}
HTML part
<table>
<tr v-for="(time, i) in time" :key="i">
<td v-for="(day, j) in day" :key="j">
<span v-if="checkData(day, time)">
</span>
<span v-else>
No data in this cell
</span>
</td>
</tr>
</table>
Dont update props multiple times with different values within in render cycle.
To seperate those you can just put it into a single component:
e.g.:
{
props: ['time', 'day', 'serverData'],
computed: {
cellValue(){
let val = "No data in this cell"
this.serverData.some(a=>{
if(a.Day === this.day && a.Time === this.time){
val = a.id;return true;
}
})
return val
}
}
}
<template>
<span>cellValue</span>
</template>

Updating v-model data in form inputs with a series of methods in a Vuetify project?

I am attempting to update a series of v-text-fields (type='number') so that after the user has entered in a numeric value, the number shown in the input will be updated with commas (so a value of 5032 would become 5,032 for example). I found this article and was able to accomplish what I'm after with a single input using the example provided...
Markup:
<div id="app">
<div v-if="visible === true">
Enter Amount: <br>
<input type="number"
v-model="amount"
placeholder="Enter Amount"
#blur="onBlurNumber"/>
</div>
<div v-if="visible === false">
Enter Amount: <br>
<input type="text"
v-model="amount"
placeholder="Enter Amount"
#focus="onFocusText"/>
</div>
Script:
data: {
amount: null,
temp: null,
visible: true
},
methods: {
onBlurNumber() {
this.visible = false;
this.temp = this.amount;
this.amount = this.thousandSeprator(this.amount);
},
onFocusText() {
this.visible = true;
this.amount = this.temp;
},
thousandSeprator(amount) {
if (amount !== '' || amount !== undefined || amount !== 0 || amount !== '0' || amount !== null) {
return amount.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
} else {
return amount;
}
}
}
...but I want to make the methods generic enough to work with any numeric v-text-fields I am using. I have been able to update a parameter value within my methods, but have been unable to actually update the v-model data of the v-text-field.
Markup:
<div id="app">
<div v-if="visible === true">
<v-text-field
class="mb-3 d-inline-block"
type="number"
prepend-inner-icon="attach_money"
v-model="amount"
label="Amount"
mask="##########"
outline
:rules="[v => !!v || 'Amount is required']"
#blur="onBlurNumber(amount)"
required>
</v-text-field>
</div>
<div v-if="visible === false">
<v-text-field
class="mb-3 d-inline-block"
prepend-inner-icon="attach_money"
v-model="amount"
label="Amount"
outline
#focus="onFocusText(amount)"
>
</v-text-field>
</div>
Script:
onBlurNumber(data) {
this.visible = false;
this.temp = data;
data = this.thousandSeprator(data);
},
onFocusText(data) {
this.visible = true;
data = this.temp;
},
I can log the value of data in these methods and confirm that the commas are being applied correctly, but now I don't know how to send the data value back to update the v-text-field's v-model. I experimented with selecting the v-text-field using a ref value but the ref turns up as an undefined value when the method is triggered.
Does anyone know how I can update the v-model of the v-text-field using arguments in this sort of fashion so the methods are reusable?
I assume that you have multiple data items for each of the text fields:
data: function() {
return {
// Field 1
temp1: null,
amount1: null,
visible1: true,
// Field 2
temp2: null,
amount2: null,
visible2: true
}
}
In your markup, when calling the method you could then pass the name of the property, or maybe its suffix.
<v-text-field #blur="onBlurNumber('2')"
And in your script, you could update the data items by using dynamic properties:
methods: {
onBlurNumber(suffix) {
this["visible" + suffix] = false;
this["temp" + suffix] = this["amount" + suffix];
this["amount" + suffix] = this.thousandSeprator(this["amount" + suffix]);
},
Here's a working example of two independent text inputs that are calling the same methods to achieve this. We could refactor this to reduce the number of data items using arrays if needed.

I need to draw google custom search engine result and form in different div and allowOverwrite

I want to display the google custom search engine in two different dom.
I know about the
and
But with this option I should be able to use
allow google.search.Csedr.addOverride("mysite_");
so the searchbox-only and searchresults-only didnot fulfill the purpose.
I tried with various option , like
google.load('search', '1') and the rest as from documentation
And
<script>
(function() {
var cx = '111111111111111111:111111';
var gcse = document.createElement('script');
gcse.type = 'text/javascript';
gcse.async = true;
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
'//www.google.com/cse/cse.js?cx=' + cx;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(gcse, s);
})();
</script>
with both this style I was failed to do the desired task.
I have use the google.setOnLoadCallback or window.__gcse both.But no hope.Can any one help me please.
Finally I got the solution
<!-- ON searchbox page actually header-->
<div id="search">
<script>
function mycallBack(){
google.search.Csedr.addOverride("mysite_");
}
window.__gcse = {
callback : mycallBack
};
(function() {
var cx = 'xxxxxxxxxxxxx:yyyyyyy';
var gcse = document.createElement('script');
gcse.type = 'text/javascript';
gcse.async = true;
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
'//www.google.com/cse/cse.js?cx=' + cx;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(gcse, s);
})();
</script>
<gcse:searchbox-only></gcse:searchbox-only>
<!-- Header end -->
<!-- Result page start -->
<div style="display:none"><!-- Return the unescaped result URL.-->
<div id="mysite_webResult">
<div class="gs-webResult gs-result" data-vars="{longUrl:function() {
var i = unescapedUrl.indexOf(visibleUrl);
return i < 1 ? visibleUrl : unescapedUrl.substring(i);}}"><!-- Build the result data structure.-->
<table cellspacing="1">
<tbody>
<tr>
<td style="margin-left:30px;" valign="top"><a class="gs-title" data-attr="{href:unescapedUrl,target:target}" data-elif="typeof title !== 'undefined'" style="text-decoration:none !important;"> <img data-attr="{src:richSnippet.product.image, width:160, height:120}" data-if="typeof richSnippet !== 'undefined' && typeof richSnippet.product !== 'undefined' && typeof richSnippet.product.image !== 'undefined'" /> <img data-attr="{src:richSnippet.cseImage.src, width:160, height:120}" data-elif="typeof richSnippet !== 'undefined' && typeof richSnippet.cseImage !== 'undefined' && typeof richSnippet.cseImage.src !== 'undefined'" /> </a></td>
<td style="width:40px;"></td>
<td valign="top"><!-- Append results within the table cell.-->
<div class="gs-title" style="text-decoration:none; font-family:'ubuntu' sans-sertif;"> </div>
<div class="gs-snippet" data-body="html(content)" style="margin-bottom:30px;"></div>
<div data-if="Vars.richSnippet && typeof richSnippet.product !== 'undefined' && richSnippet.product.productid" style="color:#676767"><span class="gs-product-code-label" style="font-size:13px;font-weight:bold;color:black;">Product code: </span></div>
<div data-if="Vars.richSnippet && typeof richSnippet.product !== 'undefined' && richSnippet.product.oepartnumber" style="color:#676767"><span class="gs-oeproduct-code-label" style="font-size:13px;font-weight:bold;color:black;">OE Part Numbers: </span></div>
<div data-if="Vars.richSnippet && typeof richSnippet.offer !== 'undefined' && richSnippet.offer.price" style="color:#676767"><span class="gs-offer-price-label" style="font-size:20px;font-weight:bold;color:red;">£</span></div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<gcse:searchresults-only></gcse:searchresults-only>
<!-- Result page end -->

Select Option Change To Trigger Additional Code

Ok so I am trying to write a script that will show and hide items based on a users selection. I was able to figure out how to do this with a radio group but when it comes to a select item I just cant figure it out. Anyone have an idea what I'm doing wrong here?
my jQuery
$('select#contact').change(function() {
var isPhone = $('#phone').is(':selected');
var isEmail = $('#email').is(':selected');
$('#cell').toggleClass('req', isPhone);
if ( isPhone === true ) {
$('#phoneNum').animate({'height':'show'}, 500);
} else if ( isPhone === false ){
$('#phoneNum').animate({'height':'hide'}, 200);
}
$('#Remail').toggleClass('req', isEmail);
if ( isEmail === true ) {
$('#emailAdd').animate({'height':'show'}, 500);
} else if ( isEmail === false ){
$('#emailAdd').animate({'height':'hide'}, 200);
}
});
my HTML
<p>
<label for="contact">How Would You Like Us To Contact You?</label>
<select id="contact" name="contact" class="req">
<option></option>
<option id="phone">By Phone</option>
<option id="email">By Email</option>
</select>
</p>
<p id="phoneNum">
<label for="cell">Best Phone Number</label>
<input id="cell" name="cell" type="tel" placeholder="e.g. 555-555-5555" class=""/>
</p>
<p id="emailAdd">
<label for="Remail">Email</label>
<input id="Remail" name="Remail" placeholder="something#something.com" type="email" class=""/>
</p>
Figured it out:
$('select#contact').change(function() {
var isPhone = $(this).find("option:selected").is('#phone');
var isEmail = $(this).find("option:selected").is('#email');
$('#cell').toggleClass('req', isPhone);
if ( isPhone === true ) {
$('#phoneNum').animate({'height':'show'}, 500);
} else if ( isPhone === false ){
$('#phoneNum').animate({'height':'hide'}, 200);
}
$('#Remail').toggleClass('req', isEmail);
if ( isEmail === true ) {
$('#emailAdd').animate({'height':'show'}, 500);
} else if ( isEmail === false ){
$('#emailAdd').animate({'height':'hide'}, 200);
}
});