The Situation
I have to create a web-application that allows me to, starting from a blank page, insert new html, images and so on, and allows to edit it with features like: resize, positioning and so on.
To figure out what I'm talking about, see: https://www.scrollkit.com in its editor section.
My Question
How should I save the new html I create, with the CSS bound to it, to my server?
Should I use a JSON structure in which I put all my elements with something like:
{
attributes: "",
tag: "div",
html: "some-html",
..
}
Or should I save the entire (maybe "compiled"?) html page to the file-system?
Thanks in advance to all.
I see this as an architecture question more then a code question, especially since the asker didn't specify what server side technology they are using or are comfortable with.
Here is how I would design this:
I'd have a div where all the content would go inside. I'd optionally have a style element (with an id) that all my custom css would be written into. I'd simply save the contents of the div and css style to the server, using ajax, when various things happened (user hit save button, perhaps auto-save every so many minutes, etc), and reload it when needed (on page load, reset button, maybe undo, etc.).
Hopefully, I'd be able to build all my insert/resize/position code to work just off of html. If I needed to, I'd put data- elements on my html to store information I needed to make all my manipulation work. I'd strongly hesitate to have a duplicate JavaScript structure in memory for all my elements, because it seems that nightmares could happen if they get out of sync. However, if you have to do so, I'd also save that to the server and reload it. I'd find a way to rebuild either the structure or the data- attributes if they don't exist.
That's a good enough start, I think. Feel free to ask questions.
I'd recommend using XML+XHTML. Browsers can render XHTML just as well as HTML, but unlike with HTML, XML processing rules allows namespaces so the browser will just ignore unrecognized elements and attributes as long as you put them in a separate namespace. Your editor can use namespaced elements and attributes to store editor metadata that wouldn't be in the compiled HTML.
Creating an HTML editor is a very complicated task. I would use one of existing controls that is actively maintained. But if you insist, you can use JSON and post the HTML and CSS data to an endpoint, then save it to a file or database. I don't believe keeping a node by node structure is necessary.
So, you could try the following:
(I assume, you're using an <iframe/> for this HTML editor)
var data,
// since we're editing within an iframe,
// we'll get the iframe document to access HTML data
iframe = document.getElementById('editor-iframe'),
editorDoc = iframe.contentDocument || iframe.contentWindow.document;
// gathering post data from the edited document
data = {
// get the full html from the editor document
html: $(editorDoc).find('html').get(0).outerHTML,
// since the user is editing a file on the fly, you can
// have a <style> element within the head and modify it when
// user edits the file. So we can get the style contents
// and store it separately here.
css: $(editorDoc).find('head style').html(),
// add some extra metadata here
metadata: {
user: 'onur'
}
};
// finally, posting the data to the endpoint when the
// user clicks a "save" button. And you should also auto-save
// periodically to prevent data loss.
$.post('/saveFile', data);
Here is a demo fiddle.
When I implementing something like this I saved the raw html as XML then I parsed the page accordingly.
To be more clear I used various xml blocks for different items eg:
<xml>
<html>
</html>
<css>
</css>
</xml>
Just build the structure you need. Hope this helps
This is how I'd do it to keep things simple:
{
filelist: [
{
filename: "style.css",
contents: ""
},
{
filename: "index.js",
contents: ""
},
{
filename: "index.html",
contents: ""
}
]
}
If it's pure HTML, I would just keep it as one string when passing to the server and use an iframe on the client side to preview it. This would make loading simple and you can just manipulate the HTML using the DOM when sent to the client. Is there a particular reason you would need the HTML tags in any other format? I suppose if you wanted to implement some kind of content management system with re-usable blocks, you would want to change things up a bit.
Steo, when you are developing an application which has a feature to insert HTML, make sure you have a good control to avoid persistent/non-persistent XSS attacks.
If the HTML/CSS depended features are manageable, I would recommend you to go with JSON storage with proper server side validation, which may help you to keep your model clean and no technology dependent. So that you can parse the JSON and develop your application for mobile, tablet etc., later.
Having an array of JSON objects(CONFIG) copy will also help the application with undo or redo operations, which will be an important feature when working with editor.
Good luck! :-)
With html5 i think it's simple http://www.w3schools.com/html/html5_webstorage.asp
Related
I am making an on-line shop for selling magazines, and I need to show the image of the magazine. For that, I would like to show the same image that is shown in the website of the company that distributes the magazines.
For that, it would be easy with an absolute path, like this:
<img src="http://www.remotewebsite.com/image.jpg" />
But, it is not possible in my case, because the name of the image changes everytime there is a new magazine.
In Javascript, it is possible to get the path of an image with this code:
var strImage = document.getElementById('Image').src;
But, is it possible to use something similar to get the path of an image if it is in another HTML page?
Assuming that you know how to find the correct image in the magazine website's DOM (otherwise, forget it):
the magazine website must explicitly allow clients showing your website to fetch their content by enabling CORS
you fetch their HTML -> gets you a stream of text
parse it with DOMParser -> gets you a Document
using your knowledge or their layout (or good heuristics, if you're feeling lucky), use regular DOM navigation to find the image and get its src attribute
I'm not going to detail any of those steps (there are already lots of SO answers around), especially since you haven't described a specific issue you may have with the technical part.
You can, but it is inefficient. You would have to do a request to load all the HTML of that other page and then in that HTML find the image you are looking for.
It can be achieved (using XMLHttpRequest or fetch), but I would maybe try to find a more efficient way.
What you are asking for is technically possible, and other answers have already gone into the details about how you could accomplish this.
What I'd like to go over in this answer is how you probably should architect this given the requirements that you described. Keep in mind that what I am describing is one way to do this, there are certainly other correct methods as well.
Create a database on the server where your app will live. A simple MySQL DB will work, but you could use anything. Create a table called magazine, with a column url. Your code would pull the url from this DB. Whenever the magazine URL changes, just update the DB and the code itself won't need to be changed.
Your front-end code needs some sort of way to access the DB. One possible solution is a REST API. This code would query the DB for the latest values (in your case magazine URLs), and make them accessible to your web page. This could be done in a myriad of different languages/frameworks, here's a good tutorial on doing something like this in Node.js and express (which is what I'd personally use).
Finally, your front-end code needs to call your REST API to get the updated URLs. This needs to be done with some kind of JavaScript based language. jQuery would make this really easy, something like this:
$(document).ready(function() {
$.Get("http://uri_to_your_rest_api", function(data) {
$("#myImage").attr("scr", data.url);
}
});
Assuming you had HTML like this:
<img id="myImage" src="">
And there you go - You have a webpage that pulls the image sources dynamically from your database.
Now if you're just dipping your toes into web development, this may seem a bit overwhelming. But I promise you, in the long run it'll be easier then trying to parse code from an HTML page :)
I have an HTML file with some Javascript and css applied on.
I would like to duplicate that file, make like file1.html, file2.html, file3.html,...
All of that using Javascript, Jquery or something like that !
The idea is to create a different page (from that kind of template) that will be printed afterwards with different data in it (from a XML file).
I hope it is possible !
Feel free to ask more precision if you want !
Thank you all by advance
Note: I do not want to copy the content only but the entire file.
Edit: I Know I should use server-side language, I just don't have the option ):
There are a couple ways you could go about implementing something similar to what you are describing. Which implementation you should use would depend on exactly what your goals are.
First of all, I would recommend some sort of template system such as VueJS, AngularJS or React. However, given that you say you don't have the option of using a server side language, I suspect you won't have the option to implement one of these systems.
My next suggestion, would be to build your own 'templating system'. A simple implementation that may suit your needs could be something mirroring the following:
In your primary file (root file) which you want to route or copy the other files through to, you could use JS to include the correct HTML files. For example, you could have JS conditionally load a file depending on certain circumstances by putting something like the following after a conditional statement:
Note that while doing this could optimize your server's data usage (as it would only serve required files and not everything all the time), it would also probably increase loading times. Your site would need to wait for the additional HTTP request to come through and for whatever requested content to load & render on the client. While this sounds very slow it has the potential of not being that bad if you don't have too many discrete requests, and none of your code is unusually large or computationally expensive.
If using vanilla JS, the following snippet will illustrate the above:
In a script that comes loaded with your routing file:
function read(text) {
var xhr=new XMLHttpRequest;
xhr.open('GET',text);
xhr.onload=show;
xhr.send();
}
function show() {
var text = this.response;
document.body.innerHTML = text;//you can replace document.body with whatever element you want to wrap your imported HTML
}
read(path/to/file/on/server);
Note a couple of things about the above code. If you are testing on your computer (ie opening your html file on a browser, with a path like file://__) without a local server, you will get some sort of cross origin request error when trying to make an XML request. To bypass this error, either test your code on an actual server (not ideal constantly pushing code, I know) or, preferably, set up a local testing server. If this is something you would want to explore, its not that difficult to do, let me know and I'd be happy to walk you through the process.
Alternately, you could implement the above loading system with jQuery and the .load() function. http://api.jquery.com/load/
If none of the above solutions work for you, let me know more specifically what it is that you need, and I'll be happy to give a more useful/ relevant answer!
I'm putting together a simple website for our department. I'd like to include one of the references that we use often on the main page, a word document that contains a priority list for outstanding work. This document is generated by another department and located on a shared drive. The info is not in a table, but uses a fairly consisten format for displaying info.
Ex: (the info is actually formatted like this)
--------------
Item Title
--------------
Tracker#: 12345-0012 Due; 01/01/12
Description...
My ultimate goal is to have a table on the main page that contains the various items in the priority list. I would like a mechanism that automatically checks the word docs about once an hour, parses the document, generates a table from the info in the doc, and updates the main page accordingly.
I've never done anything like this and have no idea where to start or if what I'm asking is even possible. I'm not in IT and do not have the ability to use ASP or PHP at the moment. So I'd like to avoid server-side scripting if possible, but I may be able to work something out if absolutely necessary.
Thanks
I know how to do this in java.. you can use the docx4j library.. Without that it would be difficult. Can't the team that create the doc store the file as a flat file as well maybe?
One possible solution is to save document as html (using automation - create Word.Application object, call Open, SaveAs) and serve it directly or inside frame.
I'm am building a web app with app engine (java) and GWT, although I think my problem is moreso a general javascript question.
In my application, I want to include a side-menu which is generated from data in my database. This obviously needs to be done dynamically from a servlet.
Currently, I am sending a blank menu container, then making an ajax call to get the information i need to populate the menu. I would rather just send the menu information along in the original request, so I do not need to waste time making a second request. I used this initial approach because it seemed simpler: I just wrote a gwt rpc service that grabbed the data i needed.
My question is, can I instruct a javascript library like gwt to look for its information in the current web page? Do I have to hide this information in my original HTML response, maybe in a hidden div or something?
If the data that you'd like to embed is restricted to menu items, why not directly generate lightweight HTML out of simple <ol> and <li> elements? You can still keep HTML out of your Java code by using a template engine. The menu markup could just be styled with CSS or if you need something fancier than mere <ol> and <li> elements, you can massage the DOM with JavaScript once the page loads (read: progressive enhancement).
If you're looking for a more generic solution, beyond the menu case, then you could embed a JSON block in your page, to be consumed when the page loads for the dynamic generation of your menu.
Or, you could look into using a microformat that is suitable for menu data.
You can include a script block in the original response defining the data and then use an onload event (or similar) to create the menu based on that data; that's very similar to what you're doing now, but without the extra trip to the server. I'm assuming there that the data to construct the menu is transformed in some way by JavaScript on the client; otherwise, just include the menu markup directly.
GWT has something called JSNI (Javascript Native Interface) that can interface with other non-GWT Javascript. So, you could in your HTML page container have a containing the generated menu items as a Javascript object. Then, in your GWT code, you have a JSNI call to fetch this data and put it in the right place in your UI/DOM with GWT methods.
I asked a similar question a few weeks ago about how to store data safely inside HTML tags. It also contains a few links to other questions. Here
There are in general 2 options:
Store the data in some xml tags somewhere in the html code and later get the information from there by traversing through the DOM. (you can hide them with css)
Store the data as JSON data in a script tag. (There en- and decoders for nearly every language)
var data = { "foo" : "bar", "my_array":[] };
I'm working on an AJAXy project (Dojo and Rails, if the particulars matter). There are several places where the user should be able to sort, group, and filter results. There are also places where a user fills out a short form and the resulting item gets added to a list on the same page.
The non-AJAXy implementation works fine -- the view layer server-side already knows how to render this stuff, so it can just do it again in a different order or with an extra element. This, however, adds lots of burden to the server.
So we switched to sending JSON from the server and doing lots of (re-)rendering client-side. The downside is that now we have duplicate code for rendering every page: once in Rails, which was built for this, and once in Dojo, which was not. The latter is basically just string concatenation.
So question part one: is there a good Javascript MVC framework we could use to make the rendering on the client-side more maintainable?
And question part two: is there a way to generate the client-side views in Javascript and the server-side views in ERB from the same template? I think that's what the Pragmatic Programmers would do.
Alternatively, question part three: am I completely missing another angle? Perhaps send JSON from the server but also include the HTML snippet as an attribute so the Javascript can do the filtering, sorting, etc. and then just insert the given fragment?
Well, every time you generate HTML snippets on the client and on the server you may end up with duplicated code. There is no good way around it generally. But you can do two things:
Generate everything on the server. Use AHAH when you need to generate HTML snippets dynamically. Basically you ask server to generate an HTML fragment, receive it asynchronously, and plug it in place using innerHTML or any other similar mechanism.
Generate everything on the client (AKA the thick client paradigm). In this case even for the initial rendering you pass data instead of pre-rendered HTML, and process the data client-side using JavaScript to make HTML. Depending on the situation you can use the data island technique, or request data asynchronously. Variant: include it as <script> using JSONP so the browser will make a request for you while loading the page.
Both approaches are very simple and have different set of pros and cons. Sometimes it is possible to combine both techniques within one web application for different parts of data.
Of course you can go for exotic solutions, like using some JavaScript-based server-side framework. In this case you can share the code between the server and the client.
I don't have a complete answer for you; I too have struggled with this on a recent project. But, here is a thought:
Ajax call to Rails
Rails composes the entire grid again, with the new row.
Rails serializes HTML, which is returned to the browser.
Javascript replaces the entire grid element with the new HTML.
Note: I'm not a Rails person, so I'm not sure if those bits fit.
Has anyone tried something like the following? There's redundant data now, but all the rendering is done server-side and all the interaction is done client-side.
Server Side:
render_table_initially:
if nojs:
render big_html_table
else:
render empty_table_with_callback_to_load_table
load_table:
render '{ rows: [
{ foo: "a", bar: "b", renderedHTML: "<tr><td>...</td></tr>" },
{ foo: "c", bar: "d", renderedHTML: "<tr><td>...</td></tr>" },
...
]}'
Client side:
dojo.xhrGet({
url: '/load_table',
handleAs: 'json',
load: function(response) {
dojo.global.all_available_data = response;
dojo.each(response.rows, function(row) {
insert_row(row.renderedHTML);
}
}
});
Storing the all_available_data lets you do sorting, filtering, grouping, etc. without hitting the server.
I'm only cautious because I've never heard of it being done. It seems like there's an anti-pattern lurking in there...
"Perhaps send JSON from the server but also include the HTML snippet as an attribute so the Javascript can do the filtering, sorting, etc. and then just insert the given fragment?"
I recommend keeping the presentation layer on the client and simply downloading data as needed.
For a rudimentary templating engine, you can extend Prototype's Template construct:
http://www.prototypejs.org/api/template
As your client scales and you need a rich and flexible MVC, try PureMVC.
http://puremvc.org/content/view/102/181/
As in regular server side programming you should strive to encapsulate your entities with controls, in your case client side controls that has data properties and also render methods + events.
So for example lets say you have on the page an are that shows tree of employees, effectively you should encapsulate it behavior in a client side class that can get JSON object of the employee list / by default connect to the service and a render method to render the output, events and so on.
In ExtJS its is relatively easy to create these kind of controls - look at this article.
Maybe I'm not fully understanding your problem but this is how I would solve your requirements:
Sort, Filter
It can be done all in JavaScript, without hitting the server. It's a problem of manipulating the table rows, move rows for sorting, hide rows for filtering, there is no need for re-rendering. You will need to mark columns with the data type with custom attributes or extra class names in order to be able to parse numbers or dates.
If your reports are paginated I think it's easier and better to refresh the whole table or page.
Group
I can't help here as I don't understand how will you enable grouping. Are you switching columns to show accumulates? How do you show the data that doesn't support accumulates like text or dates?
New item
This time I would use AJAX with a JSON response to confirm that the new item was correctly saved and possibly with calculated data.
In order to add the new item to the results table I would clone a row and alter the values. Again we don't need to render anything in client-side. The last time I needed something like this I was adding an empty hidden row at the end of the results, this way you will always have a row to clone no matter if the results are empty.
Number 5 in my list of five AJAX styles tends to work pretty well.