How to use EJSpellChecker in your application
Description:
You can render EJ SpellCheck with dictionary settings defined in a WebAPI Controller.
Solution:
After installing our EssentialStudio build, the required assemblies and scripts will be shipped inside the installed location. Refer to the Syncfusion.EJ, Syncfusion.EJ.MVC, and Syncfusion.SpellChecker.Base assemblies from installed location into your project.
The following screenshot illustrates assembly reference.
Also, you need to register these assembly details in Web.config with version.
<assemblies> <add assembly="Syncfusion.SpellChecker.Base, Version=17.1450.0.38, Culture=neutral, PublicKeyToken=3d67ed1f87d44c89" /> <add assembly="Syncfusion.EJ, Version=17.1450.0.38, Culture=neutral, PublicKeyToken=3d67ed1f87d44c89" /> <add assembly="Syncfusion.EJ.Mvc, Version=17.1500.0.38, Culture=neutral, PublicKeyToken=3d67ed1f87d44c89" /> </assemblies>
|
Refer to the scripts and CSS in the master page of the project.
<head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - My ASP.NET Application</title> @Styles.Render("~/Content/css") @Styles.Render("~/Content/ej/web/default-theme/ej.web.all.min.css") @Scripts.Render("~/bundles/modernizr") @Scripts.Render("~/Scripts/jquery-3.2.1.min.js") @Scripts.Render("~/Scripts/jsrender.min.js") @Scripts.Render("~/Scripts/ej/ej.web.all.min.js") </head>
Add the following code for rendering EJ SpellCheck and specify the WebAPI path for dictionary reference.
<div id="ControlRegion"> <div> <div> <div id="TextArea" contenteditable="true"> Facebook is a social networking service headquartered in Menlo Park, California. Its website was launched on February 4, 2004, by Mark Zuckerberg with his Harvard College roommates and fellow students Eduardo, Andrew McCollum, Dustin, and Chris Hughes. The founders had initially limited the websites membership to Harvard students, but later expanded it to colleges in the Boston area, the Ivy League, and Stanford University. They gradually added support for students at various other universities and later to high-school students. </div> <div> <input type="button" id="SpellCheck" /> </div> <script type="text/javascript"> $(function () { $("#TextArea").ejSpellCheck({ dictionarySettings: { dictionaryUrl: "../api/SpellCheck/CheckWords", //default dictionary WebAPI path customDictionaryUrl: "../api/SpellCheck/AddToDictionary" //custom dictionary WebAPI path }, contextMenuSettings: { enable: false } }); $("#SpellCheck").ejButton({ click: "showDialog", text: "Spell check using dialog" }); }); function showDialog() { var spellObj = $("#TextArea").data("ejSpellCheck"); spellObj.showInDialog(); } </script> </div> </div> </div>
Add the following code in WebAPI controller to perform spell check.
public class SpellCheckController : ApiController { internal SpellCheckerBase baseDictionary, customDictionary; private readonly string _customFilePath = HttpContext.Current.Server.MapPath("~/App_Data/Custom.dic"); // Here we need to specify the corresponding file name for custom dictionary private readonly List<Status> errorWords = new List<Status>(); SpellCheckController() { if (baseDictionary == null) { string filePath = HttpContext.Current.Server.MapPath("~/App_Data/Default.dic"); // Here we need to specify the corresponding file name for dictionary Stream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read); baseDictionary = new SpellCheckerBase(stream); } this.CustomFileRead(); } #region helpers private void CustomFileRead() { Stream stream1 = new FileStream(_customFilePath, FileMode.Open, FileAccess.ReadWrite); customDictionary = new SpellCheckerBase(stream1); } private bool CheckWord(string word) { var flag = false; if (baseDictionary.HasError(word)) { flag = true; using (StreamReader sr = new StreamReader(_customFilePath)) { var contents = sr.ReadToEnd(); if (contents != "") { flag = customDictionary.HasError(word) ? true : false; } } } return flag; } }
Add the following code for adding words to custom dictionary.
private void AddToCustomDictionary(string word) { using (System.IO.StreamWriter file = new System.IO.StreamWriter(_customFilePath, true)) { file.Write(word + Environment.NewLine); } this.CustomFileRead(); }
Add the following code for adding words to the default dictionary.
[AcceptVerbs("Get", "Post")] [ScriptMethod(ResponseFormat = ResponseFormat.Json)] public object AddToDictionary(string callback, string data) { var serializer = new JavaScriptSerializer(); Actions args = (Actions)serializer.Deserialize(data, typeof(Actions)); if (args.CustomWord != null) { this.AddToCustomDictionary(args.CustomWord); // add custom words } HttpContext.Current.Response.Write(string.Format("{0}({1});", callback, serializer.Serialize(args.CustomWord))); return string.Empty; }
Check words and get suggestions.
[AcceptVerbs("Get", "Post")] [ScriptMethod(ResponseFormat = ResponseFormat.Json)] public object CheckWords(string callback, string data) { var serializer = new JavaScriptSerializer(); Actions args = (Actions)serializer.Deserialize(data, typeof(Actions)); if (args.RequestType == "checkWords") { baseDictionary.IgnoreAlphaNumericWords = args.Model.IgnoreAlphaNumericWords; baseDictionary.IgnoreEmailAddress = args.Model.IgnoreEmailAddress; baseDictionary.IgnoreMixedCaseWords = args.Model.IgnoreMixedCaseWords; baseDictionary.IgnoreUpperCaseWords = args.Model.IgnoreUpperCase; baseDictionary.IgnoreUrl = args.Model.IgnoreUrl; baseDictionary.IgnoreFileNames = args.Model.IgnoreFileNames; var errorWords = this.SplitWords(args.Text); HttpContext.Current.Response.Write(string.Format("{0}({1});", callback, serializer.Serialize(errorWords))); } else if (args.RequestType == "getSuggestions") { var suggestions = baseDictionary.GetSuggestions(args.ErrorWord); HttpContext.Current.Response.Write(string.Format("{0}({1});", callback, serializer.Serialize(suggestions))); } return string.Empty; }
Get the status of error words.
private List<Status> GetStatus(string textWord) { var splitWords = Regex.Replace(textWord, @"[^0-9a-zA-Z\'_]", " ").Split(null); foreach (var inputWord in splitWords) { if (this.CheckWord(inputWord)) { errorWords.Add(new Status { ErrorWord = inputWord }); } } return errorWords; }
Split the words using regex for checking error words.
private List<Status> SplitWords(string text) { var words = text.Split(null); foreach (var word in words) { string textWord; Uri uriResult; bool checkUrl = Uri.TryCreate(word, UriKind.Absolute, out uriResult) && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps); if (checkUrl) { textWord = word; if (this.CheckWord(textWord)) { this.GetStatus(textWord); } } else if (Regex.IsMatch(word, @"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))" + @"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$", RegexOptions.IgnoreCase)) { textWord = word; if (this.CheckWord(textWord)) { this.GetStatus(textWord); } } else if (Regex.IsMatch(word, @"[a-zA-Z0-9_$\-\.\\]*\\[a-zA-Z0-9_$\-\.\\]+")) { textWord = word; if (this.CheckWord(textWord)) { this.GetStatus(textWord); } } else { if (word.EndsWith(".") || word.EndsWith(",")) { textWord = word.Remove(word.Length - 1); } else if (word.Contains('\t') || word.Contains('\n') || word.Contains('\r')) { textWord = Regex.Replace(word, @"\t|\n|\r", ""); } else { textWord = word; } this.GetStatus(textWord); } } return errorWords; }
The sample can be downloaded from the following link: Sample
The dictionaries can be backed up, and they can be used in multiple environments by specifying the path of the file in WebApi Controller.