TinyMCE avec AJAX (Update Panel) n'a jamais de valeur

Je voulais utiliser un éditeur de texte enrichi pour une zone de texte dans un panneau de mise à jour.

J'ai trouvé cette publication: http://www.queness.com/post/212/10-jquery-and-non-jquery-javascript-rich-text-editors via cette question: Besoin d'éditeur de texte enrichi ASP.Net/MVC

Décidé d'aller avec TinyMCE comme je l'ai utilisé avant dans des situations non AJAX, et il dit dans cette liste qu'il est compatible AJAX. D'accord, je fais le bon tinyMCE.init({ //settings here }); Testez-le et disparaît après avoir effectué une mise à jour du panneau de mise à jour. Je découvre à partir d'une question ici que cela devrait être dans la fonction page_load , de sorte qu'il soit exécuté même sur les page_loadpage_load asynchrones. D'accord et le panneau reste. Cependant, en essayant de soumettre la valeur de ma zone de texte, le texte revient toujours comme vide car mon validateur de formulaire indique toujours "Vous devez saisir une description" même lorsque j'entrer du texte. Cela se produit la première fois que la page se charge et après que des retours asynchrones ont été effectués sur la page.

D'accord, je trouve ce http://www.dallasjclark.com/using-tinymce-with-ajax/ et je ne peux pas poster deux fois de la même classe de texte AJAX TinyMCE . J'essaie d'ajouter ce code dans ma fonction de chargement de la page juste après le tinyMCE.init. Faire cela brise tout mon jquery étant appelé aussi dans le page_load après lui, et il a toujours le même problème.

Je suis encore assez débutant pour les choses de script côté client, alors peut-être que je dois mettre le code dans un endroit différent de page_load? Je ne suis pas certain que les messages que j'ai reliés n'étaient pas très clairs sur l'endroit où mettre ce code.

Mon Javascript:

 <script type="text/javascript"> var redirectUrl = '<%= redirectUrl %>'; function pageLoad() { tinyMCE.init({ mode: "exact", elements: "ctl00_mainContent_tbDescription", theme: "advanced", plugins: "table,advhr,advimage,iespell,insertdatetime,preview,searchreplace,print,contextmenu,paste,fullscreen", theme_advanced_buttons1_add_before: "preview,separator", theme_advanced_buttons1: "bold,italic,underline,separator,justifyleft,justifycenter,justifyright, justifyfull,bullist,numlist,undo,redo,link,unlink,separator,styleselect,formatselect", theme_advanced_buttons2: "cut,copy,paste,pastetext,pasteword,separator,removeformat,cleanup,charmap,search,replace,separator,iespell,code,fullscreen", theme_advanced_buttons2_add_before: "", theme_advanced_buttons3: "", theme_advanced_toolbar_location: "top", theme_advanced_toolbar_align: "left", extended_valid_elements: "a[name|href|target|title|onclick],img[class|src|border=0|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name],hr[class|width|size|noshade],font[face|size|color|style],span[class|align|style]", paste_auto_cleanup_on_paste: true, paste_convert_headers_to_strong: true, button_tile_map: true }); tinyMCE.triggerSave(false, true); tiny_mce_editor = tinyMCE.get('ctl00_mainContent_tbDescription'); var newData = tiny_mce_editor.getContent(); tinyMCE.execCommand('mceRemoveControl', false, 'your_textarea_name'); //QJqueryUI dialog stuff }</script> 

Maintenant, mon code actuel n'a pas le tinyMCE.execCommand("mceAddControl",true,'content'); Ce que cette question a indiqué devrait également être ajouté. J'ai essayé de l'ajouter, mais encore une fois, je ne savais pas où le placer et le mettre dans la page_load semblait n'avoir aucun effet.

Contrôle de la zone de texte:

 <asp:TextBox ID="tbDescription" runat="server" TextMode="MultiLine" Width="500px" Height="175px"></asp:TextBox><br /> 

Comment puis-je obtenir ces valeurs afin que le code derrière puisse effectivement obtenir ce qui est tapé dans la zone de texte et mon validateur ne se présentera pas comme disant qu'il est vide? Même après les retournements asynchrones, puisque j'ai plusieurs boutons sur le formulaire qui le met à jour avant la soumission réelle.

Merci!

Edit: Pour plus de précisions, j'ai une validation de formulaire sur le back-end de la manière suivante:

 If tbDescription.Text = "" Or tbDescription.Text Is Nothing Then lblDescriptionError.Text = "You must enter a description." isError = True Else lblDescriptionError.Text = "" End If 

Et cette erreur entraînera toujours l'affichage du message d'erreur.

Modifier:

D'accord, je suis désespéré ici, j'ai passé des heures à ce sujet. J'ai finalement trouvé ce que je pensais être un gagnant sur l'échange d'experts qui indique ce qui suit (il y avait une partie sur l'encodage de la valeur dans xml, mais j'ai sauté cela): http://www.experts-exchange.com/Programming/Languages /C_Sharp/Q_25059848.html

Pour quiconque veut utiliser tinyMCE avec AJAX.Net:

  1. Ajouter les gestionnaires de début / fin à l'objet de demande AJAX. Ceux-ci supprimeront le contrôle tinyMCE avant d'envoyer les données (début), et il va recréer le contrôle tinyMCE (fin):

     Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(function(sender, args) { var edID = "<%=this.ClientID%>_rte_tmce"; // the id of your textbox/textarea. var ed = tinyMCE.getInstanceById(edID); if (ed) { tinyMCE.execCommand('mceFocus', false, edID); tinyMCE.execCommand('mceRemoveControl', false, edID); } }); Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function(sender, args) { var edID = "<%=this.ClientID%>_rte_tmce"; var ed = tinyMCE.getInstanceById(edID); if (ed) { tinyMCE.execCommand('mceAddControl', false, edID); } }); 
  2. Lorsque l'utilisateur change / flore du contrôle tinyMCE, nous voulons nous assurer que la zone de texte / la boîte à texte est correctement mise à jour:

      ed.onChange.add(function(ed, l) { tinyMCE.triggerSave(true, true); }); 

Maintenant, j'ai essayé ce code en le mettant dans sa propre étiquette de script, en mettant les requêtes de début et de fin dans leurs propres balises de script et en mettant ed.onChange dans la page_load, en mettant tout dans le page_load et en mettant tous les 3 dans son propre tag de script . Dans tous les cas, il n'a jamais fonctionné, et même parfois cassé le jquery qui est également dans ma page_load … (et oui, j'ai changé le code ci-dessus pour correspondre à ma page)

Quelqu'un peut-il travailler ou offrir une solution?

Le code

Je pense que vous voulez regarder cette publication: comment faire pour que TinyMCE fonctionne dans un UpdatePanel?

Assurez-vous d'enregistrer votre fonction init avec le scriptmanager

 ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), mce.ClientID, "pageLoad();", true); 

J'aimerais simplement ajouter ma solution à cette publication, car je luttais avec le même problème pendant quelques jours. Je me rends compte que c'est une ancienne publication, mais peut-être que ma réponse aidera quelqu'un, car je crois que la question est toujours pertinente.

Je développe une application de formulaires Web ASP.NET, et l'une des pages dispose d'un contrôle textarea contenu dans un UpdatePanel. TinyMCE se lie à cette zone de texte. Le texte de la zone de texte provient d'une zone de texte liée dans un contrôle de répéteur, car je souhaite obtenir le texte à partir d'un contrôle ObjectDataSource, et c'est un moyen légèrement clou de faire cela. À mon avis, les contrôles ObjectDataSource sont pratiques et ils s'exécutent rapidement.

Voici mon balisage contenant le contrôle ObjectDataSource, le répéteur, la zone de texte liée et la zone de texte (une asp: TextBox définie sur plusieurs lignes). Notez que la zone de texte liée est définie sur "afficher: aucune":

 <asp:ObjectDataSource ID="odsDetailText" runat="server" TypeName="Data.Document" SelectMethod="GetDocumentDetailText" /> <asp:Repeater ID="repBody" runat="server" DataSourceID="odsDetailText"> <ItemTemplate> <asp:TextBox ID="tbxBodyBound" runat="server" Text='<%# Eval("Body") %>' CssClass="hidden" /> </ItemTemplate> </asp:Repeater> <asp:TextBox ID="tbxBody" runat="server" TextMode="MultiLine" /> 

J'ai également un bouton Asp: pour enregistrer le texte dans tinyMCE vers SQL Server. Tous ces contrôles sont contenus dans un UpdatePanel.

J'ai placé tout mon code jQuery et JavaScript dans un fichier distinct. J'inclus les bits pertinents ci-dessous. Comme vue d'ensemble:

  • Je initialise tinyMCE dans l'événement JavaScript de pageLoad. Notez que cet événement se déclenche pour les postbacks complets et partiels (asynchrones), de sorte que tinyMCE est toujours affiché et ne disparaît pas entre les postbacks complets ou partiels.

  • Également dans l'événement pageLoad, si un postback est asynchrone, je commence à écouter un événement BeginRequest créé par ASP.NET PageRequestManager. Je arrête d'écouter l'événement BeginRequest dans l'événement JavaScriptUpload. Cela empêche de plus en plus d'auditeurs d'être ajoutés chaque fois que la page se déclenche.

  • Lorsque le gestionnaire d'événements pour l'événement BeginRequest se déclenche (lorsque le bouton Enregistrer de ma page est cliqué), j'obtiens le contenu HTML de l'éditeur de texte tinyMCE et enregistrez-le dans un cookie. J'utilise le plugin jQuery cookie pour faire ceci: https://github.com/carhartl/jquery-cookie . Le code HTML est codé dans le cookie, pour plus de sécurité.

  • Maintenant, dans le code du serveur qui s'exécute lorsque le bouton Enregistrer est cliqué, le texte du cookie (qui est codé en HTML) est récupéré et sauvegardé sur le serveur SQL. Le cookie est maintenant supprimé.

  • ASP.NET lie les données enregistrées au textobx caché via le contrôle ObjectDataSource, la valeur du contrôle textarea est définie sur les zones de texte cachées et la partie de la page dans UpdatePanel est retournée au navigateur.

  • TinyMCE affiche maintenant ce texte à partir de la zone de texte, mais il est codé en HTML et non lisible par l'homme.

  • Ainsi, dans l'événement JavaScript de la page JavaScript, je forme le texte tinyMCE en décodant le HTML.

  • Travail terminé!

Voici les parties pertinentes de mon fichier de script:

 // ######################################################### // Events // ######################################################### // --------------------------------------------------------- // Check for full and partial postbacks // --------------------------------------------------------- function pageLoad(sender, args) { // Register event handler for async postback beginning var prm = Sys.WebForms.PageRequestManager.getInstance(); if (!prm.get_isInAsyncPostBack()) { prm.add_beginRequest(onBeginRequest); }; // Configure HTML editor HTMLEditorConfig(); // Format HTML editor text HTMLEditorFormat(); }; // --------------------------------------------------------- // When page unloads after full or partial postback // --------------------------------------------------------- function pageUnload(sender, args) { // Deregister event handler for async postback beginning Sys.WebForms.PageRequestManager.getInstance().remove_beginRequest(onBeginRequest); }; // --------------------------------------------------------- // Event handler for async postback beginning // --------------------------------------------------------- function onBeginRequest() { // Check whether to save text editor text HTMLEditorSave(); }; // ######################################################### // Functions // ######################################################### // --------------------------------------------------------- // Configure HTML text editor. tinyMCE converts standard textarea controls // --------------------------------------------------------- function HTMLEditorConfig() { // Determine edit mode var editMode = $('input:hidden[id*=hfEditMode]').val().toLowerCase(); // If not in edit mode, prevent edits var editorReadOnly = null; var editorHeight = null; if (editMode == 'true') { editorReadOnly = ''; editorHeight = '332'; } else { editorReadOnly = 'true'; editorHeight = '342'; }; // Initialise HTML text editor tinyMCE.init({ mode: "textareas", plugins: "advhr,insertdatetime,print,preview,fullscreen", width: "488", height: editorHeight, // Theme options theme: "advanced", theme_advanced_buttons1: "newdocument,|,print,preview,|,cut,copy,paste,|,undo,redo,removeformat,|,bold,italic,underline,strikethrough,sub,sup,|,forecolor,backcolor", theme_advanced_buttons2: "justifyleft,justifycenter,justifyright,justifyfull,|,bullist,numlist,|,outdent,indent,|,fontselect,fontsizeselect", theme_advanced_buttons3: "insertdate,inserttime,|,advhr,|,charmap,|,fullscreen", theme_advanced_toolbar_location: "top", theme_advanced_toolbar_align: "left", theme_advanced_statusbar_location: "none", theme_advanced_resizing: false, // Skin options skin: "o2k7", skin_variant: "silver", // Custom css content_css: "../../Script/tiny_mce/custom.css", // Allow edits? readonly: editorReadOnly }); }; // --------------------------------------------------------- // Format HTML editor text by ensuring its HTML is decoded // --------------------------------------------------------- function HTMLEditorFormat() { // Check bound textbox containing HTML for text editor var bodyText = $('input:text[id*=tbxBody]').val(); // If HTML exists, decode it if (bodyText !== null) { tinyMCE.activeEditor.setContent(decodeURIComponent(bodyText)); }; }; // --------------------------------------------------------- // Save HTML text editor text to cookie for server-side processing. // Can't save to hidden field or asp control as this function fires after viewstate is captured (I think). // Extra content in viewstate would slow down page load anyway. // --------------------------------------------------------- function HTMLEditorSave() { // Determine edit mode var editMode = $('input:hidden[id*=hfEditMode]').val().toLowerCase(); // If in edit mode, create cookie with encoded text editor HTML. Server code will save this to database. if (editMode == 'true') { var textToSave = tinyMCE.activeEditor.getContent(); $.cookie('HTMLEditorText', textToSave); } }; 

Voici une partie du code du serveur qui se déclenche lorsque le bouton Enregistrer est cliqué:

 Private Sub Save() 'Retrieve tinyMCE text from cookie Dim cookieName As String = "tinyMCEText" Dim cookies As HttpCookieCollection = Request.Cookies Dim text As String = cookies(cookieName).Value 'Save text to database... 'Delete cookie cookies.Remove(cookieName) 'Databind text for tinyMCE repeaterTinyMCE.DataBind() Dim encodedText As String = DirectCast(repeaterTinyMCE.Controls(0).Controls(1), TextBox).Text textboxTinyMCE.Text = encodedText End Sub 

J'espère que ça aide quelqu'un.

Vous devez déclencher la fonction de sauvegarde lors de la publication, utilisez Page.RegisterOnSubmitStatement pour enregistrer le script tinyMCE.triggerSave();

J'ai remarqué que la fonction init de tinyMCE ne peut être appelée que choisissant toutes les zones de texte ou les zones de texte avec une certaine classe. L' exact ne fonctionne pas.

Bien, il y avait deux façons d'obtenir que cela fonctionne, ce qui n'a vraiment pas résolu le problème, il suffit de l'éviter.

Il s'agissait d'utiliser le contrôle FCKeditor .net, ce qui était trop chargé lentement pour moi, comme 2-3 secondes. J'ai donc décidé de faire en sorte que le formulaire comporte deux panneaux de mise à jour, et placez la zone de texte entre les deux, essentiellement en supprimant la zone de texte du panneau de mise à jour. Cela ressemblait à un truc bon marché qui ne devrait pas être nécessaire, mais ça marche bien. Aucune des solutions ou suggestions posées par quelqu'un n'a fonctionné pour moi, c'est ce que j'ai fait. Si je devais mettre la zone de texte dans le panneau de mise à jour cependant, cela n'aurait pas fonctionné.

Une chose que j'ai rencontré lors de la mise en place de TinyMCE dans un panneau de mise à jour était que je devais faire toutes sortes de trucs pour que cela fonctionne correctement. Gardez à l'esprit comment fonctionne le panneau de mise à jour, lorsque vous souhaitez le rafraîchir, il remplace complètement le DOM à l'intérieur, y compris le TinyMCE.

La solution de contournement que j'ai utilisée était de supprimer le TinyMCE du panneau de mise à jour et d'enrouler tout ce qu'il fallait pour actualiser dynamiquement dans un panneau de mise à jour. J'ajouterais ensuite des données à TinyMCE via l'API javascript qu'elle fournit si je voulais que le contenu de TinyMCE soit dynamique.