Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how can I add a dropdown with custom font style choices for editor text #59

Closed
Ashish-Raturi opened this issue Jun 10, 2021 · 19 comments
Closed
Labels
enhancement New feature or request question Further information is requested

Comments

@Ashish-Raturi
Copy link

Ashish-Raturi commented Jun 10, 2021

Hi, you guys are great,
I have a question, how can I add my custom fonts on text editor
and custom text color, or custom color widget
thanks in advance.

@Ashish-Raturi Ashish-Raturi added the question Further information is requested label Jun 10, 2021
@tneotia
Copy link
Owner

tneotia commented Jun 10, 2021

If you want custom toolbar buttons then simply do this:

HtmlEditor(
  controller: controller,
  htmlToolbarOptions: HtmlToolbarOptions(
    defaultToolbarButtons: [
      StyleButtons(),
      FontSettingButtons(fontName: false),
      FontButtons(),
      ListButtons(),
      ParagraphButtons(),
      InsertButtons(),
      OtherButtons(),
    ],
    customToolbarButtons: [
      CustomFont(),
      CustomTextColor(),
    ],
  ),
),

defaultToolbarButtons is there to disable the default font dropdown and default color pickers. Then you use customToolbarButtons to add in your own widgets however you want to.

For implementing a custom font picker or custom color picker I highly recommend checking out how I did the default version in toolbar_widget.dart at lines 500 and 905.

Now that I think about it, there is no way for custom implementations to be updated when the font family/color/font size, etc changes in the editor. Internally I handle this with a method listening to changes sent in JSON, but I think its a good idea to add some sort of callback/listener/stream to the package so custom UI elements can be updated. Therefore I am adding the "enhancement" tag to this issue.

Let me know if you need more help with the implementation

@tneotia tneotia added the enhancement New feature or request label Jun 10, 2021
@Ashish-Raturi
Copy link
Author

hi, thanks for your reply,
I added custom drop down menu item, it's showing only the font name but not changing it on editor.
or maybe i'm doing it wrong.
can you tell me how to add it,
https://user-images.githubusercontent.com/50191855/121620011-36940c80-ca87-11eb-809f-814f324cc248.mp4

I added them here

  items: [
              CustomDropdownMenuItem(
                value: 'Courier New',
                child: PointerInterceptor(
                    child: Text('Courier New',
                        style: TextStyle(fontFamily: 'Courier'))),
              ),
              CustomDropdownMenuItem(
                value: 'sans-serif',
                child: PointerInterceptor(
                    child: Text('Sans Serif',
                        style: TextStyle(fontFamily: 'sans-serif'))),
              ),
              CustomDropdownMenuItem(
                value: 'Times New Roman',
                child: PointerInterceptor(
                    child: Text('Times New Roman',
                        style: TextStyle(fontFamily: 'Times'))),
              ),
              CustomDropdownMenuItem(
                value: 'Billabong',
                child: PointerInterceptor(
                    child: Text('Billabong',
                        style: TextStyle(
                          fontFamily: 'Billabong',
                        ))),
              ),
              CustomDropdownMenuItem(
                value: 'AlexBrush',
                child: PointerInterceptor(
                    child: Text('AlexBrush',
                        style: TextStyle(
                          fontFamily: 'AlexBrush',
                        ))),
              ),
              CustomDropdownMenuItem(
                value: 'Allura',
                child: PointerInterceptor(
                    child: Text('Allura',
                        style: TextStyle(
                          fontFamily: 'Allura',
                        ))),
              ),
              CustomDropdownMenuItem(
                value: 'Arizonia',
                child: PointerInterceptor(
                    child: Text('Arizonia',
                        style: TextStyle(
                          fontFamily: 'Arizonia',
                        ))),
              ),
            ],
            value: _fontNameSelectedItem,
            onChanged: (String? changed) async {
              void updateSelectedItem(dynamic changed) async {
                if (changed is String) {
                  setState(mounted, this.setState, () {
                    _fontNameSelectedItem = changed;
                  });
                }
              }

              if (changed != null) {
                var proceed =
                    await widget.htmlToolbarOptions.onDropdownChanged?.call(
                            DropdownType.fontName,
                            changed,
                            updateSelectedItem) ??
                        true;
                if (proceed) {
                  widget.controller
                      .execCommand('fontName', argument: changed);
                  updateSelectedItem(changed);
                }
              }
            },
          ),

