Aug 072016
 

General JS

Design Patterns

jQuery

Understanding Plugins

Patterns

Best Practices:

Learning Resources

Glossary

JavaScript Object Literal.

A JavaScript object literal is a comma-separated list of name-value pairs wrapped in curly braces. Object literals encapsulate data, enclosing it in a tidy package. This minimizes the use of global variables which can cause problems when combining code.

 

Jul 012015
 

Get latest version ([FILE]) from:
http://ftp.gnu.org/pub/gnu/emacs/

cd /usr/local/src
# wget http://ftp.gnu.org/pub/gnu/emacs/[FILE]
# tar xzvf [FILE]
# cd [FILE]
# ./configure --without-x --without-selinux
# make
# make install
# which emacs
/usr/local/bin/emacs
# emacs --version

Jun 262015
 

Learning Balance
There’s a wonderful metaphor from the yoga tradition that vividly depicts the plight of the average person and points the way to a more meaningful life. It’s the carriage allegory. The carriage represents the body, the horses pulling the carriage represent the emotions, the driver is the mind, and the passenger is the soul (Atman). The story goes that the state of the average person is as follows; the carriage is in terrible disrepair, the horses are half-wild, the driver is unfocused and drunk, and the passenger is asleep. The passenger, a king or queen, is asleep, dreaming he/she is a peasant. Yoga, it is said, repairs the carriage (body), tames the horses (emotions), sobers and focuses the driver (mind), and ultimately – reawakens the passenger (soul). The soul then remembers his or her true purpose and instructs the driver on which route to take to their ultimate destination. This is the purpose of yoga, anything less is simply exercise.
-Max Strom

Nov 172014
 

update script:
/packages/intranet-cost/sql/postgresql/upgrade/upgrade-3.3.1.2.0-3.3.1.2.1.sql

contains the following sql:

delete from acs_objects
where object_type = 'relationship' and
object_id in (
select object_id
from acs_objects
where object_type = 'relationship' and
object_id not in (
select rel_id
from acs_rels
)
);

… which is quite slow.

Table acs_objects has the following trigger:

Triggers:
acs_objects_context_id_del_tr BEFORE DELETE ON acs_objects FOR EACH ROW EXECUTE PROCEDURE acs_objects_context_id_del_tr()
create or replace function acs_objects_context_id_del_tr() returns trigger as '
1:begin
2: delete from acs_object_context_index
3: where object_id = old.object_id;
4:
5: return old;
6:
7:end;' language 'plpgsql';

 

projop=# select count(*) from acs_object_context_index;
count
---------
2597510
(1 row)

 

How many tables reference to table ‘acs_objects’

SELECT
tc.table_schema,
tc.constraint_name,
tc.table_name,
kcu.column_name,
ccu.table_name AS foreign_table_name,
ccu.column_name AS foreign_column_name
FROM
information_schema.table_constraints tc
JOIN
information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name
JOIN
information_schema.constraint_column_usage ccu ON ccu.constraint_name = tc.constraint_name
WHERE
constraint_type = 'FOREIGN KEY'
AND ccu.table_name='acs_objects';
SELECT DISTINCT
tc.table_name
FROM
information_schema.table_constraints tc
JOIN
information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name
JOIN
information_schema.constraint_column_usage ccu ON ccu.constraint_name = tc.constraint_name
WHERE
constraint_type = 'FOREIGN KEY'
AND ccu.table_name='acs_objects';

