Integrating a personalized dropdown feature into the Froala editor within an AngularJS environment

After searching for a JavaScript rich text editor that doesn't use frames and allows easy customization of the toolbar with custom dropdowns, I came across the Froala editor. It also offers AngularJS-friendly directives. Previously, I tried using TextAngular, but it lacked an easy way to add dropdowns.

The Froala editor is well-documented, but I'm facing challenges integrating custom dropdowns through the Angular directive. I need to define and register the dropdown using the editor instance retrieved from the options set in my controller. However, this approach is proving difficult as the editor instance reference is still undefined when trying to define the dropdown. You can find the complete code example here:

http://plnkr.co/edit/PnqnifGE54vMUzk28Jwf

My test code snippet is as follows:

function MainController($scope) {
  var defaultHtml = "<span style=\"color:red\">Hello</span>, world!";

  function addDropdown() {
    var editor = $scope.froalaOptions.froalaEditor;
    editor.DefineIcon("myDropdown", {
      NAME: "myDropdown"
    });
    // Other dropdown configurations here...
  }
  
  // More controller logic and setup here...

}
var app = angular.module("test", [
  "ui.bootstrap", "froala"
]);
app.controller("mainController", MainController);

Uncommenting the call to the addDropdown function causes an error due to the undefined editor instance reference. Besides this issue, everything else works fine. Can anyone provide guidance on the correct approach within the Angular context?

Answer №1

I received helpful responses from both the creator of the AngularJS directive and the Froala support team (much appreciated!), so I cannot take credit for this information. It was too detailed to be a simple comment, hence why I am sharing it here: please refer to https://github.com/froala/angular-froala/issues/44.

Basically, there is no straightforward "Angular-like" method to achieve this task: we still have to "execute those commands on the global $.FroalaEditor object before configuring your editor options". A revised plnkr example can be found here:

http://plnkr.co/edit/HkWCugpVv6jT3tsgEYGZ

In essence, the function appears as follows:

function addDropdown() {
    $.FroalaEditor.DefineIcon("myDropdown", {
      NAME: "cog"
    });
    $.FroalaEditor.RegisterCommand("myDropdown", {
      title: "Example",
      type: "dropdown",
      focus: true,
      undo: true,
      refreshAfterCallback: true,
      options: {
        "v1": "Option 1",
        "v2": "Option 2"
      },
      callback: function(cmd, val) {
        console.log(val);
      },
      refresh: function($btn) {
        console.log("do refresh");
      },
      refreshOnShow: function($btn, $dropdown) {
        console.log("do refresh when show");
      }
    });
}

Additionally, it is important to specify not only the toolbarButtons array (which in V2 indicates the buttons to display in the toolbar only if the editor width is >= 1200), but also toolbarButtonsMD, toolbarButtonsSM, and toolbarButtonsXS to define button visibility at smaller screen widths.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best method to compare dates in JavaScript/JQuery to determine if one comes before the other?

I am completely new to JavaScript development and I need to accomplish the task below: I have 2 input tags containing 2 strings representing dates in the format 01/12/2014 (DAY/MONTH/YEAR). These input tags are used to search for objects with a date field ...

What is preventing my cookie from being saved?

