JavaScript: missing logic when array iterate for missing value - javascript

I am trying to fill blank values when no data available for particular months. Here is plunker.. http://plnkr.co/edit/f0IklkUfX8tkRZrn2enx?p=preview
$scope.year = [
{"month":"mar", "val":"23"},
{"month":"feb", "val":"45"},
{"month":"jan", "val":"56"}
];
var total = ["jan", "feb", "mar", "apr", "may", "jun", "aug", "sep", "oct", "nov", "dec"];
for(var i=0; i<total.length; i++){
if($scope.year[i].month === undefined){ //logic here to see absent month.
$scope.year.push(
{
"month":total[i],
"val":"0"
})
}
}
I have created array of default total months items for compare each month item from expected object, if the item is absent in expected object, need to create empty item or with value "0" in expected object itself.

You can do something like following
Js Update
var year = [
{"month":"mar", "val":"23"},
{"month":"feb", "val":"45"},
{"month":"jan", "val":"56"}
];
var total = ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"];
// Current months array
var currentMonth = [];
angular.forEach(year, function(item){
currentMonth.push(item.month);
});
// iterating over months
for(var i=0; i<total.length; i++){
//$scope.year = [];
// checking if month is absent
if(currentMonth.indexOf(total[i]) === -1){ //logic here to see absent month.
year.push(
{
"month":total[i],
"val":"0",
"order" : i
})
} else {
year[currentMonth.indexOf(total[i])].order = i; // adding order
}
}
$scope.year = year;
Markup
<!-- Order by new property order -->
<td ng-repeat="item in year | orderBy: 'order'">
{{item.val}}
</td>
For reference - http://plnkr.co/edit/km6jLQv8wxm1XP8QCxvV?p=preview

year[i] is undefined, so you try get field of object that don't exist.
try it "if($scope.year[i] === undefined)"

Your idea of using orderBy won't work based on month because you aren't looking for an alphabetical sort.
Following creates array of months that exist in the data. Then it loops over all months in year and adds missing data. Finally sort the data based on months indexing
// create array of months available in data
var availableMonths = $scope.year.map(function(item){
return item.month;
});
// loop over all months and if it doesn't exist in data add it
total.forEach(function(mo){
if(availableMonths.indexOf(mo) ===-1 ){
$scope.year.push({"month":mo, "val":"0" })
}
});
// sort data using index of months
$scope.year.sort(function(a,b){
return total.indexOf(a.month) > total.indexOf(b.month);
});
remove the orderBy filter in html since data is already sorted
Steps 2 & 3 above could actually be combined to splice() the array so final order is correct but for ease of understanding I left them as separate operations
DEMO

Try this.
$scope.year = [
{"month":"jan", "val":"56"},
{"month":"feb", "val":"45"},
{"month":"mar", "val":"23"}
];
var total = ["jan", "feb", "mar", "apr", "may", "jun", "aug", "sep", "oct", "nov", "dec"];
for(var i=0; i<total.length; i++){
if(!$scope.year[i] || $scope.year[i].month === undefined){
$scope.year.push(
{
"month":total[i],
"val":"0"
})
}
}

Related

Is there any way to print out an specific element from an array with just its index number?

Well, I want to print out the name of the month from the .getMonth() method.
Keeping in mind that the array index starts from 0, I've made this code:
let date = new Date();
let month = date.getMonth();
month -= 1;
// As array index start from 0 but month from 1, I'm subtracting 1 from it so it too will start from 0.
let months =
[
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
]
Now I want like if it's May, I will keep the value 4, then subtract 1, which is 3.
The 3rd index in the array months is "May", but how will I ask it to check for the element with its index number?
NOTE : Please don't suggest if statements, because I don't want to use if statements for just displaying elements.
Easy: use the bracket property accessor notation:
let date = new Date
let month = date.getMonth()
let months =
[
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
]
console.log(months[month])
Arrays are little more than objects with properties named after the positive integers (ie. '0', '1', '2' etc). Because JavaScript is weakly typed you can supply a number (eg. from getMonth!) to the bracket property accessor notation, and the value will be coerced to a string, giving you the result you want.
But, as Jaromanda X points out, the better way is to use the Intl API because this will guarantee accuracy for a given user locale:
const date = new Date
console.log(new Intl.DateTimeFormat('en', { month: 'short'}).format(date))

