Drag and Drop Newsletter Builder using jQuery

February 1, 2015 63 comments 245,779

In this tutorial i will teach you how to create a drag and drop interface for a newsletter builder using jQuery. You will be able to create your own template and import it in the builder because i have designed the builder to work with various templates not just the one in the example. I will explain to you how you can insert your own template at the end of this tutorial. This is one of the most complex tutorials I have created so please pay close attention if you really want to understand how it works.



I also want to point out that font icons probably won't be supported by all the email clients. This builder will have both Download and Export options. When exporting or downloading with the intend of importing it into a newsletter service you should change the setting of your service provider to convert the CSS styles into inline styles.



The Downloading side of this tutorial is using a little bit of PHP which i had to use unfortunately. If you want to run this feature you will have to make sure you run the export.php file on a PHP server. If don't want this feature or you are not familiar with PHP the newsletter builder will work perfectly without this feature. HTML So let's start out the HTML section by talking about "newsletter-preloaded-download" element. This element is not visible when you load the page, you will see that there is a text area inside a form. I will use this form to add content so i can send it using Ajax to export.php file which will push the download.



<div id="newsletter-preloaded-download"> <form id="export-form" action="export.php" method="post" name="export-form"> <textarea id="export-textarea" name="export-textarea"></textarea> </form> </div>



"newsletter-preloaded-export" will also be invisible and it will be used to hold some HTML code for formatting when doing the export.



<div id="newsletter-preloaded-export"></div>



"newsletter-preloaded-rows" will be used to store the html template rows which will later be used for insertion inside the newsletter. Inside this element the actual template starts. I will not talk about the HTML of the template I created because there is so much to talk about the actual builder. The only thing I will say about the template is that it uses a row based system which will be a requirement when creating your own templates.



<div id="newsletter-preloaded-rows"></div>



After the template rows the next important elements are 6 popup boxes that will be used to edit and export the template. I have created 5 popups for edit and 1 for export. These are the 5 edit popups: Image, Link, Title, Text and Icon.



The export popup only contains a text area and a cancel button. The export code will be generate inside the text area.



<div class="sim-edit" id="sim-edit-export"> <div class="sim-edit-box" style="height:390px;"> <div class="sim-edit-box-title">Export Template</div> <div class="sim-edit-box-content"> <div class="sim-edit-box-content-text">Select and copy the entire text below</div> <div class="sim-edit-box-content-field"><textarea class="sim-edit-box-content-field-textarea text"></textarea></div> </div> <div class="sim-edit-box-buttons"> <div class="sim-edit-box-buttons-cancel" style="margin-left:0px;">Cancel</div> </div> </div> </div>



Edit image popup will have an input field, save button and a cancel button. The input field will be used to host the URL of the image.



