I am swapping content based on a loaded in array (so the length of the array will be dynamic each time) and I'm trying to figuire out how to handle the first and last item in this method. As in - I need when you click left from the first one it would go to the last and opposite for the last.
So I just have this -
<div class="side{{side.name}} side" ng-repeat="side in sides" ng-show="side.active" >
{{side.name}}
<i class="fa fa-chevron-circle-left" ng-click="flipLeft($index)"></i>
<i class="fa fa-chevron-circle-right" ng-click="flipRight($index)"></i>
</div>
and in the controller it just looks like this
$scope.flipLeft = function (index){
$scope.sides[index].active = false;
$scope.sides[index-1].active = true;
};
$scope.flipRight = function (index){
$scope.sides[index].active = false;
$scope.sides[index+1].active = true;
};
So all it really does is swap the .active to true or false to show or hide the content. I'm not sure how to switch around my logic so it loops around so that if you click left on the first item it goes to the last and visa versa. Thanks in advance!
Check if the index you want to set is greater than or less than the minimum/maximum values. If so, adjust:
$scope.flipLeft = function (index){
var idx = index - 1;
if (idx < 0) {
idx = $scope.sides.length - 1;
}
$scope.sides[index].active = false;
$scope.sides[idx].active = true;
};
$scope.flipRight = function (index){
var idx = index + 1;
if (idx >= $scope.sides.length) {
idx = 0;
}
$scope.sides[index].active = false;
$scope.sides[idx].active = true;
};
The easiest way is to use the mod method so that incrementing or decrementing stays in the range of valid numbers. So looking at your code I would recommend
$scope.flipLeft = function (index){
$scope.sides[index].active = false;
index = (index-1).mod($scope.sides.length)
$scope.sides[index].active = true;
};
And be sure to implement this trick: Javascript modulo not behaving.
$scope.flipLeft = function (index){
var sides = $scope.sides,
first = index,
second = (index === 0) ? sides.length - 1 : first - 1;
sides[first].active = false;
sides[second].active = true;
};
$scope.flipRight = function (index){
var sides = $scope.sides,
first = index,
second = (index === sides.length - 1) ? 0 : first + 1;
sides[first].active = false;
sides[second].active = true;
};
Related
I am creating a really basic program that allows a user to cycle through images, with a set of buttons, and the major problem I'm having with it, is that it appears to just be selecting random points in the array. For example, the array starts at 1, and yet it displays the image that is in the position 0, or let's say I try to cycle backwards through images, if I go from 0 (Which is meant to be position 3), it'll jump back to the image at position 1. I can't make sense of it.
var i = 0;
var imageArr = [];
imageArr[0] = 'img/img_BMW.jpg';
imageArr[1] = 'img/img_Chr.jpg';
imageArr[2] = 'img/img_Mas.jpg';
imageArr[3] = 'img/img_Merc.jpg';
function imageCycle(){
document.imgCycle.src = imageArr[i];
if(i < imageArr.length - 1){
i++
}
else{
i = 0;
}
console.log(i);
}
function imagePrev(){
document.imgCycle.src = imageArr[i];
if(i == imageArr.length - 1){
i = 3;
}
else{
i--;
}
}
<img name="imgCycle" width="440" height="250"/>
<ul>
<li><button type="button" id="back-Btn" onclick="imagePrev();">Back</button></li>
<li><button type="button" id="forward-Btn" onclick="imageCycle();">Forward</button></li>
</ul>
You could add a method to go to the next index you want and have this function ensure that the index doesn't go out of bounds.
As a side note, binding the event handlers like you did through the onclick attribute is not really the preferred way of doing this anymore. Try using addEventListener instead.
var i = 0;
// Use some actuale images so we can see what happens in the DOM.
var imageArr = [
'//placehold.it/300/200/?text=1',
'//placehold.it/300/200/?text=2',
'//placehold.it/300/200/?text=3',
'//placehold.it/300/200/?text=4'
];
/**
* A method to alter the index. Pass 1 to go to the next slide and -1 to go to
* the previous slide. It will make sure the index is never out of bounds.
*/
function getNextIndex(index, modifier) {
// Add the modifier to the index.
index = index + modifier;
// Check if the index is less than zero, this is unvalid and we will reset the index
// to the last item in the image array. When the index is more than 0, check if it exceeds
// the index for the last item in the array. In this case reset it to 0 so we go back to
// the first image.
if (index < 0) {
index = imageArr.length - 1;
} else if (index >= imageArr.length) {
index = 0;
}
return index;
}
function updateImage(index) {
document.imgCycle.src = imageArr[index];
}
function goToNextImage() {
i = getNextIndex(i, 1);
updateImage(i);
}
function goToPreviousImage() {
i = getNextIndex(i, -1);
updateImage(i);
}
updateImage(0);
<img name="imgCycle" width="440" height="250"/>
<ul>
<li><button type="button" id="back-Btn" onclick="goToPreviousImage();">Back</button></li>
<li><button type="button" id="forward-Btn" onclick="goToNextImage();">Forward</button></li>
</ul>
You are setting the src before the value gets incremented.
Try this
var i = 0;
var imageArr = [];
imageArr[0] = 'img/img_BMW.jpg';
imageArr[1] = 'img/img_Chr.jpg';
imageArr[2] = 'img/img_Mas.jpg';
imageArr[3] = 'img/img_Merc.jpg';
function imageCycle(){
if(i < imageArr.length - 1){
i++
}
else{
i = 0;
}
document.imgCycle.src = imageArr[i];
console.log(i);
}
function imagePrev(){
if(i == imageArr.length - 1){
i = 3;
}
else{
i--;
}
document.imgCycle.src = imageArr[i];
console.log(i);
}
<img name="imgCycle" width="440" height="250"/>
<ul>
<li><button type="button" id="back-Btn" onclick="imagePrev();">Back</button></li>
<li><button type="button" id="forward-Btn" onclick="imageCycle();">Forward</button></li>
</ul>
So the person above me (#Syed) already answered the main issue but I want to point out another issue:
your imagePrev() function: It checks if i is equal to the array length minus 1, and if it does - you make i become 3.
In your case, it will make the picture be stuck on the last one, and otherwise go back (until i reaches -1 and causes issues)
Try this instead:
function imagePrev() {
if (i == 0) {
i = imageArr.length - 1;
}
else {
i--;
}
document.imgCycle.src = imageArr[i];
console.log(i);
}
Cheers
I have a function where I am sending in an object, wholesaler. There is an array of objects, wholesalers which contains multiple wholesaler objects.
I need the order number of the wholesaler that just came in to be increased by 1 and then find the wholesaler object that has a current ORDER of the new value and subtract 1.
$scope.wholesalers = [];
$scope.downWholesaler = function (wholesaler) {
if (wholesaler.id > 0) {
var orderNumber = wholesaler.ORDER;
var orderBelowNumber = orderNumber + 1;
angular.forEach($scope.wholesalers, function (myWholesaler) {
if (myWholesaler.ORDER === orderNumber) {
// raise current order +1
var add = orderNumber + 1
myWholesaler.ORDER = add;
}
//setting it
if (myWholesaler.ORDER === orderBelowNumber) {
//lower one with order below number -1
var subtract = orderNumber - 1;
myWholesaler.ORDER = subtract;
}
});
console.log($scope.wholesalers);
}
};
Above I am working on doing this. I go through $scope.wholesalers and increase the current objects ORDER number and then reduce the one next to it (ORDER +1) down one.
But the ORDER is going down and the next object is not changing at all. What am I doing wrong and how do I fix it?
edit: didn't have lastest code
Fix:
$scope.downWholesaler = function (wholesaler) {
if (wholesaler.id > 0) {
var add = parseInt(wholesaler.ORDER) + 1
angular.forEach($scope.wholesalers, function (myWholesaler) {
if (myWholesaler.ORDER == add) {
myWholesaler.ORDER = parseInt(myWholesaler.ORDER) - 1;
}
});
wholesaler.ORDER = add;
console.log($scope.wholesalers);
}
};
So I created an implicit binary tree, and a simple way of navigating through that tree that reacts when, for example, you push the left arrow, right arrow, or up arrow:
var items = [ .... ];
function newItem() {
var me = this;
this.item_location = 1;
this.leftItem = function() {
var left = items[(me.item_location * 2)];
if(left){
me.theItem = //create element, insert item from 'left' var, display item
me.item_location *= 2;
} else {}
}
this.rightItem = function() {
var right = items[(me.item_location * 2) + 1];
if(right){
me.theItem = //create element, insert item from 'right' var, display item
me.item_location = (me.item_location * 2) + 1;
} else {}
this.upItem = function() {
var up = items[Math.floor(me.item_location / 2)];
if(up){
me.theItem = //as above
me.item_location = Math.floor(me.item_location / 2);
} else {
// abandon setting this item, return to a different context/menu
}
}
My issue is that I'm finding 'duplicates' that aren't actually there, so there must be a bug in either this tree navigation code or in the code I'm using to check for duplicates:
function findItem(theItem) {
var itemLocations = [];
for(var i = items.length - 1; i >= 0; i--) {
if(items[i] === theItem) {
itemLocations.push(i);
}
}
for(var i = itemLocations.length - 1; i >= 0; i--) {
console.log(itemLocations[i]);
}
console.log(itemLocations);
return itemLocations;
}
What is wrong with this? It's consistently ending up with certain entries showing up twice, but the findItem function consistently finds only one entry.
There's nothing more to the code that could possibly cause this, so I feel like I've missed something super obvious.
Bit of a weird problem here - so I will try to explain this as clearly as possible.
I have a simple ng-repeat that will show content based on what has a key value of .active set to true. I let the user scroll through the content with some arrow buttons bound to some ng-clicks. This works great, however I want to exclude one item from the array if it has the key value of side = 'help' attached to it. So basically I want the arrow clicks to skip over it in a sense. I have no control unfortunately where in the array the help item is. So here are the click functions
//flip right
$scope.flipRight = function(index, parent){
var idx = index + 1;
if (idx >= $scope.contentHere[parent].sides.length) {
idx = 0;
}
$scope.contentHere[parent].sides[index].active = false;
$scope.contentHere[parent].sides[idx].active = true;
};
//flip left
$scope.flipLeft = function(index, parent){
var idx = index - 1;
if (idx < 0) {
idx = $scope.contentHere[parent].sides.length - 1;
}
$scope.contentHere[parent].sides[index].active = false;
$scope.contentHere[parent].sides[idx].active = true;
};
So basically what I am trying to figuire out is how to have this logic skip over the item if it has .side = 'help'. I thought about using lodash to _filter the array by items that do not have the value, but it will offset the index so that will not work. I am not sure how to approach this (maybe I am thinking about this incorrectly?), and could use some direction.
Thank you for taking the time to read!
$scope.flipRight = function(index, parent){
var idx = index + 1;
if(idx >= $scope.contentHere[parent].sides.length){
idx = 0;
}
if($scope.contentHere[parent].sides[idx] == 'help'){
$scope.flipRight(idx, parent); //Added to skip over to next item
$scope.contentHere[parent].sides[index].active = false; // Added for the first item does not turn .active to false Issue
return; // Added to skip execution of following line of codes incase of recursion
}
$scope.contentHere[parent].sides[index].active = false;
$scope.contentHere[parent].sides[idx].active = true;
};
//flip left
$scope.flipLeft = function(index, parent){
var idx = index - 1;
if (idx < 0) {
idx = $scope.contentHere[parent].sides.length - 1;
}
if($scope.contentHere[parent].sides[idx] == 'help'){
$scope.flipLeft(idx, parent); //Added to skip over to next item
$scope.contentHere[parent].sides[index].active = false; // Added for the first item does not turn .active to false Issue
return; // Added to skip execution of following line of codes incase of recursion
}
$scope.contentHere[parent].sides[index].active = false;
$scope.contentHere[parent].sides[idx].active = true;
};
I have an array of objects gAllMedicalFilesClaimantsArray with 2 properties (UserID & UserInfo)
For example:
gAllMedicalFilesClaimantsArray[0].UserID = "111";
gAllMedicalFilesClaimantsArray[0].UserInfo = "AAA-111";
gAllMedicalFilesClaimantsArray[1].UserID = "222";
gAllMedicalFilesClaimantsArray[1].UserInfo = "BDD-478333";
What is the fastest way to check whether a specific UserID exists in the array using Jquery or Javascript because gAllMedicalFilesClaimantsArray has got 8000 records?
Thanks
var match = '222';
var matches = $.grep(myArray, function(el, index) {
return (el.UserID === match);
});
You can fasten the search process by using Binary Search algorithm if the array is sorted (e.g with respect to UserId).
function binarySearch(array, userid) {
var low = 0, high = array.length - 1,
i, comparison;
while (low <= high) {
i = parseInt((low + high) / 2, 10);
if (array[i].UserId < userid) { low = i + 1; continue; };
if (array[i].UserId > userid) { high = i - 1; continue; };
return array[i];
}
return null;
};
You can find the user of which ID is 12 by using the function:
var result = binarySearch(gAllMedicalFilesClaimantsArray, 12);
Something like this, I believe:
function exists(uid) {
var k = gAllMedicalFilesClaimantsArray.length;
uid = uid.toString(); // ensure the arg is a str (this can be omitted)
while (k--) {
if (gAllMedicalFilesClaimantsArray[k].UserID === uid) {
return true;
}
}
return false;
}
Is the array sorted by the UserID? If so, it can be improved either further by using a binary search; that would change this from O(n) to O(log n). Your example suggests it is. I found a good implementation of a binary search in JavaScript on the web, here. Here is the code if the site ever dies:
function binarySearch(items, value){
var startIndex = 0,
stopIndex = items.length - 1,
middle = Math.floor((stopIndex + startIndex)/2);
while(items[middle] != value && startIndex < stopIndex){
//adjust search area
if (value < items[middle]){
stopIndex = middle - 1;
} else if (value > items[middle]){
startIndex = middle + 1;
}
//recalculate middle
middle = Math.floor((stopIndex + startIndex)/2);
}
//make sure it's the right value
return (items[middle] != value) ? -1 : middle;
}
ExistsInArray(value, array){
for(var item in array){
if(item.UserId == value){
return true;
}
}
return false;
}
You can either prototype Array object, like this:
Array.prototype.exists = function(value, prop){
var i = null;
for (i in this)
if (this[i][prop] && this[i][prop] == value)
return true;
return false;
}
gAllMedicalFilesClaimantsArray.exists('222', 'UserID');