Xpages Bootstrap enabled Calendar - xpages

Using the iNotesCalendar view in my Bootstrap enabled web application provides a not so appealing calendar (see below)
Is there a way to wrap some bootstrap styling around the calendar? I couldn't find anything about bootstrap calendars in XPages4Bootstrap or on the Bootstrap page.

As Eric suggested I am going to answer my own question. A very good starting point is Frank's excellent post.
I will post a lot of code and as much explanation as I can.
First you need to get the files and add them to the WebContent folder of your NSF, which you can find in the Package Explorer. I made a sub folder named "FullCalendar" to keep things orderly.
Create a custom control for your calendar. [Code for this at the bottom of the this entry.]
There a few things in my custom control that I had to add to Frank's explanation that were particular to my environment - they may be true of yours as well.
First, notice that I set the xsp.resources.aggregate property to "true", which overrides the database setting of false. I do not remember why I had to do this, but my calendar did not work unless I did.
Note: I found the code and the reason in this post.
Next, I add three resources, 3 that are related to FullCalendar (the fourth is some common layout css). The ordering is very important here. jQuery must be loaded before moment.min.js, which must be loaded before fullcalendar.min.js. Don't see jQuery there though? jQuery is already loaded in my theme, don't want to load it again.
Notice that moment is loaded with some unfamiliar syntax using a head tag and attributes. I posted a question about using Bootstrap with Full Calendar. Long story short you must also fix the AMD issue (see the post), and load resources as I did to get this to work, although I imagine I am doing something wrong!
There is some standard type of code for buttons and so on, and a div container. The real work is in the script block, and the important part is calling the rest service. I tried to make this fairly standard - I always put rest elements in a design element called XpRest.xsp and then put a specific name on each of the elements, this one being CalendarEvents.
This rest service element calls a java Rest service. The code for the rest service extension library design element is:
<xe:restService
id="restService2"
pathInfo="calendarEvents"
ignoreRequestParams="false"
state="false"
preventDojoStore="true">
<xe:this.service>
<xe:customRestService
contentType="application/json"
serviceBean="com.XXXX.rest.CalendarEvents">
</xe:customRestService>
</xe:this.service>
</xe:restService>
So this is going to call a java rest service, and the code for this is...
package com.XXXXX.rest;
import java.io.IOException;
import java.io.Writer;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.openntf.domino.Database;
import org.openntf.domino.Session;
import org.openntf.domino.View;
import org.openntf.domino.ViewEntry;
import org.openntf.domino.ViewNavigator;
import org.openntf.domino.utils.Factory;
import org.openntf.domino.DateTime;
import com.ibm.commons.util.io.json.JsonException;
import com.ibm.commons.util.io.json.util.JsonWriter;
import com.ibm.domino.services.ServiceException;
import com.ibm.domino.services.rest.RestServiceEngine;
import com.ibm.xsp.extlib.component.rest.CustomService;
import com.ibm.xsp.extlib.component.rest.CustomServiceBean;
import com.scoular.cache.CacheBean;
public class CalendarEvents extends CustomServiceBean {
#SuppressWarnings("unused")
private Database dataDB;
#Override
public void renderService(CustomService service, RestServiceEngine engine) throws ServiceException {
try {
HttpServletRequest request = engine.getHttpRequest();
HttpServletResponse response = engine.getHttpResponse();
response.setHeader("Content-Type", "application/json; charset=UTF-8");
response.setContentType("application/json");
response.setHeader("Cache-Control", "no-cache");
response.setCharacterEncoding("utf-8");
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Credentials", "true");
response.addHeader("Access-Control-Allow-Methods", "GET, POST");
response.addHeader("Access-Control-Allow-Headers", "Content-Type");
response.addHeader("Access-Control-Max-Age", "86400");
String method = request.getMethod();
if (method.equals("GET")) {
this.doGet(request, response);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, JsonException {
try {
Integer cnt = 0;
ViewNavigator nav;
View chgView;
DateTime tmpDte;
Date tmpDte2;
Database DB = this.getDataDB();
chgView = DB.getView("(xpViewCalendar01)");
nav = chgView.createViewNav();
Writer out = response.getWriter();
JsonWriter writer = new JsonWriter(out, false);
writer.isCompact();
writer.startArray();
for (ViewEntry entry : nav) {
//Vector<?> columnValues = entry.getColumnValues();
cnt = cnt + 1;
writer.startArrayItem();
writer.startObject();
//Event Title
writer.startProperty("title");
writer.outStringLiteral(String.valueOf(entry.getColumnValues().get(0)));
writer.endProperty();
//Change id
writer.startProperty("id");
writer.outStringLiteral(cnt.toString());
writer.endProperty();
//Start Date and Time
writer.startProperty("start");
tmpDte = (DateTime) entry.getColumnValues().get(4);
tmpDte2 = tmpDte.toJavaDate();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
String tmpStr = df.format(tmpDte2);
writer.outStringLiteral(tmpStr);
writer.endProperty();
//End Date and Time (same as start)
writer.startProperty("end");
writer.outStringLiteral(tmpStr);
writer.endProperty();
writer.endObject();
writer.endArrayItem();
}
writer.endArray();
writer.flush();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public Database getDataDB() {
Session session = Factory.getSession();
Database DataDB = session.getDatabase(CacheBean.get().getAppDataDBPath());
return DataDB;
}
public void setDataDB(Database dataDB) {
this.dataDB = dataDB;
}
}
This rest service is not totally completed yet, as I am not grabbing the "end" date nor grabbing the allDay element, although I have put in hooks for them in the entry form. But I think that would be pretty easy to add to this code.
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xe="http://www.ibm.com/xsp/coreex">
<xp:this.properties>
<xp:parameter name="xsp.resources.aggregate" value="true" />
</xp:this.properties>
<xp:this.resources>
<xp:headTag tagName="script">
<xp:this.attributes>
<xp:parameter name="type" value="text/javascript" />
<xp:parameter name="src"
value="FullCalendar/moment.min.js" />
</xp:this.attributes>
</xp:headTag>
<xp:script src="FullCalendar/fullcalendar.min.js"
clientSide="true">
</xp:script>
<xp:styleSheet href="FullCalendar/fullcalendar1.min.css"></xp:styleSheet>
<xp:styleSheet href="/cc_CommonGrid.css"></xp:styleSheet>
</xp:this.resources>
<!--The Container-->
<div class="container-fluid">
<!--The Button Bar-->
<div class="toolbar" style="width: 100% !important">
<div class="row">
<span style="margin-right:10px">
<button type="button" id="newDoc"
class="btn btn-primary">
Add Event
</button>
</span>
<span style="float: right">
<div class="input-group" style="width:300px">
<input type="text" id="searchInput"
class="form-control"
style="border-radius: 5px; border-bottom-right-radius:0px ;border-top-right-radius: 0px"
placeholder="Search for..." />
</div>
</span>
</div>
</div>
<!--The Button Bar-->
<!--The Grid-->
<div
id="div1"
class="row"
style="margin-top:15px">
<!--The Grid-->
<xp:div
id="grid"
style="background-color:rgb(255,255,255)"
styleClass="cal">
</xp:div>
<!--The Grid-->
</div>
<!--The Grid-->
</div>
<!--The Container-->
<xp:scriptBlock id="scriptBlock1">
<xp:this.value><![CDATA[// Add Document
$('#newDoc').click(function(event){
var url = "xpFormEvent.xsp";
window.open(url,"_self");
});
$(document).ready(function() {
//Get URL for web serice
var b1 = "#{javascript:context.getUrl().getAddress().replace(view.getPageName(), '');}"
var b2 = b1 + "/xpRest.xsp/calendarEvents";
var calCon = $(".cal");
calCon.fullCalendar({
header: {
left: 'prevYear,nextYear',
center: 'title',
right: 'today,month,prev,next'
},
eventSources: [
{
url: b2
}
]
});
})
]]></xp:this.value>
</xp:scriptBlock>
</xp:view>
OK so here is the code for the ccCalendarView01:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xe="http://www.ibm.com/xsp/coreex">
<xp:this.properties>
<xp:parameter name="xsp.resources.aggregate" value="true" />
</xp:this.properties>
<xp:this.resources>
<xp:headTag tagName="script">
<xp:this.attributes>
<xp:parameter name="type" value="text/javascript" />
<xp:parameter name="src"
value="FullCalendar/moment.min.js" />
</xp:this.attributes>
</xp:headTag>
<xp:script src="FullCalendar/fullcalendar.min.js"
clientSide="true">
</xp:script>
<xp:styleSheet href="FullCalendar/fullcalendar1.min.css"></xp:styleSheet>
<xp:styleSheet href="/cc_CommonGrid.css"></xp:styleSheet>
</xp:this.resources>
<!--The Container-->
<div class="container-fluid">
<!--The Button Bar-->
<div class="toolbar" style="width: 100% !important">
<div class="row">
<span style="margin-right:10px">
<button type="button" id="newDoc"
class="btn btn-primary">
Add Event
</button>
</span>
<span style="float: right">
<div class="input-group" style="width:300px">
<input type="text" id="searchInput"
class="form-control"
style="border-radius: 5px; border-bottom-right-radius:0px ;border-top-right-radius: 0px"
placeholder="Search for..." />
</div>
</span>
</div>
</div>
<!--The Button Bar-->
<!--The Grid-->
<div
id="div1"
class="row"
style="margin-top:15px">
<!--The Grid-->
<xp:div
id="grid"
style="background-color:rgb(255,255,255)"
styleClass="cal">
</xp:div>
<!--The Grid-->
</div>
<!--The Grid-->
</div>
<!--The Container-->
<xp:scriptBlock id="scriptBlock1">
<xp:this.value><![CDATA[// Add Document
$('#newDoc').click(function(event){
var url = "xpFormEvent.xsp";
window.open(url,"_self");
});
$(document).ready(function() {
//Get URL for web serice
var b1 = "#{javascript:context.getUrl().getAddress().replace(view.getPageName(), '');}"
var b2 = b1 + "/xpRest.xsp/calendarEvents";
var calCon = $(".cal");
calCon.fullCalendar({
header: {
left: 'prevYear,nextYear',
center: 'title',
right: 'today,month,prev,next'
},
eventSources: [
{
url: b2
}
]
});
})
]]></xp:this.value>
</xp:scriptBlock>
</xp:view>

Related

JSF couldn't pass data to bootsrtap modal

hello everyone i have a bootsfaces dataTabble, each row has an edit end delete action, i want to show a modal that contains selected row data to edit that object.
i successfully get the selected row i pass data to the managedBean, i assign data to managedProperties, but nothing is shown in Modal input elements.
this is my dataTable code:
<b:dataTable id="articleslist" value="#{listeArticlesAction.listeArticles}" var="article" page-length="10" paginated="true"
page-length-menu="10,20,30">
<b:dataTableColumn value="#{article.code}" label="Code" />
<b:dataTableColumn value="#{article.nom}" label="Nom" />
<b:dataTableColumn value="#{article.description}" label="Description" />
<b:dataTableColumn value="#{article.prix}" label="Prix (DH)" />
<b:dataTableColumn label="Modifier" style="text-align: center">
<h:commandButton style="padding: 0 4px;" iconAwesome="pencil" look="link" pt:data-target="#userEditModal" pt:data-toggle="modal"
action="#{listeArticlesAction.modifierArticle}">
<f:setPropertyActionListener target="#{listeArticlesAction.editArticle}" value="#{article}"
/>
<f:ajax render="#form"/>
</h:commandButton >
</b:dataTableColumn>
<b:dataTableColumn label="Supprimer" style="text-align: center">
<h:commandButton style="padding: 0 4px; text-align: center;" iconAwesome="trash" look="link" pt:data-target="#userEditModal" pt:data-toggle="modal"
onclick="confirmDelete()" action="#{listeArticlesAction.supprimerArticle}" >
<f:param name="actionDelete" value="article" />
</h:commandButton >
</b:dataTableColumn>
</b:dataTable>
and this is my managedBean class:
public class ListeArticlesAction {
private List<Article> listeArticles = new ArrayList<Article>();
private String editArticleNom;
private String editArticleDescription;
private int editArticlePrix;
private Article editArticle;
/**
* Methode pour preparer la liste des articles
*/
#PostConstruct
public void init() {
listeArticles = ServiceFactory.getArticleService().allArticles();
}
public List<Article> getListeArticles() {
return listeArticles;
}
public void setListeArticles(List<Article> listeArticles) {
this.listeArticles = listeArticles;
}
public String getEditArticleNom() {
return editArticleNom;
}
public void setEditArticleNom(String editArticleNom) {
this.editArticleNom = editArticleNom;
}
public String getEditArticleDescription() {
return editArticleDescription;
}
public void setEditArticleDescription(String editArticleDescription) {
this.editArticleDescription = editArticleDescription;
}
public int getEditArticlePrix() {
return editArticlePrix;
}
public void setEditArticlePrix(int editArticlePrix) {
this.editArticlePrix = editArticlePrix;
}
public Article getEditArticle() {
return editArticle;
}
public void setEditArticle(Article editArticle) {
this.editArticle = editArticle;
}
public void supprimerArticle() {
}
/**
* methode pour modifier un article quelconque
*/
public void modifierArticle() {
editArticleDescription = editArticle.getDescription();
editArticleNom = editArticle.getNom();
editArticlePrix = editArticle.getPrix();
}
}
and this is my modal html code:
<div class="modal" id="userEditModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">
Modifier le produit
</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">
×
</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label for="edit_product_name" class="form-control-label">
Nom:
</label>
<h:inputText type="text" class="form-control" id="edit_product_name"
value="#{listeArticlesAction.editArticleNom}" autocomplete="off" />
</div>
<div class="form-group">
<label for="edit_product_description" class="form-control-label">
Description:
</label>
<h:inputTextarea class="form-control" id="edit_product_description"
value="#{listeArticlesAction.editArticleDescription}" autocomplete="off" />
</div>
<div class="form-group">
<label for="edit_product_price" class="form-control-label">
Prix(DH):
</label>
<h:inputText type="text" class="form-control m-input" id="edit_product_price"
value="#{listeArticlesAction.editArticlePrix}" autocomplete="off" />
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">
Annuler
</button>
<button type="button" class="btn btn-primary">
Modifier
</button>
</div>
</div>
</div>
</div>
Most likely you're updating the wrong part of the screen. That happens to many people using modals for the first time. Thing is, the modal is rendered when the page is loaded. That's potentially a minute before the button is clicked. So the modal doesn't know which data to display. You tell it using the update attribute of the command button.
As far as I can see, the datatable and the Java bean are OK. With the exception of the update region. Your code snippets don't show where the <h:form> or <b:form> tag is, so it's almost certainly outside the datatable. However, what you should update is the content of the modal. Don't update the entire modal (because that renders it hidden again). Just the content. Something like update="#(.modal-dialog)".
The modal itself looks a bit odd to me. What is listeArticlesAction? Judging from the other code snippets, you want to use listeArticlesAction.editArticle instead.
Side remark: I suggest you choose a language for the variable names (and stuff like this) and use it consistently. French is a good choice, although most developers (except me) recommend English. But it's hard enough to remember the variable name. You don't have to add the burden of remembering the language :).

Restore the active bootstrap tab after postback when page has multiple forms

I have an ASP.Net MVC 5 project that has a page with 2 bootstrap tabs. Each tab has two forms for a total of 4 forms on the page. My viewmodel has a superset of all the fields in the 4 forms.
When I post a form, I want the response view to display the same tab that was showing when the form was posted. This SO answer Remain bootstrap tab after postback c# indicates that I should set the active tab in a hidden field, return it in the view model, then restore it on postback.
This SO answer asp.net MVC 4 multiple post via different forms indicates that returned fields must be within the form I'm returning. This presents a problem since the hidden field needs to be in the scope of all the forms.
On postback, how do I display the same tab that was showing when the form was posted when I have multiple forms on the page?
I solved this problem by removing the 4 forms and replacing it with a single form that spanned the previous 4. To get the form to post-back to the proper controller/action, I wrote some javascript that is invoked when one of the 4 submit buttons is activated.
It sets the new form's action to the appropriate controller/action and then submits the form. This way, there is only 1 form and 1 hidden field to hold the active tab and the correct action still gets invoked on post-back. A test program with 2 tabs and (for simplicity) only 2 actions is here:
View:
#model MultiPostDestinations.Models.HomeVM
#{
ViewBag.Title = "Home Page";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<br/><br /><br /><br />
<div class="row">
<div class="col-md-4">
#using (Html.BeginForm("SubmitForm", "Home", FormMethod.Post, new { id = "submitForm", enctype = "multipart/form-data" })) {
#Html.HiddenFor(m => m.ActiveTab)
<div id="Tabs" role="tabpanel" class="container" style="width: 1000px">
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li class="active">Details</li>
<li>Historic Model Analysis</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div id="details" role="tabpanel" class="tab-pane fade in active">
<h2>Details Tab</h2>
<h4>label: #Model.F1</h4><br /><br />
#Html.DisplayFor(m => m.F1)<br /><br />
#Html.EditorFor(m => m.F1)<br /><br />
#Html.ActionLink("ActionLink Submit form", "SubmitGet", "Home", new { #class = "btn btn-default" })<br /><br />
<input type="submit" value="input SubmitForm" class="btn btn-default" /><br /><br />
<input id="submitButton1" type="button" value="javascript input to /Home/Submit1" class="btn btn-default" /><br /><br />
</div>
<div id="history" role="tabpanel" class="tab-pane fade">
<h2>Historic Model Analysis tab</h2>
<h4>label: #Model.F2</h4><br /><br />
#Html.DisplayFor(m => m.F2)<br /><br />
#Html.EditorFor(m => m.F2)<br /><br />
<input type="submit" value="input SubmitForm" class="btn btn-default" /><br /><br />
<input id="submitButton2" type="button" value="javascript input to /Home/Submit2" class="btn btn-default" /><br /><br />
</div>
</div>
</div>
}
</div>
</div>
#section scripts {
<script type="text/javascript">
$(document).ready(function () {
$('#submitButton1').click(function (e) {
e.preventDefault(); // recommended in SO, does not appear to be required
$('#submitForm').attr('action', '/Home/Submit1');
$('#submitForm').submit();
});
$('#submitButton2').click(function (e) {
e.preventDefault(); // recommended in SO, does not appear to be required
$('#submitForm').attr('action', '/Home/Submit2');
$('#submitForm').submit(); // previous doesn't work - why?
});
var lastActiveTab = ($('#ActiveTab').val() !== '') ? $('#ActiveTab').val() : 'details';
$('#Tabs a[href="#' + lastActiveTab + '"]').tab('show');
$("#Tabs a").click(function () {
$('#ActiveTab').val($(this).attr("href").replace("#", ""));
});
});
</script>
}
Here is the Controller with 2 actions:
using MultiPostDestinations.Models;
using System.Web.Mvc;
namespace MultiPostDestinations.Controllers {
public class HomeController : Controller {
public ActionResult Index() {
var vm = new HomeVM() { F1 = "Index-F1", F2 = "Index-F2", ActiveTab = "" };
return View("Index", vm);
}
[HttpPost]
public ActionResult Submit1(HomeVM vm) {
System.Diagnostics.Debug.WriteLine("HomeVM.Submit1: F1={0}, F2={1}", vm.F1 ?? string.Empty, vm.F2 ?? string.Empty);
// ModelState.Clear(); // uncomment if you want Html.EditorFor() fields to update on postback
return View("Index", vm);
}
[HttpPost]
public ActionResult Submit2(HomeVM vm) {
System.Diagnostics.Debug.WriteLine("HomeVM.Submit2: F1={0}, F2={1}", vm.F1 ?? string.Empty, vm.F2 ?? string.Empty);
//ModelState.Clear(); // uncomment if you want Html.EditorFor() fields to update on postback
return View("Index", vm);
}
}
}
And finally the view-model:
namespace MultiPostDestinations.Models {
public class HomeVM {
public string ActiveTab { get; set; }
public string F1 { get; set; }
public string F2 { get; set; }
}
}

XPages save datasource - date not being saved

I have some curious behavior on an XPage. Would someone be able to shed some light on this?
In my custom control, I have the datasource defined:
<xp:this.data>
<xp:dominoDocument var="incidentDoc" formName="Incident" computeWithForm="onsave" ignoreRequestParams="true">
<xp:this.databaseName><![CDATA[#{javascript:var db = sessionScope.serverPath + "!!" + sessionScope.dbName;
return db;}]]>
</xp:this.databaseName>
</xp:dominoDocument>
</xp:this.data>
Source code for the date field follows. I'm using the eonasdan Bootstrap datepicker.
<div class="col-xs-12 col-md-3 col-lg-3">
<xp:label styleClass="text-muted" value="Date" id="label2"></xp:label>
<br></br>
<div class="form-group">
<div class='input-group date'
id='datetimepicker1'>
<xp:inputText styleClass="form-control"
readonly="true" value="#{incidentDoc.incidentDate}"
id="incidentDate">
<xp:this.attrs>
<xp:attr value="Pick a date"
name="placeholder">
</xp:attr>
</xp:this.attrs>
</xp:inputText>
<span class="input-group-addon">
<i class="zmdi zmdi-calendar"></i>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker1').datetimepicker({
format: 'MM/DD/YYYY',
pickTime: false
});
});
</script>
And the call to save the datasource is:
incidentDoc.save();
The incidentDate field in the Notes form is a text field. When I save the datasource, a document gets created with every field on the form populated except the date field.
I've tried setting it to type Date/Time on both the Notes form and the XPage (using the converter) but it does not seem to make a difference. I'm seem to be missing something basic here.
Any thoughts?
Thanks!
Update: Removing readonly="true" seems to do the trick.
Removing readonly="true" seems to do the trick.

Search box in search container

hi folks as per Search box in Search conatiner Image is here !
i just wanted to ask when the user type a name in search box then the particular field should be display.i am putting my view.jsp code is here also??
Vuew.jsp
<%#page import="com.proliferay.servicebuilder.service.BlobDemoLocalServiceUtil"%>
<%# taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%>
<%# taglib uri="http://liferay.com/tld/aui" prefix="aui"%>
<%# taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui"%>
<%#page import="javax.portlet.PortletURL"%>
<%# taglib uri="http://liferay.com/tld/portlet" prefix="liferay-portlet" %>
<%# taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %>
<%# taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>
<%# taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<liferay-theme:defineObjects />
<portlet:defineObjects />
<style>
.wrapper {
text-align: center;
}
.button {
position: absolute;
top: 20%;
}
</style>
<%
PortletURL addEmp = renderResponse.createRenderURL();
addEmp.setParameter("mvcPath", "/html/blobdemo/add.jsp");
PortletURL homeURL = renderResponse.createRenderURL();
PortletURL iteratorURL=renderResponse.createRenderURL();
iteratorURL.setParameter("mvcPath", "/html/blobdemo/display_student.jsp");
PortletURL addEmployee = renderResponse.createRenderURL();
addEmployee.setParameter("mvcPath", "html/blobdemo/add_emp.jsp");
PortletURL employeeDetailsURL = renderResponse.createRenderURL();
employeeDetailsURL.setParameter("mvcPath", "/html/empref/student_details.jsp");
PortletURL displaySearchStudent = renderResponse.createRenderURL();
displaySearchStudent.setParameter("mvcPath", "/html/blobdemo/view.jsp");
%>
Home<br/><br/>
<div class="wrapper">
<button class="btn btn-info" >Employee Referral</button>
</div>
<button class="btn btn-info">Refer an Employee</button>
<!-- <form class="form-search">
<input type="text" class="input-medium search-query" style="margin-left: 571px;margin-top:-25px;"> -->
<!-- --search button -->
<input name="<portlet:namespace/>search" type="text" style="margin-top: -42px;margin-left: 663px;"/>
<input type="submit" label="" value="search"
style=" margin-top: -40px" formaction="" name="stdForm" >
<!-- -search button ends here! -->
<liferay-ui:search-container emptyResultsMessage="There is no data to display">
<liferay-ui:search-container-results
results="<%=BlobDemoLocalServiceUtil.getBlobDemos(
searchContainer.getStart(), searchContainer.getEnd())%>"
total="<%= BlobDemoLocalServiceUtil.getBlobDemosCount() %>" />
<liferay-ui:search-container-row className="com.proliferay.servicebuilder.model.BlobDemo" modelVar="aBlobDemo">
<portlet:resourceURL var="viewURL"> <portlet:param name="dataId" value="<%=String.valueOf(aBlobDemo.getBlobId())%>" />
</portlet:resourceURL>
<liferay-ui:search-container-column-text
value="<%=String.valueOf(row.getPos() + 1)%>" name="Serial No" />
<liferay-ui:search-container-column-text property="customer" name="customer" />
<liferay-ui:search-container-column-text property="referral" name="referral ID" />
<liferay-ui:search-container-column-text property="candidateName" name="Candidate Name" />
<liferay-ui:search-container-column-text property="contactNumber" name="Contact Number" />
<liferay-ui:search-container-column-text property="qualification" name="Qualification " />
<liferay-ui:search-container-column-text property="interviewdateandtime" name="interviewdateandtime" />
<liferay-ui:search-container-column-text property="tenetavijoiningdate" name="Tenetavijoiningdate" />
<liferay-ui:search-container-column-text property="status" name="Status " />
<liferay-ui:search-container-column-text property="actualjoiningdate" name="Actualjoiningdate" />
<liferay-ui:search-container-column-text property="tanurityindays" name="Tanurityindays " />
<liferay-ui:search-container-column-jsp path="/html/blobdemo/action.jsp" align="right" />
</liferay-ui:search-container-row>
<liferay-ui:search-iterator />
</liferay-ui:search-container>
</form>
yeah itz been completd , we can write a dynamic query for this and rebuild the sevices.
steps to do this.
1:- first we have to write a dynamic query in localserviceimpl.java so that when we rebuild the services it will generate the methods in localserviceutil.java
2:- and we can call in this methods in search form search container using display terms .
3:- we can easily search using any keyvalue.
package com.data.dbservice.service.impl;
import java.util.List;
import com.data.dbservice.service.base.StudentLocalServiceBaseImpl;
import com.liferay.portal.kernel.dao.orm.DynamicQuery;
import com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil;
import com.liferay.portal.kernel.dao.orm.Junction;
import com.liferay.portal.kernel.dao.orm.Property;
import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
import com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.util.OrderByComparator;
import com.liferay.portal.kernel.util.Validator;
import com.data.dbservice.model.Student;
import com.data.dbservice.service.StudentLocalServiceUtil;
/**
* The implementation of the student local service.
*
* <p>
* All custom service methods should be put in this class. Whenever methods are added, rerun ServiceBuilder to copy their definitions into the {#link com.data.dbservice.service.StudentLocalService} interface.
*
* <p>
* This is a local service. Methods of this service will not have security checks based on the propagated JAAS credentials because this service can only be accessed from within the same VM.
* </p>
*
* #author Abhishek
* #see com.data.dbservice.service.base.StudentLocalServiceBaseImpl
* #see com.data.dbservice.service.StudentLocalServiceUtil
*/
public class StudentLocalServiceImpl extends StudentLocalServiceBaseImpl {
public List getSerachStudents(String firstName,String lastName,int studentAge,int studentGender,String studentAddress,
boolean andSearch, int start, int end, OrderByComparator orderByComparator)
throws SystemException
{
DynamicQuery dynamicQuery = buildStudentDynamicQuery(firstName, lastName, studentAge, studentGender, studentAddress, andSearch);
return StudentLocalServiceUtil.dynamicQuery(dynamicQuery, start, end, orderByComparator);
}
public int getSearchStudentsCount(String firstName,String lastName,int studentAge,int studentGender,String studentAddress,boolean andSearch)
throws SystemException
{
DynamicQuery dynamicQuery = buildStudentDynamicQuery(firstName, lastName, studentAge, studentGender, studentAddress, andSearch);
return (int)StudentLocalServiceUtil.dynamicQueryCount(dynamicQuery);
}
protected DynamicQuery buildStudentDynamicQuery(String firstName,String lastName,int studentAge,int studentGender,String studentAddress,boolean andSearch)
{
Junction junction = null;
if(andSearch)
junction = RestrictionsFactoryUtil.conjunction();
else
junction = RestrictionsFactoryUtil.disjunction();
if(Validator.isNotNull(firstName))
{
Property property = PropertyFactoryUtil.forName("firstName");
String value = (new StringBuilder("%")).append(firstName).append("%").toString();
junction.add(property.like(value));
}
if(Validator.isNotNull(lastName))
{
Property property = PropertyFactoryUtil.forName("lastName");
String value = (new StringBuilder("%")).append(lastName).append("%").toString();
junction.add(property.like(value));
}
if(studentAge > 0)
{
Property property = PropertyFactoryUtil.forName("studentAge");
junction.add(property.eq(Integer.valueOf(studentAge)));
}
if(studentGender > 0)
{
Property property = PropertyFactoryUtil.forName("studentGender");
junction.add(property.eq(Integer.valueOf(studentGender)));
}
if(Validator.isNotNull(studentAddress))
{
Property property = PropertyFactoryUtil.forName("studentAddress");
String value = (new StringBuilder("%")).append(studentAddress).append("%").toString();
junction.add(property.like(value));
}
DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(Student.class, getClassLoader());
return dynamicQuery.add(junction);
}
}

