I am working on angular. I added ngx gallery. I have used foreach loop - ngx-gallery

I have used this examle
https://www.npmjs.com/package/ngx-gallery
this.galleryImages = [
{
small: 'assets/1-small.jpg',
medium: 'assets/1-medium.jpg',
big: 'assets/1-big.jpg'
},
{
small: 'assets/2-small.jpg',
medium: 'assets/2-medium.jpg',
big: 'assets/2-big.jpg'
},
{
small: 'assets/3-small.jpg',
medium: 'assets/3-medium.jpg',
big: 'assets/3-big.jpg'
}
];
}
How can I get result like this in following code
My code in TS file is
enter code here
this.products.getProductGalleryImages(this.router.snapshot.paramMap.get('id'))
.subscribe(res => {
var loopgalleryImage = JSON.parse(res[0].galleryimage_name);
let arrayGalleryImg: String[] = [];
Array.from(loopgalleryImage).forEach(function (element) {
var singlegallaryImage: any = element
arrayGalleryImg.push(singlegallaryImage)
arrayGalleryImg.push('{ small: ' + GlobalComponent.appUrl + 'galleryimages/' + element + ', medium: ' + GlobalComponent.appUrl + 'galleryimages/' + element + ', big: ' + GlobalComponent.appUrl + 'galleryimages/' + element + ',},');
})
console.log(arrayGalleryImg);
My code in HTML file is:
enter code here
<div class="col-xs-12 col-lg-6 col-md-12 col-sm-12 w-100">
<ngx-gallery [options]="galleryOptions" [images]="galleryImages" class="ngx-gallery"></ngx-gallery>
</div>

`this.products.getProductGalleryImages(this.router.snapshot.paramMap.get('id')).subscribe(res => {
let loopgalleryImage = JSON.parse(res[0].galleryimage_name);
loopgallaeryImage.forEach(element=>{
element.small:'your image path',
element.medium:'your image path',
element.big: 'your image path'
})
this.arrayGalleryImg = loopgallaeryImage
})`

Related

redux toolkit How to change the price when the variability of the product changes

There is a json file
{
"items": [
{ "id": "0", "imageUrl": "https://dodopizza.azureedge.net/static/Img/Products/f035c7f46c0844069722f2bb3ee9f113_584x584.jpeg", "title": "Пепперони Фреш с перцем", "types": [0, 1], "sizes": [26, 30, 40], "price": 803, "category": 0, "rating": 4 },
]
}
Pizza is loaded from the file, and all data is output to react
http://joxi.ru/krDaNEVSGRlpJm
Tell me please, how in redux toolkit to make the price of the product increase depending on the selected parameter sizes. That is, if the value 26 is selected, then you need to increase the amount by 100 rubles, if the size is 30, then by 200 rubles.
I tried to do it with various crutches, but I don't have enough knowledge
Here is the code where I get the pizzas
import { createSlice } from "#reduxjs/toolkit";
const initialState = {
pizzas: [],
itemsCount: 0,
isLoading: true,
};
export const getItemsSlice = createSlice({
name: "items",
initialState,
reducers: {
setItems(state, action) {
state.pizzas = action.payload;
},
setItemsCount(state, action) {
state.itemsCount = action.payload;
},
setIsLoading(state, action) {
state.isLoading = action.payload;
},
},
});
export const { setItems, setItemsCount, setIsLoading } = getItemsSlice.actions;
export default getItemsSlice.reducer;
React output code
import React from "react";
import { useDispatch, useSelector } from "react-redux";
import { Link } from "react-router-dom";
import { addPizzaInCart } from "../../../redux/slices/CartSlice";
import { typeName } from "../../../redux/slices/GetItemsSlice";
import styles from "./PizzaBlock.module.scss";
function PizzaBlock({ id, imageUrl, title, price, types, sizes }) {
const [activeType, setActiveType] = React.useState(0);
const [activeSize, setActiveSize] = React.useState(0);
const dispatch = useDispatch();
const itemInCart = useSelector((state) => state.cart.pizzasInCart.find((obj) => obj.id === id && obj.type === typeName[activeType] && obj.size === sizes[activeSize]));
const addedCount = itemInCart ? itemInCart.count : 0;
const pizza = {
id,
imageUrl,
title,
price,
type: typeName[activeType],
size: sizes[activeSize],
};
const onClickAddPizza = () => {
dispatch(addPizzaInCart(pizza));
};
const onChangeSize = (i) => {
setActiveSize(i);
};
return (
<div className={styles.item}>
<img className={styles.item__image} src={imageUrl} alt="Pizza" />
<Link to={`/product/${pizza.id}`} className={styles.item__title}>
{title}
</Link>
<div className={styles.item__selector}>
<ul>
{types.map((type, i) => (
<li className={activeType === i ? styles.active : ""} onClick={() => setActiveType(type)} key={i}>
{typeName[type]}
</li>
))}
</ul>
<ul>
{sizes.map((size, i) => (
<li className={activeSize === i ? styles.active : ""} onClick={() => onChangeSize(i)} key={i}>
{size} см.
</li>
))}
</ul>
</div>
<div className={styles.item__bottom}>
<div className={styles.item__price}>от {Math.trunc(pizza.price * (pizza.size / 100 + 1))} ₽</div>
<div className={styles.item__buttons}>
<button className={`${styles.button} ${styles.button_outline} ${styles.button_add}`} onClick={onClickAddPizza}>
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.8 4.8H7.2V1.2C7.2 0.5373 6.6627 0 6 0C5.3373 0 4.8 0.5373 4.8 1.2V4.8H1.2C0.5373 4.8 0 5.3373 0 6C0 6.6627 0.5373 7.2 1.2 7.2H4.8V10.8C4.8 11.4627 5.3373 12 6 12C6.6627 12 7.2 11.4627 7.2 10.8V7.2H10.8C11.4627 7.2 12 6.6627 12 6C12 5.3373 11.4627 4.8 10.8 4.8Z" fill="white" />
</svg>
<span>Добавить</span>
{addedCount > 0 && <i>{addedCount}</i>}
</button>
</div>
</div>
</div>
);
}
export default PizzaBlock;
There are items with sizes 26, 30 and 40. When I change the active size, that is, I press the button 26, 30 or 40, I need the price for pizza to automatically increase by 0, 100 and 200 rubles, depending on the size of the pizza. I tried using state to pass size parameters and already substitute the required amount in redux, but in this case problems appeared, the value of this state was applied to all pizzas at once, but only to the current one
Here Cart logic
import { createSlice } from "#reduxjs/toolkit";
const initialState = {
totalPricePizzasInCart: 0,
totalCountPizzasInCart: 0,
pizzasInCart: [],
};
export const cartSlice = createSlice({
name: "cart",
initialState,
reducers: {
addPizzaInCart(state, action) {
const findItem = state.pizzasInCart.find((obj) => {
return obj.id === action.payload.id && obj.type === action.payload.type && obj.size === action.payload.size;
});
if (findItem) {
findItem.count++;
} else {
state.pizzasInCart.push({
...action.payload,
count: 1,
});
}
state.totalPricePizzasInCart = state.pizzasInCart.reduce((sum, obj) => {
return Math.trunc(obj.price * (obj.size / 100 + 1)) * obj.count + sum;
}, 0);
state.totalCountPizzasInCart = state.pizzasInCart.reduce((count, obj) => {
return obj.count + count;
}, 0);
},
minusPizzaInCart(state, action) {
const findItem = state.pizzasInCart.find((obj) => {
return obj.id === action.payload.id && obj.type === action.payload.type && obj.size === action.payload.size;
});
if (findItem && findItem.count > 0) {
findItem.count--;
state.totalPricePizzasInCart = state.totalPricePizzasInCart - Math.trunc(findItem.price * (findItem.size / 100 + 1));
}
state.totalCountPizzasInCart = state.pizzasInCart.reduce((count, obj) => {
return obj.count + count;
}, 0);
},
removePizzaInCart(state, action) {
state.pizzasInCart = state.pizzasInCart.filter((obj) => {
return obj.id !== action.payload.id || obj.type !== action.payload.type || obj.size !== action.payload.size;
});
state.totalPricePizzasInCart = state.pizzasInCart.reduce((sum, obj) => {
return Math.trunc(obj.price * (obj.size / 100 + 1)) * obj.count + sum;
}, 0);
state.totalCountPizzasInCart = state.pizzasInCart.reduce((count, obj) => {
return obj.count + count;
}, 0);
},
clearPizzasInCart(state) {
state.pizzasInCart = [];
state.totalPricePizzasInCart = 0;
state.totalCountPizzasInCart = 0;
},
},
});
export const { addPizzaInCart, removePizzaInCart, minusPizzaInCart, clearPizzasInCart } = cartSlice.actions;
export default cartSlice.reducer;
github github.com/antonboec1994/reactPizza.git
Store :
import { configureStore, createSlice } from "#reduxjs/toolkit";
const initialState = {
basePrice: 100,
total: 0,
itemsCount: 0
};
export const getItemsSlice = createSlice({
name: "items",
initialState,
reducers: {
addToCart(state, action) {
console.log(action.payload);
state.itemsCount = action.payload;
state.total = state.itemsCount * state.basePrice;
}
}
});
export const { addToCart } = getItemsSlice.actions;
export const store = configureStore({
reducer: {
pizza: getItemsSlice.reducer
}
});
export default getItemsSlice.reducer;
Component :
import React from "react";
import { useDispatch, useSelector } from "react-redux";
import { addToCart } from "../store/__counterStore__";
const PizzaComponent = () => {
const dispatch = useDispatch();
const storeData = useSelector((state) => state.pizza);
console.log(storeData);
const [itemCount, setItemCount] = React.useState(0);
const handleAdd = () => {
setItemCount(itemCount + 1);
dispatch(addToCart(itemCount));
};
return (
<div>
<button onClick={handleAdd}>Add 1 Pitzzza</button>
<h2>Cart Price</h2>
<div>{storeData.total}</div>
</div>
);
};
export default PizzaComponent;
I just updated price for one type of pitza, what you can do is you can updated price according to type of different pitzas, by setting dispatch different kind of payload of you can put locgic in your reducer.
I tried to make it simple, since purpose is to understand the folw and logic.
EDIT:
CODESANDBOX

How to setState of array of Object value and toggle the count to either 1 or 2 on click

I want to update the state of value in an array of objects on click, the value will toggle between 1 and 2, once clicked if the existing value is 1 it will update it 2 on click, and if 2 it will update it 1. The value must change for the clicked object only and not all objects.
import React, {useRef, useState} from 'react'
import {BsThreeDots, BsBookmark, BsBookmarkFill} from 'react-icons/bs'
export const TextQuoteCard = () => {
const [textQuote, setTextQuote] = useState([
{
userId: '123',
userName: 'sample',
userImageUrl: 'https://qph.fs.quoracdn.net/main-thumb-ti-406-100-gtkoukgmmuzegaytlmtaybgrsoihzyii.jpeg',
quoteId: 'TQ119',
postDateTime: '28 June at 8:20',
quoteAuthorId: '123',
quoteAuthorName: 'john len',
quoteCategory: 'Motivational',
quoteType: 'textQuote',
quoteText: 'If there’s no market, then it may not be the best thing to do. Entrepreneurship is about finding market opportunities, or creating opportunities. If there’s no market, then you need to grow one',
quoteImageUrl: '',
// 1 = yes, 2 = no
bookmarkStatus: 1,
likesCount: 3300,
commentsCount: 123,
overallShareCount: 1203,
fbShareCount: 423,
twtShareCount: 1232,
waShareCount: 1023,
viewCount: 1923,
isSelected: null
}
])
const handleBookmark = i => {
let bookmarkStatus = [...textQuote]
let bookmark = bookmarkStatus[i].bookmarkStatus
console.log('before update' , bookmark)
if(bookmark === 1) {
bookmark = 2
} else if(bookmark === 2){
bookmark = 1
}
setTextQuote(bookmarkStatus)
console.log('after update', bookmark)
}
return(
<div>
{
textQuote.map((quote, index) => (
<div className="QuoteCardPrimaryContainer" key={quote.quoteId}>
className="QuoteCardAuthorFollowButtonActionContainer">
<span className="QuoteCardAuthorFollowButtonActionSpan"
onClick={() => handleBookmark(index)}>
<span className={quote.bookmarkStatus === 1 ?
'bookmarkButtonContainer activeBookmark':
'bookmarkButtonContainer'}>
{quote.bookmarkStatus === 1 ? <BsBookmarkFill/> :
<BsBookmark/>}
</span>
</span>
</div>
))
}
</div>
)
}
First get the object at that index where the bookmarkStatus has to be updated. Then using splice method you can replace with the updated object.
const handleBookmark = i => {
let quoteObj = {...textQuote[i]};
let bookmark = quoteObj.bookmarkStatus;
console.log('before update', bookmark);
if (bookmark === 1) {
quoteObj.bookmarkStatus = 2;
} else if (bookmark === 2) {
quoteObj.bookmarkStatus = 1;
}
textQuote.splice(i, 1, quoteObj)
console.log(textQuote);
setTextQuote([...textQuote]);
console.log('after update', textQuote[i].bookmarkStatus);
};
Hope this helps.

index mismatch after column is hidden in Datatable

Hello I am using data table and as per some business logic certain columns in my table are shown or hidden for that I am sending the aoColumns as JSon from Java side, but the problem I am facing is in rowCallBack functions
I am manipulating columns on indexes which is miss-matched when I hide columns
This is how I am manipulating columns:
$('td:eq(0)', nRow).html(""+nameTrimmed+ "");
my guess is hidden columns are not counted in the index and rowCallBack just manipulates any column that is visible on that index
I can not write different rowCallBack for every case to keep it generic
Is there any way I can include the hidden column in index count?
or may be modify columns in some other way apart from indexes.
Here is the code
$('#myTable').DataTable({
"dom": 't<"pagecontrol"lip>',
"bJQueryUI": true,
"sPaginationType": "simple",
"bServerSide": true,
"sAjaxSource": "${ctx}/getData?",
"bProcessing": true,
"oLanguage":
{
"sInfo": "<fmt:message key="DataTable.key.DT_SHOWING_ENTRIES" />",
"sInfoEmpty": "<fmt:message key="DataTable.key.DT_SHOWING_ENTRIES_EMPTY" />",
"oPaginate":
{
"sNext": '<i class="fa fa-caret-right"></i>',
"sLast": '<<',
"sFirst": '>>',
"sPrevious": '<i class="fa fa-caret-left"></i>'
}
},
"lengthMenu": [[50, 100, 150, 200], [50, 100, 150, 200]],
"rowCallback": function( nRow, dtoObj, iDisplayIndex, iDisplayIndexFull ) {
if (dtoObj.firstName != '' && !showDownloadButton) {
$("#participantDownloadButton").removeClass('hide');
showDownloadButton = true;
}
if(searchStringCount == dtoObj.searchStringCounter || dtoObj.searchStringCounter == 0) {
var name = dtoObj.firstName +" "+ dtoObj.lastName;
var nameTrimmed = trimStringByCharacters(name, 25);
$('td:eq(0)', nRow).html("<label title='"+name.trim()+"'>"+nameTrimmed+ "</label>");
//column 2 email
if(dtoObj.email!='') {
var email = trimStringByCharacters(dtoObj.email,20) ;
$('td:eq(1)', nRow).html("<label title='" + email + "'>" + email + "</label>");
}else{
$('td:eq(1)', nRow).html("");
}
//column 3 List name
var listName = dtoObj.eligibilityListName;
var listNameTrimmed = "";
if(listName!=null) {
listNameTrimmed = trimStringByCharacters(listName, 20);
}
$('td:eq(2)', nRow).html("<label title='"+listName+"'>"+listNameTrimmed+ "</label>");
var packageLevel = dtoObj.packageLevel;
var packageLevelTrimmed = trimStringByCharacters(packageLevel, 15);
$('td:eq(3)', nRow).html("<label title='"+packageLevel+"' data-participant-id='"+dtoObj.userId+"'>"+packageLevelTrimmed+ "</label>");
var durationUnit ='<fmt:message key="reports.filter.months"/>';
if (dtoObj.packageDuration == 1) {
durationUnit = '<fmt:message key="reports.filter.month"/>';
}
$('td:eq(4)', nRow).html(dtoObj.packageDuration +" "+ durationUnit);
// Add icons before status
var status = dtoObj.status;
var iconLink = getIconLinkByStatus(status);
// Add icons ends
if(dtoObj.status != null) {
$('td:eq(6)', nRow).html(iconLink + dtoObj.status);
} else {
$('td:eq(6)', nRow).html("");
}
}
},
"drawCallback": function() {
$(".dataTables_wrapper").children(".pagecontrol").find("#participantsTable_length label").contents().eq(0).replaceWith('<fmt:message key="rows.per.page"/> ');
$("#participantsTable").find(".dataTables_empty").html('<fmt:message key="no.data.in.table"/>');
//Code to diaply participant details view
$('#participantsTable tbody tr').on('click',function () {
var $tds = $(this).find('td');
var userId = $tds.eq(2).find('label').attr("data-participant-id");;
var status = $tds.eq(5).text();
var listName = $tds.eq(1).text();
showParticipantDetails(userId, status, listName);
});
},
"aoColumns": columnData //coming from server side
});

convert select to vue-select with dynamic data (Laravel & Vuejs)

I have dynamic products list to create an invoice. Now I want to search the product from select->option list. I found a possible solution like Vue-select in vuejs but I could not understand how to convert my existing code to get benefit from Vue-select. Would someone help me please, how should I write code in 'select' such that I can search product at a time from the list?
My existing code is -
<td>
<select id="orderproductId" ref="selectOrderProduct" class="form-control input-sm" #change="setOrderProducts($event)">
<option>Choose Product ...</option>
<option :value="product.id + '_' + product.product_name" v-for="product in invProducts">#{{ product.product_name }}</option>
</select>
</td>
And I want to convert it something like -
<v-select :options="options"></v-select>
So that, I can search products also if I have many products. And My script file is -
<script>
Vue.component('v-select', VueSelect.VueSelect);
var app = new Vue({
el: '#poOrder',
data: {
orderEntry: {
id: 1,
product_name: '',
quantity: 1,
price: 0,
total: 0,
},
orderDetail: [],
grandTotal: 0,
invProducts: [],
invProducts: [
#foreach ($productRecords as $invProduct)
{
id:{{ $invProduct['id'] }},
product_name:'{{ $invProduct['product_name'] }}',
},
#endforeach
],
},
methods: {
setOrderProducts: function(event) {
//alert('fired');
var self = this;
var valueArr = event.target.value.split('_');
var selectProductId = valueArr[0];
var selectProductName = valueArr[1];
self.orderEntry.id = selectProductId;
self.orderEntry.product_name = selectProductName;
$('#invQuantity').select();
},
addMoreOrderFields:function(orderEntry) {
var self = this;
if(orderEntry.product_name && orderEntry.quantity && orderEntry.price > 0) {
self.orderDetail.push({
id: orderEntry.id,
product_name: orderEntry.product_name,
quantity: orderEntry.quantity,
price: orderEntry.price,
total: orderEntry.total,
});
self.orderEntry = {
id: 1,
product_name:'',
productId: 0,
quantity: 1,
price: 0,
total: 0,
}
$('#orderproductId').focus();
self.calculateGrandTotal();
} else {
$('#warningModal').modal();
}
this.$refs.selectOrderProduct.focus();
},
removeOrderField:function(removeOrderDetail) {
var self = this;
var index = self.orderDetail.indexOf(removeOrderDetail);
self.orderDetail.splice(index, 1);
self.calculateGrandTotal();
},
calculateGrandTotal:function() {
var self = this;
self.grandTotal = 0;
self.totalPrice = 0;
self.totalQuantity = 0;
self.orderDetail.map(function(order){
self.totalQuantity += parseInt(order.quantity);
self.totalPrice += parseInt(order.price);
self.grandTotal += parseInt(order.total);
});
},
setTotalPrice:function(event){
var self = this;
//self.netTotalPrice();
self.netTotalPrice;
}
},
computed: {
netTotalPrice: function(){
var self = this;
var netTotalPriceValue = self.orderEntry.quantity * self.orderEntry.price;
var netTotalPriceInDecimal = netTotalPriceValue.toFixed(2);
self.orderEntry.total = netTotalPriceInDecimal;
return netTotalPriceInDecimal;
}
}
});
Assuming that invProducts is an array of product objects and each product object has a product_name property, try this snippet.
<v-select #input="selectChange()" :label="product_name" :options="invProducts" v-model="selectedProduct">
</v-select>
Create a new data property called selectedProduct and bind it to the vue-select component. So, whenever the selection in the vue-select changes, the value of selectedProduct also changes. In addition to this, #input event can be used to trigger a method in your component. You can get the selected product in that method and do further actions within that event listener.
methods: {
selectChange : function(){
console.log(this.selectedProduct);
//do futher processing
}

CKEditor - filter html without creating an editor instance

Is there a way to do something like CKEditor.filter('some html'); ?
How can I create a filter instance with the default rules and then use it?
It's pretty simple. All you got to do is to combine CKEDITOR.htmlParser and CKEDITOR.filter:
function gimmeFilter( rules ) {
var filter = new CKEDITOR.filter( rules ),
writer = new CKEDITOR.htmlParser.basicWriter();
var fn = function( input, output, msg ) {
var fragment = CKEDITOR.htmlParser.fragment.fromHtml( input );
writer.reset();
filter.applyTo( fragment );
fragment.writeHtml( writer );
return writer.getHtml();
};
fn.allow = function( rules ) {
filter.allow( rules );
};
return fn;
}
var f = gimmeFilter( {
'p b i': {
classes: 'foo',
styles: 'text-align'
}
} );
f( '<p style="text-align:right"><b class="boom" style="color: red">foo</b> <i class="foo">bar</i> <u>bum</u></p>' );
>>> "<p style="text-align:right"><b>foo</b> <i class="foo">bar</i> bum</p>"
See that <u> tag, style="color: red" and class="boom" are gone.

Resources