How to display chats in react + socket io application - reactjs

My chat display correctly on my first react app instance but not on the second.
https://imgur.com/a/7FVCvjW
I could not figure out what is wrong. I dont find any reason why the right side ( of the image shared aove) would not show properly;
export const Message = ({ message, name }) => {
const style = (sender) => {
if (sender === "admin") {
return "admin";
} else if (sender === name) {
return "user";
} else {
return "other";
}
};
return (
<Fragment>
<div className="messageContainer">
<p className={`content ${style(message.user)}`}>{message.message}</p>
{name === message.user ? null : (
<p className="sender">{message.user}</p>
)}
</div>
</Fragment>
);
};
CSS
.content {
margin-right: 10px;
}
.admin {
color: rgb(156, 156, 156);
}
.user {
background-color: rgba(255, 255, 255, 0.712);
display: inline;
padding: 10px;
border-radius: 5px;
box-shadow: 2px 2px 2px #888888;
margin-left: auto;
}
.other {
background-color: rgba(255, 255, 255, 0.712);
display: inline;
padding: 10px;
border-radius: 5px;
box-shadow: 2px 2px 2px #888888;
}
.messageContainer {
display: flex;
align-items: center;
}
.sender {
color: rgb(156, 156, 156);
}

Just remove:
if (sender === "admin") {
return "admin";
} else
If you really need to handle this with a flag, instead of name use user = {name, isAdmin}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Add React in One Minute</title>
<style type="text/css">
h3 {
color: white;
}
.content {
margin-right: 10px;
}
.admin {
color: rgb(156, 156, 156);
}
.user {
background-color: rgba(255, 255, 255, 0.712);
display: inline;
padding: 10px;
border-radius: 5px;
box-shadow: 2px 2px 2px #888888;
margin-left: auto;
}
.other {
background-color: rgba(255, 255, 255, 0.712);
display: inline;
padding: 10px;
border-radius: 5px;
box-shadow: 2px 2px 2px #888888;
}
.messageContainer {
display: flex;
align-items: center;
}
.sender {
color: rgb(156, 156, 156);
}
</style>
</head>
<body style="background: blue">
<div id="root"></div>
<script src="https://unpkg.com/react#17/umd/react.development.js" crossorigin ></script>
<script src="https://unpkg.com/react-dom#17/umd/react-dom.development.js" crossorigin ></script>
<script src="https://unpkg.com/babel-standalone#6/babel.min.js"></script>
<script type="text/babel">
const {Fragment} = React;
const Message = ({ message, name }) => {
const style = (sender) => {
// if (sender === "admin") {
// return "admin";
// } else
if (sender === name) {
return "user";
} else {
return "other";
}
};
return (
<Fragment>
<div className="messageContainer">
<p className={`content ${style(message.user)}`}>{message.message}</p>
{name === message.user ? null : (
<p className="sender">{message.user}</p>
)}
</div>
</Fragment>
);
};
const App = () => {
return (
<Fragment>
<h3>From Jonh's point of view</h3>
<ul>
<Message message={{user: "john", message: "Hi"}} name="john"/>
<Message message={{user: "mary", message: "Hey from user"}} name="john"/>
</ul>
<h3>From Mary's point of view</h3>
<ul>
<Message message={{user: "john", message: "Hi"}} name="mary"/>
<Message message={{user: "mary", message: "Hey from user"}} name="mary"/>
</ul>
<h3>From an anonymous point of view</h3>
<ul>
<Message message={{user: "john", message: "Hi"}} name=""/>
<Message message={{user: "mary", message: "Hey from user"}} name=""/>
</ul>
</Fragment>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
</script>
</body>
</html>

Related

Is there a way to fill up the delay of useState?

I'm new to React and I'm trying to make a simple animation, but when the animation ends there is literally a split second that is showing the old values of opacitate & translate.Is there a way that i can make that dissapper?
I've tried to use useRef and re-render the component but no luck.Ignore the timeout functionz
const { useEffect, useState } = React;
const Titlu = () => {
let [opacitate, setOpacitate] = useState(0);
let [translate, setTranslate] = useState(-30);
function Schimba() {
setOpacitate(prevOpacity => prevOpacity = 1);
setTranslate(prevTranslate => prevTranslate = 20);
}
function timeout(timp) {
return new Promise((resolve, reject) => {
setTimeout(resolve, 1000);
})
}
return (
<div className="Part1">
<h1 className="ForkyTitlu"
onAnimationEnd={Schimba}
style={{
opacity:opacitate,
transform: `translate(${translate}%, 0%)`
}} >
<span className ="Forky">Forky</span>
<span className ="Nutrition">Nutrition</span>
</h1>
</div>
);
}
ReactDOM
.createRoot(root)
.render(<Titlu />);
.Part1 {
display: inline-flex;
margin-bottom: 50vh;
border-bottom: 3px black;
}
.ForkyTitlu {
color: orange;
font-size: 3vw;
/*
margin-left: 12vw;
margin-top: 40vh;
transform: translateX(-50%);
*/
animation-name: titluAnimation;
animation-delay: 1s;
animation-duration: 2s;
animation-iteration-count: 1;
position: relative;
}
#keyframes titluAnimation {
100% {
opacity: 1;
transform: translateX(20%);
}
}
.Forky {
color: black;
font-size: 9vw;
text-shadow: -30px 15px 30px #0000009c;
}
.Nutrition {
color: orange;
font-size: 3.5vw;
text-shadow: -30px 15px 30px orange;
}
<script crossorigin src="https://unpkg.com/react#18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#18/umd/react-dom.development.js"></script>
<div id="root"></div>
When onAnimationEnd calls Schimba, the animation is over, and the CSS values are resettled top their original values. This is the gap you're seeing.
However, you don't really need a state. Move all animation related properties, including the initial state to the animation:
#keyframes titluAnimation {
from {
opacity: 0;
transform: translateX(-30%);
}
to {
opacity: 1;
transform: translateX(20%);
}
}
And define the animation-fill-mode (I've used the animation shorthand) to be forwards:
animation: titluAnimation 2s forwards;
forwards
The target will retain the computed values set by the last keyframe encountered during execution.
const Titlu = () => (
<div className = "Part1">
<h1 className = "ForkyTitlu">
<span className ="Forky">Forky</span>
<span className ="Nutrition">Nutrition</span>
</h1>
</div>
);
ReactDOM
.createRoot(root)
.render(<Titlu />);
.Part1 {
display: inline-flex;
margin-bottom: 50vh;
border-bottom: 3px black;
}
.ForkyTitlu {
color: orange;
font-size: 3vw;
animation: titluAnimation 2s forwards;
position: relative;
}
#keyframes titluAnimation {
from {
opacity: 0;
transform: translateX(-30%);
}
to {
opacity: 1;
transform: translateX(20%);
}
}
.Forky {
color: black;
font-size: 9vw;
text-shadow: -30px 15px 30px #0000009c;
}
.Nutrition {
color: orange;
font-size: 3.5vw;
text-shadow: -30px 15px 30px orange;
}
<script crossorigin src="https://unpkg.com/react#18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#18/umd/react-dom.development.js"></script>
<div id="root"></div>
If you want/need to use state to control the animation, it's better to define the start/end states as classes, toggle them with the state, and use CSS transition to animate the change.
Example - click the Toggle button to see the animation:
const { useState } = React;
const Titlu = () => {
const [start, setState] = useState(true);
const toggleStart = () => setState(s => !s);
return (
<div>
<div className = "Part1">
<h1 className = {`ForkyTitlu ${start ? 'start' : 'end'}`}>
<span className ="Forky">Forky</span>
<span className ="Nutrition">Nutrition</span>
</h1>
</div>
<button onClick={toggleStart}>Toggle</button>
</div>
);
};
ReactDOM
.createRoot(root)
.render(<Titlu />);
.Part1 {
display: flex;
border-bottom: 3px black;
}
.ForkyTitlu {
color: orange;
font-size: 3vw;
position: relative;
transition: all 2s;
}
.ForkyTitlu.start {
opacity: 0;
transform: translateX(-30%);
}
.ForkyTitlu.end {
opacity: 1;
transform: translateX(20%);
}
.Forky {
color: black;
font-size: 9vw;
text-shadow: -30px 15px 30px #0000009c;
}
.Nutrition {
color: orange;
font-size: 3.5vw;
text-shadow: -30px 15px 30px orange;
}
<script crossorigin src="https://unpkg.com/react#18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#18/umd/react-dom.development.js"></script>
<div id="root"></div>