and here

   //check the font name if it matches one of the predetermined fonts and update the toolbar
  if ([
    'Courier New',
    'sans-serif',
    'Times New Roman',
    'Billabong',
    'AlexBrush'
  ].contains(fontName)) {
    setState(mounted, this.setState, () {
      _fontNameSelectedItem = fontName;
    });
  } else {
    setState(mounted, this.setState, () {
      _fontNameSelectedItem = 'sans-serif';
    });
  }

pubspec.yaml

  fonts:
    - family: AlexBrush
      fonts:
        - asset: assets/fontFamily/AlexBrush-Regular.ttf
    - family: Allura
      fonts:
        - asset: assets/fontFamily/Allura-Regular.ttf
    - family: Arizonia
      fonts:
        - asset: assets/fontFamily/Arizonia-Regular.ttf
    - family: ChunkFive
      fonts:
        - asset: assets/fontFamily/Chunk_Five_Print.ttf
    - family: GrandHotel
      fonts:
        - asset: assets/fontFamily/GrandHotel-Regular.otf
    - family: GreatVibes
      fonts:
        - asset: assets/fontFamily/GreatVibes-Regular.ttf
    - family: Lobster
      fonts:
        - asset: assets/fontFamily/Lobster-Regular.ttf
    - family: OpenSans
      fonts:
        - asset: assets/fontFamily/OpenSans-Regular.ttf
        - asset: assets/fontFamily/OpenSans-Italic.ttf
          style: italic
        - asset: assets/fontFamily/OpenSans-Bold.ttf
          weight: 700

later I tried to add a new custom button also and call this controller.execCommand('fontName', argument: 'AlexBrush');
this just changing it on drop down, not change text style

@Ashish-Raturi
Copy link
Author

and one more thing, on real device, it not showing the editor, tool are showing and it's working perfectly in emulator
did need to add any kind for permission of something else.
please help

@tneotia
Copy link
Owner

tneotia commented Jun 11, 2021

2 things you are doing wrong I think:

  1. You need to add the fonts into the editor itself because webview fonts are different from Flutter fonts, you need to make a custom HTML file like this:
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <meta name="description" content="Flutter Summernote HTML Editor">
    <meta name="author" content="tneotia">
    <title>Summernote Text Editor HTML</title>
    <script src="assets/packages/html_editor_enhanced/assets/jquery.min.js"></script>
    <link href="assets/packages/html_editor_enhanced/assets/summernote-lite.min.css" rel="stylesheet">
    <script src="assets/packages/html_editor_enhanced/assets/summernote-lite.min.js"></script>
    <style>
    <!--your font faces go here-->
    </style>
    <!--darkCSS-->
</head>
<body>
<div id="summernote-2"></div>
<!--headString-->
<!--summernoteScripts-->
</body>
</html>

Then pass the file location in your HtmlEditor > HtmlEditorOptions> filePath parameter to load it.

  1. I think to change the font you need to select the text and then change it. I could be wrong though, I haven't tested this behavior in a while.

FYI I didn't test this, don't have much time right now. If it still doesn't work I'll try to get a working solution tomorrow.

and one more thing, on real device, it not showing the editor, tool are showing and it's working perfectly in emulator
did need to add any kind for permission of something else.
please help

Can you try loading the example app? If the example app works then there is some issue in your configuration.

@Ashish-Raturi
Copy link
Author

WhatsApp Image 2021-06-12 at 8 14 45 AM

here is the image, it's not showing nothing on editor.

@tneotia
Copy link
Owner

tneotia commented Jun 12, 2021

Hmm do you get any logs when opening up the editor? I have no issues on my samsung device

@tneotia
Copy link
Owner

tneotia commented Jun 12, 2021

Okay I tried to come up with an example and I was successful. I also figured out why nothing was showing on the editor. Change your app like this:
pubspec.yaml:

flutter:
  assets:
    - assets/

