Sunday, March 31, 2013

ZK Pivottable: Get Distinct Values of Field


Introduction

This article how to get the distinct values of a row or column field when you click on it.

Pre-request

ZK Pivottable: Display Data in ZK Pivottable
http://ben-bai.blogspot.tw/2012/07/zk-pivottable-display-data-in-zk.html

ZK Basic MVC Pattern with SelectorComposer
http://ben-bai.blogspot.tw/2012/10/zk-basic-mvc-pattern-with_31.html

The Program

index.zul

A pivottable, a label that will show the info of clicked row/column field, a listbox that will show the distinct values of clicked row/column field

<zk>
    <!-- Tested with ZK 6.0.2 EE and ZK Pivottable 2.0.0 -->
    <!-- window, apply a SelectorComposer -->
    <window id="win" xmlns:w="client"
        apply="test.TestComposer">
        <!-- pivottable, get model from window's composer -->
        <pivottable id="pivottable" model="${win$composer.pivotModel}" />
        <!-- label, show info of clicked row or column field -->
        <div style="margin: 15px;">
            <div>
                clicked field: <label id="lb" />
            </div>
            <!-- listbox, show all distinct values of clicked row or column field -->
            values<listbox id="lbx" />
        </div>
    </window>
</zk>


TestComposer.java

Listen to onPivotPopup event (will be fired when clicking on row/column/data cell), update field info and values list as needed.

package test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.zkoss.pivot.event.PivotUIEvent;
import org.zkoss.pivot.impl.TabularPivotField;
import org.zkoss.pivot.impl.TabularPivotModel;
import org.zkoss.zk.ui.select.SelectorComposer;
import org.zkoss.zk.ui.select.annotation.Listen;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zul.Label;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listcell;
import org.zkoss.zul.Listitem;

/**
 * Tested with ZK 6.0.2 EE and ZK Pivottable 2.0.0
 *
 * @author benbai123
 */
@SuppressWarnings("rawtypes")
public class TestComposer extends SelectorComposer {

    private static final long serialVersionUID = -8249566421884806620L;

    @Wire
    Label lb; /** label, contains type and name of clicked row or column */
    @Wire
    Listbox lbx; /** listbox, contains distinct values of clicked row or column field */
    /** pivot model with the 'whole' raw data */
    private TabularPivotModel _pivotModel;
    /** model provider, provide the columns, raw data and pivot model */
    private PivotModelProvider _modelProvider = new PivotModelProvider();

    /**
     * map that contains all field index
     * use field name as the keys
     */
    private Map<String, Integer> _indexMap = new HashMap<String, Integer>();

    /**
     * Get pivottable's model
     * @return TabularPivotModel the pivottable's model
     * @throws Exception
     */
    public TabularPivotModel getPivotModel () throws Exception {
        if (_pivotModel == null) {
            _pivotModel = _modelProvider.getPivotModel();
        }
        return _pivotModel;
    }

