How to highlight a range of selected months - html

I'm new to Angular. All the answers that i came accross are using jquery and javascript. Few weeks ago there was a requirement in my team that we need a month only picker. But the condition is that we cannot outsource the component from anywhere outside the organization. Not even bootstrap, material or primeng. So I decided to create a custom one from the scratch using HTML and CSS. Here is the screenshot:
app-monthpicker is a component and on top of it there is a parent component app-timeselector.
The monthpicker is working perfectly. But I'm not able to implement the logic for highlighting the selected range of months. All the solutions on stackoverflow and other websites are using jquery or js. But here We're talking typescript. I've created a minimal stackblitz and here is one more stackblitz created by one of the answerer. Can someone help me in this regard please. With HTML and CSS and Typescript only. I badly need someones help here. I want this:
You can see 6 months from the previous year and all the months from next year also. And they also need to be highlighted if they're in range. For now I need this for 2017 to 2025 only. I don't mind even if you hard-code these values for now.
PS: I'm afraid that my whole implementation is incorrect. Please correct me.

Ideally, for such a use case you should not re-invent the wheel and leverage a good library that solved this problem. But if you want to make your current code works for the use case here is what can be done:
demo: https://angular-zedvjx.stackblitz.io
implementation: https://stackblitz.com/edit/angular-zedvjx
At high level:
I used approach where overall months are represented by one large
Array (monthsData) since the use case needs to support months
selection across years and this way it is easier to iterate over it.
Then each month view is just a "slice" into this big array, so
switching between years is switching between the "views" (view here
is monthArray.slice(viewStart, viewFinish) )
Also introduced state for the range to keep track of it easier.
Update: wrote an article with cleaner implementation here: https://medium.com/better-programming/month-range-picker-in-angular-8-4ce93ef7d76b

I'll take another aproach. You has four variables:lboundMonth,lboundYear,uboundMonth and uboundYear.
I think that you can has some like, I put and example from october 2020 to febrary 2021
lbound:{year:2020,month:10,yearMonth:"202010"} //yearMonth it's the way yyyyMM
ubound:{year:2020,month:1,ueatMonth:"202101"}
Futhermore, you create an array with the month. As #Sergey say, we can create an array of months. But in my case, I'll take that was in the way
{monthName: "january",month:1,monthYear:202001}
So, when you change the year
month=arr.map((x,index)=>{
return {
monthName:x,
month:(index+1)
monthYear:displayYear+('00'+(x+1)).slice(-2)
})
You only need compare in the loop monthYear with lbound and ubound. Some like
<div *ngFor="let month of months>
<span [ngClass]="{'ubound':month.yearMonth==ubound.yearMonth,
'lbound':month.yearMonth==lbound.yearMonth,
'range':month.yearMonth>lbound.yearMonth &&
month.yearMonth<ubound.yearMonth
}"
(click)="click(month)"
</div>
When you click you has in
click(month:any)
{
const my={
year:this.displayYear
month:month.month
monthYear:month.monthYear
}
..asing to lbound or tbound
//you emit:
this.ouputToparent({
lbound:this.lbound,
ubound:this.ubound,
})
//or
this.ouputToparent({
lbound:{year:this.lbound.year,month:this.lbound.month},
ubound:{year:this.ubound.year,month:this.ubound.month},
})
}

Related

Jquery find - increase of number

I have a simple jQuery function as I was just trying to find that best way to write this. So basically,I want the correct div to find the correct contact form. E.g. cf1 will show contactform1, cf2 will find contactform2 etc... What is the best way to write this, rather then duplicating and writing this code multiple times?
$('.cf1').parent().parent().parent().find('.contactform1').show();
$('.cf2').parent().parent().parent().find('.contactform2').show();
$('.cf3').parent().parent().parent().find('.contactform3').show();
Thank you
You can use closest function.
Example Code
$('.cf1').closest('.contactform1').show();
$('.cf2').closest('.contactform2').show();
$('.cf3').closest('.contactform3').show();
You must use both, closest and find jquery methods.
With the closest method you go up to an element which is parent of both your elements (eg. .cf1 and .contactform1), then with the find method you will go down to find the right form.
$('.cf1').closest('.selector-parent-of-both').find('.contactform1').show();
$('.cf2').closest('.selector-parent-of-both').find('.contactform2').show();
$('.cf3').closest('.selector-parent-of-both').find('.contactform3').show();

