2

I'm working with MarkDownDeep. It has a similar "insert image" function like SO does.

I'd like to extend this function to use a bootstrap modal that would allow the user to upload their own images or at least get a typeahead working so that a user could pick something uploaded from another page.

I've tried to use a callback function in replace of the the prompt below but it doesn't insert str into the textbox like the original function.

pub.cmd_img = function (ctx) {
    ctx.TrimSelection();
    if (!ctx.CheckSimpleSelection())
        return false;

    imagePopUp(function(results) {

        $("#" + ctx.m_textarea.id).focus();

        var url = results;

        if (url === null)
            return false;

        var alttext = ctx.getSelectedText();
        if (alttext.length == 0) {
            alttext = "Image Text";
        }

        var str = "![" + alttext + "](" + url + ")";

        ctx.ReplaceSelection(str);
        ctx.m_selectionStart += 2;
        ctx.m_selectionEnd = ctx.m_selectionStart + alttext.length;
        return true;
    });
    return false;

uploadImageUrl is a holding variable because at the moment I'm using an iframe inside the modal so the user can upload, the iframe then sets parent.uploadImageUrl

uploadImageUrl = "baz"; 
function imagePopUp(callback) {
    $('#imageUpload').modal('show');

    $('#confirmTrue').click(function () {
        $('#imageUpload').modal('hide');

        if (callback) callback(uploadImageUrl);
    });
}

Original

 pub.cmd_img = function (ctx) {
        ctx.TrimSelection();
        if (!ctx.CheckSimpleSelection())
            return false;

        var url = prompt("Enter the image URL"); //need to change what this does

        if (url === null)
            return false;

        var alttext = ctx.getSelectedText();
        if (alttext.length == 0) {
            alttext = "Image Text";
        }

        var str = "![" + alttext + "](" + url + ")";

        ctx.ReplaceSelection(str);
        ctx.m_selectionStart += 2;
        ctx.m_selectionEnd = ctx.m_selectionStart + alttext.length;
        return true;
    };

You can see my none-working fiddle

Eonasdan
  • 7,563
  • 8
  • 55
  • 82

2 Answers2

4

This should do the trick:

pub.cmd_img = function(ctx){

   ctx.TrimSelection();
   if (!ctx.CheckSimpleSelection())
      return false;

   //call popup
   imagePopUp(function(results){

      $("#" + ctx.m_textarea.id).focus();

      var url = results;
      if (url === null)
         return false;

      var alttext = ctx.getSelectedText();
      if (alttext.length == 0){
         alttext = "Image Text";
      }

      var str = "![" + alttext + "](" + url + ")";
      var editor = $(ctx.m_textarea).data("mdd");

      editor.cmd_img_core = function(state){
         state.ReplaceSelection(str);
         state.m_selectionStart += 2;
         state.m_selectionEnd = state.m_selectionStart + alttext.length;
         return true;
      };

      editor.InvokeCommand("img_core");
      delete editor.cmd_img_core;
   });             
   return false;
};
Moses Machua
  • 11,245
  • 3
  • 36
  • 50
Richard Deeming
  • 29,830
  • 10
  • 79
  • 151
  • a brief test looks like it works! I've got some other things on my plate this morning so I'll need some time to test the rest of of it. – Eonasdan Nov 20 '12 at 14:05
  • also, could you explain what you did? – Eonasdan Nov 20 '12 at 14:10
  • The `InvokeCommand` function performs some additional processing when the command function returns `true`. Your original function was returning `false`, because you're waiting for the user to select a file. You either need to replicate the extra processing when the user has selected the file, or call `InvokeCommand` again, passing the selected file somehow. The simplest option seemed to be to add a temporary command to the editor, invoke it, and then delete it. – Richard Deeming Nov 20 '12 at 14:28
  • sweet! it works just the way I hoped it would! I shall promptly reward you with the bounty as in 10 hours [eh..give or take :)] – Eonasdan Nov 21 '12 at 02:11
  • This has helped me no end, thank you. However, I am finding that if I try to add a second image, the InvokeCommand runs twice, leaving me with a mangled tag like this: ![![Image Text](http://127.0.0.1:10000/devstoreaccount1/devstore/b7f301ac-5d83-44cc-b29c-a36d27de6cb2building_final.png)](http://127.0.0.1:10000/devstoreaccount1/devstore/b7f301ac-5d83-44cc-b29c-a36d27de6cb2building_final.png) and if I try and add a third image, it runs 3 times inserting the Url again. The logic around that ReplaceSelection needs to be looked at. – Mark Jones Feb 13 '14 at 09:20
  • @MarkJones: I can't reproduce that problem in Firefox, Chrome or IE. – Richard Deeming Feb 13 '14 at 10:45
  • How are you guys calling this function. do you have an example I can download? – James Pressley Aug 25 '15 at 08:10
1

I had some issues with this code, in that when I tried to insert a second image into the editor it would insert the URL twice, and the third image three times and so on. It seemed to be running the imagePopup callback the same number of times as the number of images inserted. I resolved the issue with the following changes. Not perfect but it works:

var isImageInserted = false; 
pub.cmd_img = function (ctx) {
    ctx.TrimSelection();
    if (!ctx.CheckSimpleSelection())
        return false;

    isImageInserted = false;
    //call popup
    imagePopUp(function (results) {

        $("#" + ctx.m_textarea.id).focus();

        var url = results;
        if (url === null)
            return false;

        var alttext = ctx.getSelectedText();
        if (alttext.length == 0) {
            alttext = "Image Text";
        }
        var str = "";
        if (!alttext.indexOf(url) > -1) {
            str = "![" + alttext + "](" + url + ")";
        } else {
            str = alttext;
        }

        var editor = $(ctx.m_textarea).data("mdd");
        if (!isImageInserted) {
            editor.cmd_img_core = function (state) {
                state.ReplaceSelection(str);
                state.m_selectionStart += 2;
                state.m_selectionEnd = state.m_selectionStart + alttext.length;
                isImageInserted = true;
                return true;
            };

            editor.InvokeCommand("img_core");
            delete editor.cmd_img_core;
        }

    });
    return false;

}

hope this helps someone else as pretty much every markdowndeep search seems to come here.

Mark Jones
  • 1,461
  • 1
  • 14
  • 23