<?xml version="1.0"?>
<ZopeData>
  <record id="1" aka="AAAAAAAAAAE=">
    <pickle>
      <global name="File" module="OFS.Image"/>
    </pickle>
    <pickle>
      <dictionary>
        <item>
            <key> <string>_Cacheable__manager_id</string> </key>
            <value> <string>http_cache</string> </value>
        </item>
        <item>
            <key> <string>_EtagSupport__etag</string> </key>
            <value> <string>ts31551734.18</string> </value>
        </item>
        <item>
            <key> <string>__name__</string> </key>
            <value> <string>renderjs.js</string> </value>
        </item>
        <item>
            <key> <string>content_type</string> </key>
            <value> <string>application/javascript</string> </value>
        </item>
        <item>
            <key> <string>data</string> </key>
            <value> <string encoding="cdata"><![CDATA[

var TabbularGadget = {\n
\n
  addNewTabGadget: function(form_id){\n
            \n
    // add new gadget and render it\n
    form_gadget = $("#form_gadget");\n
    tab_container = form_gadget.parent();\n
    form_gadget.remove();\n
    // XXX: \n
    html_string =[\'<div id="form_gadget" \',\n
                  \'gadget="\' + form_id + \'/Form_asRenderJSGadget" \',\n
                  \'gadget:data-source="Form_asJSON?form_id=\' + form_id + \'"\',\n
                  \'gadget:property="{&quot;cacheable&quot;: &quot;1&quot;, &quot;cache_id&quot;: &quot;\' + form_id + \'&quot;}"></div>\'].join(\'\\n\');\n
    tab_container.append(html_string);\n
\n
    form_gadget = $("#form_gadget");\n
    Form.setCurrentFormId(form_id);\n
    \n
    // render new gadget\n
    RenderJs.loadGadgetFromUrl(form_gadget);\n
\n
    // Update it (XXX: how to know gadget loaded the DOM?)\n
    window.setTimeout("RenderJs.updateGadgetData(form_gadget)", 500);\n
\n
    // mark tab as active visually\n
    $("li.selected").addClass("not_selected"); $("li.selected").removeClass("selected");\n
    $("#"+form_id).addClass("selected"); $("#"+form_id).removeClass("not_selected")\n
    \n
  }\n
  \n
}\n
\n
/*\n
  Form field renderer\n
*/\n
var Form = {\n
\n
  // elements marked with this class can be serizlized to server\n
  SERIALIZE_ABLE_CLASS_NAME: "serialize-able",\n
\n
  CURRENT_FORM_ID: "",\n
\n
  getCurrentFormId: function (){\n
                    /* Get current form ID (return hard coded one for now) */\n
                    return Form.CURRENT_FORM_ID;\n
  },\n
\n
  setCurrentFormId: function (form_id){\n
                    /* Set current form ID (return hard coded one for now) */\n
                    Form.CURRENT_FORM_ID = form_id;\n
  },\n
  \n
  \n
  getFieldId: function(field_id){\n
              /* Generate local form field id */\n
              return "field_" + field_id;\n
  },\n
\n
  updateField: function (dom, field_dict){\n
              /* General purpose field updater */\n
              editable = Boolean(field_dict[\'editable\']);\n
              if (editable){\n
                dom.val(field_dict["value"]);}\n
              else{\n
                // if field is not editable just show its value\n
                dom.replaceWith(field_dict["value"]);}\n
  },\n
\n
  addOptionTagList: function (index, value){\n
              if(value[1]==field_value){\n
                select_dom.append(\'<option selected value="\' + value[1] + \'">\'  + value[0] + \'</option>\');}\n
              else{\n
                select_dom.append(\'<option value="\' + value[1] + \'">\'  + value[0] + \'</option>\'); }\n
              },\n
  \n
  BaseInputField: function (field_id, field_dict){\n
              /* HTML based input field */\n
              dom = $("[name=" + Form.getFieldId(field_id) + "]");\n
              Form.updateField(dom, field_dict);\n
              dom.attr("size", field_dict["display_width"]);\n
              return dom;\n
  },\n
  \n
  ListField: function (field_id, field_dict){\n
              /* Select field */\n
              field_value = field_dict["value"]\n
              select_dom = $("select[name=" + Form.getFieldId(field_id) + "]");\n
              $.each(field_dict["items"], Form.addOptionTagList);\n
              return select_dom;              \n
  },\n
  \n
  ParallelListField: function (field_id, field_dict){\n
              /* mutiple select fields */\n
              // XXX: we render only first value but it can be many how to get them ?\n
              field_value = field_dict["value"][0]\n
              select_dom = $("select[name=subfield_field_" + field_id + "]");\n
              $.each(field_dict["items"], Form.addOptionTagList);\n
              return select_dom;\n
  },\n
  \n
  CheckBoxField: function (field_id, field_dict){\n
              /* CheckBoxField field */\n
              checked = Boolean(field_dict["value"])\n
              checkbox_dom = $("input[name=" + Form.getFieldId(field_id) + "]");\n
              if (checked){\n
                  checkbox_dom.attr(\'checked\', true)}\n
              return checkbox_dom;\n
  },\n
\n
  TextAreaField: function (field_id, field_dict){\n
              /* TextArea field */\n
              return Form.BaseInputField(field_id, field_dict);\n
  },\n
  \n
  StringField: function (field_id, field_dict){\n
              /* String field */\n
              return Form.BaseInputField(field_id, field_dict);\n
  },\n
  \n
  IntegerField: function (field_id, field_dict){\n
              /* Int field */\n
              return Form.BaseInputField(field_id, field_dict);\n
  },\n
  \n
  PasswordField: function (field_id, field_dict){\n
              /* PasswordField field */\n
              return Form.BaseInputField(field_id, field_dict);\n
  },\n
\n
  DateTimeField: function (field_id, field_dict){\n
              /* DateTimeField field */\n
              //alert(field_id);\n
              return Form.BaseInputField(field_id, field_dict);\n
  },\n
  \n
  EmailField: function (field_id, field_dict){\n
              /* Email field */\n
              return Form.BaseInputField(field_id, field_dict);\n
  },\n
  \n
  FormBox: function (field_id, field_dict){\n
              /* Email field */\n
              return Form.BaseInputField(field_id, field_dict);\n
  },\n
\n
  RelationStringField: function (field_id, field_dict){\n
              /* Relation field */\n
              return Form.BaseInputField(field_id, field_dict);\n
  },\n
\n
  ImageField:  function (field_id, field_dict){\n
              /* Image field */\n
              dom = $("img[name=" + Form.getFieldId(field_id) + "]");\n
              // XXX: image field should return details like quality, etc ...\n
              dom.attr("src", field_dict["value"]+ "?quality=75.0&display=thumbnail&format=png");\n
  },\n
  \n
  ListBox:  function (field_id, field_dict){\n
              /* Listbox field */\n
              listbox_id = "field_" + field_id;\n
              navigation_id = listbox_id + "_pager";              \n
              listbox_table = jQuery("#"+listbox_id);\n
              current_form_id = Form.getCurrentFormId();\n
              \n
              listbox_dict = field_dict[\'listbox\']\n
              listbox_data_url = listbox_dict["listbox_data_url"]\n
              colModel = []\n
              column_title_list = [];\n
              $.each(listbox_dict[\'columns\'],\n
                       function(i, value){\n
                         index = value[0];\n
                         title = value[1];\n
                         column_title_list.push(title);\n
                         column = {\'name\': index,\n
                                   \'index\': index,\n
                                   \'width\': 100,\n
                                   \'align\': \'left\'}\n
                         colModel.push(column);\n
              });\n
             \n
              listbox_table.jqGrid( {url:listbox_data_url + \'?form_id=\' + current_form_id + \'&amps;listbox_id=\' + field_id,\n
                            datatype: "json",\n
                            colNames:  column_title_list,\n
                            colModel: colModel,\n
                            rowNum:listbox_dict[\'lines\'],\n
                            pager: \'#\'+navigation_id,\n
                            sortname: \'id\',\n
                            viewrecords: true,\n
                            sortorder: "desc",\n
                            caption: field_dict["title"] });\n
              listbox_table.jqGrid(\'navGrid\', \'#\'+navigation_id, {edit:false,add:false,del:false});\n
              return listbox_table;\n
  },\n
\n
}\n
\n
/* Generic form updater */\n
var FormUpdater = {\n
                   \n
\n
  update: function(data){\n
              /* Update form values */\n
              $.each(data[\'form_data\'],\n
                     function(field_id, field_dict){\n
                        type = field_dict["type"];\n
                        dom = undefined;\n
                        if (type=="ListField"){\n
                          dom = Form.ListField(field_id, field_dict);}\n
                        if (type=="ParallelListField"){\n
                          dom = Form.ParallelListField(field_id, field_dict);}\n
                        if (type=="TextAreaField"){\n
                          dom = Form.TextAreaField(field_id, field_dict);}\n
                        if (type=="StringField"){\n
                          dom = Form.StringField(field_id, field_dict);}\n
                        if (type=="IntegerField"){\n
                          dom = Form.IntegerField(field_id, field_dict);}\n
                        if (type=="EmailField"){\n
                          dom = Form.EmailField(field_id, field_dict);}\n
                        if (type=="FormBox"){\n
                          dom = Form.FormBox(field_id, field_dict);}\n
                        if (type=="RelationStringField"){\n
                          dom = Form.RelationStringField(field_id, field_dict);}\n
                        if (type=="CheckBoxField"){\n
                          dom = Form.CheckBoxField(field_id, field_dict);}\n
                        if (type=="ListBox"){\n
                          dom = Form.ListBox(field_id, field_dict);}\n
                        if (type=="ImageField"){\n
                          dom = Form.ImageField(field_id, field_dict);}\n
                        if (type=="PasswordField"){\n
                          dom = Form.PasswordField(field_id, field_dict);}\n
                        if (type=="DateTimeField"){\n
                          dom = Form.DateTimeField(field_id, field_dict);}\n
                          \n
                        // add a class that these fields are editable so asJSON\n
                        // can serialize for for sending to server\n
                        if (dom!=undefined||field_dict["editable"]){\n
                          dom.addClass(Form.SERIALIZE_ABLE_CLASS_NAME);}                        \n
\n
                        // mark required fields visually\n
                        if (field_dict["required"]){\n
                          dom.parent().parent().children("label").css("font-weight", "bold");}\n
                         \n
                      });\n
  },\n
\n
  save: function(){\n
              /* save form to server*/\n
              form_value_dict = {}\n
              $("." + Form.SERIALIZE_ABLE_CLASS_NAME).each(function(index) {\n
                // DOM can change values, i.e. alter checkbox (on / off)\n
                element = $(this); \n
                name = element.attr("name");\n
                value = element.val();\n
                type = element.attr("type");\n
                if (type=="checkbox"){\n
                  value = element.is(":checked");\n
                  value = {true:1, false:0}[value];}\n
                // XXX: how to handle file uploads ?\n
                form_value_dict[name] = value;\n
              });\n
              console.log(form_value_dict);\n
              \n
              // add form_id as we need to know structure we\'re saving at server side\n
              form_value_dict["form_id"] = Form.getCurrentFormId();\n
                \n
              // validation happens at server side\n
              $.ajax({url:\'Form_save\',\n
                      data: form_value_dict,\n
                      dataType: "json",\n
                      success: function (data) {\n
                        field_errors = data.field_errors;\n
                        if (field_errors!=undefined){\n
                          console.log(field_errors);\n
                          $.each(field_errors, function(index, value){\n
                              dom = $("[name=" + Form.getFieldId(index) + "]");\n
                              dom.css("border", "1px solid red"); // XXX: use class / css\n
                              field = dom.parent().parent();\n
                              if (field.children("span.error").length > 0){\n
                                // just update message\n
                                field.children("span.error").html(value);}\n
                              else{\n
                                // no validation error message exists\n
                                field.append(\'<span class="error">\' + value + \'</span>\');}\n
                            }\n
                          );}\n
                        else{\n
                          // validation OK at server side\n
                          $("span.error").each(function(index) {\n
                            // delete validation messages\n
                            element = $(this);\n
                            element.parent().children("div.input").children("." +Form.SERIALIZE_ABLE_CLASS_NAME).css("border", "none");\n
                            element.remove();\n
                          });\n
                          // show a fading portal_status_message\n
                          $("#portal_status_message").toggle();\n
                          $("#portal_status_message p").html("Saved");\n
                          window.setTimeout( \'$("#portal_status_message").toggle()\', 4000);\n
                        }\n
                      }});\n
  },\n
}\n
\n
/*\n
 * Generic Gadget library renderer\n
 */\n
\n
var RenderJs = {\n
\n
    // Local cache ID\n
    APP_CACHE_ID : "app_cache10",\n
    \n
    bootstrap: function (root){\n
              /* initial load application gadget */\n
              RenderJs.loadGadgetFromUrl(root);\n
              RenderJs.load(root);\n
    },\n
    \n
    load: function (root) {\n
              /* Load gadget layout by traversing DOM */\n
              gadget_list = root.find("[gadget]");\n
              // Load chilren\n
              gadget_list.each(function(i,v){RenderJs.loadGadgetFromUrl($(this));});\n
    },\n
\n
    updateAndRecurse: function(gadget, data){\n
              /* Update current gadget and recurse down */\n
              gadget.append(data);\n
              // a gadget may contain sub gadgets\n
              RenderJs.load(gadget);\n
    },\n
    \n
    loadGadgetFromUrl: function(gadget) {\n
              /* Load gadget\'s SPECs from URL */\n
              url = gadget.attr("gadget");\n
\n
              // XXX: based on URL and more ? generate gadget uid?\n
\n
              // XXX: How to know how long a form should be cached locally\n
              // i.e. what happens if it changes at server side ?\n
              \n
              // handle caching\n
              gadget_property = gadget.attr("gadget:property");\n
\n
              cacheable = false;\n
              if (gadget_property!=undefined){\n
                gadget_property = $.parseJSON(gadget_property)\n
                cacheable = Boolean(gadget_property.cacheable);}\n
              //cacheable = false ; // to develop faster\n
              if (cacheable){\n
                  // get from cache if possible, use last part from URL as cache_key\n
                  cache_id = gadget_property.cache_id\n
                  cache_id = RenderJs.APP_CACHE_ID + "_" + cache_id\n
                  app_cache = $.jStorage.get(cache_id, undefined);\n
                                      \n
                  if(app_cache==undefined){\n
                    // not in cache so we pull from network and cache\n
                    //console.log("not in cache: " + cache_id + "  " + url);\n
                    $.ajax({url:url,\n
                            yourCustomData: {"cache_id": cache_id},\n
                            success: function (data) {\n
                                        cache_id = this.yourCustomData.cache_id;\n
                                        console.log("set in cache: " + cache_id);\n
                                        $.jStorage.set(cache_id, data)\n
                                        RenderJs.updateAndRecurse(gadget, data);\n
                              }});\n
                    }\n
                  else{\n
                    // get from cache\n
                    //console.log("get from cache " +cache_id);\n
                    data = app_cache; //app_cache[cache_id];\n
                    RenderJs.updateAndRecurse(gadget, data);}\n
                }\n
              else{\n
                // not to be cached\n
                //console.log("Not to be cached " + url);\n
                $.ajax({url:url,\n
                        success: function (data) {\n
                          RenderJs.updateAndRecurse(gadget, data);},});\n
                }\n
              \n
    },\n
\n
    update: function (root) {\n
              /* update gadget with data from remote source */\n
              root.find("[gadget]").each(function(i,v){RenderJs.updateGadgetData($(this));});\n
    },\n
    \n
    updateGadgetData: function(gadget) {\n
              /* Do real gagdet update here */\n
              data_source = gadget.attr("gadget:data-source");\n
              data_handler = gadget.attr("gadget:data-handler");\n
              // acquire data and pass it to method handler\n
              if (data_source!=undefined){\n
                // XXX: what if we don\'t have a data-handler and all is in data-source?\n
                $.getJSON(data_source,\n
                          function (result) {FormUpdater.update(result);});\n
              }\n
    },   \n
}\n
\n
\n
function test(){\n
  RenderJs.update($("#content"));\n
}\n
\n
// init all when DOM is ready\n
$(document).ready(function() {\n
   RenderJs.bootstrap($("#content"));\n
   // XXX: we use timeouts as we do not know if gadget structure is yet ready, how to do that in a generic way?\n
   window.setTimeout("test()", 500);\n
 });  \n


]]></string> </value>
        </item>
        <item>
            <key> <string>precondition</string> </key>
            <value> <string></string> </value>
        </item>
        <item>
            <key> <string>size</string> </key>
            <value> <int>16870</int> </value>
        </item>
        <item>
            <key> <string>title</string> </key>
            <value> <string>renderjs.js</string> </value>
        </item>
      </dictionary>
    </pickle>
  </record>
</ZopeData>
