3686aa2f0d98c79401498560aae71e2f62e6f534
[atutor.git] / docs / jscripts / infusion / components / inlineEdit / js / InlineEdit.js
1 var fluid_1_4=fluid_1_4||{};(function($,fluid){function sendKey(control,event,virtualCode,charCode){var kE=document.createEvent("KeyEvents");kE.initKeyEvent(event,1,1,null,0,0,0,0,virtualCode,charCode);control.dispatchEvent(kE)}fluid.setCaretToEnd=function(control,value){var pos=value?value.length:0;try{control.focus();if(control.setSelectionRange){control.setSelectionRange(pos,pos);if($.browser.mozilla&&pos>0){sendKey(control,"keypress",92,92);sendKey(control,"keydown",8,0);sendKey(control,"keypress",8,0)}}else{if(control.createTextRange){var range=control.createTextRange();range.move("character",pos);range.select()}}}catch(e){}};var switchToViewMode=function(that){that.editContainer.hide();that.displayModeRenderer.show()};var cancel=function(that){if(that.isEditing()){setTimeout(function(){that.editView.value(that.model.value)},1);switchToViewMode(that);that.events.afterFinishEdit.fire(that.model.value,that.model.value,that.editField[0],that.viewEl[0])}};var finish=function(that){var newValue=that.editView.value();var oldValue=that.model.value;var viewNode=that.viewEl[0];var editNode=that.editField[0];var ret=that.events.onFinishEdit.fire(newValue,oldValue,editNode,viewNode);if(ret===false){return }that.updateModelValue(newValue);that.events.afterFinishEdit.fire(newValue,oldValue,editNode,viewNode);switchToViewMode(that)};var bindEditFinish=function(that){if(that.options.submitOnEnter===undefined){that.options.submitOnEnter="textarea"!==fluid.unwrap(that.editField).nodeName.toLowerCase()}function keyCode(evt){return evt.keyCode?evt.keyCode:(evt.which?evt.which:0)}var escHandler=function(evt){var code=keyCode(evt);if(code===$.ui.keyCode.ESCAPE){that.textEditButton.focus(0);cancel(that);return false}};var finishHandler=function(evt){var code=keyCode(evt);if(code!==$.ui.keyCode.ENTER){that.textEditButton.blur();return true}else{finish(that);that.textEditButton.focus(0)}return false};if(that.options.submitOnEnter){that.editContainer.keypress(finishHandler)}that.editContainer.keydown(escHandler)};var bindBlurHandler=function(that){if(that.options.blurHandlerBinder){that.options.blurHandlerBinder(that)}else{var blurHandler=function(evt){if(that.isEditing()){finish(that)}return false};that.editField.blur(blurHandler)}};var initializeEditView=function(that,initial){if(!that.editInitialized){fluid.inlineEdit.renderEditContainer(that,!that.options.lazyEditView||!initial);if(!that.options.lazyEditView||!initial){that.editView=fluid.initSubcomponent(that,"editView",that.editField);$.extend(true,that.editView,fluid.initSubcomponent(that,"editAccessor",that.editField));bindEditFinish(that);bindBlurHandler(that);that.editView.refreshView(that);that.editInitialized=true}}};var edit=function(that){initializeEditView(that,false);var viewEl=that.viewEl;var displayText=that.displayView.value();that.updateModelValue(that.model.value===""?"":displayText);if(that.options.applyEditPadding){that.editField.width(Math.max(viewEl.width()+that.options.paddings.edit,that.options.paddings.minimumEdit))}that.displayModeRenderer.hide();that.editContainer.show();setTimeout(function(){fluid.setCaretToEnd(that.editField[0],that.editView.value());if(that.options.selectOnEdit){that.editField[0].select()}},0);that.events.afterBeginEdit.fire()};var clearEmptyViewStyles=function(textEl,styles,originalViewPadding){textEl.removeClass(styles.defaultViewStyle);textEl.css("padding-right",originalViewPadding);textEl.removeClass(styles.emptyDefaultViewText)};var showDefaultViewText=function(that){that.displayView.value(that.options.defaultViewText);that.viewEl.css("padding-right",that.existingPadding);that.viewEl.addClass(that.options.styles.defaultViewStyle)};var showNothing=function(that){that.displayView.value("");if($.browser.msie){if(that.viewEl.css("display")==="inline"){that.viewEl.css("display","inline-block")}}};var showEditedText=function(that){that.displayView.value(that.model.value);clearEmptyViewStyles(that.viewEl,that.options.styles,that.existingPadding)};var refreshView=function(that,source){that.displayView.refreshView(that,source);if(that.editView){that.editView.refreshView(that,source)}};var initModel=function(that,value){that.model.value=value;that.refreshView()};var updateModelValue=function(that,newValue,source){var comparator=that.options.modelComparator;var unchanged=comparator?comparator(that.model.value,newValue):that.model.value===newValue;if(!unchanged){var oldModel=$.extend(true,{},that.model);that.model.value=newValue;that.events.modelChanged.fire(that.model,oldModel,source);that.refreshView(source)}};var makeIsEditing=function(that){var isEditing=false;that.events.onBeginEdit.addListener(function(){isEditing=true});that.events.afterFinishEdit.addListener(function(){isEditing=false});return function(){return isEditing}};var makeEditHandler=function(that){return function(){var prevent=that.events.onBeginEdit.fire();if(prevent===false){return false}edit(that);return true}};var initTooltips=function(that){var tooltipOptions={content:that.options.tooltipText,position:{my:"left top",at:"left bottom",offset:"0 5"},target:"*",delay:that.options.tooltipDelay,styles:{tooltip:that.options.styles.tooltip}};fluid.tooltip(that.viewEl,tooltipOptions);if(that.textEditButton){fluid.tooltip(that.textEditButton,tooltipOptions)}};var calculateInitialPadding=function(viewEl){var padding=viewEl.css("padding-right");return padding?parseFloat(padding):0};var setupInlineEdit=function(componentContainer,that){if(that.editContainer){that.editContainer.hide()}if(that.tooltipEnabled()){initTooltips(that)}that.decorators=fluid.initSubcomponents(that,"componentDecorators",[that,fluid.COMPONENT_OPTIONS])};var setupInlineEdits=function(editables,options){var editors=[];editables.each(function(idx,editable){editors.push(fluid.inlineEdit($(editable),options))});return editors};fluid.inlineEdit=function(componentContainer,userOptions){var that=fluid.initView("inlineEdit",componentContainer,userOptions);that.viewEl=fluid.inlineEdit.setupDisplayText(that);that.displayView=fluid.initSubcomponent(that,"displayView",that.viewEl);$.extend(true,that.displayView,fluid.initSubcomponent(that,"displayAccessor",that.viewEl));that.model={value:""};that.edit=makeEditHandler(that);that.isEditing=makeIsEditing(that);that.finish=function(){finish(that)};that.cancel=function(){cancel(that)};that.tooltipEnabled=function(){return that.options.useTooltip&&$.fn.tooltip};that.refreshView=function(source){refreshView(that,source)};that.updateModelValue=function(newValue,source){updateModelValue(that,newValue,source)};that.updateModel=function(newModel,source){updateModelValue(that,newModel.value,source)};that.existingPadding=calculateInitialPadding(that.viewEl);initModel(that,that.displayView.value());that.displayModeRenderer=that.options.displayModeRenderer(that);initializeEditView(that,true);setupInlineEdit(componentContainer,that);return that};fluid.inlineEdit.setupEditField=function(editStyle,editField){var eField=$(editField);eField=eField.length?eField:$("<input type='text' class='flc-inlineEdit-edit'/>");eField.addClass(editStyle);return eField};fluid.inlineEdit.setupEditContainer=function(displayContainer,editField,editContainer){var eContainer=$(editContainer);eContainer=eContainer.length?eContainer:$("<span></span>");displayContainer.after(eContainer);eContainer.append(editField);return eContainer};fluid.inlineEdit.defaultEditModeRenderer=function(that){var editField=fluid.inlineEdit.setupEditField(that.options.styles.edit,that.editField);var editContainer=fluid.inlineEdit.setupEditContainer(that.displayModeRenderer,editField,that.editContainer);var editModeInstruction=fluid.inlineEdit.setupEditModeInstruction(that.options.styles.editModeInstruction,that.options.strings.editModeInstruction);var id=fluid.allocateSimpleId(editModeInstruction);editField.attr("aria-describedby",id);fluid.inlineEdit.positionEditModeInstruction(editModeInstruction,editContainer,editField);return{container:editContainer,field:editField}};fluid.inlineEdit.renderEditContainer=function(that,lazyEditView){that.editContainer=that.locate("editContainer");that.editField=that.locate("edit");if(that.editContainer.length!==1){if(that.editContainer.length>1){fluid.fail("InlineEdit did not find a unique container for selector "+that.options.selectors.editContainer+": "+fluid.dumpEl(that.editContainer))}}if(!lazyEditView){return }var editElms=that.options.editModeRenderer(that);if(editElms){that.editContainer=editElms.container;that.editField=editElms.field}};fluid.inlineEdit.setupEditModeInstruction=function(editModeInstructionStyle,editModeInstructionText){var editModeInstruction=$("<p></p>");editModeInstruction.addClass(editModeInstructionStyle);editModeInstruction.text(editModeInstructionText);return editModeInstruction};fluid.inlineEdit.positionEditModeInstruction=function(editModeInstruction,editContainer,editField){editContainer.append(editModeInstruction);editField.focus(function(){editModeInstruction.show();var editFieldPosition=editField.offset();editModeInstruction.css({left:editFieldPosition.left});editModeInstruction.css({top:editFieldPosition.top+editField.height()+5})})};fluid.inlineEdit.setupDisplayModeContainer=function(styles,displayModeWrapper){var displayModeContainer=$(displayModeWrapper);displayModeContainer=displayModeContainer.length?displayModeContainer:$("<span></span>");displayModeContainer.addClass(styles.displayView);return displayModeContainer};fluid.inlineEdit.setupDisplayText=function(that){var viewEl=that.locate("text");viewEl.attr("tabindex","-1");viewEl.addClass(that.options.styles.text);return viewEl};fluid.inlineEdit.setupTextEditButton=function(that){var opts=that.options;var textEditButton=that.locate("textEditButton");if(textEditButton.length===0){var markup=$("<a href='#_' class='flc-inlineEdit-textEditButton'></a>");markup.addClass(opts.styles.textEditButton);markup.text(opts.tooltipText);fluid.inlineEdit.updateTextEditButton(markup,that.model.value||opts.defaultViewText,opts.strings.textEditButton);that.events.modelChanged.addListener(function(){fluid.inlineEdit.updateTextEditButton(markup,that.model.value||opts.defaultViewText,opts.strings.textEditButton)});that.locate("text").after(markup);textEditButton=that.locate("textEditButton")}return textEditButton};fluid.inlineEdit.updateTextEditButton=function(textEditButton,value,stringTemplate){var buttonText=fluid.stringTemplate(stringTemplate,{text:value});textEditButton.text(buttonText)};fluid.inlineEdit.bindHoverHandlers=function(displayModeRenderer,invitationStyle){var over=function(evt){displayModeRenderer.addClass(invitationStyle)};var out=function(evt){displayModeRenderer.removeClass(invitationStyle)};displayModeRenderer.hover(over,out)};fluid.inlineEdit.bindHighlightHandler=function(element,displayModeRenderer,styles){element=$(element);var focusOn=function(){displayModeRenderer.addClass(styles.focus);displayModeRenderer.addClass(styles.invitation)};var focusOff=function(){displayModeRenderer.removeClass(styles.focus);displayModeRenderer.removeClass(styles.invitation)};element.focus(focusOn);element.blur(focusOff)};fluid.inlineEdit.bindMouseHandlers=function(element,edit){element=$(element);var triggerGuard=fluid.inlineEdit.makeEditTriggerGuard(element,edit);element.click(function(e){triggerGuard(e);return false})};fluid.inlineEdit.bindKeyboardHandlers=function(element,edit){element=$(element);element.attr("role","button");var guard=fluid.inlineEdit.makeEditTriggerGuard(element,edit);fluid.activatable(element,function(event){return guard(event)})};fluid.inlineEdit.makeEditTriggerGuard=function(element,edit){var selector=fluid.unwrap(element);return function(event){var outer=fluid.findAncestor(event.target,function(elem){if(/input|select|textarea|button|a/i.test(elem.nodeName)||elem===selector){return true}});if(outer===selector){edit();return false}}};fluid.inlineEdit.defaultDisplayModeRenderer=function(that){var styles=that.options.styles;var displayModeWrapper=fluid.inlineEdit.setupDisplayModeContainer(styles);var displayModeRenderer=that.viewEl.wrap(displayModeWrapper).parent();that.textEditButton=fluid.inlineEdit.setupTextEditButton(that);displayModeRenderer.append(that.textEditButton);fluid.inlineEdit.bindHoverHandlers(displayModeRenderer,styles.invitation);fluid.inlineEdit.bindMouseHandlers(that.viewEl,that.edit);fluid.inlineEdit.bindMouseHandlers(that.textEditButton,that.edit);fluid.inlineEdit.bindKeyboardHandlers(that.textEditButton,that.edit);fluid.inlineEdit.bindHighlightHandler(that.viewEl,displayModeRenderer,styles);fluid.inlineEdit.bindHighlightHandler(that.textEditButton,displayModeRenderer,styles);return displayModeRenderer};fluid.inlineEdit.standardAccessor=function(element){var nodeName=element.nodeName.toLowerCase();return{value:function(newValue){return"input"===nodeName||"textarea"===nodeName?fluid.value($(element),newValue):$(element).text(newValue)}}};fluid.inlineEdit.standardDisplayView=function(viewEl){var that={refreshView:function(componentThat,source){if(componentThat.model.value){showEditedText(componentThat)}else{if(componentThat.options.defaultViewText){showDefaultViewText(componentThat)}else{showNothing(componentThat)}}if($.trim(componentThat.viewEl.text()).length===0){componentThat.viewEl.addClass(componentThat.options.styles.emptyDefaultViewText);if(componentThat.existingPadding<componentThat.options.paddings.minimumView){componentThat.viewEl.css("padding-right",componentThat.options.paddings.minimumView)}}}};return that};fluid.inlineEdit.standardEditView=function(editField){var that={refreshView:function(componentThat,source){if(!source||(componentThat.editField&&componentThat.editField.index(source)===-1)){componentThat.editView.value(componentThat.model.value)}}};$.extend(true,that,fluid.inlineEdit.standardAccessor(editField));return that};fluid.inlineEdits=function(componentContainer,options){options=options||{};var selectors=$.extend({},fluid.defaults("inlineEdits").selectors,options.selectors);var container=fluid.container(componentContainer);var editables=$(selectors.editables,container);return setupInlineEdits(editables,options)};fluid.defaults("inlineEdit",{selectors:{text:".flc-inlineEdit-text",editContainer:".flc-inlineEdit-editContainer",edit:".flc-inlineEdit-edit",textEditButton:".flc-inlineEdit-textEditButton"},styles:{text:"fl-inlineEdit-text",edit:"fl-inlineEdit-edit",invitation:"fl-inlineEdit-invitation",defaultViewStyle:"fl-inlineEdit-emptyText-invitation",emptyDefaultViewText:"fl-inlineEdit-emptyDefaultViewText",focus:"fl-inlineEdit-focus",tooltip:"fl-inlineEdit-tooltip",editModeInstruction:"fl-inlineEdit-editModeInstruction",displayView:"fl-inlineEdit-simple-editableText fl-inlineEdit-textContainer",textEditButton:"fl-offScreen-hidden"},events:{modelChanged:null,onBeginEdit:"preventable",afterBeginEdit:null,onFinishEdit:"preventable",afterFinishEdit:null,afterInitEdit:null},strings:{textEditButton:"Edit text %text",editModeInstruction:"Escape to cancel, Enter or Tab when finished"},paddings:{edit:10,minimumEdit:80,minimumView:60},applyEditPadding:true,blurHandlerBinder:null,submitOnEnter:undefined,modelComparator:null,displayAccessor:{type:"fluid.inlineEdit.standardAccessor"},displayView:{type:"fluid.inlineEdit.standardDisplayView"},editAccessor:{type:"fluid.inlineEdit.standardAccessor"},editView:{type:"fluid.inlineEdit.standardEditView"},displayModeRenderer:fluid.inlineEdit.defaultDisplayModeRenderer,editModeRenderer:fluid.inlineEdit.defaultEditModeRenderer,lazyEditView:false,defaultViewText:"Click here to edit",useTooltip:true,tooltipText:"Select or press Enter to edit",tooltipDelay:1000,selectOnEdit:false});fluid.defaults("inlineEdits",{selectors:{editables:".flc-inlineEditable"}})})(jQuery,fluid_1_4);