I have an array of objects, where each object has a textValue, an active, info, etc. This arrangement I walk through and show buttons for each element. To each button inside I add a div and inside 3 paragraphs, I'm trying to add classes and display some of the paragraphs by condition to each button. I add an event to the button and pass it an id, with this I set the active to true and show information, this for each different id. Clicking on a button makes an active class and shows a quantity, clicking outside or on the button itself eliminates the class and the quantity (p), when I click on a button information opens, here I have a button that when clicking, the div with the information is hidden (I already do this) and I want to keep the class visible and the paragraph visible, I'm using conditionals for this, but I can't do it, this is the code:
<button
v-for="filter in addedFilters"
:key="filter"
:value="filter.textValue"
#click="(e) => {openInfoFiltro(filter, e)}"
:class="{'filter-active': filter.active && !optionButtonValue.includes(filter.textValue), 'active-filter-options': filter.active && optionButtonValue.includes(filter.textValue)}">
<div>
<p v-if="filter.active && filter.textValue !== 'Uso de suelo' && filter.textValue !== 'Amenidades' && filter.textValue !== 'Clasificación de la tierra' & filter.textValue !== 'Vocaciones'" class="m-0">
{{ $filters.numeralFormatBtnInfo(filter.info[0]) }} - {{$filters.numeralFormatBtnInfo(filter.info[1]) }}
</p>
<p v-else-if="filter.active || filter.textValue === 'Uso de suelo' && filter.textValue === 'Amenidades' && filter.textValue === 'Clasificación de la tierra' && filter.textValue === 'Vocaciones'" class="m-0 amount">
<span v-if="filter.info">({{filter.info === 0 ? '' : filter.info }})</span>
</p>
<p class="m-0">{{filter.textValue}}</p>
</div>
</button>
function when clicking on the button and setting the active of the object to true
const openInfoFiltro = (id,e) => {
selectedFilter.value = addedFilters.value.find(val => val.textValue === id.textValue);
console.log(selectedFilter.value)
if(selectedFilter.value){
selectedFilter.value.active = !selectedFilter.value.active
}
}
array where i have the different text Value
const optionButtonValue = ['Uso de suelo', 'Amenidades', 'Clasificación de la tierra', 'Vocaciones' ]
In another component I go through provide and reject the ref, where I pass the selected filter (selectedFilter) and here I have a function where when clicked, I want the button to remain active and depending on the optionButtonValue, show one paragraph or the other, but leave it active, right here I pass the active to false to hide the information of each button
const showResults = () => {
console.log('Mostrar resultados')
landsStore.lands = []
landsStore.landsadd = []
selectedFilter.value.active = false
landsStore.fetchLands('', { filters: filtersStore.getAllFiltersAlgoliaFormat, facetFilters: filtersStore.getAllFacetFilterFormat })
}
Actually, v-if waits from you only true and false. But you are use in v-if text definition. This is not correctly. Firstly, you can change v-if only conditionally like v-if="{filter.active || filter} " also in your p tag you can type define directly change text {{ filter.active && 'bla bla' }}
Related
I can usage .slice method for cut a word. Here is example:
let UserID = 4EA1FC29-08D0-5A49-8754-DBD2691A0D36
let ShortUserID = UserID.slice(0, 14)
console.log(ShortUserID) here is console print: 4EA1FC29-08D0-
But my idea is click "..." button and open "selected row only" id.
Click a "..." button and show full id on just selected row(in this example clicking the button opens the id of all rows). My template is wrong. Here is my template:
Click button and show all ID's. Not "selected row". I want a click "..." button and show just selected row full id. I hope i could explain.
Here is my code template:
let ShortUserID = UserID.slice(0, 14)
const handleFullUserID = (index) => {
setIsClicked(!isClicked) //True-False Operator
}
if (isClicked) {
ShortUserID = UserID
}
return (
<tr key={index}>
<td>
{ShortUserID}(notfixed)
<button onClick={(index) => handleFullUserID(index)}>
...
</button>
</td>
</tr>
)
{isClicked ? UserID : ShortUserID}
I am looping over some data and rendering it into the browser like
{paymentPeriods.map((item, index) => {
return (
<>
<div
className={`payment-card ${
type.toLowerCase() == item.type.toLowerCase()
? "payment-card-active"
: ""
}`}
key={index}
onClick={() => {
setPaymentPeriodValue(item);
}}
>
<div
className={`payment-card-title ${
type.toLowerCase() == item.type.toLowerCase()
? "payment-card-title-active"
: ""
}`}
>
{item.type.toLowerCase() == "annual"
? "ANNUAL"
: "MONTHLY"}
</div>
<div className="payment-card-body">
//Some dummy text
</div>
{item.type.toLowerCase() != "annual" && (
<p className="installments_check" onClick={()=>alert('123')}>
Verifique todas as outras parcelas
</p>
)}
</div>
</>
);
})}
As you can see upon clicking on div, I am running a function
setPaymentPeriodValue(item);
which is used to set the div as active so that it is highlighted upon click and the info get stored in my react state locally, now there is also a text inside my div which i am showing like
{item.type.toLowerCase() != "annual" && (
<p className="installments_check" onClick={()=>alert('123')}>
Verifique todas as outras parcelas
</p>
)}
So on clicking on this text (it is inside the main div) the alert is seen by the user but then it also runs setPaymentPeriodValue function which sets div to the active state, and i do not want this as i only need to show the alert on click of the text
Thanks
You can do it by using stopPropagation method of the Event (this method stops the bubbling of an event to parent elements). like this:
{
item.type.toLowerCase() != "annual" && (
<p className="installments_check" onClick={(e)=>{ alert('123'); e.stopPropagation(); } }> Verifique todas as outras parcelas </p>
)
}
I have an array that contains Title1, Title2, Title3, all the way to Title8. If that item is not empty I want to display with it's corresponding information. Currently that works.
However I want to add a button that will allow me to display all fields. For example let's say Title1 through Title3 is not null. It will show that (which it currently does). I want to add a button that when clicked will display all Titles 1-8.
Here is my current code. In the code below I'm only showing 4 if statements and removed all content to save space:
{ this.state.showExtraRows? <div>
{ this.state.Product[0].Title1 ?
<div>
//Display some fields here
</div>
: null
}
{ this.state.Product[0].Title2 ?
<div>
//Display some fields here
</div>
: null
}
{ this.state.Product[0].Title3 ?
<div>
//Display some fields here
</div>
: null
}
{ this.state.Product[0].Title4 ?
<div>
//Display some fields here
</div>
: null
}
</div>
: null
}
<button className={styles.btn}
type="button"
onClick={()=>{this.setState({showExtraRows:!this.state.showExtraRows})}}>
{ this.state.showExtraRows? 'Hide Rows' : 'Show Rows'}
</button>
I'm not too sure if I'm supposed to wrap the whole thing in the this.state.showExtraRows? statement.
I think it's better to use a map function here
const productWithTitles = this.state.Product.filter((Product) => !!Product.title);
return (
<div>
{this.state.showExtraRows && (
<div>
{productWithTitles.slice(0, 3).map((product) => {
return (
<div>
//Display some fields here
</div>
);
})}
</div>
)}
</div>
);
I have multiple buttons on one page, "Add to cart" buttons where each button has a unique id attribute.
I want to hide a particular button when the user clicks on it.
The issue:
What's happening currently is that when a user clicks on a button 1 it hides, then clicks on button 2 it hides but on the same time it shows button 1
The expected behavior:
When the user clicks on button 1 it should hide and keep hiding even after clicking on button 2
P.S. the information of the buttons (products) gets added to an array.
Current code:
Html:
<div *ngFor="let product of products; let i = index">
<div *ngIf="hideButton != i" [attr.id]="i" class="addButton" (click)="addToCart(product, i)">ADD</div>
</div>
JS
addToCart(itemDetails, index) {
this.hideButton = index;
}
You need an array of hidden buttons and you need to add the index to that array:
JS:
// at the top
hiddenButtons = [];
addToCart(itemDetails, index) {
this.hiddenButtons.push(index);
}
HTML:
<div *ngFor="let product of products; let i = index">
<div *ngIf="hiddenButton.indexOf(i) === -1" [attr.id]="i" class="addButton" (click)="addToCart(product, i)">ADD</div>
</div>
If you have a cart to which products are being added, you can look in the cart to check whether the product already exists in it, and use that to decide whether to display the ADD button.
If your product objects can have more properties to them, you can do away with indexes completely.
HTML
<div *ngFor="let product of products">
<div *ngIf="productInCart(product)" [attr.id]="product.id" class="addButton" (click)="addToCart(product)">ADD</div>
</div>
JS
productInCart(product) {
return this.products.findIndex(p => p.id==product.id)!=-1;
}
addToCart(product) {
this.products.push(product);
}
<div *ngFor="let product of products; let i = index">
<div *ngIf="!product.isHidden" [attr.id]="i" class="addButton" (click)="addToCart(product, i)">ADD</div>
</div>
In component
addToCart(itemDetails, index) {
itemDetails.isHidden = true;
this.products[index] = itemDetails;
}
Logic behind this is to create a new property in product when it clicked for add to cart. Initially there will be no property with name isHidden. SO, it will return undefined and undefined will treat as false.
I would suggest the following:
<div *ngFor="let product of products; let i = index">
<div *ngIf="!isInCart(product)" [attr.id]="i" class="addButton" (click)="addToCart(product, i)">ADD</div>
</div>
private hiddenProducts = new Set<FooProduct>();
products: FooProduct[] = [];
loadProducts(){
this.products = // some value
hiddenProducts = new Set<FooProduct>();
}
isInCart(product: FooProduct): boolean {
return this.hiddenProducts.has(product);
}
addToCart(product: FooProduct, index: number){
// optional: check if the element is already added?
this.hiddenProducts.add(product);
// rest of your addToCart logic
}
Why using a set instead of a simple array?
Performance: access time is constant.
Why not use the index as identifier?
Weak against list mutations (filter, reorder, etc)
<i class="fa-trash-o fa" /> ( from http://fortawesome.github.io/Font-Awesome/icons/ )
I want the above class to be the result for a column icon:
<xp:this.iconSrc><![CDATA[#{javascript:var class = "fa-trash-o fa";
if (rowData.isDocument() && rowData.getDocument()!= null) {
var formName = rowData.getDocument().getItemValueString("Form");
if ( formName == "Aform") {
// How can I reffer to the class? => The icon from the class will be shown. }
]]></xp:this.iconSrc>
You then shouldn't use the iconSrc / view icon setting of the column. Instead you have to compute your own HTML as a value in that column and set the FA-class depending on your column value(s). Make sure you set the content type for the column to "HTML" and not "Text".