⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 conditional_usage.js.svn-base

📁 PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。
💻 SVN-BASE
字号:
// simple event stacking.// i don't like Mochikit's one.function getBindTarget(fieldset) {    var possibles = getElementsByTagAndClassName('DIV','conditional_target', fieldset);	    return possibles[0];}function attachToElementEvent(elem, event_name, func) {    // catch IE (grumble)    if (elem.attachEvent) {        elem.attachEvent('on'+event_name, func);    } else {        elem.addEventListener(event_name, func, false);    }}function removeFromElementEvent(elem, event_name, func) {    // catch IE (grumble)    if (elem.detachEvent) {        elem.detachEvent('on'+event_name, func);    } else {        elem.removeEventListener(event_name, func, false);    }}// quick and dirty helper - find the nearest parent item matching tagName. // FIXME steal the klass or tagName logic from MochiK.// FIXME add to a core js-lib, and add some unit-tests.function breadcrumbFind(elem, tagName) {    var stopTag = 'BODY';    var currentTag = elem.tagName;    var currentElem = elem;    while ((currentTag != stopTag) && (currentTag != tagName)) {        currentElem = currentElem.parentNode;        currentTag = currentElem.tagName;    }    if (currentTag == tagName) {         return currentElem;     } else {        return null;    }}/* Conditional Metadata Usage * * Allows the system to respond to conditional metadata events. *//**== Basic process around Conditional Metadata JS/HTML interaction ==The system works based on 3 concepts: 1. on the appropriate "activation" command, the entire "field" is serialised and replaced with a hidden    input var, and a "user friendly" label. 2. a undo stack needs to be kept, which provides the user with a way to "un-fix" items. 3. When an item is activated, the system:        (i)     polls the page for fixed input-vars:  this _includes_ (for example) fieldset_id, as well as later items.        (ii)    submits these to a targeturl (set as a "global var" - currently in _this_ file.)        // FIXME:  this needs to be programmatically settable. // TODO make this operate on a particular subset of the page, and be _instantiable_. (use fieldset as the "controlling component". // TODO lazy bind all activation handlers to ensure that the above problem is solveable. // TODO ensure that this functions across the required browser sets. // TODO verify that the entire set of "lookup" values works here: select and input seem to work.*/var conditional_usage_undostack = new Array();var conditional_usage_keys = new Array();// sorry mom. function checkStackForFieldset(fieldset) {    for (var i=0; i<conditional_usage_keys.length; i++) {        if (conditional_usage_keys[i] == fieldset) {            simpleLog('DEBUG','found undostack at keyindex '+i);            return true;        }    }    return false;}// grow and go.function getStackForFieldset(fieldset) {    for (var i=0; i<conditional_usage_keys.length; i++) {        if (conditional_usage_keys[i] == fieldset) {            simpleLog('DEBUG','found undostack at keyindex '+i);            return conditional_usage_undostack[i];        }    }    // we would have returned by now.  onward, and upward.    // i == conditional_usage_keys.length == conditional_usage_undostack.length    conditional_usage_undostack.push(Array());    conditional_usage_keys.push(fieldset);    simpleLog('DEBUG','created undostack at keyindex '+i+' for fieldset '+fieldset);    simpleLog('DEBUG','undoStack: '+conditional_usage_undostack+'\nundoKeyStack: '+conditional_usage_keys)    return conditional_usage_undostack[i];      // must be the "new" element, which is 1 past the old size.}// Stack implementationfunction pushStack(fieldset, subtree) {    // FIXME how do I bind this to a particular fieldset object.    // FIXME at worst, we need to use the HTMLFieldSet object as a "key" of sorts into a stack it's O(n) initially, unless we can do some other magic ...    simpleLog('DEBUG','pushStack received: '+fieldset);    var undostack = getStackForFieldset(fieldset);        undostack.push(subtree);        // onto the end, so it can be popped.     simpleLog('ERROR','added item to undo stack..');}function popStack(fieldset) {    var undostack = getStackForFieldset(fieldset);    if (undostack.length == 0) {           return ;    }    var last_item = undostack.pop();    simpleLog('DEBUG','popping item\n'+toHTML(last_item));    last_item.parentNode.removeChild(last_item);    updateFieldset(fieldset);}/**     - creates a replacement widget,    - adds the _old_ widget to the correct stack.*/function createFixedWidget(fieldset, widget, i_name, i_value, i_label) {    // bad, but there's nothing else we can do in the current design.    // we need to walk the TR for the TH (widget.tagName == TR)    if (widget.tagName != 'DIV')    {        // alert('Invalid widget in conditional.'+widget);        simpleLog('ERROR','invalid widget in conditional.');        return false;    }    simpleLog('DEBUG','creating fixed widget');    var header = widget.getElementsByTagName('LABEL')[0];  // FIXME _could_ fail if pathalogical.    simpleLog('DEBUG','got label');        // check for "requird" and edit.    var headlist = header.getElementsByTagName('SPAN');    simpleLog('DEBUG','got headlist - ' + headlist.length);            if (headlist.length != 0) {    	header.removeChild(headlist[0]);	}    simpleLog('DEBUG','getting name');        	    var i_friendly_name = scrapeText(header);    var newWidget = DIV({'class':'field fixed'},        createDOM('LABEL',null, i_friendly_name),        DIV(null,             INPUT({'type':'hidden','name':i_name, 'value':i_value,'class':'fixed'}),            SPAN(null, i_label)        )    );    swapDOM(widget, newWidget);    pushStack(fieldset, newWidget);    simpleLog('ERROR','conditional_usage passed in fieldset '+fieldset+' and widget '+newWidget); }/** handles the "update" event.         needs to:        - "replace" the contents of the widget with a "fixed" input.        -  trigger the "updateFieldset"*/function handleSelectChange(fieldset, widget, select_object) {     simpleLog('DEBUG','handleSelectChange on select with name "'+select_object.name+'"');     var i_name = select_object.name;    var i_value = select_object.value;    var i_label = scrapeText(select_object.options[select_object.selectedIndex]);    simpleLog('DEBUG','handleSelectChange creating');     createFixedWidget(fieldset, widget, i_name, i_value, i_label);         simpleLog('DEBUG','handleSelectChange updating');         updateFieldset(fieldset);}function handleRadioChange(fieldset, widget, radio_object) {     simpleLog('ERROR','call to stub: handleRadioChange on radio with name "'+radio_object.name+'"');     var i_name = radio_object.name;    var i_value = radio_object.value;    var oLabel = breadcrumbFind(radio_object, 'LABEL');    if (oLabel == null) {        simpleLog('ERROR','radiobutton ('+radio_object.name+':'+radio_object.value+') has no associated label.  failing.');        return false;    } else {        var i_label = scrapeText(oLabel);    }    createFixedWidget(fieldset, widget, i_name, i_value, i_label);         updateFieldset(fieldset);}/** extract all the appropriate input-vars from a given fieldset, so that it can    be passed into a backed.  Returns an array ("formKeys" => array(), "formValues" => array())    that can be passed to be backend.     // actually, this is ONLY and issue for the "fieldset_id" form-field:    // for the rest of them, the backend should handle this sanely (e.g. in what it sends _us_).   Suspect the "best" option is to call this    // 'fieldset_id[]' since the backend can then extract which fieldsets have been called.  other vars will get converted    // from <input type="radio" ... name="xxxx"> and <select ... name="xxxx"> to <input type="hidden" class="fixed">    // */function parseFieldsetToForm(fieldset) {    simpleLog('ERROR','call to untested fn: parseFieldsetToForm. ');    var formContent = new Array();    var input_vars = getElementsByTagAndClassName('input','fixed',fieldset);    formContent["formKeys"] = new Array();    formContent["formValues"] = new Array();    for (var i=0; i<input_vars.length; i++) {        var input_object = input_vars[i];        // don't delete the undo button.        if (input_object.type != 'button') {            formContent["formKeys"].push(input_object.name);            formContent["formValues"].push(input_object.value);        }    }    return formContent;}/** bind a "widget" to a particular fieldset, and populate the appropriate event-handlers      - find the various types of input objects and hook in appropriately:          make sure that the function binds:               - fieldset               - pseudo-widget (the div that surrounds each group of options.)                -handler.    // FIXME: this assumes that inputs are either "select" or "<input type='radio'>"    // FIXME: is that a valid assumption?*/function bindToConditionalFieldset(fieldset, widget) {     // handleChange needs to be bound to each input widget.    // for <input type != "hidden"> type  variables this means binding to onclick    // for <select> this means binding to onchange        var select_fields = widget.getElementsByTagName('SELECT');    var input_fields = widget.getElementsByTagName('INPUT');    // needs to be filtered - no "hidden" vars.    for (var i=0; i<select_fields.length; i++) {        var select_object = select_fields[i];        var handler = partial(handleSelectChange, fieldset, widget, select_object);        attachToElementEvent(select_object, 'change', handler);    }    for (var i=0; i<input_fields.length; i++) {        var input_object = input_fields[i];        var handler = partial(handleRadioChange, fieldset, widget, input_object);        if (input_object.type == 'radio') {            attachToElementEvent(input_object, 'click', handler);        } else if (input_object.type == 'hidden') {            ;       // this is OK, and expected.        } else {            simpleLog('ERROR','bindToConditionalFieldset found a non-hidden input field of type: '+input_object.type);        }    }    simpleLog('DEBUG','bindToConditionalFieldset complete');} function clearUnfixedWidgets(fieldset) {    var widgets = getElementsByTagAndClassName('DIV', 'field', fieldset);    for (var i=0; i<widgets.length; i++) {        var w = widgets[i];        if (hasElementClass(w, 'fixed')) {            simpleLog('DEBUG','Not deleting widget with class '+w.getAttribute('class'));        } else {            w.parentNode.removeChild(w);            simpleLog('DEBUG','Deleting widget with class '+w.getAttribute('class'));        }    }}/* XMLHttpRequest functions * */function updateFieldset(fieldset) {   var baseurl = getElement('kt-core-baseurl').value;   var targeturl = baseurl + '/presentation/lookAndFeel/knowledgeTree/ajaxConditional.php'; // test_metadata_update.txt';   simpleLog('DEBUG','AJAX function called: updateFieldset');   var formdata = parseFieldsetToForm(fieldset);   formdata.formKeys.push('action');   formdata.formValues.push('updateFieldset');   var POSTval = queryString(formdata.formKeys, formdata.formValues);   var req = getXMLHttpRequest();   req.open('POST',targeturl, true);        // MUST be async.   //simpleLog('DEBUG','form submission from updateFieldset: '+logFormSubmission(formdata));   simpleLog('DEBUG','form submission from updateFieldset: '+(formdata));   req.setRequestHeader('Content-Type','application/x-www-form-urlencoded');   var deferred = sendXMLHttpRequest(req, POSTval);   deferred.addErrback(partial(do_handleError, 'updateFieldset'));   deferred.addCallback(partial(do_updateFieldset, fieldset));}function do_handleError(function_name, err) {   simpleLog('ERROR','AJAX request from function '+function_name+' failed on exception: '+err);}function do_updateFieldset(fieldset, req) {   simpleLog('DEBUG','AJAX function do_updateFieldset received: \n'+req.responseText);       // clear unfixed widgets before we start.   clearUnfixedWidgets(fieldset);   // create an unparented div for HTML insertion.   var hold = DIV(null);      hold.innerHTML = req.responseText;      var new_widgets = getElementsByTagAndClassName('DIV','field', hold);      simpleLog('DEBUG','new_widgets.length: '+new_widgets.length);   var target = getBindTarget(fieldset);   simpleLog('DEBUG','new_widgets.length: '+new_widgets.length);        for (var i=0; i<new_widgets.length; i++) {       var w = new_widgets[i];       simpleLog('DEBUG','binding: '+toHTML(w));            target.appendChild(w);       bindToConditionalFieldset(fieldset, w);   }   simpleLog('DEBUG','fieldset ends as: \n'+toHTML(fieldset));        delete t; // clean this up.}/* HTML callbacks - functions called on-event. * */ function reviseConditional(buttonsource) {    var fieldset = breadcrumbFind(buttonsource, 'FIELDSET');	setElementClass(fieldset, 'conditional_metadata');        if (!checkStackForFieldset(fieldset)) {        var undo_button = INPUT({'type':'button','value':_('Undo')},null);        attachToElementEvent(undo_button,'click',partial(popStack, fieldset));        fieldset.appendChild(undo_button);        // initialise the stack.        getStackForFieldset(fieldset);        updateFieldset(fieldset);		buttonsource.parentNode.removeChild(buttonsource);	}		}/* Fieldset creation and update. * */function initialiseConditionalFieldsets() {        var fieldsets = getElementsByTagAndClassName('FIELDSET','conditional_metadata');    simpleLog('DEBUG','found fieldsets: '+fieldsets.length);    // triggers initial update - since this contains no "fixed" vars, it'll remove "unfixed" widgets     // and insert the initial (master) field.     for (var i=0; i<fieldsets.length; i++) {        if (!checkStackForFieldset(fieldsets[i])) {        var undo_button = INPUT({'type':'button','value':_('Undo')},null);        attachToElementEvent(undo_button,'click',partial(popStack, fieldsets[i]));        fieldsets[i].appendChild(undo_button);        // initialise the stack.        getStackForFieldset(fieldsets[i]);        updateFieldset(fieldsets[i]);	}    }}addLoadEvent(initialiseConditionalFieldsets);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -