Vue: Components added through "v-for" ignore flexbox layout - javascript

I am trying to have navigation controls displayed horizontally in the upper right hand section of the screen. The following works and displays with each item in a row:
<template>
<div id="navControlPanel">
<div id="controls">
<NavControl />
<NavControl />
<NavControl />
</div>
</div>
</template>
<style>
#navControlPanel{
display: flex;
flex-direction: row;
width: 100px;
height: 50px;
background: purple;
}
#controls{
display: flex;
flex-direction: row;
width: 100%;
}
</style>
yet this does not, and instead displays with them in a column:
<template>
<div id="navControlPanel">
<div id="controls" v-bind:key="control.id" v-for="control in controls">
<NavControl v-bind:control="control" />
</div>
</div>
</template>
NavControl:
<template>
<div id="navControl">
{{control.id}} //Set to just plain text when not dynamically binded
</div>
</template>
<style scoped>
#navControl{
width: 30pt;
height: 30pt;
background: blue;
border-radius: 1000px;
}
</style>
I can't find a logical reason why these would be any different, unless this is some inherent way Vue works that I'm missing.

The issue here seems to be that in the first example you got one div with multiple components in it:
<div id="controls">
<NavControl />
<NavControl />
<NavControl />
</div>
The problem is that in the second example you are creating multiple div elements with the same id and each of them have nested component inside of it.
Here, in a loop, you create multiple div elements with id="controls"
<div id="controls" v-bind:key="control.id" v-for="control in controls">
<NavControl v-bind:control="control" />
</div>
It ends up being something similar to this:
<div id="controls">
<NavControl />
</div>
<div id="controls">
<NavControl />
</div>
<div id="controls">
<NavControl />
</div>
You would probably see it better if you inspected your code in the browser tools.
As a side note: please, keep in mind that if you for whatever reason wanted to do something like this then you would use class instead of id.
Solution:
What you would want to do instead is to create multiple components inside your <div id="controls"></div>.
To do that you would place v-for inside the component and not the outer div.
<NavControl v-for="control in controls" v-bind:control="control" :key="control.id"/>

I am unsure of the actual desired scope, so I will go over both.
If we want multiple controls in the template, as laid out, switch id="controls" to class="controls":
<template>
<div id="navControlPanel">
<div class="controls" v-bind:key="control.id" v-for="control in controls">
<NavControl v-bind:control="control" />
</div>
</div>
</template>
...
.controls {
/* my styles */
}
If the v-for is out of scope, and we only want this ran on those items on NavControl:
<template>
<div id="navControlPanel">
<div class="controls">
<NavControl
v-for="control in controls"
/>
</div>
</div>
</template>

Related

Keep all style of page inside page block element

I have this code :
<div class="page-payment">
<div class="payment-methods" v-if="!pending">
<sepa-modal
ref="sepaModal"
/>
</div>
</div>
SepaModal.vue :
<b-modal
id="sepaModal"
centered
top
no-fade
size="md"
ref="modal"
hide-footer
#show="showPopup"
#hidden="closePopup"
>
<template #modal-header-close>
<icon width="20" height="20" class="d-none d-md-block" type="times"/>
<icon width="10" height="18" class="d-md-none" type="arrow-left"/>
</template>
<template #modal-title>
</template>
<div>
<div class="content-modal content-modal-sepa">
<div class="modal-header"></div>
..........
</div>
</div>
The .css :
.page-payment {
.payment-methods {
.content-modal {
padding: 20px !important
}
}
}
The style is not getting into account. But I want to keep all styles inside: .page-payment{}. How can I solve it?

How to align 2 rows horizontally in react?

I am making a react app and I have few columns which are to be mapped to values,I want to map the field names horizontally with field values.I tried with the below code but still it is a bit un-aligned.
my code:
Task class:
return (
<div >
<div>
<a className="clientparams1">{task.clientName} </a>
</div>
<div>
<a className="clientparams1">{task.clientId}</a>
</div>
<div>
<a className="clientparams1">{task.clientSecret}</a>
</div>
<div>
<a className="clientparams1">{task.status}</a>
</div>
<div>
<a className="clientparams1">{task.generated_on}</a>
</div>
{/* <div>
<FaTimes
className="clientparams"
style={{ color: "red", cursor: "pointer" }}
onClick={() => onDelete(task.clientId)}
/>
</div> */}
</div>
);
};
export default Task;
Tasks class:
It contains headings.
return (
<div>
<div className="form1">
<div>
<a className="clientparams1">clientName</a>
</div>
<div>
<a className="clientparams1">clientId</a>
</div>
<div>
<a className="clientparams1">clientSecret</a>
</div>
<div>
<a className="clientparams1">status</a>
</div>
<div>
<a className="clientparams1">generated_on</a>
</div>
</div>
{tasks.map((task, index) => (
<Task key={index} task={task} onDelete={onDelete} />
))}
</div>
)
}
In this code I have a parent div inside which there are 2 div tags and 1st div has all the field names and 2nd field has all the values to their corresponding field names.
Here are my css classes that i am using above:
.clientparams{
margin: 40px;
height: 30px;
width: 250px;
font-size: medium;
}
.form1{
display: flex;
}
.main_container{
display: inline-block;
justify-content: center;
align-items: center;
flex-wrap: wrap;
text-align: justify;
}
Can someone help me with this?
Thanks
You can try html table like this.
<table>
<tr>
<th>clientName</th>
<th>clientId</th>
<th>clientSecret</th>
<th>status</th>
<th>generated_on</th>
</tr>
<tr>
<td>{task.clientName}</td>
<td>{task.clientId}</td>
<td>{task.clientSecret}</td>
<td>{task.status}</td>
<td>{task.generated_on}</td>
</tr>
</table>
Hope that will solve your issue.
in your Task component, inside of .form1 div, I have made two div. In the first one, I have added ur client info. and in the second div, I have added the Task component. These 2 divs have their own className client_container and task_container respectively. Their className is assigned with CSS property.
return (
<div className="main_container>
<div className="form1">
<div className="client_container">
<div>
<a className="clientparams1">clientName</a>
</div>
<div>
<a className="clientparams1">clientId</a>
</div>
<div>
<a className="clientparams1">clientSecret</a>
</div>
<div>
<a className="clientparams1">status</a>
</div>
<div>
<a className="clientparams1">generated_on</a>
</div>
</div>
<div className="task_container">
{tasks.map((task, index) => (
<Task key={index} task={task} onDelete={onDelete} />
))}
</div>
</div>
)
}
#css
.form1{
display: flex;
flex-direction: column;
}
.client_container{
display: flex;
}
.task_container{
display: flex;
}