<div class="sim-edit" id="sim-edit-image"> <div class="sim-edit-box" style="height:230px;" > <div class="sim-edit-box-title">Edit Image</div> <div class="sim-edit-box-content"> <div class="sim-edit-box-content-text">URL:<span>(full address including http://)</span></div> <div class="sim-edit-box-content-field"><input type="text" class="sim-edit-box-content-field-input image"/></div> </div> <div class="sim-edit-box-buttons"> <div class="sim-edit-box-buttons-save">Save</div> <div class="sim-edit-box-buttons-cancel">Cancel</div> </div> </div> </div>



Edit link popup will have a title, URL, save and cancel buttons.



<div class="sim-edit" id="sim-edit-link"> <div class="sim-edit-box" style="height:310px;"> <div class="sim-edit-box-title">Edit Link</div> <div class="sim-edit-box-content"> <div class="sim-edit-box-content-text">Title</div> <div class="sim-edit-box-content-field"><input type="text" class="sim-edit-box-content-field-input title"/></div> <div class="sim-edit-box-content-text">URL:<span>(full address including http://)</span></div> <div class="sim-edit-box-content-field"><input type="text" class="sim-edit-box-content-field-input url"/></div> </div> <div class="sim-edit-box-buttons"> <div class="sim-edit-box-buttons-save">Save</div> <div class="sim-edit-box-buttons-cancel">Cancel</div> </div> </div> </div>



Edit title field will host input field, which will be used to edit titles, save button and cancel button.



<div class="sim-edit" id="sim-edit-title"> <div class="sim-edit-box" style="height:230px;"> <div class="sim-edit-box-title">Edit Title</div> <div class="sim-edit-box-content"> <div class="sim-edit-box-content-text">Title</div> <div class="sim-edit-box-content-field"><input type="text" class="sim-edit-box-content-field-input title"/></div> </div> <div class="sim-edit-box-buttons"> <div class="sim-edit-box-buttons-save">Save</div> <div class="sim-edit-box-buttons-cancel">Cancel</div> </div> </div> </div>



The edit text popup will be exactly like the edit title popup except instead of input field we have a text area to help us edit larger texts.



<div class="sim-edit" id="sim-edit-text"> <div class="sim-edit-box" style="height:390px;"> <div class="sim-edit-box-title">Edit Text</div> <div class="sim-edit-box-content"> <div class="sim-edit-box-content-text">Text</div> <div class="sim-edit-box-content-field"><textarea class="sim-edit-box-content-field-textarea text"></textarea></div> </div> <div class="sim-edit-box-buttons"> <div class="sim-edit-box-buttons-save">Save</div> <div class="sim-edit-box-buttons-cancel">Cancel</div> </div> </div> </div>



The icon edit popup it is a bit different than the rest of the edit popups. It will not contain a save button because the save will happen once someone clicks on an icon. To save time i only included 3 icons here. The final tutorial will have much more. You will find all the icons once you download the source code of this tutorial.



<div class="sim-edit" id="sim-edit-icon"> <div class="sim-edit-box" style="height:580px;"> <div class="sim-edit-box-title">Edit Icon</div> <div class="sim-edit-box-content"> <div class="sim-edit-box-content-text">Select Icon</div> <div class="sim-edit-box-content-icons"> <i class="fa fa-glass"></i> <i class="fa fa-music"></i> <i class="fa fa-search"></i> </div> </div> <div class="sim-edit-box-buttons"> <div class="sim-edit-box-buttons-cancel" style="margin-left:0px;">Cancel</div> </div> </div> </div>



The main HTML element is "newsletter-builder". Inside this element we will host "newsletter-builder-sidebar" and "newsletter-builder-area".



<div id="newsletter-builder" class="resize-height"></div>



Sidebar element will appear in the left and it will contain Download and Export buttons.



<div id="newsletter-builder-sidebar"> <div id="newsletter-builder-sidebar-logo"><img src="http://simbyone.com/newsletter-builder/_assets/logo.png" width="150" height="150" /></div> <div id="newsletter-builder-sidebar-buttons"> <div id="newsletter-builder-sidebar-buttons-abutton">Download Template</div> <div id="newsletter-builder-sidebar-buttons-bbutton">Export</div> </div> </div>



"newsletter-builder-area" has a series of child elements like "newsletter-builder-area-center" and "newsletter-builder-area-center-frame" which only purpose is to resize the building area nicely.



<div id="newsletter-builder-area-center"> <div id="newsletter-builder-area-center-frame"> </div></div>



Inside "newsletter-builder-area-center-frame" there are two main elements the buttons part "newsletter-builder-area-center-frame-buttons" which is at the actual building area "newsletter-builder-area-center-frame-content". The top contains Add and Reset buttons. Inside Add button there is a dropdown that contains photos with all the template rows.



<div id="newsletter-builder-area-center-frame-buttons"> <div id="newsletter-builder-area-center-frame-buttons-add">Add <i class="fa fa-caret-down"></i> <div id="newsletter-builder-area-center-frame-buttons-dropdown"> <div class="newsletter-builder-area-center-frame-buttons-dropdown-tab" id="add-header"><p>Header</p><i class="fa fa-caret-right"></i></div> <div class="newsletter-builder-area-center-frame-buttons-dropdown-tab" id="add-content"><p>Content</p><i class="fa fa-caret-right"></i></div> <div class="newsletter-builder-area-center-frame-buttons-dropdown-tab" id="add-footer"><p>Footer</p><i class="fa fa-caret-right"></i></div> <div class="newsletter-builder-area-center-frame-buttons-content"> <div class="newsletter-builder-area-center-frame-buttons-content-tab" data-type="header" data-id="1"><img src="_row_thumbs/sim-row-thumb_1.png" /></div> <div class="newsletter-builder-area-center-frame-buttons-content-tab" data-type="header" data-id="2"><img src="_row_thumbs/sim-row-thumb_2.png" /></div> <div class="newsletter-builder-area-center-frame-buttons-content-tab" data-type="header" data-id="3"><img src="_row_thumbs/sim-row-thumb_3.png" /></div> <div class="newsletter-builder-area-center-frame-buttons-content-tab" data-type="content" data-id="4"><img src="_row_thumbs/sim-row-thumb_4.png" /></div> <div class="newsletter-builder-area-center-frame-buttons-content-tab" data-type="content" data-id="5"><img src="_row_thumbs/sim-row-thumb_5.png" /></div> <div class="newsletter-builder-area-center-frame-buttons-content-tab" data-type="content" data-id="6"><img src="_row_thumbs/sim-row-thumb_6.png" /></div> <div class="newsletter-builder-area-center-frame-buttons-content-tab" data-type="content" data-id="7"><img src="_row_thumbs/sim-row-thumb_7.png" /></div> <div class="newsletter-builder-area-center-frame-buttons-content-tab" data-type="content" data-id="8"><img src="_row_thumbs/sim-row-thumb_8.png" /></div> <div class="newsletter-builder-area-center-frame-buttons-content-tab" data-type="content" data-id="9"><img src="_row_thumbs/sim-row-thumb_9.png" /></div> <div class="newsletter-builder-area-center-frame-buttons-content-tab" data-type="content" data-id="10"><img src="_row_thumbs/sim-row-thumb_10.png" /></div> <div class="newsletter-builder-area-center-frame-buttons-content-tab" data-type="content" data-id="11"><img src="_row_thumbs/sim-row-thumb_11.png" /></div> <div class="newsletter-builder-area-center-frame-buttons-content-tab" data-type="content" data-id="12"><img src="_row_thumbs/sim-row-thumb_12.png" /></div> <div class="newsletter-builder-area-center-frame-buttons-content-tab" data-type="content" data-id="13"><img src="_row_thumbs/sim-row-thumb_13.png" /></div> <div class="newsletter-builder-area-center-frame-buttons-content-tab" data-type="content" data-id="14"><img src="_row_thumbs/sim-row-thumb_14.png" /></div> <div class="newsletter-builder-area-center-frame-buttons-content-tab" data-type="content" data-id="15"><img src="_row_thumbs/sim-row-thumb_15.png" /></div> <div class="newsletter-builder-area-center-frame-buttons-content-tab" data-type="footer" data-id="16"><img src="_row_thumbs/sim-row-thumb_16.png" /></div> <div class="newsletter-builder-area-center-frame-buttons-content-tab" data-type="footer" data-id="17"><img src="_row_thumbs/sim-row-thumb_17.png" /></div> <div class="newsletter-builder-area-center-frame-buttons-content-tab" data-type="footer" data-id="18"><img src="_row_thumbs/sim-row-thumb_18.png" /></div> </div> </div> </div> <div id="newsletter-builder-area-center-frame-buttons-reset"><a href="index.html"><i class="icon-reload-CCW"></i> Reset</a></div> </div>



"newsletter-builder-area-center-frame-content" is where the real magic happens at the beginning it will store the default template but the content inside will changed using the edit buttons.



<div id="newsletter-builder-area-center-frame-content"></div>



That is everything important regarding the HTML the rest of the content inside "newsletter-builder-area-center-frame-content" is the actual newsletter template which is not important for now because the purpose of this tutorial is to teach you how to create the builder not the template. CSS You will see that besides the Google Fonts and Font Awesome icons attached style sheets there two more attached style sheets, newsletter-builder.css is the style sheet for the builder and newsletter.css is the style sheet for the newsletter template used in this example. I will only talk about the newsletter-builder.css.



I will go ahead and set #newsletter-builder position to relative so we can position other elements inside using absolute position as well as setting the overflow to hidden.



#newsletter-builder { position: relative; overflow: hidden; width: 100%; float: left; }



The #newsletter-builder-sidebar will be positioned at the left of the screen using the absolute position.



#newsletter-builder-sidebar{ float: left; width: 250px; position: absolute; left: 0px; top: 0px; background-color: #FFFFFF; overflow-y: auto; height: 100%; z-index: 1; }



I have set the overflow of #newsletter-builder-area to auto so that the proper scrolling bars will appear when the content inside #newsletter-builder-area is larger than the actual element.



#newsletter-builder-area{ float: right; overflow: auto; }



All popups are using the .sim-edit class which is set to a fixed position and it is used manly as the background.



.sim-edit{ height: 100%; width: 100%; position: fixed; z-index: 2; display: none; background-image: url(../_assets/background.png); background-repeat: repeat; }



.sim-edit-box is the actual popup box. Both .sim-edit-box and .sim-edit have the display set to none because I will turn those on and off individually from each other at different time intervals.



.sim-edit-box{ width: 400px; background-color: rgba(255,255,255,1); margin-right: auto; margin-left: auto; margin-top: 10%; -webkit-box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.5); -moz-box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.5); box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.5); padding: 25px; height: 300px; display: none; } JavaScript Let's start out by making some elements resizable. Because i have designed the builder with the sidebar floating to the left and when you resize the window only the #newsletter-builder-area will have the scrolling bars and not the whole page. To make this possible i had to create a resize function that changes the width and the height of some elements based on the size of the window. After i have declared the function you will see that i have set it up in the case of a browser resize the widths and the heights will have to be resized once again. Once i finished with the browser resize i have summoned the resize function so that this function will take effect every time you refresh the page.



