Primefaces Calendar - disabling specific dates using EL - java

so from my previous question, Disable specific dates on p:calendar, i know that i can disable specific dates using Javascript like this:
var disabledDays = ["5-15-2013", "6-23-2013"];
function disableAllTheseDays(date) {
var m = date.getMonth(), d = date.getDate(), y = date.getFullYear();
for (i = 0; i < disabledDays.length; i++) {
if($.inArray((m+1) + '-' + d + '-' + y,disabledDays) != -1) {
return [false];
}
}
return [true];
}
with:
<p:calendar id="pfdate" navigator="true" pattern="MM-dd-yyyy"
value="#{day}" BeforeShowDay="disableAllTheseDays" showOn="button"/>
However, my question is that how can i store dates in disabledDays array using EL expressions? I need to do this because the dates that i need to disable varies. Disabling dates needs to be dynamic. If i can't do this with EL expressions, is there anyways to use an array that will have dynamic data?
Thanks

One possibility is just converting the value in a bean (["5-15-2013", "6-23-2013"]), and put it directly in the Javascript code:
var disabledDays = #{myBean.disabledDays};
It's not the cleanest one, but the easiest. Another possibility is just having the list of strings in the bean and use <ui:repeat> to print it as a comma separated list.

Related

Expand the range of numbers

I was trying a solve a issue which is bothering me for a while. I created a small parser that reads an .ini file and then stores the data in an ArrayList. However, I got stuck with the following snippet:
while (!(sCurrentLine.equals("[End]"))) {
formats.add(sCurrentLine);
for (int i = 0; formats.size() > 0; i++) {
}
sCurrentLine = br.readLine();
}
Now this is the place where I have to add values into formats, which is of type ArrayList.
The values that will be added like this:
0900.013-017=LABEL
0900.018-029=LABEL
Now the range is in between and I also have to make sure that '0900' and '=label' repeats themselves along with the expansion of numbers, for example:
0900.013=LABEL
0900.014=LABEL
0900.015=LABEL
0900.016=LABEL and so on...
and store it back in the ArrayList.
I don't want to depend upon third-party libraries. Please help me out with this.
Use a regular expression to parse the range, then loop over the parsed values. There is some fine tuning to be done but I think this should get you started.
Pattern rangePattern = Pattern.compile("([0-9]+)\\.([0-9]+)-([0-9]+)=(.*)$");
Matcher rangeMatcher = rangePattern.matcher("0900.13-17=First label");
if (rangeMatcher.matches()) {
String prefix = rangeMatcher.group(1);
int start = Integer.parseInt(rangeMatcher.group(2));
int end = Integer.parseInt(rangeMatcher.group(3));
String label = rangeMatcher.group(4);
for (int r = start; r < end; r++) {
System.out.println(prefix + "." + r + "=" + label);
}
}
Create the pattern once and then just get new matchers each time through your loop.
The results:
0900.13=First label
0900.14=First label
0900.15=First label
0900.16=First label

Comparing an arrayList to itself using foreach and not including duplicates