Whenever a user clicks "sign in", I trigger a POST ajax request. Here is the function handling that request: app.post('/auth', function(req,res,next){ var token = req.body.token ...

The && operator is not executed when the button is disabled

There is a button on the page that has been disabled using the [disabled] property. <button class="btn btn-primary center-block" (click)="sign(sf.value)" [disabled]="validateInsuredFirstName(firstName.value) && validateInsuredLastName(l ...

Verify if a specific key is present in associative arrays

Can you please explain the correct way to check for the existence of a key in associative arrays? For instance: var mydata = { key1: '', key2: { subkey1: { subkey1_1: { value1: '' ...

Angular's $watch function does not receive the parameter 'newVal'

I have been facing an issue displaying messages from a backend response in an Angular AJAX call. I am using a ShareDataService to share data between different controllers. 'use strict'; var angularApp = angular.module('angularApp'); ...

After compiling, global variables in Vue.js 2 + Typescript may lose their values

I am currently working on a Vue.js 2 project that uses Typescript. I have declared two variables in the main.ts file that I need to access globally throughout my project: // ... Vue.prototype.$http = http; // This library is imported from another file and ...

The resend email feature isn't functioning properly on the production environment with next js, however, it works seamlessly in the development environment

import { EmailTemplate } from "@/components/email-template"; import { Resend } from "resend"; const resend = new Resend("myApiKey"); // this works only in dev // const resend = new Resend(process.env.NEXT_PUBLIC_RESEND_API_KE ...

AngularJS ng-include nested form configuration

My application utilizes nested ng-includes. The outer include is a login screen for one application while the inner ng-include includes two templates. The login screen is designed in two steps where the email is checked first and then the password entered. ...

Steps for styling an AngularJS Popup:1. Determine the desired appearance for

I have some code that displays a popup when clicked, along with its automatically generated CSS. I want to be able to make changes to the CSS by adding IDs or classes to it. How can I assign IDs or classes to this element so that I can easily target them f ...

How to implement an Angular Animation that is customizable with an @Input() parameter?

Have you ever wondered if it's possible to integrate custom parameters into an Angular animation by passing them through a function, and then proceed to use the resulting animation in a component? To exemplify this concept, consider this demo where t ...

My Tailwind CSS toggle button disappears in dark mode, why is that happening?

<button aria-label="Toggle Dark Mode" type="button" className="lg:inline-flex lg:w-40 md:w-screen p-3 h-12 w-12 order-2 md:order-3" onClick={() => setTheme(theme === 'dark' ? &ap ...

When my route in NextJS processes the request, it returns a ReadableStream from req

I am encountering an issue with my code and I have tried looking for solutions in other similar questions without any success. Is there anyone who can assist me? Here is the content of my route.js file: import dbConnect from "@/lib/dbConnect"; i ...

Changes in a deep copy of an object in a child component are directly reflected in the parent object in VueJS

Let's begin by discussing the layout. I have a page dedicated to showcasing information about a specific company, with a component Classification.vue. This component displays categories of labels and the actual labels assigned to the current company. ...

A step-by-step guide to incorporating expandable and collapsible images within a div element using X

I have successfully created dynamic divs with some data that expand and collapse perfectly. Now I am looking to add expand and collapse images on these divs. I am relatively new to designing in xslt. <xsl:template match="category[key!='org.model.C ...

Leverage the `dispatch` hook within a useEffect function

When it comes to triggering an action upon the React component unmounting, I faced a challenge due to hooks not allowing the use of componentWillUnmount. In order to address this, I turned to the useEffect hook: const dispatch = useDispatch(); useEffect(( ...

Enhancing URLs with jQuery/AJAX: A Comprehensive Guide to Adding Parameters

Whenever I try to use the get method on an HTML form, the submitted data automatically appears in the URL. You can see what I mean here. Interestingly, when attempting to achieve the same result with JQuery and AJAX using the get method, the data doesn&apo ...

Steps for combining two collections into a single output in MongoDB with Node.js

My MongoDB collections consist of data that I need to merge using the $lookup operation. However, the result I get contains a nested array structure that is not ideal. I am looking for a solution to format the result as shown below: First collection locati ...

Subcomponent in React is not rendering as expected

I have a primary React component with a subcomponent named AttributeInput. To prevent redundancy in my code, I moved some of the logic from the main component to a method within AttributeInput. My attempt at referencing this code looks like this: {this.s ...

In Javascript, assign default values to an array and update them with new values upon the click of a

My goal is to create a quiz that populates an array. Initially, the quiz is empty but I aim to assign it a default value. This serves as my question navigation: /** * * @param {int} question * @returns {QuizPart} ...

Executing JavaScript functions when a browser tab is closed

When a user closes the browser tab, I want to call a specific JavaScript function. However, I only want this to occur when the user is actually closing the browser, not during page refreshes, link navigation, form submissions, or pressing the back button. ...