    /**
     * update the value list and label if clicked on row or column field
     * @param e
     * @throws Exception 
     */
    @Listen("onPivotPopup = #pivottable")
    public void updateValueList (PivotUIEvent e) throws Exception {
        TabularPivotField field = getClickedField(e);
        if (field != null) {
            updateValueList(field);
        } else {
            lb.setValue("");
            lbx.getChildren().clear();
        }
    }
    /**
     * get the clicked row or column field
     * @param e
     */
    private TabularPivotField getClickedField (PivotUIEvent e) {
        TabularPivotField field = null;
        if (e != null
            && (e.getRowContext() == null
                || e.getColumnContext() == null)) {
            // not clicked on data field

            if (e.getRowContext() != null) {
                // clicked on row field
                field = _pivotModel.getRowFields()[e.getRowContext().getNode().getDepth() - 1];
            } else {
                // clicked on column field
                field = _pivotModel.getColumnFields()[e.getColumnContext().getNode().getDepth() - 1];
            }
        }
        return field;
    }
    /**
     * create the value list of clicked row/column field
     * @param field pivot field, used to get fieldName
     * @throws Exception 
     */
    @SuppressWarnings({ "unchecked" })
    private void updateValueList (TabularPivotField field) throws Exception {
        // clear old children
        lbx.getChildren().clear();

        List<String> columns = _modelProvider.getColumns();
        // index of field name in columns
        int index = getFieldIndex(columns, field.getFieldName());
        // raw data of pivot model
        Iterable<List<Object>> rawData = (Iterable<List<Object>>)getPivotModel().getRawData();
        // distinct values of the given field
        List<Object> distinctValues = getDistinctValues(rawData, columns, index);

        // create listitem for each value
        for (final Object value : distinctValues) {
            Listitem li = new Listitem();
            Listcell lc = new Listcell(value.toString());

            lc.setParent(li);
            li.setParent(lbx);
        }
        // update field info label
        lb.setValue("field type: " + field.getType() + ", field name: " + field.getFieldName());
    }
    /**
     * get all different values of a field
     * @param rawData the raw data to get different values from
     * @param columns all columns in pivot model
     * @param index the index to get value from list
     * @return
     */
    @SuppressWarnings({ "unchecked" })
    private static List getDistinctValues (Iterable<List<Object>> rawData, List<String> columns, int index) {
        // set used to hold distinct values
        Set s = new HashSet();
        // result list
        List result = new ArrayList();

        if (index == -1) return result;
        // add all value to set directly
        for (List<Object> data : rawData) {
            s.add(data.get(index));
        }
        // copy to list then sort the list
        for (Object o : s) {
            result.add(o);
        }
        Collections.sort(result);
        return result;
    }
    /**
     * get the index in raw data of a field
     * @param columns columns used in pivot model
     * @param fieldName name of the field to search index
     * @return int the found index
     */
    private int getFieldIndex (List<String> columns, String fieldName) {
        // search it from index map at first
        if (_indexMap.containsKey(fieldName)) {
            return _indexMap.get(fieldName);
        } else { // not found
            int index = -1;
            // search field name in columns
            for (int i = 0; i < columns.size(); i++) {
                if (columns.get(i).equals(fieldName)) {
                    index = i;
                    break;
                }
            }
            // store it to index map
            _indexMap.put(fieldName, index);
            return index;
        }
    }
}


PivotModelProvider.java

Simply provide pivot model.

package test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

import org.zkoss.pivot.PivotField;
import org.zkoss.pivot.impl.TabularPivotModel;