// Resize function resize(){ $('.resize-height').height(window.innerHeight - 50); $('.resize-width').width(window.innerWidth - 250); //if(window.innerWidth<=1150){$('.resize-width').css('overflow','auto');} } $( window ).resize(function() {resize();}); resize();



In order for the resize function to work we will have to apply the .resize-height class to #newsletter-builder and #newsletter-builder-area and .resize-width class to only #newsletter-builder-area.



Unfortunately guys i know i shouldn't include PHP in my tutorials because i only want my tutorials to be about CSS and JavaScript related stuff but i just had to do it. The download aspect could only be done using PHP and since this is a very nice aspect of the whole builder just being able to download the newly created template in a .html format was so awesome that i told myself, what the heck let's just do it. Before going over the JavaScript role in the download button i wanted to let you guys know that in order to download the files you need to run the export.php file on a PHP server. I will talk about the PHP code inside export.php in the next section but for now let's just talk about JavaScript. The add content, #newsletter-builder-area-center-frame-buttons-add contains the dropdown #newsletter-builder-area-center-frame-buttons-dropdown that will only be visible when the mouse is over the add button.



$("#newsletter-builder-area-center-frame-buttons-add").hover( function() { $("#newsletter-builder-area-center-frame-buttons-dropdown").fadeIn(200); }, function() { $("#newsletter-builder-area-center-frame-buttons-dropdown").fadeOut(200); } );