Javascript array output

Given the following code I need two things:
This one I know how to do, basically user inputs a number and matching month is provided in an output.
But in the same prompt if user writes a month (for eksample "Aug"), how do I return the index number?
The first part I would solve with a for loop and if/else, but how do I include also the second part with only one prompt from user?
var months = ["Not in use", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"];
var userInput = prompt("Choose a month by number or name!");
You can apply a check on the input value and return response accordingly:
let months = ["Not in use", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"];
let locator = v => Number.isNaN(Number(v)) ? months.indexOf(v) : months[v];
console.log(locator("Aug"));
console.log(locator("3"));
You can check the type of your user prompt with a if/else.
let userInput = prompt('Choose a month by number or name')
let monthNumber = parseInt(userInput)
if (monthNumber === NaN) {
// Do your stuff using userInput as a monthName
} else {
// Do your stuff using monthNumber
}
Instead of an empty first element in the array you should add 1 to the index. Next you should check if the userInput is one of the months and change it to the index of the month + 1.
let months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"]
let userInput = prompt("Choose a month by number or name!");
if (months.include(userInput) {
userInput = months[userInput + 1]
}
In addition you have to turn the user input wich is a string into an integer if it is within the range between 1 and 12
let parsedInt = parseInt(userInput)
if (parsedInt >= 1 && parsedInt <= 12) {
userInput = parsedInt
}

How to calculate the previous months in JS?

In JavaScript,
How to calculate all the previous months from this month (for a year) in the fastest way?
Say, for input: Jun should expect Jun,May,Apr,...Jan,Dec...Jun
You could follow an approach like this:
const MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
function getPreviousMonths(currentMonth) {
let index = MONTHS.indexOf(currentMonth);
let result = [];
for(let j = 0; j < MONTHS.length; j++) {
let access = index - j;
if(access < 0) {
access += MONTHS.length;
}
result.push(MONTHS[access]);
}
return result.join(",");
}
I would rather have some mapping, like this.
let months = [Jaunary, February, March, April, May]
Then Having got for example 'March' - find its index in array months, and take previous index or whatever you want

Show items in a box after clicking one by one using Javascript AngularJS

I have written a code, where it will show the next 12 months from current month. Suppose, now is Oct 2015, so it will show all next 12 months, that is upto Oct 2016. I am showing it in a list. But, I want to create a box with right-left arrow enabled. After clicking on left-right arrow it will show next item. After clicking on right arrow it will show next item and after clicking on left arrow it will show previous item. Data items will be shown in a box. Please check my below code, which will print next 12 months from current.
angular.module('picker', []).controller('pickercontroller', function($scope) {
var date = new Date();
var months = [],
monthNames = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ];
for(var i = 0; i <= 12; i++) {
months.push(monthNames[date.getMonth()] + ' ' + date.getFullYear());
date.setMonth(date.getMonth() + 1);
}
$scope.months = months;
});
<div ng-app="picker">
<div ng-controller="pickercontroller">
<li ng-repeat="currMonth in months">{{currMonth}}</li>
</div>
</div>
Also, check my fiddle :- http://jsfiddle.net/abhijitloco/cqbqow2L/
Check this code to see how you can change the selected month via ng-click
https://jsfiddle.net/jddg3som/
Controller
angular.module('picker', []).controller('pickerCtrl', function($scope) {
var date = new Date();
var months = [],
monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
];
for (var i = 0; i < 12; i++) {
months.push(monthNames[date.getMonth()] + ' ' + date.getFullYear());
date.setMonth(date.getMonth() + 1);
}
$scope.changeMonth = function(steps) {
if ($scope.monthIndex + steps >= 0 &&
$scope.monthIndex + steps <= 11
) {
$scope.monthIndex = $scope.monthIndex + steps;
$scope.monthName = $scope.months[$scope.monthIndex];
}
};
$scope.monthIndex = 0;
$scope.months = months;
$scope.monthName = months[0];
});
View
<div ng-app="picker">
<div ng-controller="pickerCtrl">
<h1> {{monthName}} </h1>
<button ng-click="changeMonth(1);">Next Month</button>
<button ng-click="changeMonth(-1);">Previous Month</button>
<li ng-repeat="currMonth in months">{{currMonth}}</li>
</div>
</div>
Use ng-click to handle button event and for next month check whether next month is available in months array or not. If available then set next month from array.
Same for previous month
angular.module('picker', []).controller('pickercontroller', function($scope) {
var date = new Date();
var months = [],
monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
];
for (var i = 0; i <= 12; i++) {
months.push(monthNames[date.getMonth()] + ' ' + date.getFullYear());
date.setMonth(date.getMonth() + 1);
}
$scope.months = months;
$scope.currMonth = months[0];
$scope.nextMonth = nextMonth;
$scope.prevMonth = prevMonth;
function prevMonth() {
var index = $scope.months.indexOf($scope.currMonth);
if (index != 0 && index < $scope.months.length) {
$scope.currMonth = $scope.months[index - 1];
}
}
function nextMonth() {
var index = $scope.months.indexOf($scope.currMonth);
if (index < $scope.months.length - 1) {
$scope.currMonth = $scope.months[index + 1];
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="picker">
<div ng-controller="pickercontroller">
<p>{{currMonth}}</p>
<button ng-click="prevMonth()">Previous Month</button>
<button ng-click="nextMonth()">Next Month</button>
</div>
</div>

jquery make date from integer value

I am in need of making a program which can convert an integer number into a date using javascript/jquery. WhatI am thinking is to divide the numbers by 10 and then split them so then, depending upon the numbers I want to display the date in another input field.
The input given by the user should be like this:
910111
and the output should be
11/jan/1991
My code is:
<input type="text" id="id1"/>
<input type="text" id="id2" />
$("#id1").change('input', function(){
var input = $(this).val();
var remainder = [10];
var quotient = 0;
var divisor = 10;
var dividend = input;
var j=0;
var array1 = [10];
while(dividend >= 10)
{
remainder[j] = dividend % divisor;
quotient = dividend / divisor;
dividend = quotient;
j++;
}
});
The Updated code after the discussion is as follows which is not working when I pass the variable "input" instead of a hard coded value.
<html>
<head>
<title>
Inzamam Tahir
</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js" type="text/javascript"></script>
<script src="moment.js" type="text/javascript"></script>
<script>
$(document).ready(function(){
var input = $("#id1").val();
$("#id1").change(function () {
var date = moment(input).format('DD/MM/YY');
$("#id2").val(date);
});
});
</script>
</head>
<body>
<input type= "text" id = "id1"/>
<input type = "text" id = "id2"/>
<input type = "submit" id = "id3"/>
</body>
</html>
Connect Moment.js and use this snippet:
moment("910111", "YYMMDD").format('DD/MMMM/YYYY'))
http://jsfiddle.net/400abej7/
Parse date: http://momentjs.com/docs/#/parsing/string-format/
Print (parsed) date: http://momentjs.com/docs/#/displaying/
You can create an array for months. And then you could do this
var months = ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"];
var input = "910111";
var output = input.replace(/(\d\d)(\d\d)(\d\d)/, function(m, g1, g2, g3){
return g3 + "/" + (months[g2-1]) + "/19" + g1;
});
best to assume 4 digit years, or you will have problems when you cross the 2000 boundary, but you can do this really simply with with modulus and divide. Much faster that most other solutions (looping or regEx etc):
var months = ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"];
$("#id1").change('input', function () {
var input = ~~$(this).val()
var year = ~~(input / 10000);
var month = ~~(input % 10000 / 100);
var day = ~~(input %100)
var date = "" + day +"/" +months[month-1]+ "/" + year
alert(date);
});
http://jsfiddle.net/TrueBlueAussie/na46owxu/2/
Notes:
~~ is a shortcut integer conversion.

Categories

Resources