I'm comparing an arrayList to itself using foreach.
I have an arrayList containing tips for waiters, each object has a date "dd-MM-yyy" and an amount (double),
Now i want to add all transactions for the same day, so i get a total for the day that can be divided between the waiters.
Without duplicates.
I've looked all over especially here, but I can't seem to find a solution.
I really hope you guys can help, I know it's a bit embarrassing, seeing as the problem being so simple, but I've been working on it for a couple of days now and I'm stuck.
I had a longer algorithm but it wouldn't work and I couldn't find any solutions online, so i broke it all down to it's most basic components and checked for each step and pretty early on this problem occured:
I'm using a local arrayList to make sure that I'm not comparing the same days to eachother over and over again.
The if(!alreadyMade.contains(tips1.getTime()) followed by alreadyMade.add(tips1.getTime()) seems to be producing duplicates, which in my mind makes no sense.
All I want is to add all the transactions for the same day from the same arrayList.
public void dist(){
double day = 0;
List<String> alreadyMade = new ArrayList<>();
for (Tips tips : data.getTips()) {
for (Tips tips1 : data.getTips()) {
if(tips.getTime().equals(tips1.getTime())) {
if (!alreadyMade.contains(tips1.getTime())){
alreadyMade.add(tips1.getTime());
day += tips.getTips();
}
}
}
System.out.println(day);
day = 0;
}
}
I wanted the print to be for a single day, but it is printing a lot of numbers that doesn't make sense
I think you're trying to do something like this:
Map<String,Double> alreadyMade = new HashMap<>();
for (Tips tips : new ArrayList<Tips>()) {
// If this time doesn't exist in the map then add it to the map with the
// value tips.getTips(). If this time does exist in the map then add
// the value of tips.getTips() to the value that is already in the map.
alreadyMade.merge(tips.getTime(), tips.getTips(), (Double a, Double b) -> a + b);
}
// go through each map entry. The keys are the times and the values are the tip totals for that time.
for (Map.Entry<String, Double> entry : alreadyMade.entrySet()) {
System.out.println("Time: " + entry.getKey() + " Tips: " + entry.getValue());
}
Note: I couldn't test this because I'm running Java 7 and this map function isn't available until java 8.
In Java 8+ you can use the stream API to group by the time:
Map<Date, Integer> alreadyMade = data.getTips().stream()
  .collect(groupingBy(Tip::getTime, summingInt(Tip::getTips)));
I would do it like the following:
This is your Tip class(I think)
public class Tip{
Date date;
float tip;
public Tip(Date date, float tip){
this.date = date;
this.tip = tip;
}
}
And this is the ("Algorithm")
//To Format the Dates
SimpleDateFormat ft = new SimpleDateFormat("dd-MM-yyyy");
//Input
ArrayList<Tip> tips = new ArrayList<Tip>();
//Just some Data for testing
tips.add(new Tip(ft.parse("11-04-2019"), 2.40F));
tips.add(new Tip(ft.parse("25-04-2019"), 3.30F));
tips.add(new Tip(ft.parse("25-04-2019"), 0.90F));
//Output
ArrayList<Date> dates = new ArrayList<Date>();
ArrayList<Float> sum = new ArrayList<Float>();
for(Tip tip : tips){ //Go through each Tip
int match = dates.indexOf(tip.date); //Look if the date is already in the array (if not -> -1)
if(match == -1){ //If not add it
dates.add(tip.date);
sum.add(tip.tip);
}else { //If yes set it
sum.set(match, sum.get(match) + tip.tip);
}
}
//Output to console
for(int i = 0; i < dates.size(); i++){
System.out.println(ft.format(dates.get(i)).toString() + " " + String.valueOf(sum.get(i)));
}
There is also a solution with maps or pairs but I never worked with them (not a professional coder). Also make sure to try-catch the ParseException. I Hope thats what you meant. :)

Dynamic addition & use of variable outside for loop- Selenium

Below is the scenario i am trying to automate:
Put all numerical values of the links in a Selenium Weblist & perform an addition and later to verify if the sum of count matches a fixed number.
The issue is that the numerical links returns a number engulfed in braces example:(20)(35)(16)(15)
I need to first trim these brackets & fetch only the numbers & then perform the addition i.e: 20+35+16+15
Later i need to assert the total against the number i.e: Assert.assertequals(sum,'86')
List<WebElement> lists=driver.findElements(By.cssSelector("span.ndocs"));
for (int i=0; i<lists.size(); ){
String trimmed_value=lists.get(i).getText();
trimmed_value=lists.get(i).getText().trim().substring(trimmed_value.indexOf("(") + 1);
trimmed_value=lists.get(i).getText().trim().substring(0, trimmed_value.indexOf(")"));
System.out.println(trimmed_value);
int numerical_value = Integer.parseInt(trimmed_value);
i++;
}
Till now i am able to get the elements, iterate them & able to remove the braces & get the numbers, I am stuck upon how to perform the addition operation & then do an Assert for the count.
Any help will be much appreciated here.
Try using below code.
Initialize a variable outside the method and add every trimmed_value to it as explained below.
import assertEquals(import static org.junit.Assert.assertEquals;)
int expected_value=86;
int numerical_value=0;
List<WebElement> lists = driver.findElements(By.cssSelector("span.ndocs"));
for (int i = 0; i < lists.size(); ) {
String trimmed_value = lists.get(i).getText();
trimmed_value = lists.get(i).getText().trim().substring(trimmed_value.indexOf("(") + 1);
trimmed_value = lists.get(i).getText().trim().substring(0, trimmed_value.indexOf(")"));
System.out.println(trimmed_value);
numerical_value =numerical_value+Integer.parseInt(trimmed_value);
i++;
}
assertEquals(expected_value, numerical_value);

