How to integrate Tinymce with ASP.NET MVC

Asked

Viewed 177 times

3

Implementation of the TinyMCE in ASP.NET MVC I found a problem when realizing image upload.

The way I’m trying to implement is the following:

I have a View with the Script who calls a Controller containing a method of upload which does its job by saving the image on my server, as it is a common method and is working perfectly, I left it on Gist, in order to shorten the question a little. And mine View :

@model EuVotoAf.Models.Publicacao

@{
    ViewBag.Title = "Create";

}
<script src="~/Scripts/tinymce/tinymce.js"></script>
<h2>Create</h2>

<iframe id="form_target" name="form_target" style="display:none"></iframe>

@using (Html.BeginForm("Upload", "Publicacao", FormMethod.Post, new { @id = "my_form", target = "form_target", enctype = "multipart/form-data", style = "width:0;height:0;overflow:hidden" }))
{
    @Html.AntiForgeryToken()
    <input name="file" type="file" onchange="$('#my_form').submit();this.value='';">
}


<script type="text/javascript">
    tinymce.init({
        selector: "textarea",
        theme: "modern",
        plugins: [
            "advlist autolink lists link image charmap print preview hr anchor pagebreak",
            "searchreplace wordcount visualblocks visualchars code fullscreen",
            "insertdatetime media nonbreaking save table contextmenu directionality",
            "emoticons template paste textcolor colorpicker textpattern imagetools"
        ],
        toolbar1: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image",
        toolbar2: "print preview media | forecolor backcolor emoticons | ltr rtl",
        image_advtab: true,
        templates: [
            { title: 'Test template 1', content: 'Test 1' },
            { title: 'Test template 2', content: 'Test 2' }
        ],
        file_browser_callback: function (field_name, url, type, win) {
            if (type == 'image') $('#my_form input').click();
        }
    });
</script>

@Html.TextAreaFor(model => model.Conteudo, new { id = "my_editor", @class = "mceEditor" })

@using (Html.BeginForm("Create", "Publicacao", FormMethod.Post))
{
    @Html.AntiForgeryToken()


    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
}

What I need is basically to send the text to be saved on DB and the image to be saved to the server. If I put, the line

@Html.TextAreaFor(model => model.Conteudo, new { id = "my_editor", @class = "mceEditor" })

Within the first form it does not render on the screen, if I put in the second, the upload is not done. What, is the way I can make it work somehow.

I’m doing it wrong?

That’s right, but it contains errors in the code ?

There’s a better way to do it ?

If you have any other important details that I didn’t enter, I can put.

1 answer

4


I’m not gonna talk too much about Tinymce, I’m gonna talk about his problems and a way generic to solve.

First, you own two forms on the same page. Even using Ajax indirectly, you may have some problems.

Another thing, don’t put scripts in the middle of the View. You own a section only for her.

And his biggest problem. Tinymce is nowhere form. In short, when sending the form @using (Html.BeginForm("Create", "Publicacao", FormMethod.Post)) the value of Conteudo will not be sent.

Good, now we go to the solution generic.

First, update your View to this:

<h2>Create</h2>


<input name="file" type="file" id="file">

@using (Html.BeginForm("Create", "Publicacao", FormMethod.Post))
{
    @Html.AntiForgeryToken()

    @Html.TextAreaFor(model => model.Conteudo, new { id = "my_editor", @class = "mceEditor" })

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
}

@section Scripts{
    <script src="//cdn.tinymce.com/4/tinymce.min.js"></script>
    <script type="text/javascript">
        tinymce.init({
            selector: "textarea",
            theme: "modern",
            plugins: [
                "advlist autolink lists link image charmap print preview hr anchor pagebreak",
                "searchreplace wordcount visualblocks visualchars code fullscreen",
                "insertdatetime media nonbreaking save table contextmenu directionality",
                "emoticons template paste textcolor colorpicker textpattern imagetools"
            ],
            toolbar1: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image",
            toolbar2: "print preview media | forecolor backcolor emoticons | ltr rtl",
            image_advtab: true,
            templates: [
                { title: 'Test template 1', content: 'Test 1' },
                { title: 'Test template 2', content: 'Test 2' }
            ],
            file_browser_callback: function (field_name, url, type, win) {
                if (type == 'image') $('#my_form input').click();
            }
        });
    </script>

    <script>
        $('#file').change(function () {
            var formData = new FormData();
            var file = this.files[0];
            console.log(file)
            formData.append('file', file);
            $.ajax({
                url: '@Url.Action("Upload", "Home")',  
                type: 'POST',
                data: formData,
                processData: false,
                contentType: false,
                success: function (data) {
                    console.log(data)
                    tinyMCE.get('my_editor').setContent('dsdsdsds');
                    tinymce.activeEditor.execCommand('mceInsertContent', false, data);
                }
            });
        });
    </script>
}

And your Controller for that:

  public string Upload(HttpPostedFileBase file)
    {
        string path;
        string saveloc = "~/Uploads/Imagens";
        string filename = file.FileName;

        if (file != null && file.ContentLength > 0)
        {
            try
            {
                path = Path.Combine(HttpContext.Server.MapPath(saveloc), Path.GetFileName(filename));
                file.SaveAs(path);
            }
            catch (Exception e)
            {
                return "<script>alert('Failed: " + e + "');</script>";
            }
        }
        else
        {
            return "<script>alert('Failed: Unkown Error. This form only accepts valid images.');</script>";
        }

        return @"<img src=/Uploads/Imagens/" + filename + " >";
    }

Note that now I’m doing the Upload at the event change(). After that, I send the file to the Controller via Ajax and the return I insert in Tinymce, through the tinymce.activeEditor.execCommand('mceInsertContent', false, data);.

Note that the return of the Controller is no longer a script, but an image return @"<img src=/Uploads/Imagens/" + filename + " >";. I did it this way because if you change the WYSIWYG, the code may remain the same.

Now, if you want to add the upload on the Insert/Edit image, things change a little.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.