Skip to content

Model Not Updating Last Action #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
pgtruesdell opened this issue Jun 18, 2014 · 17 comments
Closed

Model Not Updating Last Action #15

pgtruesdell opened this issue Jun 18, 2014 · 17 comments
Assignees

Comments

@pgtruesdell
Copy link

I've noticed a peculiar issue.

When your last action is not a keystroke but an action from the menubar, like adding a link to a selected bit of text or changing font size or what have you, the model isn't being updated. If you type a bit of text and remove it, or something of that nature the model is updated and works as expected. This appears to be a design flaw in how the model is updated.

As I am not an Angular expert quite yet I would appreciate some assistance.

Thanks.

@outsideris
Copy link
Owner

I think your problem is similar with #4
The issue is fixed. Therefore check your angular-summernote's version or provide more detail to let me find bugs.

@Krooted
Copy link

Krooted commented Jun 27, 2014

Inserting an image doesn't update the ng-model. If you then perform any other action after the image is entered the image is saved to the ng-model. This has only been tested with local images using the browse function.

@outsideris
Copy link
Owner

I will check it out again.

@amondnet
Copy link

amondnet commented Jul 6, 2014

Inserting an image doesn't update the ng-model. +1)

@outsideris
Copy link
Owner

@amondnet I got it. obviously something is wrong. I'm pretty busy now, so I will check soon.

@shuhankuang
Copy link

Inserting an image doesn't update the ng-model. +1 :P

@mentat
Copy link

mentat commented Aug 14, 2014

+1

@jhoganrg
Copy link

Any progress on stabilizing the ng-model updates I too an waiting for image insert fix

@outsideris
Copy link
Owner

@jhoganrg
I'm pretty busy now. I expect to fix this within 1 or 2 weeks.

@mentat
Copy link

mentat commented Aug 22, 2014

Hi all, this is how I fixed this:

https://gist.github.com/mentat/05f906fa9b99e33308e4

I added an extra callback to the summernote insertImage function that creates an "onChange" event and a small function on angular-summernote that listens for the event and calls updateNgModel().

There is probably a much better way to do this, but this is what I came up with.

@biblicalph
Copy link

Am not entirely sure this is a good fix but works all the same with little overhead. I implemented the onfocus method to call updateNgModel.

So you can add this after the summernoteConfig.onkeyup function:

summernoteConfig.onfocus = function(evt) {
updateNgModel();
$scope.focus({evt: evt});
};

Note: The editable area gains focus after a link, image or video is inserted so this method works.

@outsideris outsideris self-assigned this Aug 25, 2014
@monad98
Copy link

monad98 commented Aug 26, 2014

@biblicalph
I got this error message when I hit refresh button on the web browser. I use chrome 36.0.1985.143