create assets/summernote.html:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <meta name="description" content="Flutter Summernote HTML Editor">
    <meta name="author" content="tneotia">
    <title>Summernote Text Editor HTML</title>
    <script src="file:///android_asset/flutter_assets/packages/html_editor_enhanced/assets/jquery.min.js"></script>
    <link href="file:///android_asset/flutter_assets/packages/html_editor_enhanced/assets/summernote-lite.min.css" rel="stylesheet">
    <script src="file:///android_asset/flutter_assets/packages/html_editor_enhanced/assets/summernote-lite.min.js"></script>
    <style>
        @font-face {
            font-family: 'Billabong';
            font-style: normal;
            font-weight: 400;
            src: local('Billabong'), url('https://fonts.cdnfonts.com/s/13949/Billabong.woff') format('woff');
        }
        you need to add the other fonts here!!
    </style>
</head>
<body>
<div id="summernote-2"></div>
</body>
</html>

HtmlEditor:

HtmlEditor(
  controller: controller,
  htmlEditorOptions: HtmlEditorOptions(
    filePath: "assets/summernote.html",
  ),
  htmlToolbarOptions: HtmlToolbarOptions(
    defaultToolbarButtons: [
      StyleButtons(),
    ],
    customToolbarButtons: [
      Container(
        padding: const EdgeInsets.only(left: 8.0),
        height: kMinInteractiveDimension,
        decoration:
            BoxDecoration(
                color: Theme.of(context).scaffoldBackgroundColor,
                border: Border.all(
                    color: Theme.of(context)
                        .colorScheme
                        .onSurface
                        .withOpacity(0.12))),
        child: CustomDropdownButtonHideUnderline(
          child: CustomDropdownButton<String>(
            menuMaxHeight: MediaQuery.of(context).size.height / 3,
            menuDirection: DropdownMenuDirection.down,
            items: [
              CustomDropdownMenuItem(
                value: 'Courier New',
                child: PointerInterceptor(
                    child: Text('Courier New',
                        style: TextStyle(fontFamily: 'Courier'))),
              ),
              CustomDropdownMenuItem(
                value: 'sans-serif',
                child: PointerInterceptor(
                    child: Text('Sans Serif',
                        style: TextStyle(fontFamily: 'sans-serif'))),
              ),
              CustomDropdownMenuItem(
                value: 'Times New Roman',
                child: PointerInterceptor(
                    child: Text('Times New Roman',
                        style: TextStyle(fontFamily: 'Times'))),
              ),
              CustomDropdownMenuItem(
                value: 'Billabong',
                child: PointerInterceptor(
                    child: Text('Billabong',
                        style: TextStyle(
                          fontFamily: 'Billabong',
                        ))),
              ),
              //add your other fonts here!!
            ],
            value: 'Courier New',
            onChanged: (String? changed) async {
              if (changed != null) {
                controller.execCommand('fontName', argument: changed);
              }
            },
          ),
        ),
      )
      //add the other widgets here!!
    ],
  ),
),

To simplify my testing I didn't include font asset files in the Flutter app and I did not make it so that updating the font style changes the selected item for the dropdown. You should re-implement those functionalities.

View screenshot

image

Edit:

I think its a good idea to add some sort of callback/listener/stream to the package so custom UI elements can be updated.

This has been added to the package to make your code a bit easier when you make the custom button :)

@tneotia tneotia changed the title how can I add my custom fonts on text editor how can I add a dropdown with custom font style choices for editor text Jun 12, 2021
@Ashish-Raturi
Copy link
Author

bingo, it's worked, thanks bro, you are the best. :)
keep it up, have a great day.

@AceChen1
Copy link

@tneotia @Ashish-Raturi hey , looks like this code is not work, may i know need copy those resource to my project's asset ? i am using ios device to do the POC

   <script src="assets/packages/html_editor_enhanced/assets/jquery.min.js"></script>
   <link href="assets/packages/html_editor_enhanced/assets/summernote-lite.min.css" rel="stylesheet">
   <script src="assets/packages/html_editor_enhanced/assets/summernote-lite.min.js"></script>

@tneotia
Copy link
Owner

tneotia commented Nov 18, 2021

The package asset path may be different on iOS. You can copy those assets to your project if you'd like, then the code becomes

<script src="assets/jquery.min.js"></script>
   <link href="assets/summernote-lite.min.css" rel="stylesheet">
   <script src="assets/summernote-lite.min.js"></script>

