Rails5 + Paperclip: Image_tag for a collection of images displays whole image array - erb

Models:
Place has_many Photos
Photo belongs_to Place
I wan to find and display all photos that belong to a place.
Controller:
#place = Place.find(params[:id])
view:
<% if #place.photos.exists %>
<%= #place.photos.each do |place| %>
<%= image_tag place.photo.url(:medium)%>
<% end %>
<% end %>
Id displays requested photos - but also whole photo array:
[#<Photo id: 1, place_id: 6, title: nil, status: nil, description: nil, photo_file_name: "IMG_0436.JPG", photo_content_type: "image/jpeg", photo_file_size: 4751995, photo_updated_at: "2016-10-19 22:11:35", created_at: "2016-10-19 22:11:38", updated_at: "2016-10-19 22:11:38">, #<Photo id: 2, place_id: 6, title: nil, status: nil, description: nil, photo_file_name: "IMG_0427.JPG", photo_content_type: "image/jpeg", photo_file_size: 5683007, photo_updated_at: "2016-10-19 22:13:21", created_at: "2016-10-19 22:13:24", updated_at: "2016-10-19 22:13:24">, #<Photo id: 3, place_id: 6, title: nil, status: nil, description: nil, photo_file_name: "IMG_0428.JPG", photo_content_type: "image/jpeg", photo_file_size: 4957508, photo_updated_at: "2016-10-20 19:42:56", created_at: "2016-10-20 19:42:58", updated_at: "2016-10-20 19:42:58">]
How to display only images?

You are outputting the #places each
change
<%= #place.photos.each do |place| %>
into
<% #place.photos.each do |place| %>

Related

Vue Vee-validate select (dropdown list)

So I am using this input template I got from a tutorial #logaretm created, which works great for just about anything I need. I would like to know if there is a way to modify this template to validate as a Select (drop-down) and how would I populate the option values?
I looked at vee-validation documentation but haven't been able to figure this out on my own. Any help would with this is greatly appreciated.
<template>
<div
class="TextInput"
:class="{ 'has-error': !!errorMessage, success: meta.valid }"
>
<label :for="name">{{ label }}</label>
<input
:name="name"
:id="name"
:type="type"
:value="inputValue"
:placeholder="placeholder"
#input="handleChange"
#blur="handleBlur"
/>
<p class="help-message" v-show="errorMessage || meta.valid">
{{ errorMessage || successMessage }}
</p>
</div>
</template>
<script>
import { toRef } from "vue";
import { useField } from "vee-validate";
export default {
props: {
type: {
type: String,
default: "text",
},
value: {
type: String,
default: "",
},
name: {
type: String,
required: true,
},
label: {
type: String,
required: true,
},
successMessage: {
type: String,
default: "",
},
placeholder: {
type: String,
default: "",
},
},
setup(props) {
// use `toRef` to create reactive references to `name` prop which is passed to `useField`
// this is important because vee-validte needs to know if the field name changes
// https://vee-validate.logaretm.com/v4/guide/composition-api/caveats
const name = toRef(props, "name");
// we don't provide any rules here because we are using form-level validation
// https://vee-validate.logaretm.com/v4/guide/validation#form-level-validation
const {
value: inputValue,
errorMessage,
handleBlur,
handleChange,
meta,
} = useField(name, undefined, {
initialValue: props.value,
});
return {
handleChange,
handleBlur,
errorMessage,
inputValue,
meta,
};
},
};
</script>

Change colour of money formatted cell to red if negative

I have a column which is formatted using the built in money formatter. I would like to change the text of the cell to red if the numeric value of the cell is negative. I can't create a custom formatter because the column formatter option is already set to money.
You have to use a custom formatter, Mimic the money formatter in this code. I can't think of anything else
let tabledata = [{
id: 1,
name: "Oli ",
money: 1,
col: "red",
dob: ""
},
{
id: 2,
name: "Mary ",
money: -1,
col: "blue",
dob: "14/05/1982"
},
{
id: 3,
name: "Christine ",
money: 0,
col: "green",
dob: "22/05/1982"
},
{
id: 4,
name: "Brendon ",
money: 10,
col: "orange",
dob: "01/08/1980"
},
{
id: 5,
name: "Margret ",
money: -10,
col: "yellow",
dob: "31/01/1999"
},
];
for (let i = 0; i < tabledata.length; i++) {
if (tabledata[i].money < 0) {
tabledata[i].money = "<span class='red'>$" +
tabledata[i].money +
"</span>"
} else {
tabledata[i].money = '$' + tabledata[i].money;
}
}
const table = new Tabulator("#example-table", {
data: tabledata,
layout: "fitColumns",
columns: [{
title: "id",
field: "id"
},
{
title: "name",
field: "name"
},
{
title: "money",
field: "money",
formatter: "html"
},
{
title: "col",
field: "col"
},
{
title: "dob",
field: "dob"
},
]
});
.red {
color: red;
}
<!DOCTYPE html>
<html lang="en">
<script src="https://unpkg.com/tabulator-tables#4.2.4/dist/js/tabulator.min.js"></script>
<link href="https://unpkg.com/tabulator-tables#4.2.4/dist/css/tabulator.min.css" rel="stylesheet" />
<body>
<div id="example-table"></div>
</body>
</html>
I think I found a solution for this problem:
formatter:function(cell,params,callback) {
let money = cell.getTable().modules.format.getFormatter("money");
cell.getElement().style...
return money(cell,params,callback);
}
https://jsfiddle.net/baumrock/vxpbhLsg/14/

How to vue watch a specific property in an array of objects

I'm using vue.js 2.5.2
I have an array of objects and I'd like to watch forms[*].selected and if it changes call a function.
This is my attempt, but obviously, it is not correct. I tried putting the array into a for loop to watch each object's property selected.
watch: {
for (var i = 0; i < forms.length; i++)
{
forms[i].selected: function(){
console.log("change made to selection");
}
}
},
This is the array of objects called forms[]
forms: [
{
day: '12',
month: '9',
year: '2035',
colors: 'lightblue',//default colour in case none is chosen
selected: true
},
{
day: '28',
month: '01',
year: '2017',
colors: 'lightgreen',//default colour in case none is chosen
selected: true
}
],
Any help would be greatly appreciated,
Thanks
You could use a deep watcher, but a more elegant solution would be to create computed property of the data you want to watch, and watch that instead:
new Vue({
el: '#app',
data: () => ({
forms: [{
day: '12',
month: '9',
year: '2035',
colors: 'lightblue',
selected: true
},
{
day: '28',
month: '01',
year: '2017',
colors: 'lightgreen',
selected: true
}
],
}),
computed: {
selected() {
return this.forms.map(form => form.selected)
}
},
watch: {
selected(newValue) {
console.log("change made to selection")
}
}
})
<html>
<head>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<ul>
<li v-for="(form, i) in forms" :key="i">
<input type="checkbox" v-model="form.selected"> {{form.colors}}
</li>
</ul>
</div>
</body>
</html>
Vue Watchers
Using deep tag is a simpler option but be careful with lists with many objects. It is not very optimized
watch: {
colours: {
// This will let Vue know to look inside the array
deep: true,
// We have to move our method to a handler field
handler()
console.log('The list of colours has changed!');
}
}
}