Inside the dropdown there is a list with 3 types of content and also a content area .newsletter-builder-area-center-frame-buttons-content filled up with elements which holds pictures. This content area will only be shown when someone hovers the mouse over #newsletter-builder-area-center-frame-buttons-dropdown.



$("#newsletter-builder-area-center-frame-buttons-dropdown").hover( function() { $(".newsletter-builder-area-center-frame-buttons-content").fadeIn(200); }, function() { $(".newsletter-builder-area-center-frame-buttons-content").fadeOut(200); } );



Each tab element inside .newsletter-builder-area-center-frame-buttons-content has a data-type HTML5 attribute which is used to store the type of content which that image holds. There can be three types of values there: header, content and footer. We will show those elements accordingly. When they hover over #add-header we will only show the elements with the data-type equal to header and hide the rest. When they hover over #add-content we will only show the elements with the data-type equal to content and hide the rest. When they hover over #add-footer we will only show the elements with the data-type equal to footer and hide the rest.



$("#add-header").hover(function() { $(".newsletter-builder-area-center-frame-buttons-content-tab[data-type='header']").show() $(".newsletter-builder-area-center-frame-buttons-content-tab[data-type='content']").hide() $(".newsletter-builder-area-center-frame-buttons-content-tab[data-type='footer']").hide() }); $("#add-content").hover(function() { $(".newsletter-builder-area-center-frame-buttons-content-tab[data-type='header']").hide() $(".newsletter-builder-area-center-frame-buttons-content-tab[data-type='content']").show() $(".newsletter-builder-area-center-frame-buttons-content-tab[data-type='footer']").hide() }); $("#add-footer").hover(function() { $(".newsletter-builder-area-center-frame-buttons-content-tab[data-type='header']").hide() $(".newsletter-builder-area-center-frame-buttons-content-tab[data-type='content']").hide() $(".newsletter-builder-area-center-frame-buttons-content-tab[data-type='footer']").show() });



You will notice that when you hover the mouse on the images inside content you will see a small insert button. The button is not inside the HTML but is inserted when the mouse is over the picture and removed when the mouse if off the picture. This adding and removing helps us to get rid of a lot of functions refresh. When the mouse is in a hover state we have to append the insert button to the tab in which that particular image is located. Inside this hover state function we will also run a click function which will expire in the off hover state. The click function will add the appropriate content when you click on the insert button. The whole builder works with elements called rows so when you click on a certain insert button we will pick the appropriate content which stays inside #newsletter-preloaded-rows and add it to #newsletter-builder-area-center-frame-content. How do we know which row to add ? You will see that each .newsletter-builder-area-center-frame-buttons-content-tab has it's own data-id attribute which coincides with the data-id attribute of one of the template rows .sim-row located inside #newsletter-preloaded-rows. At this point not only that we have to add the appropriate content but we also have to add the appropriate edit elements like the on hover pen icon as well as the delete icon on the newly added content inside the main building area. After doing this we will close the #newsletter-builder-area-center-frame-buttons-dropdown because i decided it makes for a better user experience if we close the add element section.



$(".newsletter-builder-area-center-frame-buttons-content-tab").hover( function() { $(this).append('<div class="newsletter-builder-area-center-frame-buttons-content-tab-add"><i class="fa fa-plus"></i> Insert</div>'); $('.newsletter-builder-area-center-frame-buttons-content-tab-add').click(function() { $("#newsletter-builder-area-center-frame-content").prepend($("#newsletter-preloaded-rows .sim-row[data-id='"+$(this).parent().attr("data-id")+"']").clone()); hover_edit(); perform_delete(); $("#newsletter-builder-area-center-frame-buttons-dropdown").fadeOut(200); }) }, function() { $(this).children(".newsletter-builder-area-center-frame-buttons-content-tab-add").remove(); } );



I will explain to you now how does the little pen icon appears when you hover the mouse on any element inside the building area. Before that i have to tell something i haven't previously talked about which is the newsletter template itself. You will see that every editable element inside each template row has the class .sim-row-edit attached to it as well as the data-type attribute. The data-type attribute can have 5 possible values which will indicate what kind of content are we dealing with. The values can be the following: image, link, title, text and icon. Now let's talk about the pen icon hover function. This functions similarly to the add content popup i talked previously. Every time you hover over the .sim-row-edit class this function will append the pen icon inside .sim-row-edit and disable the default link functions. The '.sim-row-edit-hover i' click function will be declared inside the hover section because we will get rid of it once the hove is over. At the time of the click we store the .sim-row-edit element inside the big_parent variable which is the second parent for the pen icon.



//Edit function hover_edit(){ $(".sim-row-edit").hover( function() { $(this).append('<div class="sim-row-edit-hover"><i class="fa fa-pencil" style="line-height:30px;"></i></div>'); $(".sim-row-edit-hover").click(function(e) {e.preventDefault()}) $(".sim-row-edit-hover i").click(function(e) { e.preventDefault(); big_parent = $(this).parent().parent(); //edit image if(big_parent.attr("data-type")=='image'){ $("#sim-edit-image .image").val(big_parent.children('img').attr("src")); $("#sim-edit-image").fadeIn(500); $("#sim-edit-image .sim-edit-box").slideDown(500); $("#sim-edit-image .sim-edit-box-buttons-save").click(function() { $(this).parent().parent().parent().fadeOut(500) $(this).parent().parent().slideUp(500) big_parent.children('img').attr("src",$("#sim-edit-image .image").val()); }); } //edit link if(big_parent.attr("data-type")=='link'){ $("#sim-edit-link .title").val(big_parent.text()); $("#sim-edit-link .url").val(big_parent.attr("href")); $("#sim-edit-link").fadeIn(500); $("#sim-edit-link .sim-edit-box").slideDown(500); $("#sim-edit-link .sim-edit-box-buttons-save").click(function() { $(this).parent().parent().parent().fadeOut(500) $(this).parent().parent().slideUp(500) big_parent.text($("#sim-edit-link .title").val()); big_parent.attr("href",$("#sim-edit-link .url").val()); }); } //edit title if(big_parent.attr("data-type")=='title'){ $("#sim-edit-title .title").val(big_parent.text()); $("#sim-edit-title").fadeIn(500); $("#sim-edit-title .sim-edit-box").slideDown(500); $("#sim-edit-title .sim-edit-box-buttons-save").click(function() { $(this).parent().parent().parent().fadeOut(500) $(this).parent().parent().slideUp(500) big_parent.text($("#sim-edit-title .title").val()); }); } //edit text if(big_parent.attr("data-type")=='text'){ $("#sim-edit-text .text").val(big_parent.text()); $("#sim-edit-text").fadeIn(500); $("#sim-edit-text .sim-edit-box").slideDown(500); $("#sim-edit-text .sim-edit-box-buttons-save").click(function() { $(this).parent().parent().parent().fadeOut(500) $(this).parent().parent().slideUp(500) big_parent.text($("#sim-edit-text .text").val()); }); } //edit icon if(big_parent.attr("data-type")=='icon'){ $("#sim-edit-icon").fadeIn(500); $("#sim-edit-icon .sim-edit-box").slideDown(500); $("#sim-edit-icon i").click(function() { $(this).parent().parent().parent().parent().fadeOut(500) $(this).parent().parent().parent().slideUp(500) big_parent.children('i').attr('class',$(this).attr('class')); }); }// }); }, function() { $(this).children(".sim-row-edit-hover").remove(); } ); } hover_edit();



I have to point out that the whole .sim-row-edit hover function is inside hover_edit function because we have to refresh this function each time we add new content. There is also a click function for when you click the close button on one of the popups designed for edit.



//close edit $(".sim-edit-box-buttons-cancel").click(function() { $(this).parent().parent().parent().fadeOut(500) $(this).parent().parent().slideUp(500) });