JVisualVM HeapDump OQL rendering array inside an Object

I am trying to write a query such as this:
select {r: referrers(f), count:count(referrers(f))}
from com.a.b.myClass f
However, the output doesn't show the actual objects:
{
count = 3.0,
r = [object Object]
}
Removing the Javascript Object notation once again shows referrers normally, but they are no longer compartmentalized. Is there a way to format it inside the Object notation?
So I see that you asked this question a year ago, so I don't know if you still need the answer, but since I was searching around for something similar, I can answer this. The problem is that referrers(f) returns an enumeration and so it doesn't really translate well when you try to put it into your hashmap. I was doing a similar type of analysis where I was trying to find unique char arrays (count the unique combinations of char arrays up to the first 50 characters). What I came up with was this:
var counts = {};
filter(
map(
unique(
map(
filter(heap.objects('char[]'), "it.length > 50"), // filter out strings less than 50 chars in length
function(charArray) { // chop the string at 50 chars and then count the unique combos
var subs = charArray.toString().substr(0,50);
if (! counts[subs]) {
counts[subs] = 1;
} else {
counts[subs] = counts[subs] + 1;
}
return subs;
}
) // map
) // unique
, function(subs) { // map the strings into an array that has the string and the counts of that string
return { string: subs, count: counts[subs] };
}) // map
, "it.count > 5000"); // filter out strings that have counts < 5000
This essentially shows how to take an enumeration (heap.objects('char[]') in this case) and filter it and map it so that you can compute statistics on it. Hope this helps someone.

GWT - passing Java arrays to Javascript

I am a newcomer to GWT and Javascript.
I am trying to send in a java int[] to my javascript function. I am using a gwt-exporter to handle the processing for me. This is how I have set things up.
static class gwtExplorerTest implements Exportable {
#Export("$wnd.handleAnchorClick")
public static void handleAnchorClick(int param1, int param2 , int[] a1 , int[] a2)
{
//process things here
}
}
Can someone help me with javascript code to pass in the arrays I need here? What I currently have is:
href="javascript:window.handleAnchorClick(" + currentRow + "," + currentColumn + "," + rowVals + "," + colVals + ",") "
as my JS function call, where rowVals and colVals are the two arrays I need to pass in. It does not seem to work. Can someone please help me out?
Thanks
Your function in java is right and gwt-exporter supports this syntax. The call from JS should be like:
window.handleAnchorClick(1, 2, [3,4], [5,6])
Your problem is that you are trying to call the exported method from a href attribute in your html and you are using a bad syntax.
First, it is better to use the onClick attribute instead of href, because you dont need the javascript: tag, and it is better to prevent default. And, I'd rather define a function to do the call to avoid syntax issues.
<script>
var currentRow = 1;
var currentColumn = 2;
var rowVals = [3,4];
var colVals = [5,6];
function mycall() {
window.handleAnchorClick(currentRow, currentColumn, rowVals, colVals);
}
</script>
<!-- I prefer this -->
click
<!-- But this should work as well -->
click
If you are using json string, then i hope you need to change parameter type to string in handleAnchorClick method. Then you need to typecast to json.

Categories

Resources