switching background image using array - arraylist

im trying to change the bacground-image attribute using an array and a time interval, this in the code i have so far.
$(document).ready(function(){
var bgArray =[
"IMG/Trusti/phones/01.png",
"IMG/Trusti/phones/02.png",
"IMG/Trusti/phones/03.png",
"IMG/Trusti/phones/04.png",
"IMG/Trusti/phones/05.png",
"IMG/Trusti/phones/06.png"
];
var i = 0;
setInterval(function(){
$("#telefoondiv").animate({'background-image' : 'bgArray[i]'});
i++;
}100);
});
hope someone can help me.

use css function to set styles instead of animate.
$(document).ready(function(){
var bgArray =[
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRHN0Fxrd_RQqqwpnngUjjkah_tap84fzu6ltuH1lAZs3yGT2QH",
"https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcTUgm_VIAjymgGEkYLhQVSQajHCr4qGAC2yqnzu7YbKAefn-iYJ-w",
"http://www.freedigitalphotos.net/images/img/homepage/87357.jpg"
];
var i = 0;
setInterval(function(){
$("#telefoondiv").css({'background-image' : "url(" + bgArray[i] + ")"});
i++;
if(i == bgArray.length){
i = 0;
}
}, 1000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="telefoondiv" style="height: 200px;"></div>

Related

Update v-html without misbehaving focus on typing VUE JS

I need help,
Requirement
when the user types in an input box I want to highlight the link with blue color if any
My Research
when I dig into it, I realize that without using a contenteditable div it's not possible to do, also there is no v-model associated with contenteditable div I am manually updating the state.
so far I have this, courtesy- contenteditable div append a html element and v-model it in Vuejs
<div id="app"><div class="flex">
<div class="message" #input="updateHtml" v-html="html" contenteditable="true"></div>
<br>
<div class="message">{{ html }}</div>
</div>
</div>
<script>
let app = new Vue({
el: '#app',
data: {
html: 'some text',
},
methods: {
updateHtml: function(e) {
this.html = e.target.innerHTML;
},
renderHtml: function(){
this.html += '<img src="https://cdn-images-1.medium.com/max/853/1*FH12a2fX61aHOn39pff9vA.jpeg" alt="" width=200px>';
}
}
});</script>
Issue
every time user types something, the focus is misbehaving which is strange to me, I want v-html to update along with user types #keyup,#keydown also have the same behavior.it works ok on #blur #focusout events, but that's not what I want
Appreciate Help.Thanks
I figured it out myself. Posting the answer so that may help other developers. v-HTML doesn't do all the trick. You’ll need to store the cursor position so it can be restored properly each time the content updates as well as parse the content so that it renders as expected. Here is the example
HTML
<p>
An example of live syntax highlighting in a content-editable element. The hard part is storing and restoring selection after changing the DOM to account for highlighting.
<p>
<div contentEditable='true' id='editor'>
Edit text here. Try some words like bold and red
</div>
<p>
Just a demo trivial syntax highlighter, should work with any syntax highlighting you want to implement.
</p>
JS
const editor = document.getElementById('editor');
const selectionOutput = document.getElementById('selection');
function getTextSegments(element) {
const textSegments = [];
Array.from(element.childNodes).forEach((node) => {
switch(node.nodeType) {
case Node.TEXT_NODE:
textSegments.push({text: node.nodeValue, node});
break;
case Node.ELEMENT_NODE:
textSegments.splice(textSegments.length, 0, ...(getTextSegments(node)));
break;
default:
throw new Error(`Unexpected node type: ${node.nodeType}`);
}
});
return textSegments;
}
editor.addEventListener('input', updateEditor);
function updateEditor() {
const sel = window.getSelection();
const textSegments = getTextSegments(editor);
const textContent = textSegments.map(({text}) => text).join('');
let anchorIndex = null;
let focusIndex = null;
let currentIndex = 0;
textSegments.forEach(({text, node}) => {
if (node === sel.anchorNode) {
anchorIndex = currentIndex + sel.anchorOffset;
}
if (node === sel.focusNode) {
focusIndex = currentIndex + sel.focusOffset;
}
currentIndex += text.length;
});
editor.innerHTML = renderText(textContent);
restoreSelection(anchorIndex, focusIndex);
}
function restoreSelection(absoluteAnchorIndex, absoluteFocusIndex) {
const sel = window.getSelection();
const textSegments = getTextSegments(editor);
let anchorNode = editor;
let anchorIndex = 0;
let focusNode = editor;
let focusIndex = 0;
let currentIndex = 0;
textSegments.forEach(({text, node}) => {
const startIndexOfNode = currentIndex;
const endIndexOfNode = startIndexOfNode + text.length;
if (startIndexOfNode <= absoluteAnchorIndex && absoluteAnchorIndex <= endIndexOfNode) {
anchorNode = node;
anchorIndex = absoluteAnchorIndex - startIndexOfNode;
}
if (startIndexOfNode <= absoluteFocusIndex && absoluteFocusIndex <= endIndexOfNode) {
focusNode = node;
focusIndex = absoluteFocusIndex - startIndexOfNode;
}
currentIndex += text.length;
});
sel.setBaseAndExtent(anchorNode,anchorIndex,focusNode,focusIndex);
}
function renderText(text) {
const words = text.split(/(\s+)/);
const output = words.map((word) => {
if (word === 'bold') {
return `<strong>${word}</strong>`;
}
else if (word === 'red') {
return `<span style='color:red'>${word}</span>`;
}
else {
return word;
}
})
return output.join('');
}
updateEditor();
Hope this helps...

ngIf on div containing dynamically generated compoent

I have a dynamically generated component which generates on run time. following is the .ts file
`#ViewChild(TermsheetDirective) termHost: TermsheetDirective;
#Input() term;
#Input() title = '';
#Input() Qnumber = '';
#Output() result = new EventEmitter<any>();
section_title = '';
number = '';
component = [];
show = false;
constructor(private componentFactoryResolver: ComponentFactoryResolver) {
}
ngOnInit() {
this.number = this.Qnumber;
this.section_title = this.title;
}
ngAfterViewInit() {
}
ngAfterContentInit() {
}
loadcomponents() {
console.log(this.termHost);
for (let j = 0; j < this.term.components.length; j++) {
let termItem = this.term.components[j];
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(termItem.component);
let viewContainerRef = this.termHost.viewContainerRef;
let componentRef = viewContainerRef.createComponent(componentFactory);
(<TermComponent>componentRef.instance).data = termItem.data;
this.component[j] = componentRef;
}
}
getdata() {
let output = [];
for (let i = 0; i < this.component.length; i++) {
let temp = {
slug : this.section_title,
type : this.component[i].type,
value : this.component[i]._component.getdata()
};
output[i] = temp;
}
this.result.emit(output);
return output;
}
showcomp() {
console.log("In if");
this.show = true;
this.loadcomponents();
}
hidecomp() {
this.show = false;
}`
and following is my html
`<div class="main">
<div class="div_for_ques">
<div class="question">
<div class="number">
{{number}}
</div>
<div class="textbox">
{{section_title}}
</div>
<div class="arrow" *ngIf="!show">
<a (click)="showcomp()" class="glyphicon"></a>
</div>
<div class="arrow" *ngIf="show">
<a (click)="hidecomp()" class="glyphicon"></a>
</div>
</div>
<div class="sec_two" *ngIf="show">
<ng-template term-host></ng-template>
</div>
</div>
</div>`
I want the div that contains the dynamically generated component to appear only when a certain button is clicked. but i am having following response.
But when I try to show this div without ngIf it is working fine. But with ngIf termHost is undefined! Can someone please explain what is happening here!
Well, you are trying to reference to viewContainerRef before change detection cycle has completed, that is why you get that error.
There is more than one solution to this, you can use a setter for the ViewChild, that will be called once after the *ngIf becomes true
e.g
#ViewChild('') set content(x:x) {
this.x = x;
}
OR you can inject the change detector manually
constructor(private changeDetector : ChangeDetectorRef) {}
You can then call it after you click your button
this.changeDetector.detectChanges();
OR You can also use a QueryList to achieve the same effect because you can subscribe to changes
Please apply these techniques to your logic to solve your problem

Change avatar with vue.js without refresh?

I have this in view:
<div class="seller_image" :style="{background: 'url(' + user_credentials.avatar +')', backgroundSize: 'cover ', display: 'block'}">
</div>
In vue i have this:
setAvatar:function(x,y,w,h){
this.setAvatarLoader = true;
var data = new FormData();
this.x1 = $('#x1').val();
this.y1 = $('#y1').val();
this.w = $('#w').val();
this.h = $('#h').val();
this.x2 = $('#x2').val();
this.y2 = $('#y2').val();
data.append('avatar',this.$els.fileAvatarImage.files[0]);
data.append('x1',this.x1);
data.append('x2',this.x2);
data.append('y1',this.y1);
data.append('y2',this.y2);
data.append('w',this.w);
data.append('h',this.h);
user_id = this.user_credentials.user_id;
this.$http.post('/profile/' + user_id + '/basic_info/set_avatar',data).then(function(response){
this.avatarImageSet = false;
public_path = response.data.public_path;
url_path = response.data.url_path;
filename = response.data.filename;
this.setAvatarLoader = false;
this.basic_status = true;
this.basic_success_message = response.data.successMsg;
this.profile_image = url_path;
this.user_credentials.avatar = url_path
this.getAvatar();
$("html, body").animate({ scrollTop: 0 }, "slow");
}, function(response) {
this.setAvatarLoader = false;
$('#myModal').modal('hide');
this.getAvatar();
console.log('error');
});
},
When I refresh the page I get the avatar but in time when I set it it does not change the image.
Any suggestion?
As #AWolf said, it's difficult to guess what's the problem with your code because I can see only a part of your code base.
Another possible issue could be the url_path. If it remains the same, will never change. So, you need to append the timestamp:
this.user_credentials.avatar = url_path + '?' + Date.now()
https://jsfiddle.net/pespantelis/fy0re26m/
As mentioned in the comments, try to avoid jQuery because it's most of the time not needed and it is making things more complicated.
Please have a look at the demo below for a simple image uploader/avatar changer or at this fiddle.
The demo just opens a file picker dialog and then the returned file is used to update the displayed image. (Posting to server is not added in the demo.)
To your code:
Something like $('#x1').val() shouldn't be done with Vue.js because in Vue you're doing that model driven.
So the only source of truth is your data model and not the stuff displayed in the DOM.
Not sure what you're trying to do with the x1,y1, ... code. That's not clear from your snippet with-out the html markup.
new Vue({
el: '#app',
data() {
return {
user_credentials: {
avatar: 'https://unsplash.it/100/100'
}
}
},
methods: {
changeAvatar() {
const input = document.createElement('input');
let self = this;
input.setAttribute("type", "file");
input.addEventListener('change', function(e) {
// uploading code from this fiddle: http://jsfiddle.net/vacidesign/ja0tyj0f/
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
// image is loaded callback
self.user_credentials.avatar = e.target.result;
// here you can post the data to your backend...
};
reader.readAsDataURL(this.files[0]);
}
})
input.click(); // opening dialog
return false; // avoiding navigation
}
}
})
.seller_image {
width: 200px;
height: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
<div id="app">
<div class="seller_image" :style="{background: 'url(' + user_credentials.avatar +')', backgroundSize: 'cover ', display: 'block'}">
</div>
<button #click="changeAvatar()">
Change
</button>
</div>

Dojo - don't repeat yourself

Is there a simpler way to write something like this in dojo (instead of having a function for each thing i want to show or hide)? I know there must be a way to avoid such repetition but I'm not sure how to do it.
on(dom.byId("thing_toggle2"), "click", function(){
if(thing_list2.style.display == "none") {
thing_list2.style.display = "block";
dom.byId("toggle2_sign").innerHTML = "(-)";
} else {
thing_list2.style.display = "none";
dom.byId("toggle2_sign").innerHTML = "(+)";
};
});
on(dom.byId("thing_toggle3"), "click", function(){
if(thing_list3.style.display == "none") {
thing_list3.style.display = "block";
dom.byId("toggle3_sign").innerHTML = "(-)";
} else {
thing_list3.style.display = "none";
dom.byId("toggle3_sign").innerHTML = "(+)";
};
});
I didn't test this, but it should give you a starting point. Adding an additional section, would just involve adding to the array of data.
var fnToggle = function(nodeMap) {
var expand = domStyle.get(dom.byId(nodeMap.contentNode), 'display') == 'none';
domStyle.set(dom.byId(nodeMap.contentNode), 'display', expand ? 'block' : '');
html.set(dom.byId(nodeMap.expandoNode), expand ? '+' : '-');
};
var nodes = [
{ eventNode: 'thing_toggle2', contentNode: thing_list2, expandoNode: 'toggle2_sign' },
{ eventNode: 'thing_toggle3', contentNode: thing_list3, expandoNode: 'toggle3_sign' }
];
array.forEach(nodes, function(nodeMap) {
on(dom.byId(nodeMap.eventNode), "click", function(){ fnToggle(nodeMap); });
});
// domStyle -> dojo/dom-style
// html -> dojo/html
// array -> dojo/_base/array
You could use dojo/fx/Toggler which uses dojo/_base/fx.fadeOut and dojo/_base/fx.fadeIn
I actually decided to do this as a plain old javascript function which I can reuse elsewhere, including pages that might not need dojo. Something like this:
[1]
[2]
<div id="myName" style="display:none;">Antonio</div>
<div id="anothername" style="display:none;">Elliot</div>
<script type="text/javascript">
function showlayer(layer){
var myLayer = document.getElementById(layer).style.display;
if(myLayer=="none"){
document.getElementById(layer).style.display="block";
} else {
document.getElementById(layer).style.display="none";
};
}
</script>

jQuery - Animation content inside a div when it becomes the current container on a horizontal slider

The Setup I have a full screen horizontal slider with 5+ divs that moves to the left when you click on an anchor link. I have some basic knowledge of jquery, and did attempted to use (scrollLeft). But the div is the wrapper div is hiding over flow and doesn't really go anywhere.
The goal is to animate the content inside the container div when it becomes the current container, and undo animation when it does to a different div.
The Issue: I got the animation to play, but have no control over when it starts.
The HTML
<div class="contentItem" id="content2">
<div id="top-box"></div>
<div id="bottom-box"></div>
</div>
<div class="contentItem" id="content3"></div>
<div class="contentItem" id="content4"></div>
<div class="contentItem" id="content5"></div>
The javascript
var theWidth;
var theHeight;
var currentContent = 0;
$(window).resize(function () {
sizeContent();
});
$(window).ready(function () {
sizeContent();
});
function sizeContent() {
theWidth = $(window).width();
theHeight = $(window).height();
sizeContentItems();
setLeftOnContentItems();
sizeContentWrapper(theWidth, theHeight);
moveContent(currentContent, theWidth);
changeSelected(currentContent);
}
function sizeContentItems() {
$(".contentItem").css('width', theWidth);
$(".contentItem").css('height', theHeight);
}
function setLeftOnContentItems() {
var contentCount = 0;
$(".contentItem").each(function (i) {
contentCount += i;
$(this).css('left', i * 990); //slider contern hight
});
}
function sizeContentWrapper(width, height) {
$("#contentWrapper").css('width', width);
$("#contentWrapper").css('height', height);
}
function moveContent(i, width) {
$("#contentWrapper").scrollLeft(i * width);
}
function changeSelected(i) {
$(".selected").removeClass("selected");
$("li:eq(" + i + ") a").addClass("selected");
}
function scrollContentNext() {
scrollContent(currentContent + 1);
}
function scrollContent(i) {
i = checkMax(i);
scrollLogo(i);
scrollTriangle(i);
changeSelected(i)
currentContent = i;
$("#contentWrapper").animate({ scrollLeft: i * 990 }, 400); // how far to go
}
function scrollLogo(i) {
var left = (i * +200);
$("#logo").animate({ left: left }, 1000);
}
function scrollTriangle(i) {
var left = (i * -300);
$("#triangle").animate({ left: left }, 700);
}
// **my edit**
function scrollbox(i) {
var i = currentContent;
if ( currentContent = 2) {
$("#bottom-box").stop().animate({'margin-top': '200px'}, 1500);
}
}
function checkMax(i) {
var maxItems = $("li").length;
if (i >= maxItems) {
return 0;
}
return i;
}