Disable specific dates on p:calendar - jsf

Is it possible to disable specific dates (for example: 15th May or 23rd June) on the PrimeFaces 3.5 <p:calendar> component? There is min and max, but I need to disable specific dates like public holidays using el expressions so I can use dynamic dates.
Using Hieu's answer, make sure the dates you disable have NO leading zeros in front (eg. '03/03/2013' should be '3/3/2013').

Step 1: write a javascript function to disable a list of dates
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];
}
Step 2: use beforeShowDay attribute of Primefaces datepicker
<p:calendar id="pfdate" navigator="true" pattern="MM-dd-yyyy"
value="#{day}" beforeShowDay="disableAllTheseDays" showOn="button"/>

To disable all friday days, i have used the beforeShowDay attribute on the p:calendar , the code beloow explains this :
<p:calendar ..... mask="true" locale="fr" beforeShowDay="fridaysDisabled" .... required="true" maxdate="new Date();"/>
AND the JavaScript function :
function fridaysDisabled(date)
{
var day = date.getDay();
return [day != 5, '']
}

To disable an array of dates, follow these steps:
Create a string object that contains all the dates:
festivosArray = "[";
for(CalendarioDao dia : festivos){
festivosArray += "'" + dia.getFecha() + "',";
}
festivosArray += "]";
Create a JavaScript function:
<script type="text/javascript">
function deshabFest(date) {
var disabledDays = #{calendarioView.festivosArray};
var string = jQuery.datepicker.formatDate('dd/mm/yy', date);
return [disabledDays.indexOf(string) == -1, '']
}
</script>
Use the beforeshowday attribute to call the function
<p:calendar mode="inline" locale="es" value="#{calendarioView.fechaFestivo}" id="calendarioFestivo" widgetVar="calendarioFestivo" beforeShowDay="deshabFest" />

Related

How to get row number in SlickGrid by pressing the Enter key-Solved

