tried posting to json db but only gets the Id in the json server with no postdate, posttitle, postdesc and image. i dont know i am doing wrong.
I would also like to like to update a post and then should be redirected to the homepage after updating the post.
I had tried using Redirect, useHistory and then useNavigate ffrom react-router-dom but still isnt working
import { useEffect, useState } from "react";
import "./write.css";
import { useNavigate } from "react-router-dom";
export default function Write() {
const [image, setImage] = useState();
const [posttitle, setPostTitle] = useState("");
const [postdesc, setPostDesc] = useState("");
const [postdate, setPostDate] = useState("20/30/2020");
// const [postDate, setPostDate] = useState("");
const navigate = useNavigate();
//==============================================================//
//Publishing or posting a post to the json server
const formSubmit = (e)=> {
e.preventDefault();
const docs = {
image,
posttitle,
postdate,
postdesc,
};
fetch("http://localhost:8005/posts", {
method: "POST",
headers: { contentType: "application/json" },
body: JSON.stringify(docs),
}).then(() => {
navigate.push("/home");
});
console.log(docs);
}
//===============================================================//
// const { id } = useParams(); not working
// getting the id of the post to be edited using window.location.href
const url = window.location.href;
const id = url.substring(url.lastIndexOf("=") + 1);
// //editing/Updating post data in the json-server file
// function editBtn() {
// fetch("http://localhost:8005/posts/" + id, {
// method: "PUT",
// body: JSON.stringify(),
// headers: {
// contentType: "application.json",
// },
// });
// }
return (
<div className="write">
<form className="writeform" onSubmit={formSubmit}>
<div>
<input />
date here
</div>
<div className="image_container">
{image && (
<div>
<img
className="writeimage"
alt="postimage"
src={URL.createObjectURL(image)}
onChange={(e) => {
setImage(e.target.src);
}}
/>
</div>
)}
</div>
<div className="writeformgroup">
<label htmlFor="fileinput">
<i className="writeicon fa-solid fa-plus"></i>
</label>
<input
id="fileinput"
type="file"
onChange={(e) => {
setImage(e.target.files[0]);
}}
style={{ display: "none" }}
/>
<input
type="text"
// value={postTitle}
className="writeinput"
onChange={(e) => {
setPostTitle(e.target.value);
}}
autoFocus
/>
</div>
<div className="writeformgroup">
<textarea
// value={postDesc}
onChange={(e) => {
setPostDesc(e.target.value);
}}
type="text"
className="writeinput writetext"
></textarea>
</div>
<button className="writesubmit">Publish</button>
</form>
<p>{posttitle}</p>
</div>
);
}
//JSON DB
{
"posts": [
{
"image": "https://images.pexels.com/photos/9968415/pexels-photo-9968415.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
"posttitle": "Lorem ipsum dolor sit amet ",
"postdate": "20-29-2022",
"postdesc": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Saepe, suscipit inventore. Facilis ducimus quod ratione, fugiat temporibus, porro vitae consequuntur aspernatur Lorem ipsum dolor sit amet consectetur adipisicing elit. Saepe, suscipit inventore. Facilis ducimus quod ratione, fugiat temporibus, porro vitae consequuntur aspernatur sequi ad eveniet necessitatibus reiciendis dolor deleniti qui mod",
"id": 1
},
{
"image": "https://images.pexels.com/photos/13957041/pexels-photo-13957041.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
"posttitle": "Lorem ipsum dolor sit amet ",
"postdate": "20-29-2022",
"postdesc": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Saepe, suscipit inventore. Facilis ducimus quod ratione, fugiat temporibus, porro vitae consequuntur aspernatur Lorem ipsum dolor sit amet consectetur adipisicing elit. Saepe, suscipit inventore. Facilis ducimus quod ratione, fugiat temporibus, porro vitae consequuntur aspernatur sequi ad eveniet necessitatibus reiciendis dolor deleniti qui mod",
"id": 2
},
{
"image": "https://images.pexels.com/photos/13715795/pexels-photo-13715795.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
"posttitle": "Lorem ipsum dolor sit amet ",
"postdate": "20-29-2022",
"postdesc": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Saepe, suscipit inventore. Facilis ducimus quod ratione, fugiat temporibus, porro vitae consequuntur aspernatur Lorem ipsum dolor sit amet consectetur adipisicing elit. Saepe, suscipit inventore. Facilis ducimus quod ratione, fugiat temporibus, porro vitae consequuntur aspernatur sequi ad eveniet necessitatibus reiciendis dolor deleniti qui mod",
"id": 3
},
{
"image": "https://images.pexels.com/photos/13420447/pexels-photo-13420447.jpeg?auto=compress&cs=tinysrgb&w=400&lazy=load",
"posttitle": "Lorem ipsum dolor sit amet ",
"postdate": "20-29-2022",
"postdesc": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Saepe, suscipit inventore. Facilis ducimus quod ratione, fugiat temporibus, porro vitae consequuntur aspernatur Lorem ipsum dolor sit amet consectetur adipisicing elit. Saepe, suscipit inventore. Facilis ducimus quod ratione, fugiat temporibus, porro vitae consequuntur aspernatur sequi ad eveniet necessitatibus reiciendis dolor deleniti qui mod",
"id": 4
},
{
"image": "https://images.pexels.com/photos/13950829/pexels-photo-13950829.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
"posttitle": "Lorem ipsum dolor sit amet ",
"postdate": "20-29-2022",
"postdesc": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Saepe, suscipit inventore. Facilis ducimus quod ratione, fugiat temporibus, porro vitae consequuntur aspernatur sequi ad eveniet necessitatibus reiciendis dolor deleniti qui mod",
"id": 5
},
{
"image": "https://images.pexels.com/photos/11055161/pexels-photo-11055161.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
"posttitle": "Lorem ipsum dolor sit amet ",
"postdate": "20-29-2022",
"postdesc": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Saepe, suscipit inventore. Facilis ducimus quod ratione, fugiat temporibus, porro vitae consequuntur aspernatur sequi ad eveniet necessitatibus reiciendis dolor deleniti qui mod",
"id": 6
}
]
}
Try useHistory for redirect issues
import { useHistory } from 'react-router-dom';
const histroy = useHistory();
histroy.push({ pathname: '/home' });
Try async /await for fetch
const formSubmit = async () => {
try{
const response = await fetch("http://localhost:8005/posts", {
method: "POST",
headers: { contentType: "application/json" },
body: JSON.stringify(docs),
});
if(!response || !response.ok){
throw new Error('error message');
}
const data = response.json();
console.log(data);
}catch(error){
console.log(error);
}
}
Related
I am making a blog Component with React.
By giving createContext to a separate blogData.jsx, the contents of data.JSON were brought as it is. (It was put in a variable)
Since the value of the "thumbnail" key is '/assets/post-img1.jpg' and in my Local it is '../../assets/post-img1.jpg', So I wrote the following in Post.jsx.
// Post.jsx
<img
className="postImg"
src={`../..${thumbnail}`}
alt=""
/>
<img src={`../..${profileImg}`} alt="" />
The results confirmed in Developer Tools Elements are as follows. Path is correct.
// in Developer Tools Elements
<img class="postImg" src="../../assets/post-img6.jpg" alt="">
<img src="../../assets/profile.jpg" alt="">
However, the image is not rendered and an alternate image(x box?) is displayed.
react-blog
├── package-lock.json
├── package.json
├── node_modules
├── public
│ ├── data.json
│ ├── index.html
│ └── reset.css
│
└── src
├── assets
│ ├── post-img1.jpg
│ └── ...
│
├── components
│ ├── banner
│ ├── footer
│ ├── post
│ ├── posts
│ ├── sidebar
│ ├── thumbnail
│ └── topbar
│
├── contexts
│ └── blogData.jsx
│
├── pages
├── App.jsx
└── index.js
blogData.jsx ↓
import { createContext } from 'react';
const blogData = createContext(
{
"blog": {
...
},
"posts": [
{
"id": 1,
"thumbnail": "/assets/post-img1.jpg",
"title": "Dipisicing elit. Inventore illum nostrum perferendis.",
"mainBg": "/assets/post-background1.jpg",
"category": ["Life", "style"],
"profileImg": "/assets/profile.jpg",
"contents": [
{
"type": "p",
"text": "Adipisicing elit. Inventore illum nostrum perferendis voluptas, voluptate soluta corrupti dolore quidem. Placeat, eaque! Exercitationem est facilis dolor quas odio cum incidunt repudiandae vel. Lorem ipsum dolor sit amet consectetur, adipisicing elit. Inventore illum nostrum perferendis voluptas, voluptate soluta corrupti dolore quidem. Placeat, eaque! Exercitationem est facilis dolor quas odio cum incidunt repudiandae vel. Lorem ipsum dolor sit amet consectetur, adipisicing elit. Inventore illum nostrum perferendis voluptas, voluptate soluta corrupti dolore quidem. Placeat, eaque! Exercitationem est facilis dolor quas odio cum incidunt repudiandae vel. Lorem ipsum dolor sit amet consectetur, adipisicing elit. Inventore illum nostrum perferendis voluptas, voluptate soluta corrupti dolore quidem. Placeat, eaque! Exercitationem est facilis dolor quas odio cum incidunt repudiandae vel. Lorem ipsum dolor sit amet consectetur, adipisicing elit. Inventore illum nostrum perferendis voluptas, voluptate soluta corrupti dolore quidem. Placeat, eaque! Exercitationem est facilis dolor quas odio cum incidunt repudiandae vel. Lorem ipsum dolor sit amet consectetur, adipisicing elit. Inventore illum nostrum perferendis voluptas, voluptate soluta corrupti dolore quidem. Placeat, eaque! Exercitationem est facilis dolor quas odio cum incidunt repudiandae vel. Lorem ipsum dolor sit amet consectetur, adipisicing elit. Inventore illum nostrum perferendis voluptas, voluptate soluta corrupti dolore quidem. Placeat, eaque! Exercitationem est facilis dolor quas odio cum incidunt repudiandae vel. Lorem ipsum dolor sit amet consectetur, adipisicing elit. Inventore illum nostrum perferendis voluptas, voluptate soluta corrupti dolore quidem. Placeat, eaque! Exercitationem est facilis dolor quas odio cum incidunt repudiandae vel."
},
{
"type": "img",
"src": "/assets/post-background1.jpg"
},
{
"type": "p",
"text": "Inventore illum nostrum perferendis voluptas, voluptate soluta corrupti dolore quidem. Placeat, eaque! Exercitationem est facilis dolor quas odio cum incidunt repudiandae vel. Lorem ipsum dolor sit amet consectetur, adipisicing elit. Inventore illum nostrum perferendis voluptas, voluptate soluta corrupti dolore quidem. Placeat, eaque! Exercitationem est facilis dolor quas odio cum incidunt repudiandae vel. Lorem ipsum dolor sit amet consectetur, adipisicing elit. Inventore illum nostrum perferendis voluptas, voluptate soluta corrupti dolore quidem. Placeat, eaque! Exercitationem est facilis dolor quas odio cum incidunt repudiandae vel. Lorem ipsum dolor sit amet consectetur, adipisicing elit. Inventore illum nostrum perferendis voluptas, voluptate soluta corrupti dolore quidem. Placeat, eaque! Exercitationem est facilis dolor quas odio cum incidunt repudiandae vel."
}
],
"userName": "Chilli",
"created": "2022.04.01"
},{...},{...},{...},{...},{...}
],
"users": [
{...},{...}
]
}
);
export default blogData;
Post.jsx ↓
import "./post.css";
export default function Post({data}) {
const {id, thumbnail, title, category, contents, profileImg, userName, created} = data;
return (
<div className="post">
<img
className="postImg"
src={`../..${thumbnail}`}
alt=""
/>
<div className="postInfo">
<dl className="postCats">
<dt className="hidden">Category</dt>
<dd className="postCat">
{category}
</dd>
</dl>
<h3 className="postTitle">
{title}
</h3>
<dl className="authorWrap">
<dt className="hidden">Author</dt>
<dd className="author">
<img src={`../..${profileImg}`} alt="" />
{userName}
</dd>
<dt className="hidden">post date</dt>
<dd className="postDate">
{created}
</dd>
</dl>
<p className="postDesc">
{contents[0].text}
</p>
</div>
</div>
);
}
Posts.jsx ↓
import React, { useContext } from "react";
import Post from "../post/Post";
import "./posts.css";
import blogData from "../../contexts/blogData";
export default function Posts() {
const { posts } = useContext(blogData);
const postArray = [];
for (let i = 0; i < posts.length; i++) {
postArray.push(<Post key={i+1} data={posts[i]} />);
}
console.log('postArray', postArray);
return (
<div className="posts">
{postArray.reverse()}
</div>
);
}
the main situation is the next one: I want to use the current url as the param in order to find and use the props of that object. My issue... I wondering if this is the suppose method I should use, I willing to heard your ideas.
'''
class Lista extends React.Component {
constructor () {
super();
this.state = {
servicios : [{
servicio : 'Comerciales',
video : '',
descripcion : 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Inventore, aliquid nulla harum illo eius cumque esse error similique molestiae molestias non eligendi! Ex laboriosam consequatur laborum recusandae aut ullam velit.',
link : '/servicios/comerciales',
id : 0
},
{
servicio : 'Eventos',
video : '',
descripcion : 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Inventore, aliquid nulla harum illo eius cumque esse error similique molestiae molestias non eligendi! Ex laboriosam consequatur laborum recusandae aut ullam velit.',
link : '/servicios/eventos',
id : 1
},
{
servicio : 'Branding',
video : '',
descripcion : 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Inventore, aliquid nulla harum illo eius cumque esse error similique molestiae molestias non eligendi! Ex laboriosam consequatur laborum recusandae aut ullam velit.',
link : '/servicios/branding',
id : 2
},
{
servicio : 'Tecnicos',
video : '',
descripcion : 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Inventore, aliquid nulla harum illo eius cumque esse error similique molestiae molestias non eligendi! Ex laboriosam consequatur laborum recusandae aut ullam velit.',
link : '/servicios/tecnicos',
id : 3
},
{
servicio : 'Operacion con Dron',
video : '',
descripcion : 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Inventore, aliquid nulla harum illo eius cumque esse error similique molestiae molestias non eligendi! Ex laboriosam consequatur laborum recusandae aut ullam velit.',
link : '/servicios/operacion-con-dron',
id : 4
}
]
}
}
render(props) {
return (
this.state.servicios.find((lista => lista.link == props.match.url) => (
<Servicio/>
))
)
}
}
'''
As expected the code itself is actually incomplete, and even I could made it showing the whole list but for some reason I now completely stuck with this problem. I will update if I achieve progress. cheers
You're right about using Array.prototype.find to find a matching service object if one exists.
You could spread the service object and pass it as props to the Servicio component if there's a match. And you have to access the props in a class component via this.props.
render() {
const service = this.state.servicios.find(
service => service.link === this.props.match.url
)
if (service) {
return <Servicio {...service} /> // this will pass `servicio`, `video`, `link`, `desscription`, and `id` as props
}
return <p>Not Found</p> // or whatever you want to return
}
You can use map method to iterate the array and use if condition to check props.match.url matches with link key in each object and return <Servicio/>
class Lista extends React.Component {
constructor () {
super();
this.state = {
servicios : [{
servicio : 'Comerciales',
video : '',
descripcion : 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Inventore, aliquid nulla harum illo eius cumque esse error similique molestiae molestias non eligendi! Ex laboriosam consequatur laborum recusandae aut ullam velit.',
link : '/servicios/comerciales',
id : 0
},
{
servicio : 'Eventos',
video : '',
descripcion : 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Inventore, aliquid nulla harum illo eius cumque esse error similique molestiae molestias non eligendi! Ex laboriosam consequatur laborum recusandae aut ullam velit.',
link : '/servicios/eventos',
id : 1
},
{
servicio : 'Branding',
video : '',
descripcion : 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Inventore, aliquid nulla harum illo eius cumque esse error similique molestiae molestias non eligendi! Ex laboriosam consequatur laborum recusandae aut ullam velit.',
link : '/servicios/branding',
id : 2
},
{
servicio : 'Tecnicos',
video : '',
descripcion : 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Inventore, aliquid nulla harum illo eius cumque esse error similique molestiae molestias non eligendi! Ex laboriosam consequatur laborum recusandae aut ullam velit.',
link : '/servicios/tecnicos',
id : 3
},
{
servicio : 'Operacion con Dron',
video : '',
descripcion : 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Inventore, aliquid nulla harum illo eius cumque esse error similique molestiae molestias non eligendi! Ex laboriosam consequatur laborum recusandae aut ullam velit.',
link : '/servicios/operacion-con-dron',
id : 4
}
]
}
}
render() {
return (
<>{this.state.servicios.map(lista =>{
if(lista.link == this.props.match.url) {
return (<Servicio/>);
}})
}
</>
)
}
}
help me please, I display the html markup of 6 posts, the first click works correctly, the second click I display the same posts. how should I add six new posts, and so every time I click?
I don't know what can be used instead of the slice method. demo https://jsfiddle.net/u9zc7p5v/13/
const content = mrd.map(function(data, elem) {
return `
<div class="blog__item">
<h2 class="blog__item-title">
${data.title}
</h2>
<input type="checkbox" class="read-more-state" id="post-${elem}" />
<p class="blog__item-text">
${data.body} <span class="blog__item-more">Lorem ipsum dolor sit amet consectetur adipisicing elit. Autem itaque ducimus unde harum vitae quam provident. Lorem ipsum dolor sit amet consectetur adipisicing elit. Dicta sapiente odit laborum tempore sed quaerat a aliquam? Corrupti dolorum, tempora iste qui modi consectetur explicabo quia vel reiciendis nesciunt? Id!</span>
</p>
<label for="post-${elem}" class="blog__item-toggle" >Read More</label>
<div>${elem}</div>
</div>
`
}).slice(startNum, endNum).join('');
Increase the startNum value startNum+=6. then in slice function do startNum + endNum.
$(function(){
const blogs = document.querySelector('.blog__items')
const moreBtn = document.querySelector('.blog-btn')
let startNum = 0;
let endNum = 6;
async function getContent() {
let responce = await fetch('https://jsonplaceholder.typicode.com/posts');
let data = await responce.json();
return data;
}
$(moreBtn).on('click', async function(e) {
let mrd = await getContent();
console.log(mrd.length)
const content = mrd.map(function(data, elem) {
return `
<div class="blog__item">
<h2 class="blog__item-title">
${data.title}
</h2>
<p class="blog__item-text">
${data.body} <span class="blog__item-more">Lorem ipsum dolor sit amet consectetur adipisicing elit. Autem itaque ducimus unde harum vitae quam provident. Lorem ipsum dolor sit amet consectetur adipisicing elit. Dicta sapiente odit laborum tempore sed quaerat a aliquam? Corrupti dolorum, tempora iste qui modi consectetur explicabo quia vel reiciendis nesciunt? Id!</span>
</p>
<label class="blog__item-toggle" >Read More</label>
<div>${elem}</div>
</div>
`
}).slice(startNum, startNum+endNum).join('');
console.log(startNum)
const el = $(content);
$(blogs).append(el)
el.on('click', function() {
});
startNum+= 6
});
});
I have 2 columns on my page... my issue is that I want the right column to stack underneath my left column if browser size is made smaller. I am using angular material but don't mind using custom styling to fix this. Any help will be appreciated.
HTML:
<div layout="row" layout-align="center center" flex>
<section layout="row">
<div id="nav" flex="20" layout="column" layout-align="space-around">
<md-calendar class="fixed-calendar" ng-model="myDate"></md-calendar>
</div>
<div id="content" flex>
<h2>Right Column</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas maxime officia aliquam nesciunt debitis quam optio odio soluta corrupti, mollitia, possimus iure quos nostrum eius nam. Aperiam voluptatum voluptate unde.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas maxime officia aliquam nesciunt debitis quam optio odio soluta corrupti, mollitia, possimus iure quos nostrum eius nam. Aperiam voluptatum voluptate unde.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas maxime officia aliquam nesciunt debitis quam optio odio soluta corrupti, mollitia, possimus iure quos nostrum eius nam. Aperiam voluptatum voluptate unde.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas maxime officia aliquam nesciunt debitis quam optio odio soluta corrupti, mollitia, possimus iure quos nostrum eius nam. Aperiam voluptatum voluptate unde.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas maxime officia aliquam nesciunt debitis quam optio odio soluta corrupti, mollitia, possimus iure quos nostrum eius nam. Aperiam voluptatum voluptate unde.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas maxime officia aliquam nesciunt debitis quam optio odio soluta corrupti, mollitia, possimus iure quos nostrum eius nam. Aperiam voluptatum voluptate unde.</p>
</div>
</section>
</div>
CSS:
.datepickerdemoBasicUsage md-content {
padding-bottom: 200px; }
.datepickerdemoBasicUsage .validation-messages {
font-size: 11px;
color: darkred;
margin: 10px 0 0 25px; }
.fixed-calendar {
width: 340px;
height: 340px;
display: block;
}
.fixed-calendar .md-calendar-scroll-mask {
width: 340px !important;
}
.fixed-calendar .md-virtual-repeat-scroller {
width: 340px !important;
height: 308px;
overflow: hidden !important;
}
JSFiddle Demo
Something like this on your parent layout="column" layout-gt-xs="row"
<div ng-app="sandbox">
<div>
<section layout="column" layout-gt-xs="row">
<div id="nav" flex>
<md-calendar class="fixed-calendar" ng-model="myDate"></md-calendar>
</div>
<div id="content" flex>
<h2>Right Column</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas maxime officia aliquam nesciunt debitis quam optio odio soluta corrupti, mollitia, possimus iure quos nostrum eius nam. Aperiam voluptatum voluptate unde.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas maxime officia aliquam nesciunt debitis quam optio odio soluta corrupti, mollitia, possimus iure quos nostrum eius nam. Aperiam voluptatum voluptate unde.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas maxime officia aliquam nesciunt debitis quam optio odio soluta corrupti, mollitia, possimus iure quos nostrum eius nam. Aperiam voluptatum voluptate unde.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas maxime officia aliquam nesciunt debitis quam optio odio soluta corrupti, mollitia, possimus iure quos nostrum eius nam. Aperiam voluptatum voluptate unde.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas maxime officia aliquam nesciunt debitis quam optio odio soluta corrupti, mollitia, possimus iure quos nostrum eius nam. Aperiam voluptatum voluptate unde.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas maxime officia aliquam nesciunt debitis quam optio odio soluta corrupti, mollitia, possimus iure quos nostrum eius nam. Aperiam voluptatum voluptate unde.</p>
</div>
</section>
</div>
</div>
This says stack child elements into a column.
Then if the browser width gets to greater than or equal xs (>= 600px), make child elements into a row.
Fiddle
I have done this before but I can't for the life of me remember how. I want a user to be able to select a product by clicking a button in an <li> then have that passed to an array. As well as that, the <li> needs to have a class 'active' once that item is in the selected array:
<li class="row" data-ng-repeat="product in products">
<div class="col-lg-9">
<h3>{{product.name}}</h3>
<p>{{product.description}}</p>
</div>
<div class="col-lg-3">
<button class="btn btn-primary" data-ng-click="selectProduct(product.id)">Select Product</button>
</div>
</li>
is the HTML and this is the controller:
app.controller("MainController", function($scope, $http) {
$scope.selected_products = []
$scope.products = [
{
name: 'Example product',
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Id, assumenda, dolor, ipsa, atque obcaecati tempora perspiciatis earum vitae amet cum nostrum blanditiis ducimus culpa molestiae temporibus porro debitis voluptatibus libero.',
category: 'VT'
},
{
name: 'Example product 2',
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Id, assumenda, dolor, ipsa, atque obcaecati tempora perspiciatis earum vitae amet cum nostrum blanditiis ducimus culpa molestiae temporibus porro debitis voluptatibus libero.',
category: 'VT'
}
]
$scope.selectProduct = function(name) {
console.log(name)
}
})
Does anyone have any pointers as to how to do this?
Here you are:
$scope.isSelected = function(product){
return this.selected_products.indexOf(product)>-1;
}
$scope.selectProduct = function(product) {
if(!this.isSelected(product)){
this.selected_products.push(product);
}
}
Use it like:
<button ng-disabled="isSelected(product)" data-ng-click="selectProduct(product)">Select Product</button>
Working example: http://plnkr.co/edit/sPAN36?p=preview