I want to make that styles are added to images only under a certain condition.
Here is code:
<div>
<div v-for="(item, index) in productsList" :key="item.id" class="cart-img">
<img
v-if="item.file"
:src="
`https://server.com/${
index === productsListBigIndex ? item.fileWide : item.file
}`
"
:alt="item.altText || item.text"
draggable="false"
/>
<img
v-else
:alt="item.altText || item.text"
:src="'https://server.com/empty.png'"
/>
<p style="font-size: medium">{{item.text}}</p>
</div>
</div>
The style should depend on the index and productsListBigIndex. For example, if the index is 0 or 2, then this style (in particular the size of the picture) will be added, otherwise it will not.
Thanks for answers!
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
Like this you can conditionally add or remove a classname and styles specified,
v-bind:class="getClass()"
methods:{
getClass(){
//logic to check the condition and return the class name
}
}
Related
I need to add a className based on the condtion in flatmap looping.
previousDataJson
var previousDataJson = {
"Queue1": "req_ares_crt1",
"Queue2": "req_cres_crt2",
"Queue3": "req_rres_crt3",
}
{_.flatMap(previousDataJson, (value,key) =>
<div className="columns">
<div className="column">
<div className={"transaction__info " + ({if(previousDataJson[key] != newDataJson[key]){ return "bg-blue" }})}>
<span className="transaction__title">
{key}:
</span>
<div className="transaction__desc">
<span style={{wordBreak:'break-all'}}>
{value}
</span>
</div>
</div>
</div>
</div>
)}
I need to add the classname dynamically based on the conditions.
className={"transaction__info" + (previousDataJson[key]!==newDataJson[key]?" bg-blue":"")}
Are you taking an error or isn't it compiling?
Or
You can use style object instead of appending classnames
I am making an if block per the Svelte Guide for if blocks. It seems simple enough, but Svelte thinks it's a syntax error:
[!] (svelte plugin) ParseError: Unexpected character '#'
public\js\templates\works.html
3: <div class="slides js_slides">
4: {#each works as work, index}
5: <div class="js_slide {#if index === currentIndex }selected{/if} {#if index === 0 }first{/if}">
^
6: <img src="/images/work/screenshots/{ works[index].slug }-0.{ works[index].imageExtension }"/>
7: </div>
Why isn't {#if index === currentIndex } considered valid? How can I do a conditional in Svelte?
Not I could create seperate class= blocks for every possible outcome, but that's a massive amount of work.
Blocks ({#if..., {#each... etc) can't be used inside attributes — they can only define the structure of your markup.
Instead, the convention is to use ternary expressions...
<div class="
js_slide
{index === currentIndex ? 'selected' : ''}
{index === 0 ? 'first' : ''}
">
<img src="/images/work/screenshots/{ works[index].slug }-0.{ works[index].imageExtension }"/>
</div>
...or to use a helper:
<!-- language: lang-html -->
<div class="js_slide {getClass(work, index, currentIndex)}">
<img src="/images/work/screenshots/{ works[index].slug }-0.{ works[index].imageExtension }"/>
</div>
Some people prefer to do things like data-selected={index === currentIndex} and data=first={index === 0}, and style based on [data-selected=true] selectors instead.
Since Svelte 2.13 you can also do
<div class:selected={index === currentIndex}>...</div>
See https://svelte.dev/docs#class_name
As stated in https://svelte.dev/docs#class_name , it require extra JS variable to operate if else inside class
here is a example where a each loop iterate from a to b and when if is true the css will be applied
{#each Array.from(Array(b+1).keys()).slice(a) as i }
<div class="{ i===4 ? "border-l-2 border-blue-500" : ""} p-3 space-y-4">
some sample text
</div>
{/each}
example (1 to 15) :
{#each Array.from(Array(15+1).keys()).slice(1) as i }
<div class="{ i===3 ? "border-l-2 border-blue-500" : ""} p-3 space-y-4">
some sample text
</div>
{/each}
I my vue.js application I want to know the last repeated element in a v-for directive. I know there is something similar in angularjs with the $last loop variable in its ngRepeat directive:
<div ng-repeat="(key, value) in myObj">
<span ng-if="$last">Shows if it is the last loop element</span>
</div>
Is there any equivalent in vue.js which I am not aware of or do I have to implement some own logic?
It works for me :)
<div v-for="(item, index) in items">
<span v-if="index === (items.length-1)">This is the last loop element</span>
</div>
you can also put the logic in a computed property :
<div v-for="(value, key) in myObj">
<span v-if="key === last">This is the last loop element : {{ value }}</span>
</div>
//...
computed: {
last() {
let keys = Object.keys(this.myObj)
return keys.slice(-1)[0]
}
}
fiddle here
There's no equivalent for this in Vue, no.
You can do this instead, check for index if it is last
<div v-for="(value, key, index) in myObj">
<div v-if="index === Object.keys(myObj).length-1"> my content</div>
</div>
You can try this
<div v-repeat="myObj">
<span v-if="$index === (myObj.length-1)">Shows if it is the last loop element</span>
</div>
Based on #Nisha answer I have been doing this:
<template v-for="(obj, index) in originalData">
<template v-if="index == 0 || (index >= 1 && obj.valueA !== originalData[index - 1].valueA)">
{{ obj.valueA }}
</template>
</template>
I want the loop to always happen the first time, but to conditionally check a value for every loop afterwards. I am using <template> tags to avoid outputting unnecessary markup. In my example originalData is an array of objects.
I am trying to put a "col-sm-6" inside a row with checking a condition . But when null value is coming it is returning a blank div with ".col-sm-6" class, I need to hide that class when value is null.
<div className="row">
{attribute.attributeValues.map((list, index) =>
<div className="col-sm-6" >
{list.isSelected === 1 ?
<div className="style">
<span><i className="fa fa-check"></i>{list.tag_value}</span>
</div>:''
}
</div>
)}
</div>
this is giving results like:
like:
<div class="row">
<div class="col-sm-6">Some Value</div>
<div class="col-sm-6"></div>
<div class="col-sm-6"></div>
</div>
But I want:
<div class="col-sm-6">Some Value</div>
<div class="col-sm-6">Some Value</div>
<div class="col-sm-6">Some Value</div>
You can make use of React.Fragment like
<div className="row">
{attribute.attributeValues.map((list, index) =>
<React.Fragment key={index}>
{list.isSelected === 1 ?
<div className="style">
<span><i className="fa fa-check"></i>{list.tag_value}</span>
</div>:''
}
</React.Fragment>
)}
</div>
According to the docs:
A common pattern in React is for a component to return multiple
elements. Fragments let you group a list of children without adding
extra nodes to the DOM.
Second method to remove the wrapping {} in the ternary condition
<div className="row">
{attribute.attributeValues.map((list, index) =>
list.isSelected === 1 ?
<div className="style">
<span><i className="fa fa-check"></i>{list.tag_value}</span>
</div>: null
)}
</div>
Actually, you just need to use filter (MDN documentation) before the map. You can do something like:
attribute.attributeValues.filter(list => list.tag_value).map(...
That way, with filter, you return a new Array in which only items with a "real" list.tag_value value.
In JavaScript, everything without a "Value" is False (JavaScript Booleans). That means that the filter above will filter out any list.tag_value equal to: undefined, null, empty String ("") or Number equal to 0.
I want to render image from my api, I first used size of lodash to check the array is empty or not, if it's empty display the upload button, else just render the images.
When I do
{item.photos.toString()} I'm able to see the url but why below code just doesn't work? no error at all in my console.
<div id="photo_upload">
{size(item.photos) > 1 ?
item.photos.forEach(photo =>{
<img src={photo} />
})
: <div><button>Upload</buton>
</div>}
</div>
You use condition size(item.photos) > 1 only so it won't show if you have only 1 photo.
Another thing is you should add key for each element while doing the loop
item.photos.forEach(photo =>{
<img key={photo} src={photo} />
})
forEach doesn't return anything, so that operand in your conditional will have the value undefined. You wanted map (and return inside it). Also note your closing button tag for the Upload button is missing a t (fixed below):
<div id="photo_upload">
{size(item.photos) > 1 ?
item.photos.map(photo =>{
return <img src={photo} />;
})
: <div><button>Upload</button>
</div>}
</div>
You can also use the concise arrow form:
<div id="photo_upload">
{size(item.photos) > 1 ?
item.photos.map(photo => <img src={photo} />)
: <div><button>Upload</button>
</div>}
</div>
Adding in the points raised by Đào Minh Hạt in his answer (> 0 rather than > 1, and key):
<div id="photo_upload">
{size(item.photos) > 0 ?
item.photos.map(photo => <img key={photo} src={photo} />)
: <div><button>Upload</button>
</div>}
</div>