drag and drop items between sections - html

See here
I have two sections. I want to drag and drop elements between that two sections, but here's the element is appending but I need to drop the element at the first in that sections. When we drop the element it should place as first element for that section.
this is my code:
class Sections extends React.Component {
constructor(props) {
super(props);
this.state = {
sections: [
{
"idFolder":1,
"idUser":1,
"title":"Your Materials",
"products":[
{ "id":1,
"productType":"textile",
"name":"cotton"
"images":[
{
"original_file_name":"bear.jpeg"
}
]
},
{ "id":3,
"productType":"textile",
"name":"cotton"
}
]
},
{
"idFolder":2,
"idUser":1,
"title":"Your Materials",
"products":[
{ "id":5,
"productType":"textile",
"name":"cotton"
},
{ "id":6,
"productType":"textile",
"name":"cotton"
}
]
}
]
}
};
onDragStart(e){
e.dataTransfer.dropEffect = "copy";
e.dataTransfer.setData( "text", e.target.getAttribute('id'));
}
allowDrop (ev){
ev.preventDefault();
}
onDrop(e){
const data = e.dataTransfer.getData("text");
e.target.appendChild(document.getElementById(data));
}
render(){
return(
<div>
<div className="row">
{
this.state.sections.map((sec_head, index) => {
return (
<div key={index} className="sec_container">
<h4 data-toggle="collapse" data-target={'#'+sec_head.idFolder}>{sec_head.title}</h4>
<ul id="list" className="sec_cont collapse in" id={sec_head.idFolder}
onDrop={this.onDrop}
onDragOver={this.allowDrop}
>
{
sec_head.products.map((product, i) => {
return(
<li
index={i} key={i} className="sec_items col-md-3 alert alert-dismissable"
onDragStart={ (e) => this.onDragStart(e) }
id={product.id} draggable="true"
>
×
<img />
<h5>{product.name}</h5>
</li>
)
})
}
</ul>
</div>
)
})
}
</div>
</div>
)
}
}

Related

How to calculate total in jQuery from JSON

I have a JSON file that contains the price of a product. I need to calculate the price of an individual item and the total price of the item. I succeeded in calculating the individual price of the product, but the final one did not work.
Here is the code jQuery:
var cart = {};
function init() {
$.getJSON("goods.json", goodsOut);
}
function goodsOut(data) {
var out='';
for (var key in data) {
out +='<div class="cart">';
out +=`<p class="name">${data[key].name}</p>`;
out +=`<img src="img/${data[key].img}" alt="">`;
out +=`<div class="cost">${data[key].cost} $</div>`;
out +=`<button class="add-to-cart" data-id="${key}">Купить</button>`;
out +='</div>';
}
$('.goods-out').html(out);
$('.add-to-cart').on('click', addToCart);
}
function addToCart() {
//добавляем товар в корзину
var id = $(this).attr('data-id');
if (cart[id]==undefined) {
cart[id] = 1;
}
else {
cart[id]++;
}
showMiniCart();
saveCart();
}
function saveCart() {
localStorage.setItem('cart', JSON.stringify(cart));
}
function showMiniCart() {
if (!isEmpty(cart)) {
$('.mini-basket').html('Basket is empty!');
}
else {
$.getJSON('goods.json', function (data) {
var geds = data;
var out="";
for (var key in cart) {
out += '<div class="mini-basket_list">'
out += `<img src="img/${geds[key].img}" alt="Error" class="cart-product__img">`;
out += `<span class="name-basket">${geds[key].name}</span>`+'<br>';
out += ` <button data-id="${key}" class="plus-goods btn">+</button> `;
out += `<span class="quantityy">${cart[key]}</span>`;
out += ` <button data-id="${key}" class="minus-goods btn">-</button> `;
out += `<p class="cost-basket">Цена: <span class="cost-basket_plus">${Number(cart[key])*Number(geds[key].cost)}</span> $</p>`;
out += `<button data-id="${key}" class="del-goods btn">x</button> `;
out += '</div>'
}
$('.mini-basket').html(out);
$('.del-goods').on('click', delGoods);
$('.plus-goods').on('click', plusGoods);
$('.minus-goods').on('click', minusGoods);
});
}
}
function delGoods() {
var id = $(this).attr('data-id');
delete cart[id];
saveCart();
showMiniCart();
}
function plusGoods() {
var id = $(this).attr('data-id');
cart[id]++;
saveCart();
showMiniCart();
}
function minusGoods() {
var id = $(this).attr('data-id');
if (cart[id]==1) {
delete cart[id];
}
else {
cart[id]--;
}
saveCart();
showMiniCart();
}
function loadCart() {
if (localStorage.getItem('cart')) {
cart = JSON.parse(localStorage.getItem('cart'));
showMiniCart();
}
}
function isEmpty(object) {
for (var key in object)
if (object.hasOwnProperty(key)) return true;
return false;
}
$(document).ready(function () {
init();
loadCart();
});
Here is the code JSON:
{
"1234": {
"name": "Aplle",
"cost": "5",
"img" : "apple.png"
},
"1235": {
"name": "Cherry",
"cost": "7",
"img" : "cherry.png"
},
"1236": {
"name": "Grape",
"cost": "10",
"img" : "grape.png"
},
"1237": {
"name": "Slice of watermelon",
"cost": "12",
"img" : "watermelon.png"
}
}
Here is the code HTML:
<body>
<header class="header">
<nav class="nav">
<div class="basket">
<div class="cart__text">
Basket
</div>
<div class="cart-content">
<div class="block" data-simplebar>
<div class="mini-basket">
</div>
</div>
<div class="cart-content__bottom">
<div class="cart-content__fullprice">
<span>Total: </span>
<span class="fullprice"></span> <!--Here I want to display a total-->
<span>$</span>
</div>
</div>
</div>
</div>
</nav>
</header>
<section>
<div class="goods-out"></div>
</section>
<script src="js/jquery-3.5.1.min.js"></script>
<script src="js/simplebar.js"></script>
<script src="js/main.js"></script>
</body>
Total should be shown in a span with fullprice class.

Show Submenu On Mouse Enter Vuejs

Sorry I'm really new to all this.
I'm trying display a submenu during a menu item mouse-over. I've been given hints on recording the index of menu items, and recording the boolean value of whether the user currently has their mouse over the top menu's nav container. However I do not know how to proceed on using these to create conditional renderings for the submenu. Here's what I've tried:
HTML:
<div id="vuemain">
<nav v-on:mouseover="mouseOverNav" v-on:mouseleave="mouseLeaveNav" class="pure-menu pure-menu-horizontal">
<ul id="topmenu" class="pure-menu-list">
<li v-for="(item, index) in topmenu" v-on:mouseover="mouseOver(index)" class="pure-menu-item">
<a v-bind:href="item.url" class="pure-menu-link">{{ item.title }}</a>
</li>
</ul>
<div class="pure-menu">
<ul id="submenu" class="pure-menu-list">
<li v-if= "topmenuhover == true" class="pure-menu-item">
<a v-bind:href="topmenu[topmenuitem].submenus.url" class="pure-menu-link">{{ topmenu[topmenuitem].submenus.title }}</a></li>
</ul>
</div>
</nav>
</div>
JS:
var vueinst = new Vue({
el: '#vuemain',
data: {
topmenuitem : -1,
topmenuhover : false,
topmenu: [
{ title:'Home', url:'/', submenus: [] },
{ title:'About', url:'/about',
submenus: [
{ title:'Who we are', url:'/about#us' },
{ title:'What we do', url:'/about#store' },
{ title:'Our range', url:'/about#range' }
]
},
{ title:'Contact Us', url:'/contact',
submenus: [
{ title:'Information', url:'/contact#info' },
{ title:'Returns', url:'/contact#return' },
{ title:'Locate Us', url:'/contact#locate' }
]
}
]
},
methods: {
mouseOver: function(index){
this.topmenuitem=index;
},
mouseOverNav: function(){
this.topmenuhover = true;
},
mouseLeaveNav: function(){
this.topmenuhover = false;
}
}
});
Can anyone help me with this? Thank you!
The Javascript part should do the trick, you just need to tweak the template a bit to actually render the submenu. Here's how you could do it:
var vueinst = new Vue({
el: "#vuemain",
data: {
topmenuitem: -1,
topmenuhover: false,
topmenu: [
{ title: "Home", url: "/", submenus: [] },
{
title: "About",
url: "/about",
submenus: [
{ title: "Who we are", url: "/about#us" },
{ title: "What we do", url: "/about#store" },
{ title: "Our range", url: "/about#range" },
],
},
{
title: "Contact Us",
url: "/contact",
submenus: [
{ title: "Information", url: "/contact#info" },
{ title: "Returns", url: "/contact#return" },
{ title: "Locate Us", url: "/contact#locate" },
],
},
],
},
methods: {
mouseOver: function (index) {
this.topmenuitem = index;
},
mouseOverNav: function () {
this.topmenuhover = true;
},
mouseLeaveNav: function () {
this.topmenuhover = false;
},
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="vuemain">
<nav v-on:mouseover="mouseOverNav" v-on:mouseleave="mouseLeaveNav" class="pure-menu pure-menu-horizontal">
<ul id="topmenu" class="pure-menu-list">
<li v-for="(item, index) in topmenu" v-on:mouseover="mouseOver(index)" class="pure-menu-item">
<a v-bind:href="item.url" class="pure-menu-link">{{ item.title }}</a>
</li>
</ul>
<div class="pure-menu">
<ul v-if="topmenuhover" id="submenu" class="pure-menu-list">
<li v-for="subitem in topmenu[topmenuitem].submenus" class="pure-menu-item">
<a v-bind:href="subitem.url" class="pure-menu-link">{{ subitem.title }}</a></li>
</ul>
</div>
</nav>
</div>

How can I give transition effect for this code?

import React from "react";
import "./About.css";
import About_Main from "../components/About_Main";
import About_Data1 from "../components/About_Data1";
import About_Data2 from "../components/About_Data2";
class About extends React.Component {
state = {
main: {
display:"block",
opacity:1
},
data: {
display:"none",
opacity:0
}
};
changeSelect = id => {
if (id === "select1") {
this.setState({
main: {
display:"block",
opacity:1
},
data: {
display:"none",
opacity:0
}});
} else if (id === "select2") {
this.setState({
main: {
display:"none",
opacity:0
},
data: {
display:"block",
opacity:1
}});
}
};
clickHandler = event => {
event.preventDefault();
this.changeSelect(event.target.id);
};
render() {
return (
<div>
<section className="selects">
<div
id="select1"
className="select"
onClick={this.clickHandler}
></div>
<div
id="select2"
className="select"
onClick={this.clickHandler}
></div>
</section>
<section className="about">
<div
className="about_div"
style={{ display: this.state.main.display, opacity: this.state.main.opacity }}
>
<About_Main></About_Main>
</div>
<div
className="about_data"
style={{ display: this.state.data.display, opacity:this.state.data.opacity }}
>
<About_Data1></About_Data1>
<About_Data2></About_Data2>
</div>
</section>
</div>
);
}
}
export default About;
By clicking 2 different buttons, I want to show only one out of two.
Also, I like to give a transition effect so I used opacity. But it is not working!
Is this the only way to set style property using javascript in react?
Can't I use querySelector or something else?
I feel like javascript is much easier than react 😭😭

is there a way i can fix my accordion in angular?

I'm new to angular and I tried to make an accordion component, and it' didn't work like I wanted it to, here's my html code.
<div class="faq-item-container">
<h1 class="mt-1 mb-5"><strong>Frequently Aksed Questions</strong></h1>
<div class="row" (click)="toggleDetail(); toggleIcon();" *ngFor= "let faq of faqs">
<div class="col my-2">
<h3> {{faq.title}} <a><fa-icon [icon]="faChevronDown" class="float-right"></fa-icon></a></h3>
</div>
<div class="col-12" *ngIf="showDetail">
<div class="faq-detail-container mt-1">
<div class="col-12">
<p><small>
{{faq.content}}
</small></p>
</div>
</div>
</div>
</div>
</div>
and here's the ts code
import { Component, OnInit } from '#angular/core';
import {faChevronUp, faChevronDown, IconDefinition, faSquare} from '#fortawesome/free-solid-svg-icons';
#Component({
selector: 'app-jobs-faq',
templateUrl: './jobs-faq.component.html',
styleUrls: ['./jobs-faq.component.scss']
})
export class JobsFaqComponent implements OnInit {
faChevronUp: IconDefinition = faChevronUp;
faChevronDown: IconDefinition = faChevronDown;
showDetail: boolean;
faqs = [
{
id: 1,
title: 'faq1',
content: 'content1'
},
{
id: 2,
title: 'faq2',
content: 'content2'
},
{
id: 3,
title: 'faq3',
content: 'content3'
}
];
constructor() {
this.showDetail = false;
}
toggleDetail(): void {
this.showDetail = !this.showDetail;
}
toggleIcon() {
if (this.faChevronDown === faChevronDown) {
this.faChevronDown = faChevronUp;
} else {
this.faChevronDown = faChevronDown;
}
}
ngOnInit() {
}
}
The problem is when I click faq1, the others also collpasing, yes I know it's because I called the same function, and that is what I want to ask about, how to call the function separately to make this accordion working like it's supposed to be? thanks.
It depends on whether you want to close all other sections when you click one or not, but a solution could look somewhat like this:
<div class="faq-item-container">
<h1 class="mt-1 mb-5"><strong>Frequently Aksed Questions</strong></h1>
<div class="row" (click)="toggleDetail(faq.id); toggleIcon();" *ngFor= "let faq of faqs">
<div class="col my-2">
<h3> {{faq.title}} <a><fa-icon [icon]="faChevronDown" class="float-right"></fa-icon></a></h3>
</div>
<div class="col-12" *ngIf="faq.showDetail">
<div class="faq-detail-container mt-1">
<div class="col-12">
<p><small>
{{faq.content}}
</small></p>
</div>
</div>
</div>
</div>
</div>
import { Component, OnInit } from '#angular/core';
import {faChevronUp, faChevronDown, IconDefinition, faSquare} from '#fortawesome/free-solid-svg-icons';
#Component({
selector: 'app-jobs-faq',
templateUrl: './jobs-faq.component.html',
styleUrls: ['./jobs-faq.component.scss']
})
export class JobsFaqComponent implements OnInit {
faChevronUp: IconDefinition = faChevronUp;
faChevronDown: IconDefinition = faChevronDown;
faqs = [
{
id: 1,
title: 'faq1',
content: 'content1',
showDetail: false
},
{
id: 2,
title: 'faq2',
content: 'content2',
showDetail: false
},
{
id: 3,
title: 'faq3',
content: 'content3',
showDetail: false
}
];
toggleDetail(faqId: number): void {
this.faqs = this.faqs.map(faq => {
faq.showDetail = (faq.id == faqId) ? !faq.showDetail : false;
return faq;
});
}
toggleIcon() {
if (this.faChevronDown === faChevronDown) {
this.faChevronDown = faChevronUp;
} else {
this.faChevronDown = faChevronDown;
}
}
ngOnInit() {
}
}
Note that your [icon]="faChevronDown" should be based on the faq in the thes scope of your *ngFor. I'll leave it to you as practice to find a solution for that. (Hint: you could use a ternary operation based on faq.showDetail)

