Skip to main content

Spell Check

  • 4 minutes to read

The RichEdit control allows you to use third-party tools to implement spell check. Use the client spellCheck option or the server SpellCheck(Action<SpellCheckBuilder>) method (for .NET Core) to specify the following settings:

Client Property .NET Core Server Method Description
enabled Enabled(Boolean) Specifies whether the spell check is enabled.
checkWordSpelling CheckWordSpelling(String) A function that checks a word.
suggestionCount SuggestionCount(Int32) The maximum number of suggested words that can be displayed in the context menu.
addWordToDictionary AddWordToDictionary(String) A function that is called when a user clicks the Add to Dictionary context menu command.

Context menu with suggested words

The isEnabled property allows you to enable and disable spell check at runtime:

richEdit.spellCheckerOptions.isEnabled = false;

Tip

If your application is built on the Angular framework, refer to following section for instructions on how to implement spell check in the RichEdit: Angular Application - Spell Check.

Create an nspell Bundle for the RichEdit

The RichEdit npm package includes a webpack configuration file that allows you to compile the nspell library and dictionaries into a package bundle. The configuration file references the English dictionary.

Follow the steps below to compile the bundle.

  1. Run the following commands within the root directory:

    npm i nspell@2.1.5 --save-dev
    npm i webpack@5.91.0 --save-dev
    npm i webpack-cli@5.1.4 --save-dev
    npm i dictionary-en@3.2.0 --save-dev
    

    If you need additional dictionaries, install them as follows:

    npm i dictionary-fr@2.8.0 --save-dev
    
  2. Add the import directive for every additional dictionary to the node_modules/devexpress-richedit/bin/nspell-index.js file.

  3. Register additional dictionaries with a corresponding “lang” attribute prior to the default English dictionary to use them first while spell checking.

    import enAff from 'dictionary-en/index.aff';
    import enDic from 'dictionary-en/index.dic';
    
    import frAff from 'dictionary-fr/index.aff';
    import frDic from 'dictionary-fr/index.dic';
    
    export const nspell = nspellImport;
    export const dictionaries = [
        { lang: 'fr', aff: frAff, dic: frDic },
        { lang: 'en', aff: enAff, dic: enDic },
    ];
    
  4. Run the following command that builds an nspell bundle according to the node_modules/devexpress-richedit/bin/nspell.webpack.config.js configuration file:

    npx webpack --mode production --config=node_modules/devexpress-richedit/bin/nspell.webpack.config.js
    

    The command creates the node_modules/devexpress-richedit/dist/custom/nspell.js file. A script in the file appends the nspell object to the JavaScript window object.

Use nspell With Web Worker

  1. Create the spell-checker-worker.js file with the following content:

    importScripts('./nspell.js');
    var checkers;
    
    function checkWord(word) {
        for(var i = 0; i < checkers.length; i++)
            if(checkers[i].correct(word))
                return true;
        return false;
    }
    
    function getSuggestions(word) {
        var suggestions = [];
        for (var i = 0; i < checkers.length; i++)
            suggestions = suggestions.concat(checkers[i].suggest(word));
        return suggestions;
    }
    
    onmessage = function(e) {
        if (!checkers) {
            checkers = [];
            NSpell.dictionaries.forEach(function (dic) {
                checkers.push(new NSpell.nspell(dic));
            });
        }
        switch(e.data.command) {
            case 'checkWord': {
                var isCorrect = checkWord(e.data.word);
                postMessage({
                    id: e.data.id,
                    isCorrect: isCorrect,
                    suggestions: isCorrect ? undefined : getSuggestions(e.data.word),
                });
                break;
            }
            case 'addWord': {
                checkers[0].add(e.data.word);
                break;
            }
        }
    };
    
  2. Place the nspell.js and spell-checker-worker.js files into the directory that contains the control scripts (wwwroot for .NET Core, Scripts for MVC and Web Forms).

  3. For an application on a client framework, add the following code to the page that contains the RichEdit control:

    var spellCheckerWorker = null;
    var spellCheckerCallbacks = Object.create(null);
    var spellCheckerWorkerCommandId = 0;
    ...
    options.spellCheck.enabled = true;
    options.spellCheck.suggestionCount = 5;
    options.spellCheck.checkWordSpelling = function (word, callback) {
        if (!spellCheckerWorker) {
            var myDictionary = JSON.parse(localStorage.getItem('myDictionary')) || [];
            spellCheckerWorker = new Worker('./spell-checker-worker.js');
            myDictionary.forEach(function (word) {
                spellCheckerWorker.postMessage({
                    command: 'addWord',
                    word: word,
                });
            });
    
            spellCheckerWorker.onmessage = function (e) {
                var savedCallback = spellCheckerCallbacks[e.data.id];
                delete spellCheckerCallbacks[e.data.id];
                savedCallback(e.data.isCorrect, e.data.suggestions);
            };
        }
    
        var currId = spellCheckerWorkerCommandId++;
        spellCheckerCallbacks[currId] = callback;
        spellCheckerWorker.postMessage({
            command: 'checkWord',
            word: word,
            id: currId,
        });
    };
    options.spellCheck.addWordToDictionary = function(word) {
        var myDictionary = JSON.parse(localStorage.getItem('myDictionary')) || [];
        myDictionary.push(word);
        localStorage.setItem('myDictionary', JSON.stringify(myDictionary));
    
        spellCheckerWorker.postMessage({
            command: 'addWord',
            word: word,
        });
    };
    

    For an application on the .NET Core framework, add a script file with the following content into the wwwroot directory and specify spell check options in the RichEdit builder object:

    var spellCheckerWorker = null;
    var spellCheckerCallbacks = Object.create(null);
    var spellCheckerWorkerCommandId = 0;
    function checkWordSpelling(word, callback) {
        if (!spellCheckerWorker) {
            var myDictionary = JSON.parse(localStorage.getItem('myDictionary')) || [];
            spellCheckerWorker = new Worker('./spell-checker-worker.js');
            myDictionary.forEach(function (word) {
                spellCheckerWorker.postMessage({
                    command: 'addWord',
                    word: word,
                });
            });
    
            spellCheckerWorker.onmessage = function (e) {
                var savedCallback = spellCheckerCallbacks[e.data.id];
                delete spellCheckerCallbacks[e.data.id];
                savedCallback(e.data.isCorrect, e.data.suggestions);
            };
        }
    
        var currId = spellCheckerWorkerCommandId++;
        spellCheckerCallbacks[currId] = callback;
        spellCheckerWorker.postMessage({
            command: 'checkWord',
            word: word,
            id: currId,
        });
    };
    function addWordToDictionary(word) {
        var myDictionary = JSON.parse(localStorage.getItem('myDictionary')) || [];
        myDictionary.push(word);
        localStorage.setItem('myDictionary', JSON.stringify(myDictionary));
    
        spellCheckerWorker.postMessage({
            command: 'addWord',
            word: word,
        });
    };
    
    <script src="~/rich-scripts.js"></script>
    ...
    @(Html.DevExpress().RichEdit("richEdit")
        .SpellCheck (s => {
            s.Enabled(true);
            s.SuggestionCount(5);
            s.AddWordToDictionary("addWordToDictionary");
            s.CheckWordSpelling("checkWordSpelling");
        })
    )