Why is git pages rendering my page different then in local?

I'm rather new to whole react thing, going through courses on FCC. My problem come from CSS/SCSS itself. I tried ordinary CSS and SCSS. My page is done in React. The page is also hosted on codepen. All three versions are the same, codepen, git and local and yet CSS is somewhat different between them. My previous projects who are also hosted on these platforms and in local have also the same CSS but they look identical. Difference between local and codepen's version isn't that drastic, but between local>codepen>github is more than noticeable as you descend. Do GitHub ignores/renders? or what, React differently? This question should also apply to codepen.
My codepen
My git page
My repoToProject
Image of localhost:
html from codepen:
<div id="root"></div>
scss from codepen:
$position: absolute;
$percentage: 100%;
$color: whitesmoke;
$car: auto;
#import url("//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-glyphicons.css");
.btn1 {
position: $position;
bottom: -30px;
left: 51.3%;
z-index: 999;
background-color: $color;
border: 1px solid gray;
color: aqua;
}
#root {
width: $percentage;
}
body,
html {
height: $percentage;
}
body {
background-color: $color;
background-image: url("../images/react1.png");
background-repeat: no-repeat;
background-size: $car;
background-position: center bottom;
overflow: hidden;
}
.grid-container {
display: grid;
grid-template-columns: 50% 50%;
background-color: $color;
padding: 10px;
grid-gap: 15px;
width: $percentage;
grid-template-rows: 30px 25px 98%;
}
.grid-item {
text-align: center;
}
#inner2 {
padding-left: 20px;
padding-right: 25px;
border-bottom: 15px solid #d6e9c6;
padding-bottom: 55px;
background-color: #fcf8e3;
width: $percentage;
margin-left: $car;
margin-right: $car;
position: $position;
top: 0px;
left: 0px;
height: $percentage;
min-height: 20%;
max-height: $percentage;
}
#editor {
width: $percentage;
background-color: white;
resize: none;
color: #495057;
border: 1px solid #ced4da;
border-radius: 0.25rem;
overflow-y: $car;
max-height: $percentage;
min-height: 40px;
margin-bottom: 40px;
}
#preview {
width: 98.9%;
background-color: white;
border-radius: 0.25rem;
border: 1px solid #ced4da;
overflow-y: $car;
max-height: $percentage;
min-height: 40px;
margin-bottom: 40px;
}
#item1,
#item2 {
font-family: "Russo One";
font-style: oblique;
font-weight: bold;
font-size: 2em;
margin-bottom: 10px;
padding-bottom: 0px;
width: $percentage;
background-color: #fcf8e3;
min-height: 50px;
border-bottom: none;
padding-top: 10px;
}
.insignia {
letter-spacing: 5px;
-webkit-transition: letter-spacing 1s;
transition: letter-spacing 1s;
}
.insignia:hover {
letter-spacing: 13px;
cursor: pointer;
}
.ui-resizable-s {
cursor: row-resize;
}
textarea:focus,
input:focus {
outline: none;
}
#arrow {
background-color: #dff0d8;
width: $percentage;
height: 15px;
position: $position;
bottom: -12px;
padding-left: 0px;
padding-right: 0px;
font-size: 1.5em;
border-bottom: 1px solid #d6e9c6;
text-align: center;
}
.glyphicon {
top: -4px;
left: 4px;
color: gray;
-ms-transform: scale(1, 0.6); /* IE 9 */
-webkit-transform: scale(1, 0.6); /* Safari */
transform: scale(1, 0.6);
}
#media screen and (max-height: 600px) {
#inner2 {
height: 90vh !important;
}
}
#eraser {
text-align: center;
grid-column: 1 / 3;
z-index: 2;
line-height: 10px;
margin-left: $car;
margin-right: $car;
}
/*Additional styling*/
td,
th {
border: 2px solid #224b4b;
padding-left: 5px;
padding-right: 5px;
}
.label {
position: $position;
top: -10px;
left: 0px;
min-width: $percentage;
z-index: 999;
}
.preview-editor {
position: fixed;
top: 55px;
left: 0px;
min-width: $percentage;
height: $percentage;
z-index: 999;
}
h1 {
border-bottom: 2px solid #224b4b;
}
h2 {
border-bottom: 1px solid #224b4b;
}
code {
background-color: #d6e9c6;
color: #e83e8c !important;
}
blockquote {
border-left: 2px solid black;
padding-left: 5px;
margin-left: 25px;
}
#media only screen and (max-width: 768px) {
img {
width: 100%;
}
#ggED {
text-align: left;
}
#ggPrev {
text-align: right;
}
.insignia,
.insignia:hover {
letter-spacing: 0px;
font-size: 1em;
}
}
js from codepen:
var renderer = new marked.Renderer();
renderer.link = function(href, title, text) {
return (
'<a target="_blank" href="' +
href +
'" title="' +
title +
'">' +
text +
"</a>"
);
};
marked.setOptions({
breaks: true,
renderer: renderer,
sanitize: true
});
class DisplayMessages extends React.Component {
constructor(props) {
super(props);
this.state = {
markdown: defaultMarkdown,
erase: false,
goFull: false,
headViewKlasa: "grid-item",
headEdKlasa: "grid-item",
editorKlasa: "",
previewKlasa: "",
stilPreview: {},
stilEditor: {},
attr: "Click on me for fullscreen",
inner2H: "",
h2Inner: false
};
this.handleChange = this.handleChange.bind(this);
this.eraseFields = this.eraseFields.bind(this);
this.inner2Height = this.inner2Height.bind(this);
}
eraseFields() {
this.setState({
erase: true
});
if (this.state.erase === false) {
this.setState({
markdown: ""
});
}
if (this.state.erase === true) {
this.setState({
markdown: defaultMarkdown,
erase: !this.state.erase
});
}
}
componentDidMount() {
this.node = ReactDOM.findDOMNode(this);
$(this.node).resizable({
handles: "s",
minHeight: 170
});
document
.querySelector(".ui-resizable-handle.ui-resizable-s")
.setAttribute(
"title",
"Double click on me or pull me down to full height"
);
}
inner2Height() {
if (this.state.h2Inner === false) {
this.setState({
inner2H: "100%",
h2Inner: true
});
}
if (this.state.h2Inner === true) {
this.setState({
inner2H: "",
h2Inner: false
});
}
}
fullScreen(clicked_id) {
if (clicked_id === "ggEd" && this.state.goFull === false) {
this.setState({
headEdKlasa: this.state.headEdKlasa + " label",
attr: "Click again to go back!",
editorKlasa: "preview-editor",
stilPreview: { display: "none" },
stilEditor: { paddingTop: "0px" },
goFull: true
});
}
if (clicked_id === "ggEd" && this.state.goFull === true) {
this.setState({
headEdKlasa: this.state.headEdKlasa.substr(0, 9),
attr: "Click on me for fullscreen",
editorKlasa: "",
stilPreview: { display: "block" },
stilEditor: { paddingTop: "10px" },
goFull: !this.state.goFull
});
}
if (clicked_id === "ggPrev" && this.state.goFull === false) {
this.setState({
headViewKlasa: this.state.headViewKlasa + " label",
attr: "Click again to go back!",
previewKlasa: "preview-editor",
stilEditor: { display: "none" },
stilPreview: { paddingTop: "0px" },
goFull: true
});
}
if (clicked_id === "ggPrev" && this.state.goFull === true) {
this.setState({
headViewKlasa: this.state.headViewKlasa.substr(0, 9),
attr: "Click on me for fullscreen",
previewKlasa: "",
stilEditor: { display: "block" },
stilPreview: { paddingTop: "10px" },
goFull: !this.state.goFull
});
}
}
handleChange(event) {
this.setState({
markdown: event.target.value
});
}
render() {
const btnText = this.state.erase ? "Populate" : "Erase";
const handleClick = e => this.fullScreen(e.target.id);
return (
<div
id="inner2"
className="grid-container animated zoomIn"
style={{ height: this.state.inner2H }}
onDoubleClick={this.inner2Height}
>
<EditorHead
id={"item1"}
style={this.state.stilEditor}
className={this.state.headEdKlasa}
onClick={handleClick}
title={this.state.attr}
/>
<PreviewHead
id={"item2"}
style={this.state.stilPreview}
className={this.state.headViewKlasa}
onClick={handleClick}
title={this.state.attr}
/>
<BtnEraser
id={"eraser"}
onClick={this.eraseFields}
type={"button"}
className={"btn btn-danger btn-lg"}
title={"Erase & populate both fields"}
value={btnText}
/>
<Editor
id={"editor"}
onChange={this.handleChange}
className={this.state.editorKlasa}
value={this.state.markdown}
placeholder={"Enter ... some kind a text!? ..."}
title={
"This is rather obvious isn't it? It's editor window Sherlock :D"
}
/>
<Preview
id={"preview"}
className={this.state.previewKlasa}
dangerouslySetInnerHTML={{
__html: marked(this.state.markdown, { renderer: renderer })
}}
title={"It's a preview window, Sherlock ;)"}
/>
<Arrow id={"arrow"} />
</div>
);
}
}
/*class Inner2 extends React.Component{
render(){
return (
<div id={this.props.id} className={this.props.className} style={this.props.style} onDoubleClick={this.props.onDoubleClick}>Editor:</div>
);
}
}*/
class EditorHead extends React.Component {
render() {
return (
<h1
id={this.props.id}
style={this.props.style}
className={this.props.className}
onClick={this.props.onClick}
>
<span className="insignia" title={this.props.title} id="ggEd">
Editor:
</span>
</h1>
);
}
}
class PreviewHead extends React.Component {
render() {
return (
<h1
id={this.props.id}
style={this.props.style}
className={this.props.className}
onClick={this.props.onClick}
>
<span className="insignia" title={this.props.title} id="ggPrev">
Previewer:
</span>
</h1>
);
}
}
class BtnEraser extends React.Component {
render() {
return (
<button
id={this.props.id}
onClick={this.props.onClick}
type={this.props.type}
className={this.props.className}
title={this.props.title}
>
{this.props.value}
</button>
);
}
}
class Editor extends React.Component {
render() {
return (
<textarea
id={this.props.id}
onChange={this.props.onChange}
className={this.props.className}
value={this.props.value}
placeholder={this.props.placeholder}
title={this.props.title}
/>
);
}
}
class Preview extends React.Component {
render() {
return (
<div
id={this.props.id}
className={this.props.className}
dangerouslySetInnerHTML={this.props.dangerouslySetInnerHTML}
title={this.props.title}
/>
);
}
}
class Arrow extends React.Component {
render() {
return (
<div id={this.props.id}>
<Glyph className={"glyphicon glyphicon-align-justify"} />
</div>
);
}
}
class Glyph extends React.Component {
render() {
return <span className={this.props.className} />;
}
}
ReactDOM.render(<DisplayMessages />, document.getElementById("root"));

