Skip to content

Instantly share code, notes, and snippets.

@bhcleek
Created January 7, 2013 17:56
Show Gist options
  • Save bhcleek/4476979 to your computer and use it in GitHub Desktop.
Save bhcleek/4476979 to your computer and use it in GitHub Desktop.
Edit in Place
# tlInPlaceEdit controls toggling between a view mode and an edit mode by specifying an edit and a view template.
#
# Before using the tlInPlaceEdit directive, consider whether it would be better to use proper routing to control the client
#
# <tl-in-place-edit success-event-object="object" success-event-key="interpolated string" success-event="event that is raised when save succeeds">
# <editor></editor>
# <view></view>
# </tl-in-place-editor>
# tl-in-place-edit@successEvent = The name of the event to which an event listener will be hooked up to switch
# back to view mode after the submit method succeeds.
# tl-in-place-edit@success-event-object = the object on which to key to toggle back to view mode when successEvent is
# raised.
# tl-in-place-edit@success-event-key = an interpolated string value on which to key to toggle back to view mode when
# successEvent is raised.
# add class tl-in-place-edit-cancel to any element to switch back to view mode when the element is clicked
# add class tl-in-place-edit-edit to any element to switch to view mode when the element is clicked
#
# One of success-event-object or success-event-key should be specified. If neither is specified, the editor will not
# be toggled back into view mode after a successful edit. If both are specified, success-event-object takes precedence.
# The success-event-object or success-event-key is used by the event handler to compare against the 2nd event argument
# (the first is the event name itself) to only toggle back into view mode if the argument matches what was expected.
directivesModule.directive 'tlInPlaceEdit', ['$rootScope',
tlInPlaceEdit2Module = ($rootScope) ->
restrict: "E"
scope:
successEventKey: "@"
successEventObject: "="
successEvent: '@'
template: '<div class="edit-in-place-container"><div class="edit-in-place-indicator" ng-hide="isEditMode" ng-click="switchToEdit()"><i class="icon-pencil"> </i></div><div class="edit-in-place-editable" ng-transclude></div></div>'
transclude: true
replace: true
controller: ($scope, $element, $attrs, $transclude) ->
$scope.original = {} # used to revert the model to it's pre-edit state
$scope.isEditMode = false #used to control visibility of the .edit-in-place-indicator element
cachePristineData = ->
$element.find(':input').each (index, element) ->
$inputElement = angular.element element
controller = $inputElement.controller 'ngModel'
$scope.original[controller.$name] = controller.$viewValue if controller?
revertData = ->
if not $.isEmptyObject $scope.original
$element.find(':input').each ( index, element ) ->
$inputElement = angular.element element
controller = $inputElement.controller 'ngModel'
if controller? and controller.$name of $scope.original
controller.$setViewValue $scope.original[controller.$name]
controller.$render()
$scope.switchToEdit = () ->
$scope.isEditMode = true
cachePristineData()
$element.find('.edit-in-place-view').first().toggle()
$element.find('.edit-in-place-editor').first().toggle()
$scope.switchToView = () ->
$scope.isEditMode = false
revertData()
$element.find('.edit-in-place-view').first().toggle()
$element.find('.edit-in-place-editor').first().toggle()
$scope.$on $attrs.successEvent, (event, data) ->
expectedData = $scope.successEventObject ? $scope.successEventKey
if data == expectedData
$scope.original = {} # the edit was successful, so clear out the cache of pre-edit data
$scope.switchToView()
link: (scope, element, attrs, controller) ->
$element = angular.element element
$element.find('.edit-in-place-editor').on 'click.tl-in-place-edit', (eventObject) ->
scope.switchToView() if angular.element(eventObject.target).hasClass('tl-in-place-edit-cancel')
scope.$apply()
$element.find('.edit-in-place-view').on 'click.tl-in-place-edit', (eventObject) ->
scope.switchToEdit() if angular.element(eventObject.target).hasClass('tl-in-place-edit-edit')
scope.$apply()
$element.find('.edit-in-place-view').first().show()
$element.find('.edit-in-place-editor').first().hide()
]
directivesModule.directive 'editor', [
tlEditorModule = ->
restrict: "E"
template: '<div class="edit-in-place-editor" ng-transclude></div>'
replace: true
transclude: true
]
directivesModule.directive 'view', [
tlViewModule = ->
restrict: "E"
template: '<div class="edit-in-place-view" ng-transclude></div>'
transclude: true
replace: true
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment