number declared in vue data can't go under 0 - vue.js

I've data which is also width in my project so everytime I click for example a button it will - my data number my code does perfectly but there's one thing, it can't go under 0 any soltuons?
data:{
monsterHealth:100,
},
methods:{
attack(){
var max = 10
var min = 3
var damage = Math.max(Math.floor(Math.random() * max) + 1, min)
this.monsterHealth -= damage;
}
<div class="monster">
<h1>MONSTER</h1><div class="healthbar" :style="{width:monsterHealth + '%'}"></div>
</div>
<button class="attack" #click="attack">Attack</button>

Related

Not being able to complete this simple calculator exercise. I am getting Nan error

I am writing a simple code from scratch and I get Nan error in console.log and undefined as a result.
Any suggestion to improve this code will be appreciated.
Many thanks.
<div>
<h1>Exercises</h1>
<h4>Items calculator</h4>
<p>Enter value</p>
<input type="number" id="numberitems">
<p>Enter price</p>
<input type="number" id="priceitems">
<br>
<br>
<button id="pricebtn">Calcular Precio</button>
<br>
<p>Resultado</p>
<span id="finalPrice"></span>
</div>
<script>
let items = document.getElementById("numberitems");
let price = document.getElementById("priceitems");
let finalPrice = items * price;
const btnprice = document.getElementById("pricebtn");
function myFunction1() {
document.getElementById("finalPrice").innerHTML += finalPrice.value;
}
btnprice.addEventListener("click", myFunction1);
console.log(finalPrice);
</script>
First of all: you are multiplying inputs, not its values.
To get values of input fields, you must get it with .value (not finalPrice.value)
As second: your price counted at the page loading, not on click event. The result is undefined, because items and price initializing at page startup, where they yet undefined.
To work it correct, you must getting the values and perform computations in function.
<script>
function myFunction1() {
let items = 0;
items = document.getElementById("numberitems").value;
let price = 0;
price = document.getElementById("priceitems").value;
let finalPrice = items * price;
document.getElementById("finalPrice").innerHTML += finalPrice;
console.log(finalPrice);
}
const btnprice = document.getElementById("pricebtn");
btnprice.addEventListener("click", myFunction1);
</script>
Try this:
let items = document.getElementById("numberitems").value;// ger value from this id
let price = document.getElementById("priceitems").value; // ger value from this id
let finalPrice = Number(items*price);
const btnprice = document.getElementById("pricebtn");
function myFunction1() {
document.getElementById("finalPrice").innerHTML += finalPrice;
}
btnprice.addEventListener("click", myFunction1);
console.log(finalPrice);

3 minutes countdown timer which do not resets

when user hits refresh or close the browser also i want my timer to repeat itself after 3 minutes. I want to achieve this using mysql database in which i have a table with two columns date and time from where i am updating the countdown timer. but i need timer of only 3 minutes which repeats itself and do not reset when user try to refresh or close the browser. please help me.
<div>
<h1 id="counter"></h1>
</div>
<script>
<?php
$data = strtotime($date);
$getDate = date("F d, Y", $data);
?>
var countDownDate = new Date("<?php echo "$getDate $time"; ?>").getTime();
// Update the count down every 1 second
var x = setInterval(timer, 1000);
function timer()
{
var now = new Date().getTime();
// Find the distance between now an the count down date
var distance = countDownDate - now;
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
document.getElementById("counter").innerHTML = minutes + " : " + seconds;
// If the count down is over, write some text
if (distance < 0)
{
clearInterval(x);
document.getElementById("counter").innerHTML="EXPIRED" ;
location.reload();
}
}
</script>

How to show owl carousel slides in multiple horizontal rows based on setting?

I want to show owl-carousel image-slides in two or three horizontal row, based on setting. How it is possible?
Also i need that, in mobile view(small screen), the image-slide should be single and should be in single row.
Something like this (guess below numbers are images):
Slides(single row): 1 2 3 4 5 6 7 8 9
I need:(if Two row)
1 3 5 7 9
2 4 6 8
I need:(if Three row)
1 4 7
2 5 8
3 6 9
I have found this answer on my own, this will helps someone who need this if it is in their project-requirement.
Note: in new owl-carousel js (version 2.3.4), just make minor property change on init-code of below jquery code.
i am putting the code here:
below is the .Net MVC HTML CODE:
Here you can see in div tag class name "clsBannerAds", we will write jquery for append the multiple row in owl-carouesel. Also see in div tag there are some data- attributes which helps to make owl-carousel slides to show dynamically, as like how many rows, or how many slides in one column (based on setting in db).
HTML::>>
<div class="clsBannerAds" data-columncount="#(Model.AdvertGroup.BlockColumnSize ?? 1)" data-autoplayinterval="#(Model.AdvertGroup.CarouselRefreshRate)" data-rowcount="#(Model.AdvertGroup.BlockRowSize ?? 1)" data-displaymode="#Model.AdvertGroup.DisplayMode.ToString()">
#foreach (var item in Model.ListAdvertIndividual)
{
int itemBannerHeight = Model.ListAdvertIndividual.Count() > 1 && string.IsNullOrWhiteSpace(item.LabelTitle) ? Model.AdvertGroup.GroupImgWithLableHeight : Model.AdvertGroup.GroupBannerHeight;
if (item.AdvertIndividualId > 0 && !string.IsNullOrWhiteSpace(item.SeoFilename)) //--#0012794
{
<div class="item" style="margin-left:7px;margin-right:7px;margin-top:5px;margin-bottom:15px;">
<div class="inner-item" style="height:#(Model.AdvertGroup.GroupImgWithLableHeight)px;width:#(Model.AdvertGroup.GroupBannerWidth);max-width:100%;margin-top:20px;">
<img class="d-block w-100" src="#(item.SeoFilename)" alt="First slide" style="width:#(Model.AdvertGroup.GroupBannerWidth);height:#(itemBannerHeight)px;max-width:100%;">
</div>
</div>
}
}
JQUERY::>> (we need below function to call on document.ready)
function bannerAdWidgetSetCarousal() {
$('.clsBannerAds').each(function (index, element) {
var columnCount = $(this).attr('data-columncount') || 1;
var columnCntDesktopSmall = columnCount > 2 ? columnCount - 1 : columnCount;
var columnCntTablet = columnCntDesktopSmall > 2 ? columnCntDesktopSmall - 1 : 1;
var playInterval = $(this).attr('data-autoplayinterval') || false;
var rowCount = $(this).attr('data-rowcount');
var displayMode = $(this).attr('data-displaymode');
var isDynamicDisplayMode = displayMode && displayMode == "Dynamic" ? true : false;
var makeAnimate = isDynamicDisplayMode;
var showNavigationArrow = !isDynamicDisplayMode ? true : false;
var arrNavText = !isDynamicDisplayMode ? ["<i class='fa fa-angle-left'></i>", "<i class='fa fa-angle-right'></i>"] : ["", ""];
var slideItems = $(element).find('.item');
//THIS is code for make carosal slide in horizontal row, based on row count [ex. slides in 1 row, 2 row, 3 row]
if (rowCount && rowCount > 1 && slideItems.length > 1) {
var loopCount = Math.ceil(slideItems.length / rowCount);
for (var i = 0; i < loopCount; i++) {
var $el = $(element).find('.item:nth-of-type(' + (i + 1) + ')');
if ($el.next().length == 0) break;
$el.next().find('.inner-item').appendTo($el);
$el.next().remove();
}
}
//Init owlCarousel
$(element).owlCarousel({
items: columnCount,
lazyLoad: true,
loop: true,
autoPlay: playInterval,
pagination: false,
itemsDesktop: [1199, columnCount],
itemsDesktopSmall: [979, columnCntDesktopSmall],
itemsTablet: [768, columnCntTablet],
itemsMobile: [479, 1],
navigation: showNavigationArrow,
navigationText: arrNavText,
singleItem: makeAnimate,
transitionStyle: "goDown"
});
});
}

new objects created in Vuejs getting updated to last value

I am new to Vuejs but am having an issue with some code.
I am trying to 'flatten' a series of line_items of orders into a list of items and then create meta information for each object. The first part works fine but it appears as if the reactive nature of Vuejs is causing the last value of these newly created objects to extend across all previous incarnations.
I have created a fiddle here. http://jsfiddle.net/trestles/ruj7hzcf/3/
I presume that the problem is in creating my item (~ line 70 in fiddle).
// here's the problem - why is quantity being updated to the last value?
var item = {item_id: line_item.menu_item_id, header: line_item.menu_item_header, quantity: line_item.quantity, locations: locations }
this.items.push(item);
Why in this case would item be updated to the last value?
In the table, the results are:
test item 3 5 8
spiced shrimp with horseradish cocktail sauce (per dozen) 9 5 8
dates with bacon & parmesan (per dozen) 5 5 8
marcona almonds (serves 8) 6 5 8
marinated olives (serves 8) 8 5 8
and should be
test item 3 3 0
spiced shrimp with horseradish cocktail sauce (per dozen) 9 2 7
dates with bacon & parmesan (per dozen) 5 5 0
marcona almonds (serves 8) 6 0 6
marinated olives (serves 8) 8 0 8
What am I doing wrong?
The root of most problems in your existing code is reusing the same objects - elements of this.locations and this.orderPickupTimes arrays - again and again as you pass those through createNewItem. Augment those lines in your code:
// instead of var location = this.locations[j];
var location = Object.assign({}, this.locations[j]);
// and within the internal loop
// instead of var order_pickup_time = this.orderPickupTimes[k];
var order_pickup_time = Object.assign({}, this.orderPickupTimes[k]);
... and see the difference it makes.
Still, it's only part of the problem. The key idea of your code is storing -alongside each 'item' object - the whole list of locations and pickup times, having the ones with some orders set their 'quantity' attribute changed.
But to do this, you need to differentiate between the items already processed (with their structures already filled) - and fresh items. It's cumbersome, yes, but might work with something like this:
var locations = [];
var item = this.items.find(it => it.item_id === line_item.menu_item_id);
if (item) {
locations = item.locations;
}
else {
item = {item_id: line_item.menu_item_id, header: line_item.menu_item_header, quantity: 0, locations: locations };
this.items.push(item);
}
... and have this repeated all the time you need to choose between creating a new location or orderPickupTime - or reusing the existing ones.
Here's the demo illustrating this approach.
Still, I'd change two major parts here.
First, I'd create a dedicated - private - function to group the order items by their locations and order pickup times. Something like this:
function _groupItemsByOrders(orders) {
return orders.reduce(function(groupedItems, order) {
var locationId = order.location_id;
var orderPickupTimeKey = order.order_pickup_time_short;
order.line_items.forEach(function(lineItem) {
if (!groupedItems.hasOwnProperty(lineItem.menu_item_id)) {
groupedItems[lineItem.menu_item_id] = {
header: lineItem.menu_item_header,
quantity: 0,
locations: {}
};
}
var groupedItem = groupedItems[lineItem.menu_item_id];
if (!groupedItem.locations.hasOwnProperty(locationId)) {
groupedItem.locations[locationId] = {};
}
var groupedItemLocation = groupedItem.locations[locationId];
if (!groupedItemLocation.hasOwnProperty(orderPickupTimeKey)) {
groupedItemLocation[orderPickupTimeKey] = 0;
}
groupedItemLocation[orderPickupTimeKey] += lineItem.quantity;
groupedItem.quantity += lineItem.quantity;
});
return groupedItems;
}, {});
}
Second, I'd rearranged that template so that it takes the order of locations and orderPickupTimes from header arrays, then maps it to groupedData. Something like this:
<tr v-for="(item, item_id) in groupedItems">
<td>{{item_id}}</td>
<td>{{item.header}}</td>
<td>{{item.quantity}}</td>
<template v-for="location in locations">
<td v-for="opt in orderPickupTimes">
{{item.locations[location.id][opt.short]}}
</td>
</template>
</tr>
Now, your 'mounted' hook would look like this:
mounted(){
axios.get('http://www.mocky.io/v2/59f8ceb52d00004d1dad41ec')
.then(response => {
this.locations = response.data.locations;
this.orderPickupTimes = response.data.order_pickup_times;
this.groupedItems = _groupItemsByOrders(response.data.orders);
});
}
Here's the demo.

What to change or add to slider so I have step motion in 5

Can someone help me with slider. What to change or add so I have step in 5 and to allow only integer numbers ? Currently, when I slide up or down step i about 3.6 . How to set value in slider from some function ?
<script type="text/javascript">
dojo.require("dijit.form.Slider");
dojo.require("dijit.form.TextBox"); // this we only include to make the textinput look prettier
dojo.addOnLoad(function() {
var vertical = dojo.byId("vertical");
var rulesNode = document.createElement('div');
vertical.appendChild(rulesNode);
var sliderRules = new dijit.form.VerticalRule({
count: 24,
style: "width:5px;"
},
rulesNode);
var slider = new dijit.form.VerticalSlider({
name: "vertical",
value: 0,
minimum: 1440,
maximum: 0,
pageIncrement:100,
showButtons:true,
slideDuration:288,
intermediateChanges:false,
style: "height:450px;",
onChange: function(value) {
dojo.byId("sliderValue").value = value;
}
},
vertical);
});
</script>
You need to define how many discrete values you want to allow in the slider. This is done with the discreteValues parameter. In your case you have a range of 0 - 1440. If you want every number that is a multiple of 5 to be a valid value, this is 1440 / 5 = 288 discrete values.
But wait! That's not including the 0! You actually want the 288 steps + the first step which is 0. That makes 289 discrete values, and so your widget should be instantiated like this:
var slider = new dijit.form.VerticalSlider({
/* .. your other properties.. */
discreteValues: 289
}, vertical);