How to extend a render DOM in react

Say I have a child class extends from parent class.
Parent class renders
<div id="container" class="style-scope ">
.....
bunch of DOM.
</div>
In child classes, how could I render a HTML DOM like any of below examples without copy paste?
<div id="container" class="style-scope ">
.....
bunch of DOM.
<div id="childContainer">
</div>
</div>
<div id="container" class="style-scope ">
.....
bunch of DOM.
</div>
<div id="childContainer">
</div>
Have the parent render it’s children.
render () {
return (
<>
<div id="container" className="style-scope ">
.....
bunch of DOM.
</div>
{ this.props.children }
</>
)
}
Then you can do:
<Parent>
<div id=“childContainer”>...</div>
</Parent>
To get:
<div id="container" class="style-scope ">
.....
bunch of DOM.
</div>
<div id=“childContainer”>...</div>

Materialize footer not staying at bottom using react

I just need a way to make the footer sticky and stay at the bottom of the page while using react.
The footer does not stay at the bottom of the page, despite following the materialize docs and creating the header, main, footer format in my app.
The footer does display correctly but refuses to go to the bottom (be a sticky footer).
Here is the render method of app.js:
render() {
return (
<React.Fragment>
<Header />
<main>
... my stuff here ...
</main>
<Footer />
</React.Fragment>
);
}
Here is the Header component:
export default function About() {
return (
<header></header>
);
}
Here is the Footer component (copied exact from the materialize docs):
export default function About() {
return (
<footer className="page-footer">
<div className="container">
<div className="row">
<div className="col l6 s12">
<h5 className="white-text">Footer Content</h5>
<p className="grey-text text-lighten-4">You can use rows and columns here to organize your footer content.</p>
</div>
<div className="col l4 offset-l2 s12">
<h5 className="white-text">Links</h5>
<ul>
<li><a className="grey-text text-lighten-3" href="#!">Link 1</a></li>
</ul>
</div>
</div>
</div>
<div className="footer-copyright">
<div className="container">
© 2014 Copyright Text
<a className="grey-text text-lighten-4 right" href="#!">More Links</a>
</div>
</div>
</footer>
);
}
The footer does display correctly but refuses to go to the bottom (be a sticky footer).
I have this in the head of index.html (the docs say this is how to make a sticky footer):
<script>
body {
display: flex;
min-height: 100vh;
flex-direction: column;
}
main {
flex: 1 0 auto;
}
</script>
(I think it is because react mounts my app content inside a <div id="root"> in index.html and thus breaks the header, main, footer format materialize requires for the footer to be sticky.)
I just need a way to make the footer sticky and stay at the bottom of the page while using react.
In react jsx you must use className instead of class.
class is a reserved word in javascript.
You can use a <div> tag instead of a <React.Fragment> with display: flex and min-height: 100vh. In the <Footer /> tag you can apply a style with align-self: flex-end it should align the footer to the bottom of the page.
You can see this fiddle: https://jsfiddle.net/brunohgv/cjypx5wL/4/

Adding inline styles to react

Currently I'm using react.js and I'm trying to get two div's to be side by side.
Currently I'm trying to
<div id="sidebar" style = "display:inline-block;" >
<script src="build/sidebar.js"></script>
</div>
<div id="map-canvas" style="display: inline-block; width: 20%; height: 50%; "></div>
with sidebar.js as the where react is stored. This unfortunately doesnt work however as it just moves map-canvas to the side while sidebar isn't to the left of it; its on top. I've tried many various combinations w/ float as well and none of them seem to work
Another option is to edit the sidebar.js code where I currently have
return <div>
<input type="text" value={this.state.searchString} onChange={this.handleChange} placeholder="Type here" />
<ul>
{ libraries.map(function(l){
return <li>{l.name} </li>
}) }
</ul>
</div>;
in which I try doing return <div style ="display: inline-block;">
However, in this case the generated html doesnt show up at all. I'm perplex to what I should try but react seems like it doesnt want to play nice with other div elements.
That's because in React, the style prop takes an object instead of a semicolon-separated string.
<div id="sidebar" style={{display : 'inline-block'}} >
<script src="build/sidebar.js"></script>
</div>
<div id="map-canvas" style={{display: 'inline-block', width: '20%', height: '50%'}}>
</div>
Edit:
So this:
return <div style="display: inline-block;">
Would become this:
return <div style={{display: 'inline-block'}}>
const styles = {
container: {
backgroundColor: '#ff9900',
...
...
textAlign: 'center'
}
}
export default class App extends React.Component {
render() {
return(
<div className="container" style={styles.container}>
// your other codes here...
</div>
);
}
}

Categories

Resources