public class PivotModelProvider {
    /** pivot model with the 'whole' raw data */
    private TabularPivotModel _pivotModel;
    /**
     * Get pivottable's model
     * @return TabularPivotModel the pivottable's model
     * @throws Exception
     */
    public TabularPivotModel getPivotModel () {
        if (_pivotModel == null) {
            _pivotModel = new TabularPivotModel(getData(), getColumns());

            // assign rows, the order matches to the level of row node field
            _pivotModel.setFieldType("Row_Level_001", PivotField.Type.ROW);
            _pivotModel.setFieldType("Row_Level_002", PivotField.Type.ROW);
            _pivotModel.setFieldType("Row_Level_003", PivotField.Type.ROW);
            _pivotModel.setFieldType("Row_Level_004", PivotField.Type.ROW);

            // assign columns, the order matches to the level of column node field
            _pivotModel.setFieldType("Column_Level_001", PivotField.Type.COLUMN);
            _pivotModel.setFieldType("Column_Level_002", PivotField.Type.COLUMN);

            // assign datas, the order matches to the order of data field
            _pivotModel.setFieldType("Data_Field_001", PivotField.Type.DATA);
            _pivotModel.setFieldType("Data_Field_002", PivotField.Type.DATA);
            _pivotModel.setFieldType("Data_Field_003", PivotField.Type.DATA);
        }
        return _pivotModel;
    }
    /**
     * prepare the data for pivottable's model
     * The order of object put into data list matches
     * the order of column names
     * @return
     * @throws Exception
     */
    public List<List<Object>> getData() {
        List<List<Object>> result = new ArrayList<List<Object>>();
        Random r = new Random();

        for (int i = 0; i < 100; i++) {
            List<Object> data = new ArrayList<Object>();
            data.add("Row_Level_001 - " + (r.nextInt(5) + 1));
            data.add("Row_Level_002 - " + (r.nextInt(5) + 1));
            data.add("Row_Level_003 - " + (r.nextInt(5) + 1));
            data.add("Row_Level_004 - " + (r.nextInt(5) + 1));
            data.add("Column_Level_001 - " + (r.nextInt(5) + 1));
            data.add("Column_Level_002 - " + (r.nextInt(5) + 1));
            data.add(r.nextInt(10000));
            data.add(r.nextDouble() * 10000.0);
            data.add(r.nextInt(100));
            result.add(data);
        }
        return result;
    }
    /**
     * prepare columns name for pivottable's model
     * @return
     */
    public List<String> getColumns() {
        return Arrays.asList(new String[]{
                "Row_Level_001", "Row_Level_002", "Row_Level_003", "Row_Level_004",
                "Column_Level_001", "Column_Level_002",
                "Data_Field_001", "Data_Field_002", "Data_Field_003"
        });
    }
}


The Result

View demo on line
http://screencast.com/t/q9fvH9M23ZJ

Reference

Start point of APIs
http://www.zkoss.org/javadoc/latest/zkpvt/org/zkoss/pivot/impl/TabularPivotModel.html

Download

Full project at github
https://github.com/benbai123/ZK_Practice/tree/master/Components/projects/Addon_Practice/PivottableTest/GetDistinctFieldValue

Demo Flash
https://github.com/benbai123/ZK_Practice/blob/master/Components/demos/addon/pvt_get_distinct_values_of_field.swf

Thursday, March 21, 2013

C String: startsWith, endsWith, indexOf, lastIndexOf in ANSI C


Introduction

This article describe how to implement several function with respect to the index of string, including startsWith, endsWith, indexOf, indexOf with a shift and lastIndexOf.

The Program

startsWith_endsWith_indexOf_lastIndexOf.c

#include <stdio.h>
#include <string.h>
#include <stdbool.h>
/**
 * 
 * Tested with Dev-C++ 4.9.9.2
 *  
 * Practice of string compare.
 *
 * char * strstr ( const char *, const char * ); 
 *            Locate substring
 *            Returns a pointer to the first occurrence of str2 in str1,
 *            or a null pointer if str2 is not part of str1.
 * bool startsWith (char* base, char* str);
 *            Custom function for detecting whether base is starts with str
 * bool endsWith (char* base, char* str);
 *            Custom function for detecting whether base is ends with str
 * int indexOf (char* base, char* str)
 *            Custom function for getting the first index of str in base
 *            -1 denotes not found
 * int indexOf_shift (char* base, char* str, int startIndex)
 *            Custom function for getting the first index of str in base
 *            after the given startIndex
 *            -1 denotes not found
 * int lastIndexOf (char* base, char* str)
 *            Custom function for getting the last index of str in base
 *            -1 denotes not found
 * References: 
 *        http://www.cplusplus.com/reference/cstring/strstr/
 * 
 */