As i stated in the title this is also a drag and drop builder so you can drag individually template rows around. We can do that with the following code:



//Drag & Drop $("#newsletter-builder-area-center-frame-content").sortable({ revert: true }); $(".sim-row").draggable({ connectToSortable: "#newsletter-builder-area-center-frame-content", //helper: "clone", revert: "invalid", handle: ".sim-row-move" });



Once we added and dragged the content we may want to remove it, for that purpose i created the following code that will add the little delete icons inside each template row. And a function for delete that template row.



/Delete function add_delete(){ $(".sim-row").append('<div class="sim-row-delete"><i class="fa fa-times" ></i></div>'); } add_delete(); function perform_delete(){ $(".sim-row-delete").click(function() { $(this).parent().remove(); }); } perform_delete();



When a user clicks on #newsletter-builder-sidebar-buttons-abutton the HTML inside #newsletter-builder-area-center-frame-content will be copied inside #newsletter-preloaded-export. We are doing this step so we can format the content in a container without effecting the main building area. Once we added the content inside #newsletter-preloaded-export we will perform the following formatting. We remove the .ui-draggable class, all the data-type attributes as well as all the .sim-row-edit class. After formatting the content inside #newsletter-preloaded-export we will go ahead and put the formatted HTML inside a variable. The #export-textarea which is the text area inside the #newsletter-preloaded-download will be submitted as a POST form to export.php defined in the form action target. Being done all that we will go ahead and remove the html inside #export-textarea so we are getting it ready for another download or export.



//Download $("#newsletter-builder-sidebar-buttons-abutton").click(function(){ $("#newsletter-preloaded-export").html($("#newsletter-builder-area-center-frame-content").html()); $("#newsletter-preloaded-export .sim-row-delete").remove(); $("#newsletter-preloaded-export .sim-row").removeClass("ui-draggable"); $("#newsletter-preloaded-export .sim-row-edit").removeAttr("data-type"); $("#newsletter-preloaded-export .sim-row-edit").removeClass("sim-row-edit"); export_content = $("#newsletter-preloaded-export").html(); $("#export-textarea").val(export_content) $( "#export-form" ).submit(); $("#export-textarea").val(' '); });



The exporting is done the same as the downloading until the point of submitting the form. We don't submit any form here but we will put the content of #newsletter-preloaded-export inside the export popup as well as attaching the newsletter.css file using Ajax.



//Export $("#newsletter-builder-sidebar-buttons-bbutton").click(function(){ $("#sim-edit-export").fadeIn(500); $("#sim-edit-export .sim-edit-box").slideDown(500); $("#newsletter-preloaded-export").html($("#newsletter-builder-area-center-frame-content").html()); $("#newsletter-preloaded-export .sim-row-delete").remove(); $("#newsletter-preloaded-export .sim-row").removeClass("ui-draggable"); $("#newsletter-preloaded-export .sim-row-edit").removeAttr("data-type"); $("#newsletter-preloaded-export .sim-row-edit").removeClass("sim-row-edit"); preload_export_html = $("#newsletter-preloaded-export").html(); $.ajax({ url: "_css/newsletter.css" }).done(function(data) { export_content = '<style>'+data+'</style><link href="http://fonts.googleapis.com/css?family=Source+Sans+Pro:200,300,400,600,700,900,200italic,300italic,400italic,600italic,700italic,900italic" rel="stylesheet" type="text/css"><link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css"><div id="sim-wrapper"><div id="sim-wrapper-newsletter">'+preload_export_html+'</div></div>'; $("#sim-edit-export .text").val(export_content); }); $("#newsletter-preloaded-export").html(' '); }); PHP Before talking a little about the code inside export.php i will point out one more time that this step is not necessary, you can remove it from your builder and if you still want this feature you will need a PHP server in order for this to run. First we will have to check if the POST variable 'export-textarea' is set. After doing the checking we will set the header of the document to a download related file. We will embed the newsletter.css inside this document surrounded by