React conditionally opening different divs

I am trying to conditionally open divs two and three, take a look at following snippet. showThird works correct however, showSecond has no effect? Basically on showSecond div-one shrinks to 50% width and div-two appears in rest 50%. Similar with div-third.
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
showSecond: false,
showThird: false
}
this.showDivTwo = this.showDivTwo.bind(this)
this.showDivThree = this.showDivThree.bind(this)
}
showDivTwo() {
this.setState(prevState => ({showThird: false, showSecond: !prevState.showSecond}))
console.log(this.state)
}
showDivThree() {
this.setState(prevState => ({ showSecond: false, showThird: !prevState.showThird}))
console.log(this.state)
}
render() {
return (
<div className={'wrapper' + (this.state.showSecond ? ' show' : '', this.state.showThird ? ' show' : '')}>
<div className="one">one
{/* Show second */}
<div>
<button onClick={this.showDivTwo}>{this.state.showSecond ? 'hideSecond' : 'showSecond'}</button>
</div>
{/* Show third */}
<div>
<button onClick={this.showDivThree}>{this.state.showThird ? 'hideThird' : 'showThird'}</button>
</div>
</div>
<div className="three">three
<div>
<button onClick={this.showDivThree}>{this.state.showThird ? 'hideThird' : 'showThird'}</button>
</div>
</div>
<div className="two">two
<div>
<button onClick={this.showDivTwo}>{this.state.showSecond ? 'hideSecond' : 'showSecond'}</button>
</div>
</div>
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
.wrapper {
overflow: hidden;
white-space: nowrap;
}
.one, .two, .three {
background: #333;
border: 2px solid #787567;
box-sizing: border-box;
color: #fff;
display: inline-block;
font-family: arial;
overflow: hidden;
padding: 20px;
text-align: center;
transition: border 0.2s, padding 0.2s, width 0.2s;
min-height: 50vh;
}
.one {
width: 100%;
}
.two {
border-width: 2px 0;
padding: 20px 0;
width: 0;
}
.three {
border-width: 2px 0;
padding: 20px 0;
width: 0;
}
.show .one, .show .two, .show .three {
border-width: 2px;
padding: 20px;
width: 50%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
What am I doing wrong here?
Changes:
1- use this condition:
className={'wrapper' + (this.state.showSecond || this.state.showThird ? ' show' : '')}
2- Use one more class hide, and put the check on className, apply that class if you want to hide the div otherwise apply class two or three.
Check the working code:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
showSecond: false,
showThird: false
}
this.showDivTwo = this.showDivTwo.bind(this)
this.showDivThree = this.showDivThree.bind(this)
}
showDivTwo() {
this.setState(prevState => ({showThird: false, showSecond: !prevState.showSecond}))
console.log(this.state)
}
showDivThree() {
this.setState(prevState => ({ showSecond: false, showThird: !prevState.showThird}))
console.log(this.state)
}
render() {
return (
<div className={'wrapper' + (this.state.showSecond || this.state.showThird ? ' show' : '')}>
<div className="one">
one
<div>
<button onClick={this.showDivTwo}>{this.state.showSecond ? 'hideSecond' : 'showSecond'}</button>
</div>
<div>
<button onClick={this.showDivThree}>{this.state.showThird ? 'hideThird' : 'showThird'}</button>
</div>
</div>
<div className={this.state.showThird?"three":'hide'}>
three
<div>
<button onClick={this.showDivThree}>{this.state.showThird ? 'hideThird' : 'showThird'}</button>
</div>
</div>
<div className={this.state.showSecond ? "two" : 'hide'}>two
<div>
<button onClick={this.showDivTwo}>{this.state.showSecond ? 'hideSecond' : 'showSecond'}</button>
</div>
</div>
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
.wrapper {
overflow: hidden;
white-space: nowrap;
}
.hide, .one, .two, .three {
background: #333;
border: 2px solid #787567;
box-sizing: border-box;
color: #fff;
display: inline-block;
font-family: arial;
overflow: hidden;
padding: 20px;
text-align: center;
transition: border 0.2s, padding 0.2s, width 0.2s;
min-height: 50vh;
}
.one {
width: 100%;
}
.hide {
border-width: 2px 0;
padding: 20px 0;
width: 0;
}
.show .one, .show .two, .show .three {
border-width: 2px;
padding: 20px;
width: 50%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Polymer dom-repeat does not update the items array when a selection made in paper-swatch-picker

I am using paper-swatch-picker for picking a color and a dom-repeat to iterate over an Array.
when I select color, it does not update in the Array.
Can somebody help me propagating swatch picker color change to Array.
I can add multiple rows, each row with 3 color picker (foreground, background and border).
What I want is to have my Array decoratorList updated when I pick a color.
Below is the codepen for reference.
http://codepen.io/khanshahid/pen/wzGrxk
<html>
<head>
<base href="https://polygit.org/polymer+1.4.0/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="paper-input/paper-input.html">
<link rel="import" href="paper-tabs/paper-tabs.html">
<link rel="import" href="paper-tabs/paper-tab.html">
<link rel="import" href="iron-pages/iron-pages.html">
<link rel="import" href="iron-flex-layout/iron-flex-layout-classes.html">
<link rel="import" href="iron-input/iron-input.html">
<link rel="import" href="iron-collapse/iron-collapse.html">
<link rel="import" href="paper-material/paper-material.html">
<link rel="import" href="paper-item/paper-item.html">
<link rel="import" href="paper-input/paper-input-container.html">
<link rel="import" href="paper-button/paper-button.html">
<link rel="import" href="paper-toast/paper-toast.html">
<link rel="import" href="paper-fab/paper-fab.html">
<link rel="import" href="paper-swatch-picker/paper-swatch-picker.html">
</head>
<body>
<div style="width:1200px;">
<msk-decorator
tag-id= 1
color-list='["#65a5f2", "#83be54", "#f0d551", "#e5943c", "#a96ddb","#aabbcc","#aaa","#ccc","#eee","#333", "transparent", "none"]'
data-type="Enum">
</msk-decorator>
</div>
<dom-module id="msk-decorator">
<template>
<style is="custom-style">
:host{
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif !important;
};
.flex-horizontal-with-ratios {
#apply(--layout-horizontal);
}
.flexchild {
#apply(--layout-flex);
}
.flex2child {
#apply(--layout-flex-2);
}
.flex-equal-justified {
#apply(--layout-horizontal);
#apply(--layout-justified);
}
.decorator-container{
margin: 15px 5px 15px 5px;
min-height: 160px;
max-height: 240px;
}
.decorator-main{
padding-top: 10px;
min-height: 120px;
max-height: 240px;
overflow-x: hidden;
overflow-y: auto;
}
.decorator-heading-text{
font-size: 14px;
font-weight: 600;
padding-right: 5px;
}
.button-add-decorator{
color: #000;
background-color: #fff;
border: 1px solid #c5c5c5;
margin-left: 10px;
box-shadow: 0 0 7px rgba(0,0,0,0.2);
-webkit-box-shadow: 0 1px 7px rgba(0,0,0,0.2);
-moz-box-shadow: 0 1px 7px rgba(0,0,0,0.2);
}
.deco-buttons{
float: right;
margin: 0px 5px 0px 0px;
}
.deco-button{
color: #000;
background-color: #fff;
border: 1px solid #c5c5c5;
box-shadow: 0 0 7px rgba(0,0,0,0.2);
-webkit-box-shadow: 0 1px 7px rgba(0,0,0,0.2);
-moz-box-shadow: 0 1px 7px rgba(0,0,0,0.2);
}
button:hover{
box-shadow: 0 0 7px rgba(0,0,0,0.6);
-webkit-box-shadow: 0 1px 7px rgba(0,0,0,0.6);
-moz-box-shadow: 0 1px 7px rgba(0,0,0,0.6);
}
input, select, textarea, .text, .password{
background: #fff;
}
input:hover, input:active, input:focus, select:hover, select:active, select:focus, textarea:hover,textarea:focus {
border-color: transparent;
box-shadow: 0 0 7px rgba(0,0,0,0.5);
-webkit-box-shadow: 0 1px 7px rgba(0,0,0,0.5);
-moz-box-shadow: 0 1px 7px rgba(0,0,0,0.5);
}
input[disabled], select[disabled]{
color: #a2a2a2;
background-color: #e1e2e5;
}
.deco-dropdown{
padding-top: 8px;
padding-right: 10px;
padding-left: 10px;
}
.fa .fa-save {
padding-left: 5px;
padding-right: 5px;
}
.label-align{
padding-right: 3px;
}
.deco-row{
border-bottom: 0.5px solid #c3c3c3;
}
</style>
<div class="decorator-container">
<div class="flex-equal-justified decorator-heading-section">
<span class="decorator-heading-text">Decorators
<button class="button-add-decorator" on-tap="addNewDecorator" >+</button>
</span>
<template is="dom-if" if="{{saveFlag}}">
<div class="deco-buttons" style="color: #000;">
<button class="deco-button" on-tap="saveDecorators">Save</button>
</div>
</template>
</div>
<div class="decorator-main">
<form id="decoratorForm">
<template is="dom-repeat" items="{{decoratorList}}">
<div class="flex-horizontal-with-ratios deco-row">
<div class="flex2child" style="padding-left: 5px;">
<span>Text color </span>
<paper-swatch-picker id="textColor" column-count=5 color-list='[[colorList]]' color=[[item.textColor]] noink ></paper-swatch-picker>
</div>
<div class="flex2child">
<span>Cell color </span>
<paper-swatch-picker id="cellColor" column-count=5 color-list='[[colorList]]' color=[[item.cellColor]] noink ></paper-swatch-picker>
</div>
<div class="flex2child">
<span>Border color </span>
<paper-swatch-picker id="borderColor" color=[[item.borderColor]] noink ></paper-swatch-picker>
</div>
<div class="" style="padding-top: 8px; padding-right: 4px;">
<button class="button-add-decorator" on-tap="removeDecorator" id="[[index]]">X</button>
</div>
</div>
</template>
</form>
</div>
</template>
</div>
<script>
Polymer({
is: 'msk-decorator',
properties: {
selectedColor: {
type: String,
value: '#E91E63',
notify: true
},
decoratorList: {
type: Array,
notify: true,
value: []
},
decoratorObject: {
type: Object,
value: {
textColor: '',
cellColor: '',
borderColor: ''
}
},
dataType: {
type: String,
notify: true
},
tagId: {
type: String,
notify: true
},
requestObj: {
type: Object,
value: {
id: null,
addDecorator: [],
editDecorator: [],
deleteDecorator: []
}
},
saveFlag: {
type: Boolean,
notify: true
},
colorList: {
type: Array,
notify: true
},
dataURL:{
type: String,
value: function (){
var url = '/api/FindDecorators';
return url;
}
}
},
ready: function () {
this.init();
},
attached: function() {
},
typeChanged: function(e) {
console.log("typeChanged", e);
},
init: function(){
this.decoratorObject = {
textColor: '#000000',
cellColor: '#000000',
borderColor: '#000000'
};
this.format = [{
id: "9999",
label: "9999"
},
{
id: "9999.9",
label: "9999.9"
},
{
id: "9999.99",
label: "9999.99"
},
{
id: "9999.999",
label: "9999.999"
}];
this.type = [{
id: "NE",
label: "NOT EQUAL"
},
{
id: "E",
label: "EQUAL"
}];
this.value = [{
id: "1",
label: "Running"
},
{
id: "0",
label: "Stopped"
}];
},
addNewDecorator: function(e){
this.push('decoratorList', this.decoratorObject);
this.saveFlag = true;
},
removeDecorator: function(e){
if(e.target.decoratorId > 0){
this.push('deletedDecoratorList',e.target.decoratorId);
}
var i = Polymer.dom(e).rootTarget.id;
this.splice('decoratorList', i, 1);
this.saveFlag = true;
},
showFormat: function(dataTypeValue){
if(dataTypeValue.indexOf('Enum') > -1)
return true;
else
return false;
},
isIdExists: function(tagId){
if(tagId){
return true;
}else{
return false;
}
},
displaySave: function(){
if(this.saveFlag){
return true;
}else{
return false;
}
},
handleResponse: function(res, ele){
this.decoratorList = [];
if(this.decoratorList.length > 0){
this.saveFlag = true;
}else{
this.saveFlag = false;
}
},
saveDecorators: function(){
console.log('saveDecorators' + this.decoratorList);
for(var i=0; i < this.decoratorList.length; i++){
console.log(this.decoratorList[i]);
}
}
});
</script>
</dom-module>
</body>
</html>
I think you can use the value-changed event which will return a CustomEvent wich has the changed element in it:
attached: function() {
let pickers = this.$.decoratorForm.querySelectorAll('paper-swatch-picker');
pickers.forEeach(el => el.addEventListener('value-changed', event => {
// Do the Array manipulation here based on the event.detail.item
});
}
// also remove the event listener in detached(), but for that you need
// to define the function elsewhere and just passing it's reference to
// the addEventListener.
Then you can make the this.decoratorList manipulation, thats will be synchronized with the {{decoratorList}} data binding.
NOTE: The value-changed event is fired when a notify: true property changed, so it may fired multiple times if an internal event changing multiple properties in an element.

angular ui tree displaying raw values (i.e directly printing json data which comes from spring mvc)

this is my tree.jsp
<html>
<head>
<link rel="stylesheet" href="resources/css/style.css" />
<script src="resources/js/controller/AutoConfigController.js"></script>
<script src="demo/jquery.2.0.3.js"></script>
<script src="demo/angular.1.2.29.js"></script>
<script src="demo/bootstrap.3.1.1.js"></script>
<script src="demo/ui-bootstrap-tpls.0.11.2.js"></script>
<script src="demo/prettify.1.0.1.js"></script>
<link href="demo/bootstrap.3.1.1.css" rel="stylesheet" type="text/css">
<link href="demo/prettify-style.css" rel="stylesheet" type="text/css">
<script src="angular-tree-control.js"></script>
<link rel="stylesheet" type="text/css" href="css/tree-control.css">
<link rel="stylesheet" type="text/css" href="css/tree-control-attribute.css">
<style type="text/css">
.header {
padding-top: 50px;
padding-bottom: 50px;
background-color: #444980;
}
.head-container {
width: 1140px;
margin: auto;
}
.header h1 {
color: #fffffa;
font-size: 60px
}
.header h2 {
color: #fffffa;
font-size: 24px;
font-style: normal
}
.example-caption {
color: #bbb;
font-size: 12px
}
.docs-body {
width: 1140px;
margin: auto auto 50px;
}
.docs-footer {
background-color: #F5F5F5;
text-align: center;
padding: 30px 0;
border-top: #e5e5e5
}
.tab-pane {
background-color: #f8f8f8;
border-right: 1px solid #ccc;
border-left: 1px solid #ccc;
border-bottom: 1px solid #ccc;
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px
}
.nav li.active a {
background-color: #f8f8f8
}
pre.code {
border: none;
background-color: #f8f8f8;
padding: 10px;
margin: 0;
font-family: Consolas, 'Liberation Mono', Courier, monospace;
}
.docs-sidenav {
margin-top: 45px;
margin-bottom: 0;
}
.docs-sidenav>li>a {
display: block;
font-size: 13px;
font-weight: 500;
color: #999;
padding: 4px 20px;
}
.docs-sidenav>li.active>a {
font-weight: 700;
color: #563d7c;
border-left: 2px solid #563d7c;
padding-left: 18px;
}
.docs-sidenav>li>a:hover {
background-color: transparent;
color: #563d7c;
border-left: 1px solid #563d7c;
padding-left: 19px;
}
.type-hint-object {
background: #999;
}
.type-hint-boolean {
background: rgb(18, 131, 39);
}
.type-hint-number {
background: rgb(189, 63, 66);
}
body, html {
background: none !important;
background-image: none !important;
}
#mydiv {
position: fixed;
top: 30%;
left: 25%;
width: 30em;
height: 18em;
margin-top: -9em; /*set to a negative number 1/2 of your height*/
margin-left: -15em; /*set to a negative number 1/2 of your width*/
background-color: #f3f3f3;
}
</style>
<body ng-controller="AutoConfigController">
<div id="mydiv">
<form>
<div>
<input id="treeSearchText" type="text" />
<button id="searchTree" class="btn">Search</button>
</div>
</form>
<treecontrol class="tree-classic" tree-model="techList" on-selection="showSelected(node)">
{{techList}}
</treecontrol>
<script>
angular.module('SuperAdminReveal')
.directive('treeControl', function () {
return {
template: '<div class="treeControl" ng-transclude></div>',
restrict: 'E',
replace: true,
transclude: true,
link: function postLink(scope, element, attrs) {
element.bind('click', function (e) {
if (e.target.tagName === "LI" && e.target.childElementCount) {
$(e.target).toggleClass('collapsed');
}
})
}
};
});
</script>
</body>
</html>
and this is my treescontroller.java: from here i am returning json value to tree.jsp
package com.reveal.web.controller;
import java.util.List;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.reveal.web.controller.EnsureCapacity.Technology;
#Controller
public class TreesController {
#RequestMapping(value="/mytree",method = RequestMethod.GET)
public String printWelcome(ModelMap model) {
return "tree";
}
#RequestMapping(value = "/getTechList", method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody List<EnsureCapacity.Technology> getTechList(){
EnsureCapacity ensureCapacity = new EnsureCapacity();
List<EnsureCapacity.Technology> techList = ensureCapacity.getTechList();
return techList;
}
}
output:
Selected Node : [{"pId":0,"techName":"Node 1","id":1},{"pId":1,"techName":"Node 1.1","id":0},{"pId":1,"techName":"Node 1.2","id":0},{"pId":0,"techName":"Node 2","id":1},{"pId":1,"techName":"Node 2.1","id":0},{"pId":1,"techName":"Node 2.2","id":0},{"pId":1,"techName":"Node 2.3","id":0},{"pId":0,"techName":"Node 3","id":1},{"pId":1,"techName":"Node 3.1","id":0},{"pId":1,"techName":"Node 3.2","id":0},{"pId":0,"techName":"Node 4","id":1},{"pId":1,"techName":"Node 4.2","id":0},{"pId":1,"techName":"Node 4.3","id":0},{"pId":1,"techName":"Node 4.4","id":0},{"pId":0,"techName":"Node 5","id":1},{"pId":1,"techName":"Node 4.5","id":0},{"pId":1,"techName":"Node 4.6","id":0},{"pId":0,"techName":"Node 6","id":1},{"pId":1,"techName":"Node 6.1","id":0},{"pId":1,"techName":"Node 6.2","id":0},{"pId":1,"techName":"Node 6.3","id":0},{"pId":1,"techName":"Node 6.4","id":0},{"pId":1,"techName":"Node 6.5","id":0},{"pId":1,"techName":"Node 6.6","id":0},{"pId":1,"techName":"Node 6.7","id":0},{"pId":1,"techName":"Node 6.8","id":0},{"pId":0,"techName":"Node 7","id":1},{"pId":1,"techName":"Node 7.1","id":0},{"pId":0,"techName":"Node 8","id":1},{"pId":1,"techName":"Node 8.1","id":0},{"pId":1,"techName":"Node 8.2","id":0},{"pId":1,"techName":"Node 8.3","id":0},{"pId":1,"techName":"Node 8.4","id":0},{"pId":1,"techName":"Node 8.5","id":0},{"pId":1,"techName":"Node 8.6","id":0},{"pId":1,"techName":"Node 8.7","id":0},{"pId":1,"techName":"Node 8.8","id":0},{"pId":1,"techName":"Node 8.9","id":0},{"pId":1,"techName":"Node 8.10","id":0},{"pId":1,"techName":"Node 8.11","id":0},{"pId":1,"techName":"Node 8.12","id":0},{"pId":1,"techName":"Node 8.12","id":0}]
this is displaying on browser how to make it in treeview .
I am using angular-tree-control module
// Update tree control below
<treecontrol class="tree-classic" tree-model="techList" on-selection="showSelected(node)">
{{node.techName}} ({{node.id}} ) {{$index}}
</treecontrol>

Resources