@AceChen1
Copy link

The package asset path may be different on iOS. You can copy those assets to your project if you'd like, then the code becomes

<script src="assets/jquery.min.js"></script>
   <link href="assets/summernote-lite.min.css" rel="stylesheet">
   <script src="assets/summernote-lite.min.js"></script>

@tneotia but i am afraid if copy those assets to my project, the plugin's version upgrade need more effort to do that, for i believe that those source file have a big chance will be updated in the future.

@tneotia
Copy link
Owner

tneotia commented Nov 18, 2021

Actually no, those source files are hardly ever updated. They will likely only be updated when there is a Summernote version upgrade, which is very infrequent.

@dishak331
Copy link

How to get those file names that you are using in your custom html code? we are using that and it is not doing anything.
@tneotia

@Isra0210
Copy link

I used this example, but it doesn't show the editor :/

@tneotia
Copy link
Owner

tneotia commented Apr 19, 2022

How to get those file names that you are using in your custom html code?

These are bundled into the package itself, if you are building Android (not web or iOS), it should work fine. Web and iOS will have different paths.

I used this example, but it doesn't show the editor :/

Check the logs, there might be some error that provides a clue what the issue is

@Isra0210
Copy link

How to get those file names that you are using in your custom html code?

These are bundled into the package itself, if you are building Android (not web or iOS), it should work fine. Web and iOS will have different paths.

I used this example, but it doesn't show the editor :/

Check the logs, there might be some error that provides a clue what the issue is

I tried using the web, but it didn't work. does anyone have an idea how I can customize font style on the web?

@jdayssol
Copy link

jdayssol commented Apr 2, 2023

For the web, the solution of tneotia is correct, but it is important to import the font in summernote.html in the ttf format.

@jdayssol
Copy link

jdayssol commented Apr 2, 2023

like this
@font-face {
font-family: 'Georgia';
font-style: normal;
font-weight: 400;
src: local('Georgia'), url('./font/Georgia.ttf') format('ttf');
}

@shabbirdudhiya
Copy link

Can you give me example code for this?
I tried implementing this but the ui is not updating ...I can't figure out what am i doing wrong.

  1. if i give the filePath to summernote.html file i am not able to write anything and cannot access the editor
  2. if i remove it i can access the editor but when i select my font the text inside the editor won't update

 HtmlEditor(
          htmlEditorOptions: const HtmlEditorOptions(
            // filePath: "assets/summernote.html",
            shouldEnsureVisible: true,
            hint: "Your text here...",
          ),
          htmlToolbarOptions: HtmlToolbarOptions(
            defaultToolbarButtons: [const StyleButtons()],
            customToolbarButtons: [
              Container(
                padding: const EdgeInsets.only(left: 8.0),
                child: CustomDropdownButtonHideUnderline(
                  child: CustomDropdownButton<String>(
                    menuMaxHeight: MediaQuery.of(context).size.height / 3,
                    menuDirection: DropdownMenuDirection.down,
                    items: const [
                      CustomDropdownMenuItem(
                        value: 'Kanz',
                        child: Text(
                          'Kanz',
                          style: TextStyle(
                            fontFamily: 'Kanz',
                          ),
                        ),
                      ),
                      CustomDropdownMenuItem(
                        value: 'Badri',
                        child: Text(
                          'Badri',
                          style: TextStyle(
                            fontFamily: 'Badri',
                          ),
                        ),
                      ),
                    ],
                    value: 'Kanz',
                    onChanged: (String? changed) async {
                      if (changed != null) {
                        if (kDebugMode) {
                          print(changed);
                        }
                        _.controller.execCommand('fontName', argument: changed);
                      }
                    },
                  ),
                ),
              )
            ],
            toolbarPosition: ToolbarPosition.aboveEditor,
            onDropdownChanged: (DropdownType type, dynamic changed,
                Function(dynamic)? updateSelectedItem) {
              if (kDebugMode) {
                print("dropdown '${describeEnum(type)}' changed to $changed");
              }
              return true;
            },
          ),
          callbacks: Callbacks(),
          controller: _.controller, //required
        ),

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request question Further information is requested
Projects
None yet
Development

No branches or pull requests

7 participants