Error: [$rootScope:inprog] $digest already in progress
http://errors.angularjs.org/1.3.0-beta.18/$rootScope/inprog?p0=%24digest
at http://localhost:9000/bower_components/angular/angular.js:78:12
at beginPhase (http://localhost:9000/bower_components/angular/angular.js:13265:15)
at Scope.$apply (http://localhost:9000/bower_components/angular/angular.js:13047:11)
at updateNgModel (http://localhost:9000/scripts/angular-summernote.js:42:19)
at HTMLDivElement.summernoteConfig.onfocus (http://localhost:9000/scripts/angular-summernote.js:53:13)

53th line is a part of calling updateNgModel() in the added onfocus func.

@biblicalph
Copy link

@monad98 Ok am not entirely sure why you are getting this error but I will check and get back to you. Fingers crossed

@biblicalph
Copy link

@monad98
I am also running chrome 36.0.1985.143 and I have tested repeatedly and everything works just fine. If it helps, here is my updated angular-summernote.js file

angular.module('summernote', [])

    .controller('SummernoteController', ['$scope', '$attrs', function($scope, $attrs) {
            'use strict';

            var currentElement,
                    summernoteConfig = $scope.summernoteConfig || {};

            if (angular.isDefined($attrs.height)) {
                summernoteConfig.height = $attrs.height;
            }
            if (angular.isDefined($attrs.focus)) {
                summernoteConfig.focus = true;
            }
            if (angular.isDefined($attrs.lang)) {
                if (!angular.isDefined($.summernote.lang[$attrs.lang])) {
                    throw new Error('"' + $attrs.lang + '" lang file must be exist.');
                }
                summernoteConfig.lang = $attrs.lang;
            }

            summernoteConfig.oninit = $scope.init;
            summernoteConfig.onenter = function(evt) {
                $scope.enter({evt: evt});
            };
            summernoteConfig.onfocus = function(evt) {
                $scope.focus({evt: evt});
            };
            summernoteConfig.onblur = function(evt) {
                $scope.blur({evt: evt});
            };
            summernoteConfig.onpaste = function(evt) {
                $scope.paste({evt: evt});
            };
            summernoteConfig.onkeydown = function(evt) {
                $scope.keydown({evt: evt});
            };

            if (angular.isDefined($attrs.onImageUpload)) {
                summernoteConfig.onImageUpload = function(files, editor, welEditable) {
                    $scope.imageUpload({files: files, editor: editor, welEditable: welEditable});
                };
            }

            this.activate = function(scope, element, ngModel) {
                var updateNgModel = function() {
                    var newValue = element.code();

                    if (ngModel && ngModel.$viewValue !== newValue) {
                        ngModel.$setViewValue(newValue);
                        if ($scope.$$phase !== '$apply' || $scope.$$phase !== '$digest') {
                            scope.$apply();
                        }
                    }
                };

                summernoteConfig.onkeyup = function(evt) {
                    updateNgModel();
                    $scope.keyup({evt: evt});
                };


                summernoteConfig.onfocus = function(evt) {
                    updateNgModel();
                    $scope.focus({evt: evt});
                };

                element.summernote(summernoteConfig);

                var editor$ = element.next('.note-editor'),
                        unwatchNgModel;

                editor$.find('.note-toolbar').click(function() {
                    updateNgModel();

                    // sync ngModel in codeview mode
                    if (editor$.hasClass('codeview')) {
                        editor$.on('keyup', updateNgModel);
                        if (ngModel) {
                            unwatchNgModel = scope.$watch(function() {
                                return ngModel.$modelValue;
                            }, function(newValue, oldValue) {
                                editor$.find('.note-codable').val(newValue);
                            });
                        }
                    } else {
                        editor$.off('keyup', updateNgModel);
                        if (angular.isFunction(unwatchNgModel)) {
                            unwatchNgModel();
                        }
                    }
                });

                if (ngModel) {
                    ngModel.$render = function() {
                        element.code(ngModel.$viewValue || '');
                    };
                }

                currentElement = element;
            };

            $scope.$on('$destroy', function() {
                currentElement.destroy();
            });
        }])
    .directive('summernote', [function() {
            'use strict';

            return {
                restrict: 'EA',
                transclude: true,
                replace: true,
                require: ['summernote', '^?ngModel'],
                controller: 'SummernoteController',
                scope: {
                    summernoteConfig: '=config',
                    init: '&onInit',
                    enter: '&onEnter',
                    focus: '&onFocus',
                    blur: '&onBlur',
                    paste: '&onPaste',
                    keyup: '&onKeyup',
                    keydown: '&onKeydown',
                    imageUpload: '&onImageUpload'
                },
                template: '<div class="summernote"></div>',
                link: function(scope, element, attrs, ctrls) {
                    var summernoteController = ctrls[0],
                            ngModel = ctrls[1];

                    summernoteController.activate(scope, element, ngModel);
                }
            };
        }]);

As you can see the only addition I have made is the onfocus event. If you can, snip and replace your angular-summernote file with the above code and let me know if it works.

Regards

@monad98
Copy link

monad98 commented Sep 2, 2014

@biblicalph
Same error occurs..But I found what the problem is.
If i don't use options object, there is no error. My options object is like this.

$scope.options = {
    height: 600,
    focus: true,
    toolbar: [
        ['style', ['bold', 'italic', 'underline', 'clear']],
        ['fontsize', ['fontsize']],
        ['color', ['color']],
        ['para', ['ul', 'ol', 'paragraph']],
        ['height', ['height']],
        ['insert', ['link', 'picture','video']]
    ]
};

@outsideris
Copy link
Owner

I'm working on this.

@outsideris
Copy link
Owner

please check v0.2.3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants