I want to write a program with Vue Js. The program is about having 2 images that continuously alternate every 3 seconds.
Please someone help me.
Here is the code
<script>
const app = Vue.createApp({
data() {
return{
src : "farkas.jpg"
}
},
methods: {
callFunction: function() {
var v = this;
setInterval(function() {
v.src = "mokus.jpg"
}, 3000);
}
},
mounted () {
this.callFunction()
}
})
const vm = app.mount('#app')
</script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image changer</title>
<script src="https://unpkg.com/vue#next"></script>
</head>
<body>
<div id="app">
<img :src="src">
</div>
</body>
</html>
You can define the list of sources in the data:
data() {
return {
src : "farkas.jpg",
srcs: ["farkas.jpg", "mokus.jpg"]
}
}
And in the function, define i initially 0, and every time increment/reset it:
callFunction: function() {
let i = 0;
setInterval(() => {
this.src = this.srcs[i];
if(++i === this.srcs.length) i = 0;
}, 3000);
}
this.interval = setInterval(function() {
if (v.src === "mokus.jpg") v.src = "farkas.jpg"
else v.src = "mokus.jpg" }, 3000);
And destroy the interval with this code in the beforeDestroy hook.
clearInterval(this.interval)
Can You Try:
const app = Vue.createApp({
data() {
return{
currentSrc : 0,
srcs: ["img1.jpg", "img2.jpg"]
}
},
methods: {
callFunction: function() {
setInterval(() => {
this.currentSrc = this.currentSrc === this.srcs.length - 1 ? 0 : this.currentSrc + 1;
}, 1000);
}
},
computed: {
src: function(){
return this.srcs[this.currentSrc]
}
},
mounted () {
this.callFunction()
}
})
const vm = app.mount('#app')
Related
As you can see below the timer is supposed to update the msg after 90s have been elapsed but it does it rather instantly. I am aware of setInterval and watch but I need to know why does the code wont work
All we doing is checking the counter is above 0 if so spawn yet another timeout and in that trigger this current function and so on
var view = new Vue({
el: '#app',
data: {
countDown: 90,
msg: "There's still time.."
},
methods: {
timer: function () {
if (this.countDown > 0) {
setTimeout(() => {
this.countDown--
this.timer()
}, 1000);
}
else if(this.countDown === 0);
{
this.msg = 'You Ran Outta Time!'
}
}
},
created () {
this.timer();
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Vue test</title>
</head>
<body>
<div id="app">
<h2>{{msg}}</h2>
</div>
</body>
</html>
Remove the ; after else if(this.countDown === 0) which is considered as statement, so your code is the same as :
if (this.countDown > 0) {
setTimeout(() => {
this.countDown--
console.log(this.countDown)
this.timer()
}, 1000);
}
else if(this.countDown === 0)
{
}
this.msg = 'You Ran Outta Time!'
var view = new Vue({
el: '#app',
data: {
countDown: 90,
msg: "There's still time.."
},
methods: {
timer: function () {
if (this.countDown > 0) {
setTimeout(() => {
this.countDown--
console.log(this.countDown)
this.timer()
}, 1000);
}
else if(this.countDown === 0)
{
this.msg = 'You Ran Outta Time!'
}
}
},
created () {
this.timer();
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Vue test</title>
</head>
<body>
<div id="app">
<h2>{{msg}}</h2>
</div>
</body>
</html>
I have some question about this problem, and I still not found the way and I wanna ask in here. Okay for the problem is I wanna delete all my empty array and not show into user view and just show the not empty array, like this for the code and result :
const objectFruits = [
{fruits: 'apple'},
{fruits: 'banana'},
{fruits: 'strawberry'},
{fruits: 'manggo'},
];
const objectMyFavorite = [
{fruits: 'apple'},
{fruits: 'apple'},
{fruits: 'banana'},
];
const getAllFruits = { fruits: objectFruits.map(item => item.fruits) }
const getAllMyFavorite = { fruits: objectMyFavorite.map(item => item.fruits) }
let myView = '';
for (let i = 0; i < getAllFruits['fruits'].length; i++) {
const nameFruits = getAllFruits['fruits'][i];
const filterMyFavorite = getAllMyFavorite['fruits'].filter(function (fruitss) {
return fruitss == nameFruits
});
// and how I delete the empty and just show array if value is not null and show it to user
myView += `
<p>${filterMyFavorite.length == 0 ? `delete this array and delete this row and not show in user view` : `is not empty => expected (apple, apple) and (banana)`}</p>
`;
}
document.getElementById("test").innerHTML = myView
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>test</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="test">
</div>
<script src="script.js"></script>
</body>
</html>
If I make a some mistake in my word you can direct again to me, thank you
You're too close for the solution. Check whether the below code fulfills your task:
const objectFruits = [{
fruits: 'apple'
},
{
fruits: 'banana'
},
{
fruits: 'strawberry'
},
{
fruits: 'manggo'
},
];
const objectMyFavorite = [{
fruits: 'apple'
},
{
fruits: 'apple'
},
{
fruits: 'banana'
},
];
const getAllFruits = {
fruits: objectFruits.map(item => item.fruits)
}
const getAllMyFavorite = {
fruits: objectMyFavorite.map(item => item.fruits)
}
let myView = '';
for (let i = 0; i < getAllFruits['fruits'].length; i++) {
const nameFruits = getAllFruits['fruits'][i];
const filterMyFavorite = getAllMyFavorite['fruits'].filter(function(fruitss) {
return fruitss == nameFruits
});
// and how I delete the empty and just show array if value is not null and show it to user
if (filterMyFavorite.length > 0){
myView += `<p>${filterMyFavorite}</p>`
}
}
document.getElementById("test").innerHTML = myView
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>test</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="test">
</div>
<script src="script.js"></script>
</body>
</html>
You can append to myView only if the value is valid:
if (filterMyFavorite.length > 0) {
myView += `
<p>Add item here</p>
`;
}
Use a simple conditional:
...
if (filterMyFavorite.length !== 0) {
myView += "<p>" + filterMyFavorite.join(",") + "</p>";
}
...
As mentioned in a comment you can't delete the array, but you can hide it - try this:
if(filterMyFavorite.length > 0) {
filterMyFavorite.map(f => { myView += `<p>${f}</p>` })
}
I have below custom control created by extending sap.m.Input that lets the user enter only numbers. However, when there is actually an error the state of control changes to Error with red borders but the valueStateText is not displayed when it has focus. How can I get the valueStateText for my custom control? Shouldn't it inherit from sap.m.Input?
Custom Control code:
sap.ui.define([
"sap/m/Input"
], function (Control) {
"use strict";
return Control.extend("sample.control.NumericInput", {
metadata: {
properties: {},
aggregations: {},
events: {}
},
init: function () {
if (sap.ui.core.Control.prototype.onInit) {
sap.ui.core.Control.prototype.onInit.apply(this, arguments);
}
this.attachLiveChange(this.onLiveChange);
},
renderer: function (oRM, oControl) {
sap.m.InputRenderer.render(oRM, oControl);
},
onLiveChange: function (e) {
var _oInput = e.getSource();
var val = _oInput.getValue();
val = val.replace(/[^\d]/g, "");
_oInput.setValue(val);
}
});
});
XML code:
<hd:NumericInput value="{path:'payload>/MyNumber',type:'sap.ui.model.type.String',constraints:{minLength:1,maxLength:10}}" valueStateText="My Number must not be empty. Maximum 10 characters."/>
In your init override you need to call the init of the parent control (not onInit of sap.ui.core.Control). The init of the sap.m.InputBase (sap.m.Input's parent class) sets up the valuestate initial values and rendering so it's missing all that code out and not working correctly as you've found.
Check out this example based on your code:
sap.ui.define([
"sap/m/Input"
], function (Control) {
"use strict";
return Control.extend("sample.control.NumericInput", {
metadata: {
properties: {},
aggregations: {},
events: {}
},
init: function () {
Control.prototype.init.apply(this, arguments);
this.attachLiveChange(this.onLiveChange);
},
renderer: function (oRM, oControl) {
sap.m.InputRenderer.render(oRM, oControl);
},
onLiveChange: function (e) {
var _oInput = e.getSource();
var val = _oInput.getValue();
val = val.replace(/[^\d]/g, "");
_oInput.setValue(val);
}
});
});
// Small model
const model = new sap.ui.model.json.JSONModel({
MyNumber: "10000000000000000000",
});
// Create an example of the control (JS not XML but idea is the same)
const input = new sample.control.NumericInput({
valueState: "Error",
valueStateText:"My Number must not be empty. Maximum 10 characters.",
value: {
path:'/MyNumber',
type:'sap.ui.model.type.String',
constraints:{minLength:1,maxLength:10}
}
});
input.setModel(model);
input.placeAt('content');
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<script
src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-theme="sap_fiori_3"
data-sap-ui-xx-bindingSyntax="complex"
data-sap-ui-libs="sap.m"></script>
</head>
<body class="sapUiBody sapUiSizeCompact">
<div id='content'></div>
</body>
</html>
you can greatly reduce your code to
Input.extend('NumericInput', {
renderer: {
},
onAfterRendering: function () {
if (Input.prototype.onAfterRendering) {
Input.prototype.onAfterRendering.apply(this, arguments);
}
this.$().find("INPUT").each(function(i, input) {
$(input).on("keypress keyup blur", function(event) {
$(this).val($(this).val().replace(/[^\d].+/, ""));
if ((event.which < 48 || event.which > 57)) {
event.preventDefault();
}
});
});
},
});
https://jsbin.com/muberid/1/edit?js,output
$(function() {
var model = {
currentCat: null,
cats: [{
name: "Felix",
clickCounter: 0,
srcImage: "cat0.jpg"
},
{
name: "Lucas",
clickCounter: 0,
srcImage: "cat1.jpg"
},
{
name: "Martin",
clickCounter: 0,
srcImage: "cat2.jpg"
},
{
name: "Pedro",
clickCounter: 0,
srcImage: "cat3.jpg"
}
]
};
var octopus = {
init: function() {
indexView.init();
displayView.init();
},
getCats: function() {
return model.cats;
},
getCurrentCat: function() {
return model.currentCat;
},
setCurrentCat: function(cat) {
model.currentCat = cat;
},
updateClickCounter: function() {
model.currentCat.clickCounter++;
displayView.render();
}
};
var displayView = {
init: function() {
this.imgSection = document.getElementById("imageSection");
this.catImg = document.getElementById("cat-img");
this.catName = document.getElementById("cat-name");
this.catCounter = document.getElementById("cat-counter");
this.catImg.addEventListener("click", function() {
octopus.updateClickCounter();
})
this.render()
},
render: function() {
var cat = octopus.getCurrentCat();
this.catName.textContent = cat.name;
this.catCounter.textContent = cat.clickCounter;
this.catImg.src = cat.srcImage;
}
};
var indexView = {
init: function() {
this.list = $("#list")
this.render();
},
render: function() {
cats = octopus.getCats();
for (i = 0; i < cats.length; i++) {
cat = cats[i];
listElement = document.createElement("li");
listElement.textContent = cat.name;
listElement.addEventListener("click", (function(copyCat) {
octopus.setCurrentCat(copyCat);
displayView.render();
})(cat));
};
}
};
octopus.init();
});
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Cat clicker</title>
<link rel="stylesheet" href="css/cat.css">
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css" type="text/css" />
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="js/cat.js"></script>
<h1 id="header"> Gatitos! </h1>
<div id="catIndex">
<h2 id="indexTitle">Index</h2>
<ul id="list">
<!-- here we have the index with the cats names -->
</ul>
</div>
<div id="imageSection">
<h2 id="cat-name"></h2>
<div id="cat-counter"></div>
<img src="" id="cat-img">
</div>
</body>
</html>
in the displayView object, I can only acces the html elements that I got with getElementById inside the method they were initialized in (I can acces catImg when I add the event listener in the init method). The problem comes when I try to acces those elements in the render method. When you run this it returns undefined when you call all the elements from the init method (this.catImg, this.catName and this.catCounter). Why does it return undefined?
you have to bind 'this' to your event handler, check out Javascript scope addEventListener and this on how to scope this to your event listener.
index.html
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>VueJS</title>
<script src="vue.js"></script>
</head>
<body>
<div id="app">
<button #click="counter++">increase</button>
<button #click="counter--">decrease</button>
<p>Counter: {{counter}}</p>
<p>Result: {{ result() }} | {{ output }}</p>
</div>
</body>
</html>
<script src="app.js"></script>
app.js
new Vue({
el: "#app",
data: {
counter: 0
},
computed: {
output() {
console.log('Computed!')
return this.counter > 5 ? 'Greater than 5' : 'Smaller than 5'
}
},
watch: {
counter(value) {
var vm = this;
setTimeout(() => {
vm.counter = 0;
}, 2000)
}
},
methods: {
result() {
console.log('Method!')
return this.counter > 5 ? 'Greater than 5' : 'Smaller than 5'
}
}
})
hi, here is my code.
once counter value is changed, watch property knows this and after 2 sec, change counter into 0.
this code has no problem!
but i got one thing that don't understand on watch property.
why does counter method in watch property work only when using closure feature?
counter(value) {
var vm = this;
setTimeout(() => {
vm.counter = 0;
}, 2000)
}
this do work!
counter(value) {
setTimeout(() => {
this.counter = 0;
}, 2000)
}
but this doesn't work! (counter doesn't become zero even after 2 sec)
why does it happen?
it's resolved. my mistake. thank you Daniel!
actually i'm new here, i don't know exactly whether it's right to end up with this question like this...