Colorpicker doesn't work

i use Liferay 6.1, I created a portlet with code (Link: http://www.liferay.com/community/wiki/-/wiki/Main/Using+Lifery+provided+Color+Picker+in+Own+Portlets)
<script type="text/javascript"> jQuery( function() { var colorPicker = new Liferay.ColorPicker( { hasImage: true } ); } ); </script>
<tr> <td> <input class="text-input" id="color" name="color" size="9" type="text" value="" />
<img align="absmiddle" alt="<liferay-ui:message key="color" />" border="0" class="use-color-picker" height="18" hspace="0" src="<%= themeDisplay.getPathThemeImages() %>/color.png" title="<liferay-ui:message key="color" />" vspace="0" width="18" style="cursor: pointer;" />
</input> </td> </tr>
but it doesn't work, please help me :)
You need to pass more options to new Liferay.ColorPicker . According to the guide you posted:
Options:
•context (Object): A DOM object which specifies the context in which
to search for the item
•hasImage: (Boolean) If set to true, it uses
the "item" param or whatever image has the .use-color-picker class as
the image
•item: (Object|String): A DOM object or a jQuery Selector
string that specifies which field to insert the selected value into
•onChange (Function): A function that will get called whenever the
color changes
•onClose (Function): A function that will get called
when the color picker is closed.

Resources