Add a rich text editor and connect it to a collection

A rich text editor lets your users enter, edit, and format text in your site. It looks like this:


You create a rich text editor using the Wix HTML element and then use code to save the formatted text in a rich text type field in a collection.

Before continuing in this post you should read the Messaging section in this article to familiarize yourself with how the HTML element works with Wix Code.

We’ll give you step by step instructions below, but first, the big picture. To make this work you need to have an HTML element and a button talk to each other. This follows the following pattern:

  1. The page code sends a message to the HTML element.

  2. The HTML element receives the message.

  3. Receiving the message triggers the HTML element to send a message to the page code with the contents of the rich text editor.

  4. The page code receives the message from the HTML element and reads the contents of the rich text editor from the sent message.
    Then all you need to do is take that data and insert it in a collection.

Now for the details:

  1. Add a button and an HTML element to your page (the HTML element is under “More”).

  2. Select the HTML element and add this code to it. It has both HTML and JavaScript comments in it.

<!doctype html>
<html>
  <head>
    <!--Define the character set for the HTML element -->
    <meta charset="utf-8">   
    <!--Call the external script to use the CDN CKEditor in your page-->
    <script src="//cdn.ckeditor.com/4.6.2/standard/ckeditor.js"></script>  
    <script type="text/javascript">
    //Define an init function that sends the rich text editor contents to the page code
     function init() {       
       //onMessage runs when the HTML element receives a message from the page code
       window.onmessage = (event) => {  
         if (event.data) {
           //postMessage sends the contents of the CKEDITOR back to the page code
           window.parent.postMessage(CKEDITOR.instances.CK1.getData(),"*"); 
         }
       }
     }
     </script>
  </head>

  <body onload="init();">
    <!--Define the HTML element as a textarea-->
    <textarea name="editor1" id="CK1"></textarea> 
    <script>
        //Use the CKEditor replace() function to turn our textarea into a CKEditor rich text editor
        CKEDITOR.replace("editor1"); 
    </script>
  </body>
</html>
  1. Add an onClick event handler to the button.
  2. Add this code to the onClick event handler:
//Send a blank message to the HTML element. This tells the HTML element you want it to send you its contents 
$w("#html1").postMessage(" ");
//Receive the message from the HTML element
$w("#html1").onMessage((event) => {
	//Create an object named "rich" from the data in the rich text editor to insert into the collection
	const rich = {
		"richtext": event.data
	};
	//Insert the "rich" object into the collection
	wixData.insert("new-collection", rich)
		//Log an error if the insert fails
		.catch((err) => {
			console.log("error", err);
		});
});

Some “Don’t forget” things:

  1. You need to add import wixData from “wix-data” to the top of your page code.

  2. This example works with the following in the page code:
    - A collection named “new-collection”
    - A richtext field named “richtext”
    - An html element named “html1”
    You’ll need to replace these in the code with the corresponding names for those items in your site.

Last notes:

  • The HTML element’s functionality isn’t perfect in preview, so you’ll need to test this on your published site. Don’t forget to look at your Live Data to check that it worked.

  • If the data looks like it has some weird codes in it, just double click the cell to open the rich text editor for the rich text field in the Content Manager. You’ll see the data formatted as it was entered on the site.

  • If you want to later display rich text in a text element you should read this to understand how rich text formatting works with the formatting settings and themes in the editor.
    -Jeff

8 Likes

:joy: can we PUHLEASE get our own text boxes to be like this in the editor too?

Thank you for this information! It almost works for me. However I’m having an issue, that when submitting the rich text along with other data fields, the rich text doesn’t appear in the same row along with the rest of the data in the database, rather on it’s own in a separate row. How do I get all submitted information into the same row?

Hey Vincent,
It sounds like you created another button and set it up to submit. In the code above we use insert to create a new item in the collection. But if you have other data and are using a submit button to save it, you want to use the setFieldValue function to add your rich text to the item you are submitting and save it all together.

Since you are going to insert data into your collection from 2 places (your input elements and your HTML element) you’ll need to set up the submit manually so it grabs both those bits of data. To do that you should remove the extra submit button you created. We’ll add code to the button we originally added above to handle that. Now, when the user clicks that button two things will happen:

  1. It will trigger the communication between the HTML element and the page code, like before.

  2. It will take the rich text content from the HTML element and set it to be the field value for the rich text field in your collection. This is where we’ll use the setFieldValue function .
    Here’s what the code in the click event for your button should look like now:

