Slice 6 random items from array - slice

I have an array with 400 items, each item is a JSON object.
I need to return 6 random items from the arr(6 JSON objects) using the slice method.
my code :
data.slice("here I need to return 6 random items ").map((item, index) => {
return (
<>
<div class="caption">
<img
src={item.avatar + `/${index}`}
key={index}
alt="avatar"
style={{ width: "100%" }}
/>
<center>
{item.firstname + " " + item.lastname}
<h5 class="job"> {item.job}</h5>
</center>{" "}
</div>
</>
how can I do this? I used Math. random but it's don't work.

You could shuffle the array with something like that :
function shuffle(array) {
array.sort(() => Math.random() - 0.5);
}
and then a .slice(0,6) will give you 6 randomized items

Related

Change pricing based on whether checkbox is checked or not in Laravel

I am trying to calculate some shipping prices in Laravel. There are only two options based on weight and I have that working with an if/else statement. The client would like to add an option that if someone would like to ship their items faster and they are under the Priority weight, they can for the additional shipping cost. I set up a checkbox in my blade template but am not 100% sure how to implement it. I would assume I have to do some kind if isset statement.
Here is the code in my blade template:
#if( $total_weight <= 16.00)
<li class="payment__item">
<label for="priority">Priority Mail</label>
<span style="padding-top: 2.5%;">
<input type="checkbox" name="priority" value="1" {{ $shipping_cost['attributes']['priority'] == '10' ? 'checked="checked"' : '1'}} >
</span>
</li>
<li class="payment__item">Total:
<span>${{ number_format($payment_total + $shipping_cost, 2, '.', '')}} </span>
</li>
#else
<li class="payment__item">Total: <span>${{ number_format($payment_total + 10, 2, '.', '')}} </span>
</li>
#endif
And in my controller I have this for my public function:
public function showPayment() {
$cart = Session::get('cart');
$payment_info = Session::get('payment_info');
if($payment_info['status'] == 'on_hold' ) {
$total_weight = $cart->totalWeight;
// $shipping_cost = $cart->totalPrice + 5;
$sales_tax = $cart->totalPrice * .085 ;
$payment_total = $cart->totalPrice + $sales_tax;
return view('cart.payments', ['payment_info' => $payment_info, 'cartItems' => $cart, 'sales_tax' => $sales_tax, 'shipping_cost' => $shipping_cost, 'total_weight'=>$total_weight, 'payment_total' => $payment_total]);
}else{
return redirect()->route("home");
}
}
Any help is much appreciated.
Edit here is the data that is being passed
Use javascript to check if the checkbox is checked. If it is, then add the priority shipping cost to the total
var input = document.querySelector('input[type=checkbox]');
function check() {
var a = input.checked ? "{{$payment_info['price'] + number_format($sales_tax, 2, '.', '') + 10 }}" : "{{$payment_info['price'] + number_format($sales_tax, 2, '.', '') + 5 }} ";
document.getElementById('total').innerHTML = '$ ' + a;
}
input.onchange = check;
check();

How to update only selected component with react hooks

I'm coding a to-do list using React hooks.
Every added item has two dropdown list where the user can decide how urgent the task (urgency value) is and how long the thing to do will take (speed value).
Updating either list will add their value into a 'score' property.
By clicking a "Sort" button I can sort the entries based on the score.
Right now the problem is that if I have more then one to-do item with different urgency and speed value, the score will always be the same for both components.
Can somebody help? Thanks
function ToDo(){
const [ input, setInput ] = React.useState('')
const [ toDo, setToDo ] = React.useState([])
const [ score, setScore ] = React.useState(0)
const [ speed, setSpeed ] = React.useState(0)
const [ urgency, setUrgency ] = React.useState(0)
return(
<div>
<h2>List of things to do</h2>
<input
value={ input }
onChange={ (e) => setInput( e.target.value ) }/>
<button
onClick={ () => {
setToDo( toDo.concat(input))
setInput('')
}}>Add
</button>
<ul>
{ toDo.map(( task, idTask ) => {
return (
<li
key={idTask}
score={ speed + urgency }>
{task}<br/>
<select onChange={(e) => { setSpeed(Number(e.target.value)) }}>
<option value={1}>slow</option>
<option value={2}>medium</option>
<option value={3}>fast</option>
</select><br/>
<select onChange={(e) => { setUrgency(Number(e.target.value)) }}>
<option value={1}>non-urgent</option>
<option value={3}>urgent</option>
</select>
<span
onClick={
(index) => {
const newTodos = [...toDo]
newTodos.splice(index, 1);
setToDo( newTodos)
}}>
[-------]
</span>
</li>
)
})
}
</ul>
<button onClick={
() => {
const sortMe = [...toDo].sort((a, b) => b - a)
setToDo( sortMe )
}}>Sort!</button>
</div>
)
}
ReactDOM.render(<ToDo/>, document.getElementById('app'));
You should implement a different data model to achieve that. You should hold an array of objects for your todos (each todo will be an object) and each object should have an urgency property so you can set that individually.
Something like this:
function App() {
const [todos,setTodos] = React.useState([
{ id: 'todo1', text: 'This is todo1', urgency: 0 },
{ id: 'todo2', text: 'This is todo2', urgency: 1 }
]);
function handleClick(id) {
setTodos((prevState) => {
let aux = Array.from(prevState);
aux = aux.map((todo) => {
if (todo.id === id) {
todo.urgency === 0 ? todo.urgency = 1 : todo.urgency = 0;
}
return todo;
});
return aux;
});
}
const todoItems = todos.map((todo) =>
<li
key={todo.id}
className={todo.urgency === 1 ? 'urgent' : 'normal'}
onClick={()=>handleClick(todo.id)}
>
{todo.text}
{!!todo.urgency && '<--- This is urgent'}
</li>
);
return(
<React.Fragment>
<div>
Click on the todos!
</div>
<ul>
{todoItems}
</ul>
</React.Fragment>
);
}
ReactDOM.render(<App/>, document.getElementById('root'));
li {
cursor: pointer;
}
.urgent {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>

Different datas for each element inside vue-for cycle

I'm new to Vue and since my start some week ago I find myself really happy about it and the way it can be combined with pure javascript.
I'm running this code inside a laravel blade template:
<template v-for = "background in backgrounds" >
<template v-if="currentBackground.path === background.path">
<div class="m-1 background inline-block rounded-circle" style="width: 100px; height: 100px; overflow: hidden">
<img class="img-fluid " :src="background.path" v-on:click="changeBack(background)" :style="circledPositionStyle" v-on:load="inquadraThumb(background)">
</div>
</template>
</template>
And in the script section:
data() { return {
[...]
frontObjects : '',
circledPositionStyle : '' }},
methods: {
[...],
inquadraThumb(back) {
var thumbHeight = 100;
var calculatedThumbPositionY = (back.Ypos * thumbHeight) / 500;
var calculatedThumbPositionX = (back.Xpos * calculatedThumbPositionY) / back.Ypos;
this.circledPositionStyle = "transform: scale(4); height: " + thumbHeight + "px;transform-origin:" + calculatedThumbPositionX + "px " + calculatedThumbPositionY + "px;";
},
Now, the code works just fine, but all the images generated in the loop have the same circledPositionStylestyle applied... How can I manage to have different values for each cycle?
You are referencing circlePositionStyle as the data property, so if that value changes, it will change for every item that refers to it.
Instead, change your function to return the value of curclePositionStyle instead of mutating the data property.
inquadraThumb(back) {
var thumbHeight = 100;
var calculatedThumbPositionY = (back.Ypos * thumbHeight) / 500;
var calculatedThumbPositionX = (back.Xpos * calculatedThumbPositionY) / back.Ypos;
return "transform: scale(4); height: " + thumbHeight + "px;transform-origin:" + calculatedThumbPositionX + "px " + calculatedThumbPositionY + "px;";
}
You will also need to slightly adjust the tag:
<img class="img-fluid " :src="background.path" v-on:click="changeBack(background)" :style="inquadraThumb(background)">

VueJS and Laravel Blade - incrementing counter in nested v-for loops

I am using v-for to create a list of people from an object, each with a number assigned. Here is a simplified example:
home.js:
data: function () {
return {
agegroups: {
adult: 3,
child: 1,
infant: 2
}
}
},
home.blade.php:
<ul>
<template v-for="(num, agegroup) in agegroups">
<li v-for="index in num">
#{{ index }}
</li>
</template>
</ul>
This produces 1 2 3 1 1 2
However, I want it to produce 1 2 3 4 5 6
How can this be done? It seems like it can easily be achieved with a simple counter, but where do I put it?
Here you go: https://jsfiddle.net/mimani/7o4k0gf2/
JS
new Vue({
el: '#app',
mounted () {
var sum = 0
for (const key of Object.keys(this.agegroups)) {
sum += this.agegroups[key]
this.offset.push(sum)
}
},
data: {
agegroups: {
adult: 3,
child: 1,
infant: 2
},
offset: [0]
}
});
HTML
<ul>
<template v-for="(num, agegroup, idx) in agegroups" v-init="getOffset(num)">
<li v-for="index in num">
{{offset[idx] + index}}
</li>
</template>
</ul>
I had to create a variable which is pre populated based on agegroups to keep track of earlier indexes, and I add this to index of nested for loop.

jquery isotope - sort, layout AND multiple filters

I'm trying to create a page with sorting, layout buttons and multiple filters. The isotope homepage is a good example, but there's only one filter there. Using that page I can't figure out how to add more filters that will work together (i.e. colour and size, working together, not one at a time). Below is the code... How do I add another filter?
<div class="option-combo">
<h2>Filter:</h2>
<ul id="filter" class="option-set clearfix" data-option-key="filter">
<li>show all</li>
<li>elements</li>
<li>features</li>
<li>examples</li>
</ul>
</div>
<div class="option-combo">
<h2>Sort:</h2>
<ul id="sort" class="option-set clearfix" data-option-key="sortBy">
<li><a href="#sortBy=original-order" data-option-value="original-order" data>original-order</a></li>
<li>name</li>
<li>year</li>
<li>size</li>
<li>random</li>
</ul>
</div>
<div class="option-combo">
<h2>Layout: </h2>
<ul id="layouts" class="option-set clearfix" data-option-key="layoutMode">
<li>masonry</li>
<li>fitRows</li>
<li>straightDown</li>
</ul>
</div>
And this is the javascript:
$(function(){
var $container = $('#container');
$container.isotope({
masonry: {
columnWidth: 70
},
sortBy: 'year',
sortAscending : false,
getSortData: {
name : function ( $elem ) {
return $elem.find('.name').text();
},
size : function ( $elem ) {
return parseInt( $elem.find('.Size').text().replace( /,/g, ''), 10 );
},
year : function ( $elem ) {
return parseInt( $elem.find('.year').text().replace( /,/g, ''), 10 );
}
}
});
var $optionSets = $('#options .option-set'),
$optionLinks = $optionSets.find('a');
$optionLinks.click(function(){
var $this = $(this);
// don't proceed if already selected
if ( $this.hasClass('selected') ) {
return false;
}
var $optionSet = $this.parents('.option-set');
$optionSet.find('.selected').removeClass('selected');
$this.addClass('selected');
// make option object dynamically, i.e. { filter: '.my-filter-class' }
var options = {},
key = $optionSet.attr('data-option-key'),
value = $this.attr('data-option-value');
// parse 'false' as false boolean
value = value === 'false' ? false : value;
options[ key ] = value;
if ( key === 'layoutMode' && typeof changeLayoutMode === 'function' ) {
// changes in layout modes need extra logic
changeLayoutMode( $this, options )
} else {
// otherwise, apply new options
$container.isotope( options );
}
return false;
});
});
Multiple filters as I understand means selection elements that share multiple properties.
So for example if we have the following isotope items
<div class="isotope-item green big"></div>
<div class="isotope-item green small"></div>
<div class="isotope-item red big"></div>
<div class="isotope-item red small"></div>
<div class="isotope-item yellow big"></div>
If you want to as a filter all the elements that are
red AND big
red OR big
then you can use with the same JavaScript that you have :
<h2>Filter:</h2>
<ul id="filter" class="option-set clearfix" data-option-key="filter">
<li><a data-option-value="*" class="selected">Show All</a></li>
<li><a data-option-value=".red">Show Red Elements</a></li>
<li><a data-option-value=".big">Show Big Elements</a></li>
<li><a data-option-value=".red, big">Show Elements Red OR Big</a></li>
<li><a data-option-value=".red.big">Show Elements Red AND Big</a></li>
</ul>
The filter works with a simple jQuery selector. Everything that matches the selection is shown, the rest is hidden.
I tried to explain my approach on this question here.
Basically the idea is to look for a restrictive AND condition using the isotope function properly in your onclick event.

Resources