jhollingworth / bootstrap-wysihtml5

Simple, beautiful wysiwyg editor
http://jhollingworth.github.com/bootstrap-wysihtml5/
MIT License
4.14k stars 1.01k forks source link

Angular JS ? #61

Open joshkurz opened 12 years ago

joshkurz commented 12 years ago

Is it possible to utilize the ng-model: directive into the textarea that is being used with wysihtml5? Currently whenever I add the ng-model="someBinding" the form does not submit the text inside of the rich text editor.

Do you have any idea why?

michalsvec commented 12 years ago

I think you will have to hack wysihtml5. Textarea used at first is not updated by wysihtml5. Try to look there.

joshkurz commented 12 years ago

At first I was trying to attach the text to the model via some scope variable. But I figured all I needed was the text after it has been rendered by the editor. So for now just calling the .val() method inside of my controller gave me access to the wysiHtml5 editor.

I do plan on creating an Open Source wyisHtml5-AngularJs widget that connects the rendered text to the scope.

joshkurz commented 12 years ago

http://jsfiddle.net/ZguhP/30/

This is almost it. The Editor is rendered with Angular, however the model is still not connected to the wysiHtml5 editor.

wgroeneveld commented 11 years ago

We used this custom directive. NOtice that we had to pry out the iframe body HTML because the txt.val() value CAN not be up to date yet due to the sync method which syncs the iframe with the textarea. If you're a fast typer, you won't save the latest html!

    .directive('wysiwygComponent', function() {
        return {
            templateUrl: 'partials/component/wysiwygComponent.html',
            restrict: 'A',

            link: function(scope, element, attrs) {
                var txt = $(element).find("textarea");

                scope.$watch('model', function(val) {
                    txt.siblings("iframe").contents().find("body").html(val);
                });

                txt.wysihtml5({
                    locale: "nl-NL",
                    stylesheets: [],
                    events: {
                        "blur": function() {
                            scope.$apply(function() {
                                var html = txt.siblings("iframe").contents().find("body").html();
                                scope.model = html;
                            });
                        }
                    }
                });
            },
            scope: { 
                label:'@',
                model:'='
            }
        };
    })

As you can see wee needed to bind both ways - the scope watch to fill the inner HTML can be left out but if you revisit the part of your site, angular re-fills the model and the wysihtml5 component doesn't really notice that...

The partial is this:

<div class="control-group">
    <label class="control-label capitalize" for="{{label}}">{{label}}:</label>
    <div class="controls" id="{{label}}_controls">
        <textarea ng-model="model" id="{{label}}_txt" class="wysiwyg"></textarea>
    </div>
</div>