table_name
--------------------------------
workflow_cases
apm_packages
auth_authorities
im_trans_prices
apm_parameter_values
wf_cases
acs_magic_objects
im_menus
acs_object_context_index
im_cost_centers
trans_edit_proof_wf_cases
im_timesheet_prices
acs_reference_repositories
rel_constraints
workflows
im_trans_trados_matrix
im_dynfield_type_attribute_map
notification_types
acs_permissions
acs_sc_impls
im_dynfield_attr_multi_value
im_fs_folders
im_freelance_rfqs
apm_package_versions
im_trans_rfq_answers
postal_addresses
acs_sc_msg_types
notification_intervals
im_component_plugins
parties
im_notes
cr_child_rels
acs_objects
acs_activity_object_map
acs_named_objects
bt_patches
journal_entries
site_nodes_selection
site_node_object_mappings
acs_rels
acs_sc_operations
im_biz_object_tree_status
acs_attribute_values
acs_events
im_dynfield_widgets
im_search_objects
acs_sc_contracts
acs_mail_gc_objects
im_dynfield_attributes
im_object_freelance_skill_map
im_companies
im_trans_tasks
cr_revisions
im_reports
im_forum_topics
im_offices
im_prices
notification_requests
notification_delivery_methods
im_projects
trans_only_wf_cases
cr_items
general_objects
acs_mail_links
im_user_absences
cr_item_rels
im_freelance_rfq_answers
notification_replies
lob_data
apm_parameters
etp_page_revisions
auth_driver_params
acs_activities
calendars
notifications
im_fs_actions
im_costs
im_biz_objects
acs_mail_bodies
cm_modules
site_nodes
im_timesheet_task_dependencies
im_trans_rfqs
(83 rows)

Get table sizes

projop=# \dt+
List of relations
                                                                                   List of relations
 Schema |              Name              | Type  | Owner  |    Size    |                                                   Description
--------+--------------------------------+-------+--------+------------+-----------------------------------------------------------------------------------------------------------------
 public | aa_test_final_results          | table | projop | 0 bytes    |
 public | aa_test_results                | table | projop | 0 bytes    |
 public | acs_activities                 | table | projop | 16 MB      |
                                                                       :     Represents what happens during an event
                                                                       :
 public | acs_activity_object_map        | table | projop | 0 bytes    |
                                                                       :     Maps between an activity and multiple ACS objects.
                                                                       :
 public | acs_attribute_descriptions     | table | projop | 0 bytes    |
 public | acs_attribute_values           | table | projop | 8192 bytes |
                                                                       :   Instead of coercing everything into a big string, we could use
                                                                       :   a "union", i.e, a string column, a number column, a date column,
                                                                       :   and a discriminator.
                                                                       :
 public | acs_attributes                 | table | projop | 24 kB      |
                                                                       :  Each row in the acs_attributes table defines an
                                                                       :  attribute of the specified object type. Each object of this type
                                                                       :  must have a minimum of min_n_values values and a maximum of
                                                                       :  max_n_values for this attribute.
                                                                       :
 public | acs_datatypes                  | table | projop | 8192 bytes |
                                                                       :  Defines the set of available datatypes for acs_attributes. These
                                                                       :  datatypes are abstract, not implementation-specific, i.e., they
                                                                       :  are not Oracle datatypes. The set of pre-defined datatypes is
                                                                       :  inspired by XForms (http://www.w3.org/TR/xforms-datamodel/).
                                                                       :
 public | acs_enum_values                | table | projop | 0 bytes    |
 public | acs_event_party_map            | table | projop | 0 bytes    |
                                                                       :         Maps a many-to-many relationship between events and parties.
                                                                       :
 public | acs_events                     | table | projop | 38 MB      |
                                                                       :     A relationship between a time span and an activity.
                                                                       :
 public | acs_function_args              | table | projop | 64 kB      |
 public | acs_logs                       | table | projop | 16 kB      |
 public | acs_magic_objects              | table | projop | 8192 bytes |
                                                                       :  This table allows us to provide semantic names for certain special

Benchmark for delete:

Other approaches considered but neglected:

Using DISABLE TRIGGER and perform delete on table ‘acs_object_context_index’ manually.

ALTER TABLE acs_objects DISABLE TRIGGER ALL;
...
ALTER TABLE acs_objects ENABLE TRIGGER ALL;

Avoiding “in clause”

select o.object_id
into temporary objects_not_in_acs_rels
from acs_objects o
left outer join acs_rels rels
on o.object_id = rels.rel_id
where o.object_type = 'relationship';

delete from acs_objects o
using objects_not_in_acs_rels r
where o.object_type = 'relationship' and
o.object_id = r.object_id;

drop table objects_not_in_acs_rels;
Nov 102014
 


CREATE OR REPLACE FUNCTION to_date(integer, text)
RETURNS date AS '
declare
p1 alias for $1;
p2 alias for $2;

return_value date;

begin

select into return_value to_date(p1::text, p2);
return return_value;

end;' LANGUAGE 'plpgsql' VOLATILE;

CREATE OR REPLACE FUNCTION to_date(timestamptz, text)
RETURNS date AS '
declare
p1 alias for $1;
p2 alias for $2;

return_value date;

begin

select into return_value to_date(p1::text, p2);
return return_value;

end;' LANGUAGE 'plpgsql' VOLATILE;

CREATE OR REPLACE FUNCTION upper(timestamptz)
RETURNS text AS '
declare
p1 alias for $1;
return_value date;

begin

select into return_value upper(p1::text);
return return_value;

end;' LANGUAGE 'plpgsql' VOLATILE;

Oct 082013
 

Search a line that contains two words (WORD1, WORD2)

^(?=.*\bWORD1\b)(?=.*\bWORD2\b).*$

Return content btw. two chars

regexp -nocase {@(.*?)@} "text:outline-level=\"2\">@price_per_unit@

Jul 072013
 

http://dl.fedoraproject.org/pub/epel/6/


yum install http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-7.noarch.rpm
yum install Pound


# *****************************************************
# /etc/pound/pound.cfg
# *****************************************************

User "nobody"
Group "nobody"
RootJail "/var/pound"
LogLevel 2

ListenHTTP
Address 0.0.0.0
Port 80
End

ListenHTTPS
Address 0.0.0.0
Port 443
Cert "/etc/pound/server.pem"
End

# "Stage" is running on 8001
Service
HeadRequire "Host:.*stage.*"
BackEnd
Address 127.0.0.1
Port 8001
TimeOut 600
End
End

# By default show the "projop" production server
Service
BackEnd
Address 127.0.0.1
Port 8000
TimeOut 600
End
End

Feb 172013
 

Writing / Editing / Publishing

Usability/GUI/UX

Gantt Editors

Nov 052012
 

Improvement Proposal

Provide generic function to support asynchronous update of combo boxes in a web form.

Example:

– Installation with hundreds of active projects.
– A report allows user to filter for “Companies” and “Projects”
– If user selects a “Company”, combo box “Projects” should show only projects of “Company” selected

Todo:

– support multiple dependencies
– support JSON

Implementation v0.5:

im_ajax_update_forms 
     project_profitibiliy_form 
     im_company im_project 
     customer_id 
     project_id 
     company_id 
     project_id
# /packages/intranet-core/tcl/intranet-ajax-procs.tcl
#
# Copyright (C) 2012 ]project-open[
# The code is based on work from ArsDigita ACS 3.4 and OpenACS 5.0
#
# This program is free software. You can redistribute it
# and/or modify it under the terms of the GNU General
# Public License as published by the Free Software Foundation;
# either version 2 of the License, or (at your option)
# any later version. This program is distributed in the
# hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
 
ad_library {
    AJAX procedures
    @author klaus.hofeditz@project-open.com
}

# -----------------------------------------------------------
# Update project widget when company will be changed by user
# -----------------------------------------------------------
 
ad_proc -public im_ajax_update_forms {
    form_id
    source_object_type
    target_object_type
    source_form_element_name
    target_form_element_name
    source_table_column_name
    target_table_column_name
} {
 
    Includes JS code for asynchronous HTML requests to be triggered
    when source element is changed. Re-populates target element based
    on biz rules as defined ajax_update_forms.js.tcl
 
    ]po[ package "intranet-rest" can't be used in all cases to get a list
    of new options for a HTML combo boxes. Combo boxes like "Projects" require
    indention which is not supported by intranet-rest. Therefore customized
    server side scripts need to be possible.
 
    @param
 
} {
    set par_str "form_id=$form_id&source_object_type=$source_object_type&target_object_type=$target_object_type&"
    append par_str "source_form_element_name=$source_form_element_name&target_form_element_name=$target_form_element_name&"
    append par_str "source_table_column_name=$source_table_column_name&target_table_column_name=$target_table_column_name"
    template::head::add_javascript -src "/intranet/js/ajax_update_select_box.js?$par_str" -order "999"
}
</code>
 
 
<code>
# /packages/intranet-core/www/js/ajax_update_company_project.js.tcl
#
# Copyright (C) 1998-2012 various parties
# The code is based on ArsDigita ACS 3.4
#
# This program is free software. You can redistribute it
# and/or modify it under the terms of the GNU General
# Public License as published by the Free Software Foundation;
# either version 2 of the License, or (at your option)
# any later version. This program is distributed in the
# hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
 
ad_page_contract {
 
    Includes JS for updating a target form field (select)
    when a source form field is changed by the user
 
    @param form_id
    @param source_object_type
    @param source_object_type
    @param source_form_element_name
    @param target_form_element_name
    @param source_table_column_name
    @param target_table_column_name
 
    @author klaus.hofeditz@project-open.com
 
} {
    form_id
    source_object_type
    target_object_type
    source_form_element_name
    target_form_element_name
    source_table_column_name
    target_table_column_name
}
 
switch $target_object_type {
    # Updating a projects drop down
    im_project {
        switch $source_object_type {
            im_company {
                # Building request string that return options in json/xml format
                # Value of source element can be found in var ${source_form_element_name}_value
                set request_str "\"GET\",\"/intranet/xmlhttp-object-options-custom?object_type=$target_object_type&"
                append request_str "source_table_column_name=$source_table_column_name&source_form_element_name=$source_form_element_name&"
                append request_str "source_table_column_name=$source_table_column_name&source_form_element_value=\" + ${source_form_element_name}_value,true"
 
                set result_ds_type "xml"
            }
            default {
                set request_str "\"GET\",\"/intranet-rest/$target_object_type?format=xml&query=$source_table_column_name=$source_form_element_name\" ,true"
                set result_ds_type "json"
            }
       }
    }
    default {
        set request_str "\"GET\",\"/intranet-rest/$target_object_type?format=xml&query=$source_table_column_name=$source_form_element_name\" ,true"
        set result_ds_type "json"
    }
}
function <%=$form_id%>_update_target_select() {
 
    console.log("Start 'update_target_select'");
 
    var xmlHttp1;
    // get value from first request
    try {
        // Firefox, Opera 8.0+, Safari
        xmlHttp1=new XMLHttpRequest();
    }
    catch (e) {
        // Internet Explorer
        try {
            xmlHttp1=new ActiveXObject("Msxml2.XMLHTTP");
        }
        catch (e) {
            try {
                xmlHttp1=new ActiveXObject("Microsoft.XMLHTTP");
            }
            catch (e) {
                alert("Your browser does not support AJAX!");
                return false;
            }
        }
    }
 
    xmlHttp1.onreadystatechange = function() {
        console.log("now in 'onreadystatechange'");
 
        if(xmlHttp1.readyState==4) {
            // Removing acual options
            for (i = oForm.<%=$target_form_element_name%>.options.length-1; i >= 0; i--) {
                oForm.<%=$target_form_element_name%>.remove(i);
            }
 
            // setting new options (XML)
            var xml_options = xmlHttp1.responseText;
            $(xml_options).find('select_item').each(function(){
                var title = $(this).find('title').text();
                var values = $(this).find('value').text();
                 $("#<%=$form_id%> select[name=<%=$target_form_element_name%>]").append("<option value='"+ $.trim(values) +"'>"+ title +"</option>");
            });
 
            // todo: setting new option (json)
 
            // remove this:
            // var opts1 = res1.split("|");
            // for (i=0; i < opts1.length; i = i+2) {
            //  var newOpt = new Option(opts1[i+1], opts1[i], false, true);
            //  newOpt.value = $.trim(newOpt.value);
            //  oForm.cost_object_category_id.options[oForm.<%=$target_form_element_name%>.options.length] = newOpt;
            // }
        }
    }
 
    // Get the current value of the source element
    // var oForm = document.getElementById('<%=$source_form_element_name%>');
    // var oForm = document.forms['<%=$form_id%>'].elements['<%=$source_form_element_name'%>];
    var oForm = document.forms['<%=$form_id%>'];
    // Set JS var named "<%=source_form_element_name%>_value"
    var <%=$source_form_element_name%>_value = oForm.elements["<%=$source_form_element_name%>"].options[oForm.elements["<%=$source_form_element_name%>"].selectedIndex].value;
 
    xmlHttp1.open(<%=$request_str%>);
    xmlHttp1.send(null);
}
jQuery().ready(function(){
        // Check if source_select has a value
        var oForm = document.forms['<%=$form_id%>'];
        var <%=$source_form_element_name%>_value = oForm.elements["<%=$source_form_element_name%>"].options[oForm.elements["<%=$source_form_element_name%>"].selectedIndex].value;
        console.log("jQuery.ready - Found <%=$source_form_element_name%>_value:%", <%=$source_form_element_name%>_value);
        if ( <%=$source_form_element_name%>_value != null && <%=$source_form_element_name%>_value != "" ) {
                 console.log("Setting target select");
                // found value, updating target
                <%=$form_id%>_update_target_select();
        }
 
        // Create "Listener" for source element
        console.log("Setting Listener for doc id <%=$source_form_element_name%>");
        // $('#<%=$source_form_element_name%>').change(<%=$form_id%>_update_target_select);
        $("#<%=$form_id%> select[name=<%=$source_form_element_name%>]").change(<%=$form_id%>_update_target_select);
});
# /packages/intranet-core/www/xmlhttp-object-options-custom.tcl
#
# Copyright (C) 2009 ]project-open[
#
# This program is free software. You can redistribute it
# and/or modify it under the terms of the GNU General
# Public License as published by the Free Software Foundation;
# either version 2 of the License, or (at your option)
# any later version. This program is distributed in the
# hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
 
ad_page_contract {
    Returns a key-value list
    @author klaus.hofeditz@project-open.com
} {
    { object_type }
    { source_form_element_name }
    { source_form_element_value:integer }
    { auto_login "" }
}

# -------------------------------------
# Security & Defaults
# -------------------------------------

# ToDo: Check usefullness of [im_rest_authenticate]
set current_user_id [ad_maybe_redirect_for_registration]

# -------------------------------------
# Body
# -------------------------------------
 
switch $object_type {
        im_project {
                if { "customer_id" == $source_form_element_name } {
                        if { [im_permission $current_user_id "view_projects_all"] } {
                                set option_list [im_project_options \
                                            -include_empty 0 \
                                            -include_empty_name 0 \
                                            -include_project_ids 1 \
                                            -exclude_subprojects_p 0 \
                                            -exclude_tasks_p 1 \
                                            -exclude_status_id [im_project_status_closed] \
                                            -company_id $source_form_element_value \
                                        ]
 
                        } else {
                                set option_list [im_project_options \
                                            -include_empty 0 \
                                            -include_empty_name 0 \
                                            -include_project_ids 1 \
                                            -exclude_subprojects_p 0 \
                                            -exclude_tasks_p 1 \
                                            -exclude_status_id [im_project_status_closed] \
                                            -member_user_id $current_user_id \
                                            -company_id $source_form_element_value \
                                        ]
                        }
                }
        }
        default {
                # not yet defined, return error
                # return [im_rest_error -format $format -http_status 404 -message " ('$auth_method')."]
        }
}
 
set result "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
append result "<dropdown>\n"
set ctr 0
foreach { key_value } $option_list {
        append result "<select_item>\n"
        append result "<title>[lindex $key_value 0]</title>\n"
        append result "<values><value>[lindex $key_value 1]</value></values>\n"
        append result "</select_item>\n"
        incr ctr
}
 
 
if { 0 == $ctr } {
    append result "<select_item>\n"
    append result "<title>[lang::message::lookup "" intranet-core.NoProjectsFound "No Projects found"]</title>\n"
    append result "<values><value></value></values>\n"
    append result "</select_item>\n"
}
append result "</dropdown>"
doc_return 200 "xml" $result