Seems like a simple task but I have been unsuccessful so far using Slickgrid to get the row number of the highlighted row in a grid when I press a key, specifically the Enter key. I need no data, just the row number so I can use it to reference an array element.
I have managed to do this with the mouse using the onDblClick event handler but not with the simple onKeyDown handler.
Here is the function I use to fill the grid with data which I call when specifically needed:
var grid;
function ttesting(){
var data=[];
load_text_resource(descsource);
grid = new Slick.Grid("#myGrid", data, columns, options);
grid.invalidate();
//load data from multidimensional array:
for (var i = 0; i < maxdesc-2; ++i) {
data[i] = {
aName: descarray[i][2] + " " + descarray[i][3] + descarray[i][4] + descarray[i][5] + descarray[i][6],
aTitle: descarray[i][8],
aDesc:descarray[i][9]
};
}
grid.setOptions(options);
// the following mouse handler works:
grid.onDblClick.subscribe(function(event) {
var cell = grid.getCellFromEvent(event),
row = cell.row;
alert(descarray[row][10]);
});
//This keyDown handler does not work:
grid.onKeyDown.subscribe(function(event) {
var cell = grid.getCellFromEvent(event),
row = cell.row;
if (event.keyCode == 13) {
alert(descarray[row][10]);
}
}
grid.setSelectionModel(new Slick.RowSelectionModel());
grid.render();
}
All I need to know is the row number of the highlighted row when I press the Enter key. I have also tried using instead in the above with no success:
if (event.keyCode == 13) {
selectRow = grid.getSelectedRows();
alert(selectRow);
}
Suggestions welcome.
The traditional way to do this is to create a custom formatter for the ID column, and embed the value (ie. the row id) into the button or link displayed. For example, here's an edit link that I use to open an external page:
function EditLinkFormatter(rowIndex, cell, value, columnDef, grid, dataProvider) {
if (value == null || value === "" || !columnDef.hyperlink) { return "-"; }
if (typeof value == 'string') { value = urlEncode(value); }
return 'edit';
}
This uses value, which is the value of the ID column for the row, but rowIndex is what you are after. It's there in the formatter parameters too.
Found the solution. I needed to include the args variable in the event function:
grid.onKeyDown.subscribe(function(event,args) {
if (event.keyCode == 13) {
var cell = args.cell,
row = args.row;
alert(descarray[row][10]);
}
});

p:autoComplete does not work with single char

I have a page with two inputtext (I'll name them "name" and "id"): one that compares the text entered with a string and another one that compares it with an int converted to string.
Now the problem is this: if I have an "id" == 1 and type 1 into the inputtext, the autocomplete shows only results with two or more digits/chars (so 11,31,117 etc but not 1)...
This is the html:
<p:autoComplete id="CustomerId" value="#{myBean.CustomerBean.id}"
completeMethod="#{myBean.autoCompleteId}"
maxResults="10">
<p:ajax event="itemSelect" listener="#{myBean.selectCustomerById}"
update="resultMessage name idComp table newAssociation" />
</p:autoComplete>
And this is the autocomplete method:
public List<String> autoCompleteId(String query) {
CustomerList = myService.selectByFilters(CustomerBean);
setAcList(new ArrayList<String>());
for (int i = 0; i < CustomerList.size(); i++) {
CustomerAnag tip = CustomerList .get(i);
if(String.valueOf(tip.getId()).contains(query) || String.valueOf(tip.getId()).equals(query)) {
acList.add(tip.getId().toString());
}
}
return acList;
}
What in the sweet heaven am I doing wrong ?!

Primefaces Multiple Value autocomplete

I'm using primefaces autocomlete force selection to search over accounts by name
JSF Component
<p:autoComplete value="#{journal.journal.debit}"
completeMethod="#{account.completeAccount}"
var="var" itemLabel="#{var.name}" itemValue="#{var}"
forceSelection="true" immediate="false" required="true">
Bean Method:
public List<Account> completeAccount(String query) {
List<Account> allAccounts = service.get(Account.class);
List<Account> filteredAccounts = new ArrayList();
for (int i = 0; i < allAccounts.size(); i++) {
Account foundAccount = allAccounts.get(i);
if (foundAccount.getName().toLowerCase().contains(query.toLowerCase())) {
filteredAccounts.add(foundAccount);
}
}
return filteredAccounts;
}
this works fine, now if I want to change the search to search also for account number in the query value. I have used the following:
if (foundAccount.getName().toLowerCase().contains(query.toLowerCase()) || foundAccount.getNumber() == Integer.parseInt(query)) {
filteredAccounts.add(foundAccount);
}
but then, the filter is only returning searching for the number and ignoring name search. How can I achieve this?
I think that what Deepak was trying to say is that what you're doing is perfectly valid, and not an issue with primefaces rather something wrong with your condition. And indeed, the most obvious thing is that there is no Integer.parseInteger(String s) method, at least no in java.lang.Integer.
If this is a typo of some sort, and if you're working with Integer objects (not the int primitives) , make sure that you're comparing them by using .equals method. Comparing Integers by == will work only in the range from -128 - 127, outside of that range it will compare references.
Hope it helps
try this
if (
(foundAccount.getName().toLowerCase().contains(query.toLowerCase()))
||
(foundAccount.getNumber() == Integer.parseInteger(query))
)
{
filteredAccounts.add(foundAccount);
}

Xpages, Compute combo box value

I have a combo box its values are 10, 20, 30, 40, 50 when I create a document and display it in a view the number is appeared but I want to display its labels (labels are text) not numbers.
Can someone please help me find out how to solve this issue.
Thanks
I tend to add values of a given checkbox into a Resource Bundle, and then access that Resource Bundle both from the xp:selectItems and the xp:viewColumn values.
First, I'll create a Resource Bundle which I set as "label", with the following values:
itemsList_status=Draft|0,Published|1,Archived|-1
itemsList_delimiter=,
Here's an example of the xp:selectItems for an xp:combobox:
<xp:selectItems>
<xp:this.value>
<![CDATA[#{javascript:return getSelectItems('status');}]
</xp:this.value>
</xp:selectItems>
Here's my getSelectItems() SSJS function:
var getSelectItems : function(key) {
try {
var returnObj = new Array();
var items = null;
switch(key) {
case "status" :
items = #Text(label.itemsList_status).split(label.itemsList_delimiter);
break
}
for( var n=0, l=items.length; n < l; n++) {
returnObj.push(items[n]);
}
return returnObj;
} catch(e) {
print(database.getTitle() + " SSJS Error for getSelectItems()");
print(e.toString());
}
}
Run this function, and it'll return 3 options that read Draft, Published, and Archived while actually storing 0, 1, and -1 respectively. The problem that you're running into - and what using this abstracted method of storing your labels:values in a Resource Bundle + SSJS to address - is when you go to read the value but actually want to display the label...
Here's my getSelectedValue() function:
var getSelectedValue : function(key, thisValue) {
try {
var returnObj = new Array();
var items = null;
switch(key) {
case "status" :
items = #Text(label.itemsList_status).split(label.itemsList_delimiter);
break
}
var s = "";
var l = "";
for( var n=0, i=items.length; n < i; n++) {
if(items[n].indexOf("|") == -1) {
s = items[n];
l = items[n];
} else {
s = items[n].split("|").pop();
l = items[n].split("|").shift();
}
if(thisValue == s) {
return l;
}
}
return thisValue;
} catch(e) {
print(database.getTitle() + " SSJS Error for getSelectedValue()");
print(e.toString());
}
}
Now you'd pass the current value and the desired label:value Resource Bundle item handle, and this function spits out the correlating label. Here is how I use it in an xp:viewColumn:
<xp:viewColumn
id="viewColumn_status">
<xp:this.value><![CDATA[#{javascript:return ""}]]></xp:this.value>
<xp:text
value="#{javascript: return
getSelectedValue('status',thisEntry.getDocument().getItemValueString('status'))}" />
<xp:viewColumnHeader
value="#{label.viewColumnHeader_posts_status}"
id="viewColumnHeader_status">
</xp:viewColumnHeader>
</xp:viewColumn>
... and that's about it - the Resource Bundle entry to "itemList_status" acts as the authoritative master for the label:value pairs, so you just check that for the input building and deconstruct it for the labeling of stored values.
Hope this helps!
Using aliases is analog to the usage in a normal form.
Use a formula item for the values:
return ["- Please select -|", "ten|10", "twenty|20", "thirty|30"];
But keep in mind that the values that is stored is always TEXT and not a number.

How to validate & compare hours part of sharepoint datetime control?

I have two sharepoint datetime controls where timeOnly=true. I need to validate as required field & validate as one controls Hours value must be Greater than & Equal to other one. I want to do it in Client side.
Note: Using timeOnly="true" means need to validate Hours & minutes Only.
you will find several good solutions by searching Google for the phrase - sharepoint datetimecontrol validation - without using quotes
Created an asp.net custom validator to compare hours & minutes part of two datetime controls.
And called javascript function from ClientValidationFunction property of asp.net custom validator.
Function is here:
function ValidateHour&Minute(sender, args){
var startDateHour = document.getElementById("<%=DateTimeControlStartDate.Controls[1].ClientID %>").value;// gets value from hours dropdown list for 1st datetime control
var startDateMinute = document.getElementById("<%=DateTimeControlStartDate.Controls[2].ClientID %>").value;// gets value from minutes dropdown list for 1st datetime control
var timeStart = new Date();
var timeEnd = new Date();
var strStartHour;
var hourType;
hourType = startDateHour.split(' ');
if (hourType[1] == "AM") {
startDateHour=startDateHour.split(' ');
strStartHour = startDateHour[0];
}
else {
startDateHour=startDateHour.split(' ');
strStartHour = startDateHour[0];
strStartHour = parseInt(strStartHour) + 12;
}
timeStart.setHours(strStartHour, startDateMinute, 0, 0);
var strEndHour;
var endDateHour = document.getElementById("<%=DateTimeControlEndDate.Controls[1].ClientID %>").value;// gets value from hours dropdown list for 2nd datetime control
var endDateMinute = document.getElementById("<%=DateTimeControlEndDate.Controls[2].ClientID %>").value;// gets value from minutes dropdown list for 2nd datetime control
hourType = endDateHour.split(' ');
if (hourType[1] == "AM") {
endDateHour=endDateHour.split(' ');
strEndHour = endDateHour[0];
}
else {
endDateHour= endDateHour.split(' ');
strEndHour = endDateHour[0];
strEndHour = parseInt(strEndHour) + 12;
}
timeEnd.setHours(strEndHour, endDateMinute, 0, 0);
if (timeStart < timeEnd) {
args.IsValid = true;
}
else {
args.IsValid = false;
}
}

Resources