bool startsWith (char* base, char* str);
bool endsWith (char* base, char* str);
int indexOf (char* base, char* str);
int indexOf_shift (char* base, char* str, int startIndex);
int lastIndexOf (char* base, char* str);
int main () {
    // a char array without '\0'
    char* chArrOne = "abcdefabcdef";

    printf("chArrOne starts with abc?\n%s\n\n", startsWith(chArrOne, "abc")? "true" : "false");
    printf("chArrOne starts with def?\n%s\n\n", startsWith(chArrOne, "def")? "true" : "false");
    printf("chArrOne ends with def?\n%s\n\n", endsWith(chArrOne, "def")? "true" : "false");
    printf("first index of abc in chArrOne?\n%d\n\n", indexOf(chArrOne, "abc"));
    printf("first index of def in chArrOne?\n%d\n\n", indexOf(chArrOne, "def"));
    printf("first index of abc in chArrOne after index 2?\n%d\n\n", indexOf_shift(chArrOne, "abc", 2));
    printf("first index of def in chArrOne after index 5?\n%d\n\n", indexOf_shift(chArrOne, "def", 5));
    printf("last index of abc in chArrOne?\n%d\n\n", lastIndexOf(chArrOne, "abc"));
    printf("last index of def in chArrOne?\n%d\n\n", lastIndexOf(chArrOne, "def"));
    

    system("PAUSE");
    return 0;
}
/** detecting whether base is starts with str
 */
bool startsWith (char* base, char* str) {
    return (strstr(base, str) - base) == 0;
}
/** detecting whether base is ends with str
 */
bool endsWith (char* base, char* str) {
    int blen = strlen(base);
    int slen = strlen(str);
    return (blen >= slen) && (0 == strcmp(base + blen - slen, str));
}
/** getting the first index of str in base
 */
int indexOf (char* base, char* str) {
    return indexOf_shift(base, str, 0);
}
int indexOf_shift (char* base, char* str, int startIndex) {
    int result;
    int baselen = strlen(base);
    // str should not longer than base
    if (strlen(str) > baselen || startIndex > baselen) {
        result = -1;
    } else {
        if (startIndex < 0 ) {
            startIndex = 0;
        }
        char* pos = strstr(base+startIndex, str);
        if (pos == NULL) {
            result = -1;
        } else {
            result = pos - base;
        }
    }
    return result;
}
/** use two index to search in two part to prevent the worst case
 * (assume search 'aaa' in 'aaaaaaaa', you cannot skip three char each time)
 */
int lastIndexOf (char* base, char* str) {
    int result;
    // str should not longer than base
    if (strlen(str) > strlen(base)) {
        result = -1;
    } else {
        int start = 0;
        int endinit = strlen(base) - strlen(str);
        int end = endinit;
        int endtmp = endinit;
        while(start != end) {
            start = indexOf_shift(base, str, start);
            end = indexOf_shift(base, str, end);

            // not found from start
            if (start == -1) {
                end = -1; // then break;
            } else if (end == -1) {
                // found from start
                // but not found from end
                // move end to middle
                if (endtmp == (start+1)) {
                    end = start; // then break;
                } else {
                    end = endtmp - (endtmp - start) / 2;
                    if (end <= start) {
                        end = start+1;
                    }
                    endtmp = end;
                }
            } else {
                // found from both start and end
                // move start to end and
                // move end to base - strlen(str)
                start = end;
                end = endinit;
            }
        }
        result = start;
    }
    return result;
}


The Result



Reference

strstr
http://www.cplusplus.com/reference/cstring/strstr/

Download

startsWith_endsWith_indexOf_lastIndexOf.c at github
https://github.com/benbai123/C_Cplusplus_Practice/blob/master/C_StringProcessing/utils/startsWith_endsWith_indexOf_lastIndexOf.c

Monday, March 18, 2013

C String: String Compare (Simple Note)


Simple Note

Code

#include <stdio.h>
#include <string.h>
/**
 * 
 * Tested with Dev-C++ 4.9.9.2
 *  
 * Practice of string compare.
 *
 * int strcmp ( const char * str1, const char * str2 );
 *             Compares the C string str1 to the C string str2.
 *             Returns an integral value indicating the relationship between the strings:
 *             A zero value indicates that both strings are equal.
 *             A value greater than zero indicates that the first character that does
 *             not match has a greater value in str1 than in str2; And a value less than zero
 *             indicates the opposite.
 * size_t strspn ( const char * str1, const char * str2 );
 *            Returns the length of the initial portion of str1 which consists only of characters that are part of str2.
 *            The length of the initial portion of str1 containing only characters that appear in str2.
 *            Therefore, if all of the characters in str1 are in str2,
 *            the function returns the length of the entire str1 string,
 *            if the first character in str1 is not in str2,
 *            the function returns zero.
 *             size_t is an unsigned integral type.
 *
 * References: 
 *         http://www.cplusplus.com/reference/cstring/strcmp/
 *        http://www.cplusplus.com/reference/cstring/strspn/
 * 
 */
int main () {
    // string
    char* chPtr = "abcdwxyz";
    int len;

    /** Compare whether two strings are
     * equal, grater than or less than
     */
    printf("chPtr equals to 'abcdwxyz'? \n%s\n", (strcmp(chPtr, "abcdwxyz") == 0? "true" : "false"));
    printf("chPtr larger than 'abcd'? \n%s\n", (strcmp(chPtr, "abcd") > 0? "true" : "false"));
    printf("chPtr less than or equal to 'abcd'? \n%s\n\n", (strcmp(chPtr, "abcd") <= 0? "true" : "false"));

    /** Use strspn to compare and find the different position
     *
     */
    len = strspn(chPtr, "abcdwxyz");
    printf("Are chPtr and 'abcdwxyz' equal? \n%s\n", (len == strlen(chPtr)? "true" : "false"));
    len = strspn(chPtr, "abcd");
    printf("Are chPtr and 'abcd' equal? \n%s\n", (len == strlen(chPtr)? "true" : "false"));
    printf("What is the first index (start from 0) that 'abcd' different with chPtr? \n%d\n\n", len);

    system("PAUSE");
    return 0;
}


Result



References

strcmp
http://www.cplusplus.com/reference/cstring/strcmp/

strspn
http://www.cplusplus.com/reference/cstring/strspn/

Download

Source code at github
https://github.com/benbai123/C_Cplusplus_Practice/blob/master/C_StringProcessing/string_compare.c

C String: String Search (Simple Note)


Simple Note

Code

#include <stdio.h>
#include <string.h>
/**
 * 
 * Tested with Dev-C++ 4.9.9.2
 *  
 * Practice of string compare.
 *
 * char * strstr ( const char *, const char * ); 
 *            Locate substring
 *            Returns a pointer to the first occurrence of str2 in str1,
 *            or a null pointer if str2 is not part of str1.
 *
 * References: 
 *        http://www.cplusplus.com/reference/cstring/strstr/
 * 
 */

int main () {
    // string
    char* chPtr = "abcdwxyz";
    char* pos;

    /** Search a string within chPtr
     *
     */
    // memory address
    pos = strstr(chPtr, "cd");
    printf("Is 'cd' in chPtr? \n%s\n", (pos != NULL? "true" : "false"));
    // start index is pos - chPtr
    if (pos != NULL) {
        printf("What is the first start index (start from 0) of 'cd' in chPtr? \n%d\n\n", (pos - chPtr));
    }

    printf("abcd starts from \n%d\n", strstr(chPtr, "abcd") - chPtr);
    printf("abcd starts from \n%d\n\n", strstr(chPtr, "wxyz") - chPtr);

    system("PAUSE");
    return 0;
}


Result



References

strstr
http://www.cplusplus.com/reference/cstring/strstr/

Download

Source code at github
https://github.com/benbai123/C_Cplusplus_Practice/blob/master/C_StringProcessing/string_search.c

Sunday, March 17, 2013

C String: substring Function for ANSI C


Introduction