How can I create a date field by HTML5 Pattern (DD.MM.YYYY)

I have that code:
(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:30))|(?:(?:0[13578]|1[02])-31))
Checks that
1) the year is numeric and starts with 19 or 20,
2) the month is numeric and between 01-12, and
3) the day is numeric between 01-29, or
b) 30 if the month value is anything other than 02, or
c) 31 if the month value is one of 01,03,05,07,08,10, or 12
It's from page http://html5pattern.com/Dates
I tried to move some part of code, but then this code doesnt work... Even I tried to find some instructions how can I do it. But I can't handle with it...
How can I get a result like with above code but in format:
DD.MM.YYYY
Also is there any possibility to add the dots in field that user can only input the numbers without dots?
(I mean that the dots will be there every time)
Thank you for help.
Sorry for my English.
I think this is something that you are looking for:
(?:(?:0[1-9]|1[0-9]|2[0-9])\.(?:0[1-9]|1[0-2])|(?:30)\.(?:(?!02)(?:0[1-9]|1[0-2]))|(?:31)\.(?:0[13578]|1[02]))\.(?:19|20)[0-9]{2}
Also tried some possible test cases and worked fine:
You can use an input mask plugin for some of what you are asking for instead I suppose.
One popular one that comes to my mind is Robin Herbots: https://github.com/RobinHerbots/Inputmask
You can find demos off his page here: https://robinherbots.github.io/Inputmask/index.html
Once you implement the plugin into your page, then it's just a matter of establishing the right input tags and jquery for them. For example:
Your phone number script would then be something along the lines of:
<script type="text/javascript">
$("#Phone").inputmask({mask: "999.999.9999"});
</script>
You should look up the documentation for it.

how to add line chart in October CMS?

