How to splice variable value in AngularJS
HTML:
<div ng-repeat="steps in data" class="card" style="padding:10px 5px 10px 5px; margin-bottom:10px; margin-top:20px; background: url(#routes.Assets.at("images/Assets/icon_move.png")) no-repeat right #FAFBFC; background-position : calc(100% - 10px) 50%;">
{{steps.title}}
<div class="pull-right" ng-click="deleteStep(steps);" style="color:#F26063; padding-right: 40px;">Delete</div>
<a class="pull-right" ng-click="openAddStep('lg');" style="color:#43C944; padding-right: 20px;">Edit</a>
</div>
JavaScript:
$scope.deleteStep = function(steps){
alert('h');
for (var i = $scope.steps.length - 1; i >= 0; i--) {
if (!$scope.steps[i].value) {
$scope.steps.splice(i, 1);
}
}
}
You can pass the current index to the delete method and then splice it as below, another option is to find the index of the data object by using the indexOf method and splice it
<div class="pull-right" ng-click="deleteStep($index);" style="color:#F26063; padding-right: 40px;">Delete</div>
js
$scope.deleteStep = function(index){
$scope.data.splice(index, 1);
}
var app = angular.module('my-app', [], function() {})
app.controller('AppController', function($scope) {
$scope.data = [];
for (var i = 0; i < 10; i++) {
$scope.data.push({
title: 'Title: ' + i
});
}
$scope.deleteStep = function(index) {
$scope.data.splice(index, 1);
}
$scope.deleteStep2 = function(steps) {
$scope.data.splice($scope.data.indexOf(steps), 1);
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="my-app">
<div ng-controller="AppController">
<div ng-repeat="steps in data" class="card" style="padding:10px 5px 10px 5px; margin-bottom:10px; margin-top:20px;">
{{steps.title}}
<div class="pull-right" ng-click="deleteStep($index);" style="color:#F26063; padding-right: 40px;">Delete</div>
<div class="pull-right" ng-click="deleteStep2(steps);" style="color:#F26063; padding-right: 40px;">Delete 2</div>
<a class="pull-right" ng-click="openAddStep('lg');" style="color:#43C944; padding-right: 20px;">Edit</a>
</div>
</div>
</div>
Related
I'm trying to display random number in a specific div or grid do i need to store number first i would like some advice on how i can achieve this. for example if random number is 4 i would like that value in div 4, then if my next random number is 10 place it in div 10
browser example
function lottoNumbers() {
var lottoNums = [];
for (var i = 0; i < 1; i++) {
var temp = Math.floor(Math.random() * 12);
if (lottoNums.indexOf(temp) == -1) {
`enter code here`
lottoNums.push(temp);
document.getElementById('square' + i).innerHTML = lottoNums[i];
} else {
i--;
}
}
}
<body bgcolor="lightblue">
<h1>
<center>GENERATE LOTTO NUMBERS</center>
</h1>
<div class="divContainer">
<div id=square0 class=num></div>
</div>
</br>
<div class="hej">
<div id=square1 class=nums></div>
<div id=square2 class=nums></div>
<div id=square3 class=nums></div>
<div id=square4 class=nums></div>
</div>
</br>
</br>
</br>
</br>
</br>
</br>
</br>
<div class=hei>
<div id=square5 class=nums></div>
<div id=square6 class=nums></div>
<div id=square7 class=nums></div>
<div id=square8 class=nums></div>
</div>
</br>
</br>
</br>
</br>
</br>
</br>
</br>
</br>
<div class="hek">
<div id=square9 class=nums></div>
<div id=square10 class=nums></div>
<div id=square11 class=nums></div>
<div id=square12 class=nums></div>
</div>
<center>
<input id="btn" class="knapp" type="button" value="lotto" onClick="lottoNumbers();">
</cennter>
</body>
</html>
Your number wasn't being placed on the right spot as You generated the temp variable which is the random number, but have addressed it to variable i which is the iterator of the for loop. This way, if You would generate 3 random numbers, they would be placed in the divs square0, square1, square2 when they actually should be placed in the divs 'square'+temp that correspond to the actual generated number. Please see my example:
document.getElementById ("btn").addEventListener ("click", lottoNumbers, false);
function lottoNumbers() {
var lottoNums = [];
for (var i = 0; i < 1; i++) {
var temp = Math.floor(Math.random() * 12) + 1;
lottoNums.push(temp);
document.getElementById('square' + temp).innerHTML = lottoNums[i];
document.getElementById('square0').innerHTML = lottoNums[i];
}
}
.num {
border: 1px solid;
width: 20px;
height: 20px;
margin: 2px;
}
.nums {
border: 1px solid;
width: 20px;
height: 20px;
margin: 2px;
float: left;
}
body {
background-color: lightblue;
}
.hej{
float: left;
width: 120px;
height: 30px;
clear: both;
}
.hei{
float: left;
width: 120px;
height: 30px;
clear: both;
}
.hek{
float: left;
width: 120px;
height: 30px;
clear: both;
}
.divContainer{
float: right;
width: 20px;
height: 20px;
font-size: 15px;
}
<h1>
<center>GENERATE LOTTO NUMBERS</center>
</h1>
<div class="divContainer">
<div id="square0" class="num"></div>
</div>
<div class="hej">
<div id="square1" class="nums"></div>
<div id="square2" class="nums"></div>
<div id="square3" class="nums"></div>
<div id="square4" class="nums"></div>
</div>
<div class="hei">
<div id="square5" class="nums"></div>
<div id="square6" class="nums"></div>
<div id="square7" class="nums"></div>
<div id="square8" class="nums"></div>
</div>
<div class="hek">
<div id="square9" class="nums"></div>
<div id="square10" class="nums"></div>
<div id="square11" class="nums"></div>
<div id="square12" class="nums"></div>
</div>
<input id="btn" class="knapp" type="button" value="lotto"">
You can just change
document.getElementById('square' + i).innerHTML = lottoNums[i];
to
document.getElementById('square' + lottoNums[i]).innerHTML = lottoNums[i];
to put each random number in the div matching that number.
I am making a rating bar with an element that has a data-rating attribute and it's children with 5 buttons. How can I change background-image of buttons depending on the data-rating attribute? For example if data-rating="3" - select first 3 buttons and change their background.
This is my code:
var rating = $('#video-list .children .branch-opened .rating');
rating.each(function() {
var value = $(this).data('rating');
var button = $(this).find('button');
});
HTML:
<div class="rating" data-rating="4">
<button value="1"></button>
<button value="2"></button>
<button value="3"></button>
<button value="4"></button>
<button value="5"></button>
</div>
Many thanks!
You could try the following (add to your rating.each callback function):
for (let i = 0; i < value; ++i) {
$(button[i]).css('background-color', '#abc');
}
Edit:
Has to be $(button[i]) instead of just button[i]
This simple code will work for you.
Updated Code
var rating = $('.rating');
rating.each(function() {
var rValue = $(this).data('rating');
$(this).find('button').slice(0, rValue).addClass('black');
});
.black {
background-color: black;
}
.rating button {
width: 10%;
display: inline-block;
padding: 20px;
border: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="rating" data-rating="4">
<button value="1"></button>
<button value="2"></button>
<button value="3"></button>
<button value="4"></button>
<button value="5"></button>
</div>
Use .each if you're already using jQuery:
var rating = $('.rating').data('rating');
$('.rating .item').slice(0,rating).each(function(index, value) {
$(this).toggleClass('highlighted');
});
.rating {
display: flex;
}
.item {
flex: 1;
padding: 10px;
background-color: #eee;
}
.item.highlighted {
background-color: goldenrod;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="rating" data-rating="4">
<button class="item" value="1"></button>
<button class="item" value="2"></button>
<button class="item" value="3"></button>
<button class="item" value="4"></button>
<button class="item" value="5"></button>
</div>
store the rating value and loop through the buttons and check condition if index lesser than rating value then add highlight class on the buttons.
var ratingValue = $('.rating').data('rating');
$('.rating .item').each(function (index, value) {
if ( index < ratingValue ) {
$(this).toggleClass('highlighted')
}
});
.rating {
display: flex;
flex-direction: column
}
.item {
flex: 1;
padding: 10px;
background-color: #eee;
}
.item.highlighted {
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="rating" data-rating="3">
<button class="item" value="1"></button>
<button class="item" value="2"></button>
<button class="item" value="3"></button>
<button class="item" value="4"></button>
<button class="item" value="5"></button>
</div>
I have a array of objects where i have a property of date_time, and in this array i wish to get the lenght of dates_times objects that are sooner with my current date_time.
Ex:
[data:[{date: "2017-02-24 16:41:51"}, {date: ""2017-02-21 16:41:51"}...],
last_clicked: "2017-02-24 19:41:51"]
I wish to get the length of objecs on "data" array that haves a date_time sooner than "last_clicked".
Maybe you can try something like this:
let length = data.filter(function(d) {
return new Date(d.date) < new Date(last_clicked)
}).length;
You can use Angulars-orderBy-filter. I set up an example for you, just swap out where I have the id key for your data's date key.
function exampleController($scope, exampleFactory, $filter) {
$scope.list = [];
$scope.reverse = false;
$scope.changeSortOrder = function() {
$scope.reverse = !$scope.reverse;
};
function getList() {
exampleFactory
.getList()
.then(function(list) {
// $scope.list = list;
//alternatively you could filter here and change the sort order with the button if needed at all.
$scope.list = $filter('orderBy')(list, '-id'); //where this would be replaced by date(note: the '-' in front of id changes the sort order ASC/DESC)
//$scope.list = $filter('orderBy')(list, 'id', true); //where 3rd argument is wether order should be reversed
});
}
getList();
}
function exampleFactory($http) {
var root = 'http://jsonplaceholder.typicode.com';
function getList() {
return $http.get(root + '/comments')
.then(function(resp) {
return resp.data;
});
}
return {
getList: getList
};
}
angular
.module('app', [])
.controller('exampleController', exampleController)
.factory('exampleFactory', exampleFactory);
.container-fluid {
background-color: #1D1F20;
color: #fff;
font-size: 14px;
font-weight: bold;
button {
margin-top: 20%;
}
}
ul li {
list-style: none;
margin: 10px;
}
.child-padding>div {
padding: 2px;
}
.col-md-2 {
position: fixed;
button {
margin-bottom: 10%;
}
}
.btn-circle {
width: 30px;
height: 30px;
text-align: center;
padding: 6px 0;
font-size: 12px;
line-height: 1.428571429;
border-radius: 50%;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<div class="container-fluid" ng-app="app">
<div class="container" ng-controller="exampleController">
<div class="row">
<div class="col-md-2 text-center">
<button class="btn btn-primary" type="button" ng-click="changeSortOrder()">Change Sort Order</button>
</div>
<div class="col-md-10 pull-right">
<ul class="ul">
<li ng-repeat="comment in list | orderBy: 'date': reverse track by $index">
<div class="child-padding">
<div>
<span ng-bind="comment.email"></span>
<span class="pull-right btn-info btn-circle" ng-bind="comment.id"></span>
</div>
<div ng-bind="comment.body"></div>
</div>
<div ng-bind="comment.name"></div>
</li>
</ul>
</div>
</div>
</div>
</div>
Use Date.parse to parse your date strings
DEMO JsFiddle
The following code will alert:
Sooner times: 1
var o = {
data:[
{date: "2017-02-24 16:41:51"},
{date: "2017-02-21 16:41:51"}
],
last_clicked: "2017-02-24 12:41:51"
};
function getSoonerLength(data, soonerThan) {
var count = 0;
for (var i = 0 ; i < data.length ; i++) {
var d = Date.parse(data[i].date);
var than = Date.parse(soonerThan);
if (d < than)
count++;
}
return count;
}
alert('Sooner times: ' + getSoonerLength(o.data, o.last_clicked))
<div ng-controller = "MyController">
<ul class="items" >
<div ng-repeat="item in colors" ng-class="{active:isActive(item)}" ng-click="select(item); whattoshow=!whattoshow">
<li class="col-md-3 col-sm-3 col-lg-3 col-xs-3" >
<img class="img-responsive" ng-src="images/colors/{{item.number}}.jpg">
</li>
<div class="col-md-12 col-sm-12 col-lg-12 col-xs-12" ng-class="whattoshow && isActive(item) ? 'show' : 'hidden'}">
<h2>{{item.bio}}</h2>
</div>
</div>
</ul>
</div>
That is my HTML code, the controller uses a JSON file to go through the items, and if you click on an item you shall see the description of it. As I try to show in this poorly drawn picture (http://i.stack.imgur.com/FCvmd.png), I can make the item bio appear after the item's picture, but as every description corresponds to its own item picture it makes my display order to change. I want every items description show on click below his own row of items.
Here is my angular controller if needed.
var myApp = angular.module('ProjectAssembly', []);
myApp.controller('MyController', ['$scope', '$http', function($scope, $http) {
$http.get('data/color.json').success(function(data) {
$scope.colors = data;
});
$scope.select= function(item) {
$scope.selected = item;
};
$scope.isActive = function(item) {
return $scope.selected === item;
};
}]);
I hope you can help my case, it seemed to be easy, but I can't find the solution :/
What you need is ng-repeat-start and ng-repeat-end and split your data into rows.
See details in example:
var myApp = angular.module('ProjectAssembly', []);
myApp.controller('MyController', ['$scope', '$http',
function($scope, $http) {
//$http.get('data/color.json').success(function(data) {});
$scope.colors = [{
number: 1,
bio: '1111111111111111111111111111111111111111'
}, {
number: 2,
bio: '2222222222222222222222222222222222222222'
}, {
number: 3,
bio: '33333333333333333333333333333333333333333'
}, {
number: 4,
bio: '4444444444444444444444444444444444444444'
}, {
number: 5,
bio: '55555555555555555555555555555'
}]
$scope.colors = (function(data) {
var result = [];
angular.forEach(data, function(val, index) {
var key = Math.floor(index / 4);
if (!result[key]) {
result[key] = [];
}
result[key].push(val);
});
return result;
})($scope.colors);
$scope.select = function(item, rowIndex, columnIndex) {
if (item == $scope.selected) {
$scope.selected = null;
$scope.selectedRowIndex = null;
$scope.selectedColumnIndex = null;
return false;
}
$scope.selected = item;
$scope.selectedRowIndex = rowIndex;
$scope.selectedColumnIndex = columnIndex;
};
$scope.isActive = function(item) {
return $scope.selected === item;
};
}
]);
.item-tr {
border: 1px solid #555;
margin-top: 5px;
position: relative;
background: #555;
}
.item-tr:before {
content: ' ';
position: absolute;
border-top: 5px solid transparent;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-bottom: 5px solid #555;
top: -11px;
}
.item-tr-0:before {
left: 12.5%;
}
.item-tr-1:before {
left: 37.5%;
}
.item-tr-2:before {
left: 62.5%;
}
.item-tr-3:before {
left: 87.5%;
}
.item-td {
border: 1px solid #555;
}
<link href="//cdn.bootcss.com/bootstrap/3.0.0/css/bootstrap-theme.css" rel="stylesheet">
<link href="//cdn.bootcss.com/bootstrap/3.0.0/css/bootstrap.css" rel="stylesheet">
<script src="//cdn.bootcss.com/jquery/2.2.1/jquery.js"></script>
<script src="//cdn.bootcss.com/bootstrap/3.0.0/js/bootstrap.js"></script>
<script src="//cdn.bootcss.com/angular.js/1.4.7/angular.js"></script>
<div ng-app="ProjectAssembly">
<div ng-controller="MyController">
<ul class="items">
<li ng-repeat-start="row in colors track by $index" class="row">
<div class="col-md-3 col-sm-3 col-lg-3 col-xs-3 item-td" ng-repeat="item in row" ng-class="{active:isActive(item)}" ng-click="select(item,$parent.$index,$index); whattoshow=!whattoshow">
<span>
<img class="img-responsive" ng-src="images/colors/{{item.number}}.jpg">
{{item.number}}
</span>
</div>
</li>
<li ng-repeat-end ng-show="selected && selectedRowIndex==$index" class="row item-tr item-tr-{{selectedColumnIndex}}">
<div>
<h2>{{selected.bio}}</h2>
</div>
</li>
</ul>
</div>
</div>
Take the following code:
<div id="work">
<div class="large-{{columns}} large-offset-{{columns}} columns projects">
</div>
</div>
The idea is that <div class="large-{{columns}} large-offset-{{columns}} columns projects"> can be generated an indefinite amount of times inside #work, and {{columns}} generates a number between 0 and 12.
What I want to do is run some JavaScript that goes through the numbers generated by {{columns}} and every time the sum is about to surpass 12, the associated divs get wrapped inside a new div with class "row".
The resulting HTML might look like this:
<div id="work">
<div class="row">
<div class="large-8 large-offset-4 columns projects"></div>
</div>
<div class="row">
<div class="large-6 large-offset-0 columns projects></div>
<div class="large-6 large-offset-0 columns projects"></div>
</div>
<div class="row">
<div class="large-4 large-offset-0 columns projects"></div>
<div class="large-8 large-offset-0 columns projects"></div>
</div>
<div class="row">
<div class="large-12 large-offset-0 columns projects"></div>
</div>
</div>
How can I accomplish this?
You can extract the {{columns}} values from each div's class name with the following regular expression:
/large-(\d+)\s* large-offset-(\d+)/
This computes the delta that should be added to the running sum:
var matches = /large-(\d+)\s* large-offset-(\d+)/.exec(item.className),
delta = parseInt(matches[1], 10) + parseInt(matches[2], 10);
You can make new row divs with document.createElement and fill them with clones of the original divs.
Demonstration:
function makeRowDiv(buildRow) {
var row = document.createElement('div');
row.className = 'row';
for (var i = 0; i < buildRow.length; ++i) {
row.appendChild(buildRow[i]);
}
return row;
}
window.onload = function () {
var work = document.getElementById('work'),
items = work.getElementsByTagName('div'),
newWork = document.createElement('div');
var buildRow = [],
count = 0;
for (var i = 0; i < items.length; ++i) {
var item = items[i];
if (item.className.indexOf('columns') == -1) {
continue;
}
// Extract the desired value.
var matches = /large-(\d+)\s* large-offset-(\d+)/.exec(item.className),
delta = parseInt(matches[1], 10) + parseInt(matches[2], 10);
if (count + delta > 12 && buildRow.length != 0) {
newWork.appendChild(makeRowDiv(buildRow));
count = 0;
buildRow = [];
}
buildRow.push(item.cloneNode(true));
count += delta;
}
if (buildRow.length != 0) {
newWork.appendChild(makeRowDiv(buildRow));
}
// Replace work with newWork.
work.parentNode.insertBefore(newWork, work);
work.parentNode.removeChild(work);
newWork.id = 'work';
};
body {
font-family: sans-serif;
font-size: 14px;
color: #444;
}
#work .row {
padding: 1px;
margin: 8px;
background: #deedff;
border: 1px solid #c4d1e1;
}
#work .row div {
/* display: inline; */
padding: 1px 4px 2px 4px;
margin: 4px;
background: #fff3fc;
border: 1px solid #ded3dc;
}
#work .row div div {
/* display: inline; */
padding: 1px 4px 2px 4px;
margin: 4px;
background: #eee;
border: 1px solid #ddd;
}
p {
padding: 0;
margin: 0;
}
<div id="work">
<div class="large-8 large-offset-4 columns projects">
<div class="child-div"><p>8</p></div>
<div class="child-div"><p>4</p></div>
</div>
<div class="large-6 large-offset-0 columns projects">
<div class="child-div"><p>6</p></div>
</div>
<div class="large-3 large-offset-3 columns projects">
<div class="child-div"><p>3</p></div>
<div class="child-div"><p>3</p></div>
</div>
<div class="large-4 large-offset-0 columns projects">
<div class="child-div"><p>4</p></div>
</div>
<div class="large-8 large-offset-0 columns projects">
<div class="child-div"><p>8</p></div>
</div>
<div class="large-6 large-offset-6 columns projects">
<div class="child-div"><p>6</p></div>
<div class="child-div"><p>6</p></div>
</div>
</div>
If you have enough horizontal space, you can uncomment the CSS line /* display: inline; */ to see the children of each row div arranged side by side.
I would use split or replace to get your integers and sum them up as suggested here.
Example:
var str = 'large-8 large-offset-6';
var large = str.replace(/.*large-(\d+)/, '$1');
var offset = str.replace(/.*large-offset-(\d+)/, '$1');
Then use a solution such as this to get your wrappers.
Example:
var divs = $("#work > .columns");
var count = <count how many cols are need to reach sum>
for(var i = 0; i < divs.length; i+=count) {
divs.slice(i, i+count).wrapAll("<div class='new'></div>");
}
I'm sure you can clean it up and finish it off but should give you the idea. I will complete when I get time tonight.