Collapse/Expand nested div in Angular 6

I am developing a schedule like structure using div. And my design looks like this.
What i want is when loading, only 1st level should be displayed (all venues) and when clicking on venue its immediate child should be displayed and so on. Is there any way to do so. my html is:
<div class="div-table">
<div class="div-table-row">
<div class="div-header-col" style="visibility: hidden;">A</div>
<div *ngFor="let date of dates" class="div-date-col">{{date | date:'d E'}}</div>
</div>
<!-- level1 -->
<div *ngFor="let venue of venues" class="level1" style="color: red">
<div class="div-table-row-level1" >
<div class="div-header-col">{{venue.name}}</div>
<div *ngFor="let x of dates" class="div-event-level1-col"></div>
</div>
<!-- level2 -->
<div *ngFor="let category of venue.categories" class="level2" style="color: blue">
<div class="div-table-row-level2">
<div class="div-header-col" style="padding-left: 10px">{{category.name}}</div>
<div *ngFor="let x of dates" class="div-event-level2-col"></div>
</div>
<!-- level3 -->
<div *ngFor="let asset of category.assets" class="level3" style="color: green">
<div class="div-table-row-level3">
<div class="div-header-col" style="padding-left: 20px">{{asset.name}}</div>
<div *ngFor="let x of dates" class="div-event-level3-col assest-hover" "></div>
</div>
</div>
</div>
</div>
</div>
My data for the table(div) is :
[
{
"id":1,
"name":"venue1",
"categories":[
{
"id":1,
"name":"cat1",
"assets":[
{
"id":1,
"name":"assest1"
},
{
"id":2,
"name":"assest2"
}
]
},
{
"id":2,
"name":"cat2",
"assets":[
{
"id":3,
"name":"assest3"
},
{
"id":4,
"name":"assest4"
}
]
}
]
},
{
"id":2,
"name":"venue2",
"categories":[
{
"id":3,
"name":"cat3",
"assets":[
{
"id":5,
"name":"assest5"
},
{
"id":6,
"name":"assest6"
}
]
},
{
"id":4,
"name":"cat4",
"assets":[
{
"id":7,
"name":"assest7"
},
{
"id":8,
"name":"assest8"
}
]
}
]
},{
"id":3,
"name":"venue3",
"categories":[
{
"id":5,
"name":"cat5",
"assets":[
{
"id":9,
"name":"assest9"
},
{
"id":10,
"name":"assest10"
}
]
},
{
"id":6,
"name":"cat6",
"assets":[
{
"id":11,
"name":"assest11"
},
{
"id":12,
"name":"assest12"
}
]
}
]
}
]
If you have entire data loaded together then you have good news that it can be implemented in a very simple way -
You can play around Element Reference. Nothing needs to be managed from ts file.
in html
<div *ngFor="let venue of venues" class="level1" style="color: red"
(click)="ele.class = ele.class == 'showChildren' ? '' : 'showChildren'"
[ngClass]="{ hideChildren : ele.class !== 'showChildren' }">
Repeat the same for all parent div
in CSS
.hideChildren>div{
display: none;
}
Here is the working copy- https://stackblitz.com/edit/angular-n43ihd
There are some more way to handle if the data is being fetched in Asynchronous fashion. Then these logic will move to ts file.
You can try to hide component's on-load, and set them to visible onClick
$scope.$on('$viewContentLoaded', function() {
// Hide all unwanted div's here
});