I want to add a line chart as a control chart in one of the widget pages in October CMS. CMS has pre-built classes for bar chart and pie chart. I was wondering if they have similar classes for other kind of analytics data.
I want to add the line chart prebuilt class to an html partials page, that can be used as a widget in october cms.
It seems that you are talking about things like this: https://octobercms.com/docs/ui/chart and you are looking for another type of chart besides those mentioned there.
I wanted to say if such a thing is not listed there then probably it does not exist. But... hey... I just went looking into the backend UI JS code.
Look at this file in your October app root: {% app root %}/modules/system/assets/ui/js/chart.line.js
/*
* Line Chart Plugin
*
* Data attributes:
* - data-control="chart-line" - enables the line chart plugin
* - data-reset-zoom-link="#reset-zoom" - specifies a link to reset zoom
* - data-zoomable - indicates that the chart is zoomable
* - data-time-mode="weeks" - if the "weeks" value is specified and the xaxis mo
de is "time", the X axis labels will be displayed as week end dates.
* - data-chart-options="xaxis: {mode: 'time'}" - specifies the Flot configurati
on in JSON format. See https://github.com/flot/flot/blob/master/API.md for detai
ls.
*
* Data sets are defined with the SPAN elements inside the chart element: <span
data-chart="dataset" data-set-data="[0,0],[1,19]">
* Data set elements could contain data attributes with names in the format "dat
a-set-color". The names for the data set
* attributes are described in the Flot documentation: https://github.com/flot/f
lot/blob/master/API.md#data-format
*
* JavaScript API:
* $('.chart').chartLine({ resetZoomLink:'#reset-zoom' })
*
So the functionality is there, it seems, but it's not in the public docs. Looks like you could try out something like this
<div
class="control-chart"
data-control="chart-line"
style="min-height:400px"
data-zoomable="1"
data-reset-zoom-link="#reset-zoom"
data->
<span data-chart="dataset" data-set-label="Graph me tender" data-set-data="[0,0],[1,5],[3,8],[4,2],[5,6]">
Graph me tender
</span>
<span data-chart="dataset" data-set-label="Graph me sweet" data-set-data="[0,0],[1,5],[3,8],[4,2]">
Graph me sweet
</span>
</div>
<a id="#reset-zoom" href="#">Reset zoom</a>
(Edit: There was a somewhat "dirty" tweak necessary here: I added a min-height css attribute, otherwise there was an error thrown. Maybe there should be some additional class for that instead which I do not know. Also, the two data-sets are not plotted in order (the second is plotted first) and are wrongly labeled in the legend, and appear horizontally connected to each other. The zoom function does not seem to work, etc, etc. I think this line graph thingy is possibly still work in progress and that might be the reason why it is not included in the docs yet. )
, play around with it and see what it does. (I have not tested this and hope it works somehow.) If I understand correctly it should give you a zoomable line graph with data points [0,0],[1,5],[3,8],[4,2],[5,6] (x,y coordinate points) and the link below should reset the zoom (edit: zooming does not work. maybe need to set some additional options for that)
The whole thing seems to be based on this Flot JQuery chart library. So you might find some good further hints there or here, besides reading October's {% app root %}/modules/system/assets/ui/js/chart.line.js source code.

MDX Children of Several Members

The children functions returns the set of the member.
But I need the children of several members.
The problem is, that I can't use Union to make it work like that:
Union([Geography].[Geography].[USA].children,[Geography].[Geography].[Canada].children)
I don't know how many member it will be... So I actually would need all children of a set of members.
like:
([Geography].[Geography].[USA],[Geography].[Geography].[Canada],[Geography].[Geography].[GB]).children
Is there a function like that?
I couldn't answer my question and so I just edit it. With the help of DHN's answer and some brain work I found a solution I could use:
Except(DRILLDOWNLEVEL( {[Geography].[Geography].[USA],[Geography].[Geography].[Canada]},,0 ),
{[Geography].[Geography].[USA],[Geography].[Geography].[Canada]})
That does work for me.
Explanation: I drilldown the elements the tool provides me, which returns children plus parents and then I use DHN's idea and except the parents so clean the list up a bit.
Hopefully it is understandable.
You can use the Descendants method (the fourth form of the description linked uses a set as its first argument. Thus,
Descendants( {
[Geography].[Geography].[USA],
[Geography].[Geography].[Canada],
[Geography].[Geography].[GB]
},
1,
SELF
)
should deliver exactly what you want.
Well actually, you could use a Crossjoin to get the set you want.
Something like
[Geography].[Geography].[USA] * [Geography].[Geography].[Canada] * [Geography].[Geography].[GB]
But this is only a proper solution, if you have only a few different search criteria.
Alternatively, you could use Except to remove those criteria you're not interested in. E.g.
Except([Geography].[Geography].children, [Geography].[Geography].[Germany])
This would give you the whole content of the [Geography] dimension, except the one of [Germany].
Hope this helps a bit.
Edit after comment of TO
Ok, this wasn't part of your question, but I think what you need is the MemberToStr() function. Please find the doc here.
I think something like this should do the trick.
with member [Measures].[Cities]
as membertostr([Geography].[Geography].members.children)
select [Measures].[Cities] on 0
from [WhatEverYourCubeNameIs]
where (
[Geography].[Geography].[USA],
[Geography].[Geography].[Canada]
)
Please note that this query is totally untested. I also may have lost some of my skills, because it's been a while, since I used mdx. You will also have to create the query dynamically, since the selection seems to be user dependant. But I'm sure that you're aware of it. ;)

how do i get values from a grid of multiple groups of radio buttons?

my code is long but i think my question is simple: How can i build a google GUI to show a grid of multiple groups of radio buttons.
in essence, i want to build something that is like:
Jane Smith:
Question 1: radio1, radio2, radio3, radio4
Question 2: radio1, radio2, radio3, radio4
John Doe:
Question 1: radio1, radio2, radio3, radio4
Question 2: radio1, radio2, radio3, radio4
etc.etc...
I have the whole code written to dynamically create the page and all the nested for loops for the logic to read each group of radio buttons back out into an array after the user submits to then be able to parse and have my way with it.
But how do i get the variables of the radio buttons themselvse?
the solutions here seem overly complicated as it is about 10 lines of code that would need to be injected into each layer of my 3 layer deep for loops to make that work, i think. unless i'm thinking about it wrong.
RadioButtons must have the same name (be part of the same group) to work as expected (exclusive-OR) so the solution to assign a client handler to each of them that sets a value to a hidden widget (or a textBox) is, AFAIK, the only working solution if you're not using a form.
The code is not so complicated and in your case it will be the same for each question so you could easily implement it in your code.