This article describe how to create a function that get a sub string from source string by start index and end index (similar to Java's String.substring) in ANSI C.

The Program

substring.c

A custom substring function and test program in this file.

#include <stdio.h>
#include <string.h>
/**
 * 
 * Tested with Dev-C++ 4.9.9.2
 *  
 * Practice of string copy and concat.
 *
 * char * strncpy ( char * destination, const char * source, size_t num );
 *         copy first n (the specified num) char
 *         from source to destination
 * void* malloc (size_t size);
 *         Allocate memory block
 *         Allocates a block of size bytes of memory,
 *         returning a pointer to the beginning of the block.
 *         
 *         The content of the newly allocated block of memory is not initialized,
 *         remaining with indeterminate values.
 *         
 *         If size is zero, the return value depends on the particular
 *         library implementation (it may or may not be a null pointer),
 *         but the returned pointer shall not be dereferenced.
 * void free (void* ptr);
 *         A block of memory previously allocated by a call to malloc,
 *         calloc or realloc is deallocated,
 *         making it available again for further allocations.
 *         
 *         If ptr does not point to a block of memory allocated with the
 *         above functions, it causes undefined behavior.
 *         
 *         If ptr is a null pointer, the function does nothing.
 *         Notice that this function does not change the value of ptr itself,
 *         hence it still points to the same (now invalid) location.
 * void * memset ( void * ptr, int value, size_t num );
 *         Fill block of memory
 *         Sets the first num bytes of the block of memory pointed by ptr to
 *         the specified value (interpreted as an unsigned char).
 * 
 * char * substring ( const char * source, int startIndex, int endIndex );
 *         custom function for getting a substring of source string
 *         source: the source string
 *         startIndex: start index (inclusive) of sub string in source string
 *         endIndex: end index (exclusive) of sub string in source string
 *         return: pointer of the sub string, or null if any error occured
 *
 *         NOTE: substring will return malloced pointer,
 *               remember to free it as needed.
 *
 * References:
 * http://www.cplusplus.com/reference/cstring/strncpy/
 * http://www.cplusplus.com/reference/cstdlib/malloc/
 * http://www.cplusplus.com/reference/cstdlib/free/
 * http://www.cplusplus.com/reference/cstring/memset/
 * 
 */
char * substring ( const char * source, int startIndex, int endIndex );
int main () {
    char* chArr = "this is substring";

    // test negitive startIndex
    char* subString = substring(chArr, -1, 8);
    printf("%s\n\n", subString);
    free(subString);

    // test endIndex smaller than or equal to startIndex
    subString = substring(chArr, 17, 8);
    printf("%s\n\n", subString);
    free(subString);

    subString = substring(chArr, 8, 8);
    printf("%s\n\n", subString);
    free(subString);

    // test startIndex out of bound
    subString = substring(chArr, 177, 178);
    printf("%s\n\n", subString);
    free(subString);

    // test endIndex out of bound
    subString = substring(chArr, 17, 178);
    printf("%s\n\n", subString);
    free(subString);

    // get sub string and show it
    subString = substring(chArr, 0, 1);
    printf("%s\n\n", subString);
    free(subString);

    subString = substring(chArr, strlen(chArr)-1, strlen(chArr));
    printf("%s\n\n", subString);
    free(subString);

    subString = substring(chArr, 8, 17);
    printf("%s\n\n", subString);
    free(subString);

    subString = substring(chArr, 14, 17);
    printf("%s\n\n", subString);
    free(subString);

    system("PAUSE");
}
/**
 * custom function for getting a substring of source string
 *         source: the source string
 *         startIndex: start index (inclusive) of sub string in source string
 *         endIndex: end index (exclusive) of sub string in source string
 *         return: pointer of the sub string, or null if any error occured
 *
 *         NOTE: substring will return malloced pointer,
 *               remember to free it as needed.
 */
char * substring ( const char * source, int startIndex, int endIndex ) {
    char* result = NULL;
    if (startIndex < 0) {
        printf("startIndex should be a positive value\n");
    }
    else if (endIndex <= startIndex) {
        printf("endIdnex should larger than startIndex\n");
    } else if (startIndex > (strlen(source))) {
        printf("startIdnex should smaller than source length\n");
    } else if (endIndex > (strlen(source)+1)) {
        printf("endIdnex should smaller than or equal to source length\n");
    } else {
        int len = endIndex - startIndex;
        result = (char*)malloc(sizeof(char)*len+1);
        memset (result, '\0', len+1);
        strncpy (result, source+startIndex, len);
    }
    return result;
}


The Result



Reference

strncpy
http://www.cplusplus.com/reference/cstring/strncpy/

malloc
http://www.cplusplus.com/reference/cstdlib/malloc/

free
http://www.cplusplus.com/reference/cstdlib/free/

memset
http://www.cplusplus.com/reference/cstring/memset/

Get a substring of a char* at stackoverflow
http://stackoverflow.com/questions/4214314/get-a-substring-of-a-char

Download

substring.c
https://github.com/benbai123/C_Cplusplus_Practice/blob/master/C_StringProcessing/utils/substring.c

Sunday, March 10, 2013

ZK Textbox with Codemirror


Introduction

This article describe how to make ZK textbox working with Codemirror.

Pre-request

Load External Javascript and CSS Files in ZK
http://ben-bai.blogspot.tw/2013/03/zk-basic-load-external-javascript-and.html

Codemirror Getting Started
http://ben-bai.blogspot.tw/2013/03/web-code-editor-codemirror-getting.html

The Program

textbox_codemirror.zul

A multiline ZK Textbox (with textarea dom element), bind the onblur of codemirror to onchange of textbox.

<?script type="text/javascript" src="resources/js/libsAndTools/codemirror/lib/codemirror.js"?>
<?style href="resources/js/libsAndTools/codemirror/lib/codemirror.css" type="text/css" ?>
<?script type="text/javascript" src="resources/js/libsAndTools/codemirror/mode/javascript/javascript.js"?>
<zk xmlns:w="client">
    <window title="ZK Textbox Codemirror Test" border="normal">
        <div width="300px" height="250px" style="overflow: hidden;">
            <textbox id="tbx" rows="10">
                <attribute w:name="bind_"><![CDATA[
                    function (a, b, c) {
                        this.$bind_(a, b, c);
                        var wgt = this;
                        myCodeMirror = CodeMirror.fromTextArea(this.$n());
                        myCodeMirror.on('blur', function () {
                            var val = myCodeMirror.getValue();
                            wgt.$n().value = val;
                            wgt.fire('onChange', {value: val}, {toServer: true});
                        });
                    }
                ]]></attribute>
            </textbox>
        </div>
        <button label="test" onClick="alert(tbx.getValue());" />
        <button label="execute">
            <attribute name="onClick"><![CDATA[
                Clients.evalJavaScript(tbx.getValue());
            ]]></attribute>
        </button>
    </window>
</zk>


The Result

View demo online
http://screencast.com/t/ZQMHIJj8

Download

textbox_codemirror.zul
https://github.com/benbai123/ZK_Practice/blob/master/Components/projects/Components_Practice/WebContent/textbox_codemirror.zul

Demo Flash
https://github.com/benbai123/ZK_Practice/blob/master/Components/demos/ZK_Textbox_Codemirror.swf

ZK Basic: Load External Javascript and CSS Files


Introduction

This article describe how to load external javascript and css files in ZK.

Project Structure

The external css and js files are under WebContent folder as below



The Program

load_external_js_css.zul

A native button apply the custom class 'custom-button' defined in external css file 'WebContent/resources/css/test.css', calling custom javascript function 'customjs.sayHello' defined in external js file 'WebContent/resources/js/test.js'

<!-- load .js file under WebContent -->
<?script type="text/javascript" src="resources/js/test.js"?>
<!-- load .css file under WebContent -->
<?style href="resources/css/test.css" type="text/css" ?>
<zk xmlns:n="native">
    <!-- a native (pure html) button,
        apply custom css style,
        call the custom js function when clicked-->
    <n:button class="custom-button"
        onclick="customjs.sayHello('Ben');">
        test
    </n:button>
</zk>


The Result

Page loaded



Button clicked



Reference

The script directive
http://books.zkoss.org/wiki/ZUML_Reference/ZUML/Processing_Instructions/script

The style directive
http://books.zkoss.org/wiki/ZUML%20Reference/ZUML/Processing%20Instructions/style

Download

load_external_js_css.zul
https://github.com/benbai123/ZK_Practice/blob/master/Components/projects/Components_Practice/WebContent/load_external_js_css.zul

test.js
https://github.com/benbai123/ZK_Practice/blob/master/Components/projects/Components_Practice/WebContent/resources/js/test.js

test.css
https://github.com/benbai123/ZK_Practice/blob/master/Components/projects/Components_Practice/WebContent/resources/css/test.css

Saturday, March 9, 2013

Web Code Editor: Codemirror, Getting Started


Introduction

From official site:
CodeMirror is a JavaScript component that provides a code editor in the browser. When a mode is available for the language you are coding in, it will color your code, and optionally help with indentation.

Setup

1. Go to official site and click "Download the latest release" to download the latest release.



2. Unzip the downloaded file, copy the lib folder and mode folder to your web project as needed.



The Program

codemirror_gettingstarted.html

<html>
    <head>
        <script src="lib/codemirror.js"></script>
        <link rel="stylesheet" href="lib/codemirror.css">
        <script src="mode/javascript/javascript.js"></script>
        <script src="mode/clike/clike.js"></script>
        <style>
            .CodeMirror {
                height: 150px;
            }
        </style>
        <script type="text/javascript">
            // do after window is loaded
            window.onload = function () {
                // jsTextarea: the dom element, textarea with id 'jsTextarea'
                // clikeTextarea: the dom element, textarea with id 'clikeTextarea'
                // jsCodeMirror: code-editor with mode 'javascript'
                // clikeCodeMirror: code-editor with mode 'clike'
                var jsTextarea = document.getElementById('jsTextarea'),
                    clikeTextarea = document.getElementById('clikeTextarea'),
                    jsCodeMirror = CodeMirror.fromTextArea(jsTextarea, {mode: "javascript"}),
                    clikeCodeMirror = CodeMirror.fromTextArea(clikeTextarea, {mode: "clike"});
                // sync value while blur code-editor
                jsCodeMirror.on('blur', function () {
                    jsTextarea.value = jsCodeMirror.getValue();
                });
                clikeCodeMirror.on('blur', function () {
                    clikeTextarea.value = clikeCodeMirror.getValue();
                });
            }
            // show textarea value
            function showJsContent () {
                alert(document.getElementById('jsTextarea').value);
            }
            function showClikeContent () {
                alert(document.getElementById('clikeTextarea').value);
            }
        </script>
    </head>
    <body>
        js:
        <textarea id="jsTextarea"></textarea>
        <button onclick="showJsContent()">show js content</button><br />
        clike:
        <textarea id="clikeTextarea" /></textarea>
        <button onclick="showClikeContent()">show clike content</button>
    </body>
</html>


The Result

View demo on line
http://screencast.com/t/SuOGRLjLjR

Reference

Official site
http://codemirror.net/

User Manual
http://codemirror.net/doc/manual.html

Download

codemirror_gettingstarted.html
https://github.com/benbai123/HTML_CSS_Javascript_practice/blob/master/libs_tools/codemirror/test/codemirror_gettingstarted.html

Demo flash
https://github.com/benbai123/HTML_CSS_Javascript_practice/blob/master/demos/libs_tools/codemirror/codemirror_gettingstarted.swf