Step 1:
Download Liferay Portal Maven 6.2.1 CE.
Extract and run: ant install
Step 2:
Download liferay-plugin-maven-support 6.2.2.
Extract and run: mvn clean install
Step 3:
Create Liferay plugin in Liferay IDE with maven build type.
Add pom.xml, like below:
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.plugins</groupId>
<artifactId>test-service</artifactId>
<packaging>war</packaging>
<name>test-service Portlet</name>
<version>1.0.0-SNAPSHOT</version>
<properties>
<liferay.version>6.2.1</liferay.version>
</properties>
<build>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
com.liferay.maven.plugins
</groupId>
<artifactId>
liferay-maven-plugin
</artifactId>
<versionRange>
[6.2.1,)
</versionRange>
<goals>
<goal>build-service</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>com.liferay.maven.plugins</groupId>
<artifactId>liferay-maven-plugin</artifactId>
<version>${liferay.maven.plugin.version}</version>
<executions>
<execution>
<id>build-service</id>
<phase>generate-sources</phase>
<goals>
<goal>build-service</goal>
</goals>
</execution>
</executions>
<configuration>
<autoDeployDir>${liferay.auto.deploy.dir}</autoDeployDir>
<appServerDeployDir>${liferay.app.server.deploy.dir}</appServerDeployDir>
<appServerLibGlobalDir>${liferay.app.server.lib.global.dir}</appServerLibGlobalDir>
<appServerPortalDir>${liferay.app.server.portal.dir}</appServerPortalDir>
<liferayVersion>${liferay.version}</liferayVersion>
<pluginType>portlet</pluginType>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>UTF-8</encoding>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.liferay.portal</groupId>
<artifactId>portal-service</artifactId>
<version>${liferay.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.liferay.portal</groupId>
<artifactId>util-bridges</artifactId>
<version>${liferay.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.liferay.portal</groupId>
<artifactId>util-taglib</artifactId>
<version>${liferay.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.liferay.portal</groupId>
<artifactId>util-java</artifactId>
<version>${liferay.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.portlet</groupId>
<artifactId>portlet-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>Liferay-v6.2-CE-(Tomcat-7)</id>
<properties>
<liferay.version>6.2.1</liferay.version>
<liferay.maven.plugin.version>6.2.1</liferay.maven.plugin.version>
<liferay.auto.deploy.dir>D:\Liferay\Soft\Liferay 6.2\liferay-portal-6.2-ce-ga2\deploy</liferay.auto.deploy.dir>
<liferay.app.server.deploy.dir>D:\Liferay\Soft\Liferay 6.2\liferay-portal-6.2-ce-ga2\tomcat-7.0.42\webapps</liferay.app.server.deploy.dir>
<liferay.app.server.lib.global.dir>D:\Liferay\Soft\Liferay 6.2\liferay-portal-6.2-ce-ga2\tomcat-7.0.42\lib\ext</liferay.app.server.lib.global.dir>
<liferay.app.server.portal.dir>D:\Liferay\Soft\Liferay 6.2\liferay-portal-6.2-ce-ga2\tomcat-7.0.42\webapps\ROOT</liferay.app.server.portal.dir>
</properties>
</profile>
</profiles>
</project>
Now, you can run generate-sources to build Liferay service.
Important: Liferay IDE must fully support Maven plugin type. Should download the newest version.
Tuesday, January 27, 2015
Monday, January 19, 2015
Override session in Liferay
With the same user login in the same browser, you open up a page and working on it. This page uses session to store some data. If you open another tab, enter the same page with the previous tab and doing it, the session in new tab may override the old stored by the previous tab. So the data may be incorrect. Be careful!
WebDAV client tool to upload file to dotCMS server
Sometimes, you cannot use window's Map network drive to connect to dotCMS webDAV, CyberDuct is an alternative. Get it from: https://cyberduck.io/?l=en, window version.
After installing, open it, new a connection and specify needed value:
Type: WebDAV
Server: localhost
Port: 8080
Username: admin@dotcms.com
Password: admin
Click "More Option":
Input Path: /webdav/autopub
After installing, open it, new a connection and specify needed value:
Type: WebDAV
Server: localhost
Port: 8080
Username: admin@dotcms.com
Password: admin
Click "More Option":
Input Path: /webdav/autopub
Tuesday, January 13, 2015
Lucene search
Maven dependencies:
<dependency><groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>4.0.0</version>
</dependency>
Create IndexWriterFactory:
public enum IndexWriterFactory {WRITER;
private static IndexWriter indexWriter = null;
public IndexWriter getIndexWriter() throws IOException {
ConfigUtil systemConfig = ConfigUtil.getInstance();
String directoryConfig = systemConfig.getValue("index.directory");
FSDirectory directory = null;
boolean isLocked = new File(directoryConfig, IndexWriter.WRITE_LOCK_NAME).exists();
if (isLocked) {
return null;
}
File indexDirectory = new File(directoryConfig);
StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_40);
IndexWriterConfig indexConfig = new IndexWriterConfig(Version.LUCENE_40, analyzer);
try {
NativeFSLockFactory lock = new NativeFSLockFactory();
directory = NIOFSDirectory.open(indexDirectory, lock);
indexWriter = new IndexWriter(directory, indexConfig);
} catch (IOException e) {
e.printStackTrace();
throw (e);
}
return indexWriter;
}
public void deleteAll() throws IOException {
indexWriter.deleteAll();
indexWriter.commit();
}
public void close() throws IOException {
indexWriter.close();
}
}
Create IndexReaderFactory:
public enum IndexReaderFactory {READER;
private static IndexReader indexReader = null;
public static IndexReader getIndexReader() throws IOException {
ConfigUtil config = ConfigUtil.getInstance();
String directoryConfig = config.getValue("index.directory");
try {
File indexDirectory = new File(directoryConfig);
FSDirectory directory = FSDirectory.open(indexDirectory);
indexReader = DirectoryReader.open(directory);
} catch (IOException e) {
e.printStackTrace();
throw (e);
}
return indexReader;
}
}
Create your index implementation:
public enum IndexServiceImpl {INDEXER;
public Set<YourModel> indexItemQueue = null;
private static Logger LOGGER = LoggerFactory.getLogger(IndexAssets.class);
{
indexItemQueue = new LinkedHashSet<YourModel>();
}
public void addIndexItem(YourModel indexItem) {
indexItemQueue.add(indexItem);
}
public void addIndexItem(List<YourModel> indexItemList) {
indexItemQueue.addAll(indexItemList);
}
public synchronized String reIndex() throws Exception {
LOGGER.debug("BEGIN: index " + indexItemQueue.size());
IndexWriter indexWriter = IndexWriterFactory.WRITER.getIndexWriter();
String status = null;
int count = 0;
if (indexWriter != null) {
YourModel entry = null;
Iterator<YourModel> iterator = indexItemQueue.iterator();
try {
while (iterator.hasNext()) {
entry = iterator.next();
iterator.remove();
Document document = new Document();
Term term = null;
//add index fields to document
document.add(new StringField("field_name", entry.getValue(), Field.Store.YES));
//create term to query to check if this index is existed or not
term = new Term("field_name", entry.getValue());
//
// Query for term above
//
if(term != null){
indexWriter.updateDocument(term, document);
} else {
indexWriter.addDocument(document);
}
}
} finally {
indexWriter.close();
}
LOGGER.debug("END: index " + count + " records");
status = "INDEX_FINISHED";
return status;
} else {
status = "INDEX_UNFINISHED";
return status;
}
}
public synchronized void reIndexAll() throws Exception {
//delete all index data first
IndexAssets.INDEXER.deleteAll();
//checkout if deleting process done, every 5s
try {
IndexReader reader = IndexAssets.getIndexReader();
int numOfDoc = reader.numDocs();
while (0 != numOfDoc) {
Thread.sleep(5000);
numOfDoc = reader.numDocs();
}
} catch (InterruptedException e) {
LOGGER.error("There is an exeception when deleting all old index items. Cause:" + e.getMessage());
} catch (Exception e) {
LOGGER.error("There is an exeception when deleting all old index items. Cause:" + e.getMessage());
}
List<YourModel> list = new ArrayList<YourModel>();
list.addAll(/*your data here*/);
LOGGER.info("INDEXING: " + list.size() + " records");
IndexAssets.INDEXER.addIndexItem(list);
IndexAssets.INDEXER.index();
}
public String deleteAll() throws Exception {
String status = null;
indexItemQueue.clear();
IndexWriter indexWriter = IndexWriterFactory.WRITER.getIndexWriter();
if (indexWriter != null) {
IndexWriterFactory.WRITER.deleteAll();
indexWriter.close();
status = "INDEX_FINISHED";
return status;
} else {
status = "INDEX_UNFINISHED";
return status;
}
}
}
Search in index:
public List<String[]> search(String keyword, int pageNum, boolean isSearchExactKeyword) {ConfigUtil config = ConfigUtil.getInstance();
String numberOfProgramPerPageStr = config.getValue("search.numberOfProgramPerPage");
int numberOfProgramPerPage = Integer.parseInt(numberOfProgramPerPageStr);
String directoryStr = config.getValue("index.directory");
// get from config
int from = (pageNum - 1) * numberOfProgramPerPage;
List<String[]> results = new ArrayList<String[]>();
//escape special characters
keyword = keyword.replaceAll("/^\\s+|\\s$/g", " ").toLowerCase();
String[] keywords_Array = keyword.split(" ");
Set<String> stopwordsSet = new HashSet<String>();
//remove out the stopword from the keyword
Iterator iter = StandardAnalyzer.STOP_WORDS_SET.iterator();
while (iter.hasNext()) {
char[] stopWord = (char[]) iter.next();
stopwordsSet.add(new String(stopWord));
}
String[] stopwordsArray = new String[stopwordsSet.size()];
stopwordsSet.toArray(stopwordsArray);
BooleanQuery bq = new BooleanQuery();
boolean isStopword = false;
for (String key : keywords_Array) {
isStopword = false;
for (String stopword : stopwordsArray) {
if (key.toLowerCase().equals(stopword)) {
isStopword = true;
break;
}
}
if (!isStopword) {
Query query = new TermQuery(new Term("field_name", key));
if (isSearchExactKeyword == true) {
bq.add(query, BooleanClause.Occur.MUST);
} else {// for program search
bq.add(query, BooleanClause.Occur.SHOULD);
}
}
}
try {
IndexReader reader = IndexReaderFactory.INDEXREADER.getIndexReader();
IndexSearcher searcher = new IndexSearcher(reader);
TotalHitCountCollector collectorCount = new TotalHitCountCollector();
searcher.search(bq, collectorCount);
int count = collectorCount.getTotalHits();
if (count <= 0) {
LOGGER.debug("No Result");
return results;
}
TopFieldCollector collector = TopFieldCollector.create(Sort.RELEVANCE, count, true, false, false, true);
searcher.search(bq, collector);
ScoreDoc[] hits = new ScoreDoc[0];
if (pageNum == -1) {
hits = collector.topDocs().scoreDocs;
} else {
hits = collector.topDocs(from, numberOfProgramPerPage).scoreDocs;
// If found nothing, return search from page 0;
if (hits.length <= 0) {
from = 0;
hits = collector.topDocs(from, numberOfProgramPerPage).scoreDocs;
}
}
int sequenceNum= 0;
String sequenceNumString = "";
for (int i = 0; i < hits.length; i++) {
int docId = hits[i].doc;
Document doc = null;
try {
doc = searcher.doc(docId);
} catch (IOException e) {
e.printStackTrace();
}
//get out the data from document
String fieldData_1 = doc.get("field_name1");
String fieldData_2 = doc.get("field_name2");
sequenceNum++;
sequenceNumString = String.valueOf(sequenceNum);
results.add(new String[] { fieldData_1, fieldData_2, sequenceNumString });
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
return results;
}
Deeper understand of Enum in Java
Reference:
http://howtodoinjava.com/2012/12/07/guide-for-understanding-enum-in-java/
Enumerations (in general) are generally a set of related constants. Each constant represents a specific instance of its Enumerations class. For example:
public
enum
DIRECTION {
EAST,
WEST,
NORTH,
SOUTH
//optionally can end with ";"
}
Here EAST, WEST, NORTH and SOUTH are final static inner classes of Direction of type Direction extends java.lang.Enum.
Enums are comparable and serializable implicitly. Also, all enum types in java are singleton by default. So, you can compare enum types using ‘==’ operator.
You can give define your own constructors to initialize the state of enum types.enum
Direction {
// Enum types
EAST(
0
), WEST(
180
), NORTH(
90
), SOUTH(
270
);
// Constructor
private
Direction(
final
int
angle) {
this
.angle = angle;
}
// Internal state
private
int
angle;
public
int
getAngle() {
return
angle;
}
}
Use template methods in enum:
package
enumTest;
public
enum
Direction {
// Enum types
EAST(
0
) {
<strong>
@Override
</strong>
public
void
shout() {
System.out.println(
"Direction is East !!!"
);
}
},
WEST(
180
) {
@Override
public
void
shout() {
System.out.println(
"Direction is West !!!"
);
}
},
NORTH(
90
) {
@Override
public
void
shout() {
System.out.println(
"Direction is North !!!"
);
}
},
SOUTH(
270
) {
@Override
public
void
shout() {
System.out.println(
"Direction is South !!!"
);
}
};
// Constructor
private
Direction(
final
int
angle) {
this
.angle = angle;
}
// Internal state
private
int
angle;
public
int
getAngle() {
return
angle;
}
<strong>
// Abstract method which need to be implemented</strong>
public
abstract
void
shout();
}
Monday, January 12, 2015
DateTime plicker
1. Introduction
Alloy UI has
been supporting DatePicker widget but it does not have ability to choose time.
That’s why we need to find another widget that meets our requirement. The timepicker addon adds a timepicker to
jQuery UI Datepicker, thus the datepicker and slider components (jQueryUI) are
required for using any of these. In addition all datepicker options are still
available through the timepicker addon
2. Usage.
2.1. Option
The timepicker does inherit all options from datepicker.
However, there are many options that are shared by them both, and many
timepicker only options.
2.1.1. Localization Options
currentText
|
Default: "Now", A Localization Setting - Text for the Now
button.
|
closeText
|
Default: "Done", A Localization Setting - Text for the Close
button.
|
amNames
|
Default: ['AM', 'A'], A Localization Setting - Array of strings to try
and parse against to determine AM.
|
pmNames
|
Default: ['PM', 'P'], A Localization Setting - Array of strings to
try and parse against to determine PM.
|
timeFormat
|
Default: "HH:mm", A Localization Setting - String of format
tokens to be replaced with the time.See Formatting.
|
timeSuffix
|
Default: "", A Localization Setting - String to place after
the formatted time.
|
|
|
timeOnlyTitle
|
Default: "Choose Time", A Localization Setting - Title of the wigit
when using only timepicker.
|
timeText
|
Default: "Time", A Localization Setting - Label used within
timepicker for the formatted time.
|
hourText
|
Default: "Hour", A Localization Setting - Label used to identify
the hour slider.
|
minuteText
|
Default: "Minute", A Localization Setting - Label used to identify
the minute slider.
|
secondText
|
Default: "Second", A Localization Setting - Label used to identify
the second slider.
|
millisecText
|
Default: "Millisecond", A Localization Setting - Label used to identify
the millisecond slider.
|
microsecText
|
Default: "Microsecond", A Localization Setting - Label used to identify
the microsecond slider.
|
timezoneText
|
Default: "Timezone", A Localization Setting - Label used to identify
the timezone slider.
|
isRTL
|
Default: false, A Localization Setting - Right to Left support.
|
2.1.2. Alt Field Options
altFieldTimeOnly
|
Default: true -
When altField is used from datepicker altField will only receive the
formatted time and the original field only receives date.
|
altSeparator
|
Default: (separator option) - String placed between
formatted date and formatted time in the altField.
|
altTimeSuffix
|
Default: (timeSuffix option) - String always placed
after the formatted time in the altField.
|
altTimeFormat
|
Default: (timeFormat option) - The time format to use
with the altField.
|
2.1.3. Timezone Options
timezoneList
|
Default: [generated timezones] - An array of timezones
used to populate the timezone select. Can be an array of values or an array
of objects: { label: "EDT", value: -240 }. The value should be the
offset number in minutes. So "-0400" which is the format
"-hhmm", would equate to -240 minutes.
|
2.1.4. Time Field Options.
controlType |
Default: 'slider' - Whether to use 'slider' or 'select'. If 'slider' is unavailable through jQueryUI, 'select' will be used. For advanced usage you may pass an object which implements "create", "options", "value" methods to use controls other than sliders or selects. See the _controls property in the source code for more details. |
showHour |
Default: null - Whether to show the hour control. The default of null will use detection from timeFormat. |
showMinute |
Default: null - Whether to show the minute control. The default of null will use detection from timeFormat. |
showSecond |
Default: null - Whether to show the second control. The default of null will use detection from timeFormat. |
showMillisec |
Default: null - Whether to show the millisecond control. The default of null will use detection from timeFormat. |
showMicrosec |
Default: null - Whether to show the microsecond control. The default of null will use detection from timeFormat. |
showTimezone |
Default: null - Whether to show the timezone select. |
showTime |
Default: true - Whether to show the time selected within the datetimepicker. |
stepHour |
Default: 1 - Hours per step the slider makes. |
stepMinute |
Default: 1 - Minutes per step the slider makes. |
stepSecond |
Default: 1 - Seconds per step the slider makes. |
stepMillisec |
Default: 1 - Milliseconds per step the slider makes. |
stepMicrosec |
Default: 1 - Microseconds per step the slider makes. |
hour |
Default: 0 - Initial hour set. |
minute |
Default: 0 - Initial minute set. |
second |
Default: 0 - Initial second set. |
millisec |
Default: 0 - Initial millisecond set. |
microsec |
|
timezone |
Default: null - Initial timezone set. This is the offset in minutes. If null the browser's local timezone will be used. If you're timezone is "-0400" you would use -240. For backwards compatibility you may pass "-0400", however the timezone is stored in minutes and more reliable. |
hourMin |
Default: 0 - The minimum hour allowed for all dates. |
minuteMin |
Default: 0 - The minimum minute allowed for all dates. |
secondMin |
Default: 0 - The minimum second allowed for all dates. |
millisecMin |
Default: 0 - The minimum millisecond allowed for all dates. |
microsecMin |
Default: 0 - The minimum microsecond allowed for all dates. |
hourMax |
Default: 23 - The maximum hour allowed for all dates. |
minuteMax |
Default: 59 - The maximum minute allowed for all dates. |
secondMax |
Default: 59 - The maximum second allowed for all dates. |
millisecMax |
Default: 999 - The maximum millisecond allowed for all dates. |
microsecMax |
Default: 999 - The maximum microsecond allowed for all dates. |
hourGrid |
Default: 0 - When greater than 0 a label grid will be generated under the slider. This number represents the units (in hours) between labels. |
minuteGrid |
Default: 0 - When greater than 0 a label grid will be generated under the slider. This number represents the units (in minutes) between labels. |
secondGrid |
Default: 0 - When greater than 0 a label grid will be genereated under the slider. This number represents the units (in seconds) between labels. |
millisecGrid |
Default: 0 - When greater than 0 a label grid will be genereated under the slider. This number represents the units (in milliseconds) between labels. |
microsecGrid |
Default: 0 - When greater than 0 a label grid will be genereated under the slider. This number represents the units (in microseconds) between labels. |
2.1.5. Other Options
showButtonPanel |
Default: true - Whether to show the button panel at the bottom. This is generally needed. |
timeOnly |
Default: false - Hide the datepicker and only provide a time interface |
onSelect |
Default: null - Function to be called when a date is chosen or time has changed (parameters: datetimeText, datepickerInstance). |
alwaysSetTime |
Default: true - Always have a time set internally, even before user has chosen one. |
separator |
Default: " " - When formatting the time this string is placed between the formatted date and formatted time. |
2.2. Formatting .
The default format is "HH:mm". To use 12 hour time
use something similar to: "hh:mm tt". When both "t" and
lower case "h" are present in the timeFormat, 12 hour time will be
used.
H
|
Hour with no leading 0 (24 hour)
|
HH
|
Hour with leading 0 (24 hour)
|
h
|
Hour with no leading 0 (12 hour)
|
hh
|
Hour with leading 0 (12 hour)
|
m
|
Minute with no leading 0
|
mm
|
Minute with leading 0
|
s
|
Second with no leading 0
|
ss
|
Second with leading 0
|
l
|
Milliseconds always with leading 0
|
c
|
Microseconds always with leading 0
|
t
|
a or p for AM/PM
|
T
|
A or P for AM/PM
|
tt
|
am or pm for AM/PM
|
TT
|
AM or PM for AM/PM
|
z
|
Timezone as defined by timezoneList
|
Z
|
Timezone in Iso 8601 format (+04:45)
|
3. Example
3.1. Basic Initializations
Add a simple datetimepicker to jQuery UI's datepicker
$('#basic_example_1').datetimepicker();
|
Add only a timepicker:
$('#basic_example_2').timepicker();
|
Format the time:
$('#basic_example_3').datetimepicker({
timeFormat: "hh:mm tt"
});
|
3.2. Using Timezones
Simplest timezone usage:
$('#timezone_example_1').datetimepicker({
timeFormat: 'hh:mm tt z'
});
|
Define your own timezone options:
$('#timezone_example_2').datetimepicker({
timeFormat: 'HH:mm z',
timezoneList: [
{ value: -300, label: 'Eastern'},
{ value: -360, label: 'Central' },
{ value: -420, label: 'Mountain' },
{ value: -480, label: 'Pacific' }
]
});
|
You may also use timezone string abbreviations for values.
This should be used with caution. Computing accurate javascript Date objects
may not be possible when trying to retrieve or set the date from timepicker
(see setDate and getDate examples below). For simple input values however this
should work.
$('#timezone_example_3').datetimepicker({
timeFormat: 'HH:mm z',
timezone: 'MT',
timezoneList: [
{ value: 'ET', label: 'Eastern'},
{ value: 'CT', label: 'Central' },
{ value: 'MT', label: 'Mountain' },
{ value: 'PT', label: 'Pacific' }
]
});
|
3.2. Slider Modifications
Add a grid to each slider:
$('#slider_example_1').timepicker({
hourGrid: 4,
minuteGrid: 10,
timeFormat: 'hh:mm tt'
});
|
Set the interval step of sliders:
$('#slider_example_2').datetimepicker({
timeFormat: 'HH:mm:ss',
stepHour: 2,
stepMinute: 10,
stepSecond: 10
});
|
Add sliderAccess plugin for touch devices
$('#slider_example_3').datetimepicker({
addSliderAccess: true,
sliderAccessArgs: { touchonly: false }
});
|
Use dropdowns instead of sliders. By default if slider is
not available dropdowns will be used.
$('#slider_example_4').datetimepicker({
controlType: 'select',
timeFormat: 'hh:mm tt'
});
|
Subscribe to:
Posts (Atom)