Search code examples
javascriptjquerydrupal-7ractivejs

2 way binding with textarea ractive js


I am currently facing 2 issue, i am new to Ractive js
1) As i am using type="text/ractive" and trying to use ckeditor for my textarea, which is not showing, if i remove type="text/ractive" then ckeditor is showing, how can i use both?

2) I am using Two way binding for textarea which seems to be working fine, but when textarea is replaced with ckeditor textarea plugin Two way binding doesn't work because changes are happening in ckeditor textarea, i think it updates the value based on some event as i am not changing textarea directly, it is being updated by ckeditor.

<script id="edit-template-quick" type="text/ractive">   
       // this is returning me the form
    drupal_render(drupal_get_form('xyz')); ?>
</script>

function xyz($form_id, $form_ids, $value) {  
  $form[$value] = array(
    '#type' => 'text_format',
    '#wysiwyg' => TRUE,
    '#attributes' => array(
      'value' => "{{ $value }}",
    ),
  );
  return $form;
}

    ractive = new Ractive({
       el: 'container-quick',
       template: '#edit-template-quick',

       data: {
                slides: json
       }
   });

Solution

  • 1) The purpose of using type=text/ractive or type=text/html is to keep the browser from attempting to parse the contents as javascript. It can be use to provide template:

    <script id="edit-template-quick" type="text/ractive">   
        <p>hello {{place}}</p>
    </script>
    

    It looks like your intent is to have the server put the html into the script tag? I would check in the browser to see what is actually being sent, I suspect it's failing somewhere along the line. If you are wanting to run a function in the browser, then remove the type specification.

    2) You could use a decorator, but I think a component works better to encapsulate the editor:

    var CKEditor = Ractive.extend({
        template: '<textarea>{{{text}}}</textarea>',
        onrender() {
            var editor = this.editor = CKEDITOR.replace( this.find('textarea') );
    
            editor.on( 'change', evt => {
                this.set( 'text', evt.editor.getData() );
            });
        },
        onteardown() {
            this.editor.destroy();
        }
    });
    

    Then, assuming something like components: { 'ck-editor': CKEditor } in your setup, you can use it via:

    <pre>{{doc}}</pre><ck-editor text="{{doc}}"></ck-editor>
    

    See http://jsfiddle.net/martypdx/jv15gjpr/ for example