export function button1_click_(event, $w) {
	//Send a blank message to the HTML element. This tells the HTML 
	//element you want it to send you its contents  
	$w("#html1").postMessage(" ");
	//Receive the message from the HTML element
	$w("#html1").onMessage((event) => {
		//Set the value for the rich text field of the dataset's 
		//current item to be the data in the HTML element
		$w("#dataset1").setFieldValue("richtextField", event.data);
		//Submit the current item of the dataset
		$w("#dataset1").save();
	});
}	

Same "Don’t forget"s and “Notes” as above. Also richtextField needs to be replaced with the field key for your rich text field in your collection.

-Jeff

Hi Jeff

This is an awesome post, thank you!

I’m experiencing the same problem as Vincent, then concluded to replace the initial code under the button with your new bit of code, but I’m afraid that now it no longer works…

What I did pick up is that when I forget to enter one of the mandatory fields before submitting, then submit and get an error, populating the mandatory field and then submitting again, it works.

I tried adding an onBeforeSave event handler, but no luck. any advice?

Code below:

export function button1_click(event) {
$w(“#dataset1”).onBeforeSave()( () => {
//Send a blank message to the HTML element. This tells the HTML
//element you want it to send you its contents
$w(“#html1”).postMessage(" “);
//Receive the message from the HTML element
$w(”#html1").onMessage((event) => {
//Set the value for the rich text field of the dataset’s
//current item to be the data in the HTML element
$w(“#dataset1”).setFieldValue(“biography”, event.data);
});
//Submit the current item of the dataset
$w(“#dataset1”).save();
});
}

Hello Yoav,
Can you please help me as well.

  1. I created a collection, import all my products to the collection via CSV,
  2. Add a gallery to a page
  3. Connected the dataset to my collection
  4. Connected the Gallery to dataset
    But I am unab

le to add a “Sort” option above the Gallery.
All I need is to connect two buttons “Price Low | High” to the Gallery.

I would really like to add Sort button so my customers would be able to click on to sort the list.

I did receive the code but when I added it to the end of the page it is not working for some reason.
I clicked on the Gallery
Clicked on onCurrentitemChanged on the properties panel
Pasted the whole script after the the lat }

import wixData from ‘wix-data’;
$w.onReady( function() {
$w(“#button227”).onClick( (event, $w) => {
$w(“#dresses1”).setSort( wixData.sort()
.descending(“price”);
} );
$w(“#button228”).onClick( (event, $w) => {
$w(“#dresses1”).setSort( wixData.sort()
.ascending(“price”);
} );
} );

This is the page I am working on.
https://deli236.wixsite.com/sweetsmilecopy/dresses

Can you please have have a look at this.
Many thanks

Hi, thank you so much for this Jeff. Can we add more fonts to this? How?

And as Tiaan has said, this code doesn’t seem to be working when combining with other user inputs?