How to extract data layer info and display this on a site

So I have a data layer with some data and I need to display a couple of these variables inside a html file.
<script type="text/javascript">
var ttConversionOptions = ttConversionOptions || [];
ttConversionOptions.push({
type: 'sales',
campaignID: '25792',
productID: '37843',
transactionID: "ORD010320",
transactionAmount: "458.19",
quantity: '1',
email: '',
descrMerchant: '',
descrAffiliate: '',
currency: "EUR",
});
</script>

I am using unsplash-js api from NPM with react

I am using unsplash-js in my react project and when i am using search query for getting some random photos, I am getting return in form of JSON check below.
{total: 303, total_pages: 31, results: Array(10)}
results
:
Array(10)
0
:
{id: "nitdfruLYys", created_at: "2016-10-12T13:04:23-04:00", updated_at: "2017-08-02T04:08:11-04:00", width: 4000, height: 6000, …}
1
:
{id: "XE87arvN3oo", created_at: "2015-12-12T11:43:35-05:00", updated_at: "2017-08-02T12:08:22-04:00", width: 4272, height: 2848, …}
2
:
{id: "iS0Aq3QPsJ4", created_at: "2016-02-26T19:51:15-05:00", updated_at: "2017-08-02T16:36:55-04:00", width: 3000, height: 1691, …}
3
:
{id: "41eXcLghVhI", created_at: "2017-07-15T20:50:43-04:00", updated_at: "2017-08-02T14:31:32-04:00", width: 4608, height: 3072, …}
4
:
{id: "EjlygRQAOik", created_at: "2017-02-07T19:59:18-05:00", updated_at: "2017-08-02T00:30:17-04:00", width: 5000, height: 3333, …}
5
:
{id: "WicMLrOSVvY", created_at: "2015-10-24T13:40:06-04:00", updated_at: "2017-07-31T07:00:30-04:00", width: 3456, height: 2304, …}
6
:
{id: "Fu8pblIzEL0", created_at: "2015-03-06T16:49:09-05:00", updated_at: "2017-08-01T20:41:35-04:00", width: 4928, height: 3264, …}
7
:
{id: "D9XX3Cjoh2s", created_at: "2016-02-21T15:45:25-05:00", updated_at: "2017-08-02T20:44:56-04:00", width: 6000, height: 4000, …}
8
:
{id: "Aka2x2D4Ph0", created_at: "2016-01-21T03:42:02-05:00", updated_at: "2017-07-28T10:24:12-04:00", width: 5616, height: 3744, …}
9
:
{id: "E-1tnSNP0y4", created_at: "2015-11-08T19:32:31-05:00", updated_at: "2017-07-30T17:19:06-04:00", width: 5472, height: 3648, …}
length
:
10
proto
:
Array(0)
total
:
303
total_pages
:
31
proto
:
Object
I need to set this in a state as an array, but while i am setting this in my code i am getting this error: Objects are not valid as a React child
this.setState({ photos: json });
try refactoring your code making use of the componentDidMount lifecycle method.
class App extends React.Component {
constructor(props) {
super(props);
this.state = { photos: [] };
}
componentDidMount() {
// make API calls here
this.setState({ photos });
}
render() {
return (
<div>
<SearchBar />
<PhotoList photos={this.state.photos} />
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
I need to set this in a state as an array, but while i am setting this in my code i am getting this error: Objects are not valid as a React child
I think this is issue may be unrelated to the setState call. This error occurs when the an object is passed to a react component as a child and would be called under the following cicumstance
render() {
const sample = {
a: 5,
b: 6,
c: 7
}
return (
<div>
{sample}
</div>
)
}
This being said, the error may be happening due to how you are using the photos within the PhotoList component. I would check the usage of photos in the PhotoList and verify that this.props.photos isnt being passed as a child to a component.

Resources