I'm running into an issue on a particular form.
If the form is submitted and there is an error with the form (maybe I forgot to fill in a required field), then the form reloads with the errors as it's supposed to. However, any image you had previously selected, disappears and needs to be reselected.
Before submitting form with errors:
After submitting form with errors:
This is the HTML tag being used:
<input type="file" accept="image/*" id="Image" name="Image"/>
What I need is for the image selector to still maintain the selected image between submits. Is there a good way to do this? Is there a way to save the file path to the session perhaps and fill it into the element again?
Browsers will not allow file upload fields to be restored automatically as a security measure. To prevent losing the file from validation, either perform all validation on the client side (though you should always validate again on the server) so the form is never submitted until everything is correct or you have to grab the file(s) that are submitted the first time and hold on to them until the form finally comes through with all validation completed.
In this second case you have a couple options:
Save the contents somewhere and return a unique ID pointer to be held in a hidden field when you return the form. You should also consider putting a visible label that shows what file has already been uploaded. You will have to clean up uploads periodically from users who give up and come back later (and thus won't be submitting a form with that correlation ID for you to match up the upload).
Base64 encode the contents of the uploaded file and return that to the view in a hidden field. This is more bandwidth intensive but it doesn't require you to store a file on your server that may never be correlated to a proper form. You might also be able to display that same image in the returned view since I believe you can specify a Base64 encoded image as the source for an image tag (or maybe CSS attribute). This might be browser specific.
As long as your file uploads are limited in size (100kb for instance) option 2 is my favored approach. It's not much bigger than all the modern JavaScript libraries that are included in a page and is a better experience for the user while leaving your server dumb of sessions, cleanup or excessive processing.
Edit: Many sites that allow uploading of images also provide validation on file size and kick it back if it's oversized. In this case the user has feedback that their asset has not been stored and you're free from having to encode and return it.
Edit 2:
Here's a post about browsers marking the file upload control value field as read-only and preventing this from being modified by JavaScript (it can only be modified by direct user action).
And here's a SO comment about using Base64 encoded image in HTML directly. The question asker is looking for a way to put the data in a separate file but this isn't what you want. The 'this works' portion is what I was referring to in Option 2 above.
I think you can use the hidden field and display the file selected in the label. When after validation get the content of the file and save it in the Session or some temp place . Then while showing the page so on the label the file path what user has selected earlier and update the same in the hidden field . If the user submit the form again check first if the file is NULL but hidden field value is there , it means you have save the file earlier, If the path is different from the hidden field you may have to get the file content again.
Just saving the path will not help you have to save the file stream uploaded first time . I think if your user will be delight with not loading the file again you have to pay something from your server resource :)
The only way you can do this is to provide validation on client side. It is because submit to server "sends" already a form, and resend it back with errors. As it was pointed out in comment, the file is cleared because of security (thanks Eric)
To do client side validation in MVC 3 you can use unobstuctive jquery validation. To do this just add in web.config:
<appSettings>
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
Related
I am reluctant to post this, but I am having trouble understanding how markdown actually "saves" to a database.
When I'm creating a migration, I will add columns and specify the type of value (i.e. integer, text, string, etc.) and in the course of operation on the website, users will input different information that is then saved in the DB. No problem there.
I just can't seem to wrap my head around the process for markdown. I've read about saving the HTML or saving the markdown file, rendering at runtime, pros and cons all that.
So, say I use an editor like Tiny MCE which attaches itself to a textarea. When I click "Submit" on the form, how does that operate? How does validation work? Feel free to answer my question directly or offer some resource to help further my understanding. I have an app built on Laravel so I'm guessing I'll need to use a package like https://github.com/GrahamCampbell/Laravel-Markdown along with an editor (i.e. Tiny MCE).
Thanks!
Let's start with a more basic example: StackOverflow. When you are writing/editing a question or answer, you are typing Markdown text into a textarea field. And below that textarea is a preview, which displays the Markdown text converted to HTML.
The way this works (simplified a little) is that StackOverflow uses a JavaScript library to parse the Markdown into HTML. This parsing happens entirely client side (in the browser) and nothing is sent to the server. With each key press in the textarea the preview is updated quickly because there is no back-and-forth with the server.
However, when you submit your question/answer, the HTML in the preview is discarded and the Markdown text from the textarea is forwarded to the StackOverflow server where is is saved to the database. At some point the server also converts the Markdown to HTML so that when another user comes alone and requests to view that question/answer, the document is sent to the user as HTML by the server. I say "at some point" because this is where you have to decide when the conversion happens. You have two options:
If the server converts the HTML when is saves it to the Database, then it will save to two columns, one for the Markdown and one of for the HTML. Later, when a user requests to view the document, the HTML document will be retrieved from the database and returned to the user. However, if a user requests to edit the document, then the Markdown document will be retrieved from the database and returned to the user so that she can edit it.
If the server only stores the Markdown text to the database, then when a user requests to view the document, the Markdown document will be retrieved from the database, converted to HTML and then returned to the user. However, if a user requests to edit the document, then the Markdown document will be retrieved from the database and returned to the user (skipping the conversion step) so that she can edit it.
Note that in either option, the server is doing the conversion to HTML. The only time the conversion happens client-side (in the browser) is for preview. But the "preview" conversion is not used to display the document outside of edit mode or to store the document in the database.
The only difference between something like StackOverflow and TinyMCE is that in TinyMCE the preview is also the editor. Behind the scenes the same process is still happening and when you submit, it is the Markdown which is sent to the server. The HTML used for preview is still discarded.
The primary concern when implementing such a system is that if the Markdown implementation used for preview is dissimilar from the implementation used by the server, the preview may not be very accurate. Therefore, it is generally best to choose two implementations that are very similar or, if available, use the same implementations for both.
It is actually very simple.
Historally, in forums, there used be BBCodes, which are basically pseudo-tags that allow you to format your text in some say. For example [b][/b] used to mean "make this text bold". In Markdown, it happens the exact same thing, but with other characters like *text* or **text**.
This happens so that you only allow your users to use a specific formatting, otherwise if you'd allow to write pure HTML, XSS (cross-site scripting) issues would arise and it's not really a good idea.
You should then save the HTML on the database. You can use, for example, markdown-js which is a Markdown parser that parses Markdown to HTML.
I have seen TinyMCE does not make use of Markdown by default, since it's simple a WYSIWYG editor, however it seems like it also supports a markdown-like formatting.
Laravel-Markdown is a server-side markdown render helper, you can use this on Laravel Blade views. markdown-js is instead client-side, it can be used, for example, to show a preview of what you're writing in real-time.
I would like to send a lot of data through ajax request to my server which will generate pdf or jpg format according to that data.
Now i have done all that, my issue is to how output that generated pdf/jpg back to the user trough ajax? I guess i might be able to use json for that, but im not really sure how, and i think there would be a lot issues with pdf.
Also if some one gonna suggest using form with hidden inputs that will not work since i have really big multidimensional array with lot's of data and it would simply take to much effort to make it work.
By the way, i am using jquery, but anything else is acceptable as long as it does the job done without making me to rewrite half of my script.
To display a JPG
AJAX: You can return the data hex encoded (be sure to set the content type appropriately: header('Content-type: image/jpeg')). Then you just inject an <img/> element into the DOM and set it's src attribute to the returned Data URI.
HTML: Also, you could inject the <img/>'s with a normal src URL to some location on your server.
For PDF
It's a little more tricky. Some browsers display PDF's natively (Chrome/Firefox), others rely on optional third-party plugins. You can detect these plugins, but can't control whether the PDF is displayed in a window/frame or is downloaded.
If you choose to display, you can create a new window/tab to display it or display it in an iframe dynamically.
The newer versions of Firefox have a new 'feature' that remembers the stuff that was filled out in a form and repopulates the form with these values on refresh (maybe in other situations as well?).
The problem is we have a quite complicated web application which uses a fair bit of ajax and hidden form fields which are never filled out by the user, but by javascript.
Because of this new 'Feature' we get a lot of errors when refreshing form because these fields are suddenly populated with invalid values.
So i'm looking for a way to turn this 'feature' off without disabling auto-completion. (because that IS useful on the fields our customers fill in)
if i put
autocomplete='off'
in my html, the effect is disabled, but this loses auto-completion (obviously).
the problem is in fields getting filled in after a refresh without any user action.
While the password manager will populate a username and password if there is exactly one match, autocomplete itself doesn't automatically populate fields. But I'm guessing you're thinking about the sort of refresh you get, say, if you reload the page. In this case the field values are restored by session history, but you might be able to turn that off by marking your page as uncacheable.
Well you should set the value of these fields to nothing or or whatever default value they have using javascript right before you start your other javascript/ajax tasks.
It is a browser feature - without going into the settings of each client browser you can't disable this.
I suggest more robust validation - client and server side.
After the page is loaded, but before you do any other logic, you should force the value to be empty:
inputElem.value = '';
Here is a jQuery solution I put together.
It doesn't disable the autofill, rather it overrides the fields after the browser has done it's thing.
I was trying to fight Chromes autofill when I made this. Just using .val('') on it's own didn't work since it triggered before chromes autofill functionality kicked it.
var noFiller = $('input[type="text"]');
noFiller.val(' ');
var t=setTimeout(function(){
noFiller.val('');
},60);//keep increasing this number until it works
The Javascript solution (setting field values to empty when the page loads or updates via Ajax) has already been mentioned.
Another option might be to generate the ids of your fields with random numbers attached to them so that the browser can't match them to cached values, but this may screw up other things.
Autocomplete isn't a new thing. Every browser has it. See this http://www.w3.org/Submission/web-forms2/#the-autocomplete
Autofill? Are you sure? Check your input's value attribute with Firebug (Firefox addon). Check you post and response in your ajax. Maybe your ajax is filling it behind scenes.
BTW: remenber to disable any external toolbar. There are some toolbars for Firefox/IE/Chrome/etc that autofill data for the user. Warning with this.
I am new to ajax and i wanted to know if we can load a complete new page and not just a part of it using ajax. Please give a small example script for understanding if this is possible. Here i am trying to display only one url to user while i change from one page to another when he clicks on any of the links in the page.
You can of course request for a new page and load it via body.innerHTML = ajax.responseText;
I would strongly recommend against this though for reasons outlined in this post: Why not just using ajax for Page Requests to load the page content?
The whole premise really is that with
AJAX you don't need to reload the
whole page to update a small
percentage of that webpage. This saves
bandwidth and is usually much quicker
than reloading the whole page.
But if you are using AJAX to load the
whole page this is in fact
counterproductive. You have to write
customised routines to deal with the
callback of the AJAX data. Its a whole
lot of extra work for little to no
increase in performance.
General rule for where to use AJAX: If
your updating >50% of your page, just
reload, else use AJAX.
You will not only need to request for the new page, but then also take care of ensuring the old styles on the current page are removed and don't interfere with the new page. Theres all sorts of problems associated with what your trying to do. It's possible, but I recommend not to do it.
edit: actually you might be able to just do document.write(ajax.responseText) which should take care of overwriting everything in the document, including css styles etc. Though still don't recommend it.
When you're finished with processing the AJAX request simply use this JS line:
window.location.replace('<URL of the new page>');
This has exactly the effect of loading the new page via
....
When you make an AJAX request, a request goes off and brings you the contents of the URL that you have requested. Now technically you can do whatever you like with the contents (which could be HTML), you can replace any element within the DOM with it. Be careful however of replacing EVERYTHING on the page, you are more likely just going to want to replace what is within the tags.
If what you want to do is show one URL for multiple pages, AJAX is overkill. Why not just use an IFRAME?
This could be useful if your page was unsure if it was expecting back errors to be inserted onto the page or a "new" submission confirmation page. This can be used when you want to put a validation servlet (or whatever) in front of the submission servlet (or whatever). If the page always hits the validation servlet, you hide the submission servlet which actually performs the data update. In the case where the validation passes, forward to the submission servlet. The user never knows what happened in the background.
When the page gets a response back you could just look at the first portion of the response text and determine if it had a keyword set by the server, which means this is a new page. Remove the keyword from the text, and do document.write(ajax.responseText); as described previously. Otherwise insert the response text into your errorBox div and let the user retry submission.
the problem I have is that I have two sets of values in a drop down list. If type 'A' is selected I want a text box to be populated with a value from the database and be read only. If Type 'B' is selected the box is to be empty and editable.
My original code is written in jsp/struts and I have sort of achieved this by using
onchange="javascript:submit()" to reload the page, but this has the obvious drawback of saving any changes you have made which means you can't really cancel.
I also have other problems with the serverside validation due to this method.
Is there a way of making a jsp page reload on change, that way I could write javascript to change the way the page looks according to the values held in the session. That way the save/submit function will only be called when the page has properly been filled out and the server side validation will work as designed.
I know that this is something that AJAX is good at doing but I am trying to avoid it if possible.
AJAX is your only other option my friend, unless on the original page load you load all the other possible values of the Text Box so you don't need to go back to the database. Well, you could try putting the text box in an IFRAME, but you will probably run into more problems with that approach than just going with AJAX.
Without AJAX what you are asking is going to be difficult. Another option (which is ugly) is to write out all possible values for the second list box into a data structure like an array or dictionary.
Then write some javascript to get the values from the data structure when the user selects from the first list box. The amount of javascript you will have to write to get this done and to do it correctly in a cross browser way will be much more difficult than simply using AJAX.
Not sure why you'd try to avoid AJAX in today's world, the JS libraries out there today make it so simple it's crazy not to try it out.
I just had to replace a page that was written as Vincent pointed out. I assume at the time it made sense for the app, given the relative size of the data 4 years ago. Now that the app has scaled though, the page was taking upwards of 30 seconds to parse the data structures repeatedly (poorly written JS? maybe).
I replaced all the logic with a very simple AJAX call to a servlet that simply returns a JSON response of values for the 2nd drop down based on what was passed to it and the response is basically instant.
Good luck to ya.
One way is to change the form's action so that you submit the form to a different url than the "save" url. This lets you reload certain aspects of the form and return to the form itself, instead of committing the data.
<script>
function reload() {
document.forms[0].action="reloadFormData.jsp";
document.forms[0].submit();
}
</script>
<form action="saveData.jsp" method="post">
<select id="A" name="B" onchange="reload()"><!-- blah --></select>
<select id="B" name="B"><!-- blah B --></select>
<input type="submit">
</form>
If I understand you correctly, that you want either a dropdown (<select>) or a textfield (<input type="text">) depending on a choice (typically a checkbox or radiobuttons) somewhere above in a form?
I that case you may need to handle the two types of input differently on the server anyway, so why not have both the selectbox and textfield in the area of the form with different names and id and one of them hidden (display = none). Then toggle visibility when the choice changes. On the server you pick eiter the selectbox or textarea input (wich will both be present unless you disable (disabled="disabled") them too, wich I think is uneccesary) depending on the choice input.
Of course if you expect that the user usually just need the text-input, and a few times only, needing a massive list; it would be better to use ajax to retrieve the list. But if it's the other way around (you need the text-field only occationally), as I assumed above, it will be faster to have both present in the initial form.
If the drop down only contain easily generateable data, like years from now to houndreds of years back it could even be much faster (requiring less bandwidth on the server) to generate the data client side using a for loop in Javascript.
I know a taglib that can fit to your problem:
AjaxTags.
I use this taglib in my J2EE projects and it is very simple to integrate it into web applications.
This taglib give you several tags designed to execute AJAX request in your jsp files.
Here is the description of each tags: http://ajaxtags.sourceforge.net/usage.html
The tag which will help you is the ajax:select tag. It allows you to populate a select tag which depends on an other field without reloading the entire jsp page.
If you more informations about it, ask me and i'll try to answer quicky.
Along the lines of what Strindhaug said, but if you need dynamic data:
Could you have the backend write JS into the page, and then the JS would change the form as required? The backend could propagate some variables for descriptions and such, and then the JS could change/update the form accordingly. If you aren't familiar with this, libs like jQuery make things like this easier and more cross-browser than rolling-your-own (at least in my experience).
Aside:
If you're not using AJAX because it was hard to code (as I didn't for a while because my first experience was from scratch and wasn't pretty), as others have said, libs like MooTools and such make it really easy now. Also, there is not shame in using AJAX properly. It has a bad rap because people do stupid things with it, but if you can't simply write premade values into the form or you have to do live look ups, this is one of AJAX's proper uses.