export function submit_onClick_(event, $w) {
//Send a blank message to the HTML element. This tells the HTML
//element you want it to send you its contents
$w(“#html1”).postMessage(" “);
//Receive the message from the HTML element
$w(”#html1").onMessage((event) => {
//Set the value for the rich text field of the dataset’s
//current item to be the data in the HTML element
$w(“#dataset2”).setFieldValue(“longDescription”, event.data);
//Submit the current item of the dataset
$w(“#dataset2”).save();
});
}

Also, we really need a success message or something so you know it has worked.

Hey Tiaan and Splatty,

Just a reminder in case this is part of the problem - the button we are using is using code to manually trigger the submit, you can’t use the submit action in the connect to data panel to do the submit. If you did it will conflict with the code and this won’t work, and you need to remove that action.

Tiaan - I saw that your code doesn’t match what I have in that you have the dataset.save outside the onMessage function and mine is inside. Again, here is mine (without the comments):

export function button2_click_1(event, $w) {
	$w("#html1").postMessage(" ");
	$w("#html1").onMessage((event) => {
		$w("#dataset1").setFieldValue("richtext", event.data);
		$w("#dataset1").save();
	});
}

Splatty - I don’t see anything wrong with your code so unless the submit action I mentioned above is the problem, I can’t tell from here. If you send me your site URL I can take a look.

About a success message - we’ve got that. See here.

Thanks Jeff. Made sure the button wasn’t connected. URL here: https://tailoredwebdesign.wixsite.com/book-the-best/add-property

Also having a strange issue when I connect the text to the success or failure. Once I have done it and click somehere else it just disappears!

And was there a way to add more fonts to the editor do you know?

Hey Splatty,

Couple of things:

  1. If I’m understanding this correctly, this page is meant to create new entries in your collection, not edit existing ones. If that’s the case your dataset needs to be set to write-only, not read-write.

  2. As far as I could see, you didn’t connect all of your input elements to your dataset. Property information, Location, Type and the image upload weren’t connected.

  3. In your onClick event you set all your input values to null or 0 before you execute the save, so you’re not going to save the user input. I realize you want to clear the form after the save, but you are doing it too early. The way to that is to add a .then to the save, since it returns a promise. Also you may want to set the value to undefined , not null or zero. This resets the fields so no option is selected. If you want them to have a selection you can replace undefined with null and zero as you had it.

export function submit_click(event, $w) {
	console.log("saving");
	//Send a blank message to the HTML element. This tells the HTML 
	//element you want it to send you its contents  
	$w("#html1").postMessage(" ");
	//Receive the message from the HTML element
	$w("#html1").onMessage((event) => {
		//Set the value for the rich text field of the dataset's 
		//current item to be the data in the HTML element
		$w("#dataset2").setFieldValue("longDescription", event.data);
		//Submit the current item of the dataset
		$w("#dataset2").save()
			.then((res) => {
				console.log("saving", res);
				$w("#PropertyInfo").value = null;
				$w("#Location").selectedIndex = undefined;
				$w("#Type").selectedIndex = undefined;
				$w("#Guests").selectedIndex = undefined;
				$w("#Bedrooms").selectedIndex = undefined;
				$w("#Bathrooms").selectedIndex = undefined;
			});
	});
}

About adding fonts - check this out.

-Jeff

Awesome thank you I will give that a go. I meant adding fonts to the ck editor though so the client can enter them the same way and they will display correctly on my dynamic page?

Hey Splatty,

That’s functionality that’s specific to the CKEditor that we happened to use in our example. You’d have to check out their resources to see if that’s possible and how.

-Jeff

Thank you Jeff, I will try check it out. Your code works great however as u mentioned it is set to read and write and needs to be only write but I have an issue, I have run into before where my dataset has disappeared and I can’t find it! Can you help at all?

Hey I tried this code but it didn’t. Can someone take a look at my code and let me know where the error is. The saved everything except the html information

Hey Nathan,

From what I can see it looks ok. Did you check it on your published site? If it doesn’t work there, send me your site’s URL and I’ll take a look.

-Jeff

Hi Jeff. This is the URL for the Form Page https://www.easternstyles.com/new-page

Hey Nathan,
You’re missing a closing } at the end of the function and the parameters in the function declaration.
This should work:

export function button1_click(event, $w) {
	//Send a blank message to the HTML element. This tells the HTML 
	//element you want it to send you its contents  
	$w("#html1").postMessage(" ");
	//Receive the message from the HTML element
	$w("#html1").onMessage((event) => {
		//Set the value for the rich text field of the dataset's 
		//current item to be the data in the HTML element
		$w("#dataset1").setFieldValue("itemDescription", event.data);
		//Submit the current item of the dataset
		$w("#dataset1").save();
	});
}

-Jeff

Hi Jeff, Thank you so much for your work, you have been very helpful!

One more for me. I am basically creating a client portal so they can add, edit and delete the holiday properties themselves. I have the add form working great, and I will duplicate for the edit form as I have seen on the article about this.

However, from my main properties page I have repeaters listing all the properties and I wish to link an ‘edit property’ button to its own dynamic page with the form filled out to edit…Is this the way to do this? And if so how?! Thank you

Hi Splatty,

The way to do what you want is exactly the way you described :wink:

Just create set up your dynamic page with the input elements for the fields in your properties collection. Connect them to the dynamic page dataset, but make sure to change the dataset to read-write. You’ll need a submit button also.

Now add a button to your repeater that links to that dynamic page and when a user clicks the button they will get to the dynamic page for the specific item that the repeater item was displaying. The input elements will display the current data in the collection. Your user can then edit the data there and submit it to update the collection.

-Jeff

Thank you Jeff. But I can’t work out what to call the dynamic page? I have one called property/title but not sure how to have one for the edit page? And how to link to dynamic page?
Site at tailoredwebdesign.wixsite.com/book-the-best
Any advice would be amazing!