Submitting data after image upload - laravel

My site has a feature that allows users to create posts (like Facebook). I have a form with a "Message" input field and a button that allows users to upload images.
Right now, how I have the code set up is that when the user submits the form, my code will submit the data first, and then upload the images.
The problem with this is that if the user cancels the image upload half way through, the database record will exist (because the data was submitted before the image upload), but there will be no images uploaded.
So my solution to this is to upload the images first and submit the data after. The problem with this is that I'm not sure how I can tie the images to the data in a database record.
Should I upload all of the images to /tmp and then move the files to a permanent directory, like /var/www/html/website/public/img/uploads/<upload_id> where upload_id is the id of the database record?
What should I do if the user uploads an image, but closes the tab half way. Then there will be an image in /tmp that will stay there forever unless the directory is cleaned up. How would I clean it up?
Is this the best way to do this or are there better ways?
I'm using Laravel 5.3 and Dropzone.js.
Thanks.

Since you are using Dropzone.js which allows files to be uploaded via ajax, you can do this the following way :
1) Send file to the backend server using Dropzone.js (ajax).
2) Since you are using laravel, each file you receive will be an instance of UploadedFile, you can use this class to access the Original Name of the file uploaded, size, MimeType etc.
3) In the Image Model in your database (create this if not done already), create a new record for this image and store the fields mentioned above if needed, along with the path where you will be storing the image. You can use this path stored in the table row to access the image later.
4) Get the 'id' of the newly inserted row in the Image Table and pass it back to the frontend where you can receive it using the 'success' event Handler for the Dropzone plugin.
5) Append this newly inserted 'id' as a hidden input element in your form.
6) When you submit the form, you will receive the image ids related to your post and you may save it using the Database relationship of your choice.
7) Yes, you need an additional check for images that have been uploaded and entered in your Image table, but those whose posts have not been created. You may create an Artisan CLI command for the same and assign it as a Cron Job.

I think you should submit your form with AJAX. This solution was useful for me.
Make a, span or other element with event "onclick" instead of button, because button pressing will confirm the form automatically, even if the button's type isn't a "submit".
Write an ajax function like this:
function newsFormSubmit(item_id){
var formData = new FormData($('.news-form')[0]);
formData.append("item_id", item_id);
$.ajax({
type: 'POST',
url: config.routes[0].savenews,
data: formData,
processData: false,
contentType: false,
success: function (data) {
if (data.error)
{
alert(data.error);
return false;
} else if (data)
{
$('#news-card-' + item_id).html(data);
}
}
});
}
Place this function on onclick event.

Related

Ajax call bring the user back to same page

I have a search page done using Laravel. On that page there is a button which makes an AJAX call to another url. That page is paginated, so the user can be on the first, second or last page.
My problem is, How can I bring the user back to the same page and point that he was.
Or, Is there a way to just call a method to perform some actions on the database?
Thats my Ajax Call:
$.ajax({
url: $(this).attr('data-href'),
dataType: 'html',
success:function(data) {
$('#ajaxResponse').html(data);
$.growl.notice({ title: 'Voto', message: 'Computado com sucesso' });
$(this).find('.fa').toggleClass('fa-heart-o fa-heart');
}
});
I know if i take the $('#ajaxResponse').html(data); bit it is going to perform the change but not update the numbers that i need. Any ideas?
Here is the documentation for pagination in Laravel with JSON. As you can see, when you paginate your data, the resulting JSON object will contain information about the next and previous pages. Update the links your users click with the provided information and they should see the correct data.
You can try to store the actual page in a session key and use a controller to check this key and display the page that you want. In this case you can keep your ajax call as it is and change only your laravel controller ad view.

ajax function which uploads the image and preview it with another string from server

I want to use file upload control to upload an image and preview it in same page without submitting the form, is this possible?
if possible, please let me know how to set the query string of the ajax function, and how to handle that query string at server side. I am using jsp or servlet.
Intention is to send the image through ajax function call, where I can store the image in server's local folder. also the form will be updated with the part of the result string which is some other component output. Along with this I can show the image which user uploaded.
1. upload the image through ajax call.
2. return string is do two things, one for shows the image in respective place holder by servers local path and another is to get the other component output which is a string.
3. if i have that string, I am manipulate at call back function to set the values.
4. after enters users data I want to submit the form finally.
I tried it, but failing to send the file object as parameter to the servlet or jsp. Also if we can send that object, how can we handle that object at jsp?

Uploading single image and showing its thumbnail using jquery and asp.net mvc3

I need to upload the photo of a user with his details from asp.net mvc3 razor view. The image selected by the user has to be shown as thumbnail before submitting the form.
The model of the view contains a byte array property called Photo. On page load i am converting this byte array to base 64 string and showing it in . this is working properly .
Now i need to show the thumbnail of the image selected by the user. And when he clicks on submit button i need to bind the selected image to the model property Photo.
After googling , i came to know that showing thumbnail is not possible until I upload that image. I tried Uploadify but its UI behavior is not what i am expecting. I also tried the article http://www.dustinhorne.com/post/2011/11/16/AJAX-File-Uploads-with-jQuery-and-MVC-3.aspx, but it is also not suitable in our scenario.
can anyone help me by sharing their experience achieving this scenario.
Thanks in advance.
You could achieve this using HTML5 File API. Take a look at the following article and more specifically the Showing thumbnails of user-selected images section which illustrates an example of how you could achieve that without uploading the image to the server.
And if you want to support legacy browsers that do not yet support the HTML5 File API you could use the jQuery.form plugin which allows you to easily send the contents of a given form to the server using AJAX and it also supports file uploads. So basically you could subscribe to the .change() event of the file input or the .click() event of some see thumbnail ... button and then submit the form to a controller action using AJAX:
$('#myform').ajaxSubmit({
url: '#Url.Action("thumbnail")',
success: function(result) {
// the result variable will contain the result of
// the execution of the Thumbnail action.
// could be a BASE64 encoded representation of
// the thumbnail you generated on the server and then
// simply set it to the src property of your preview `<img>`
// element using the Data Uri scheme
}
});

Getting YouTube views with Backbone.js

I have been using Backbone.js to act as a middleman between Wordpress (using the super rad JSON API plugin) and my front end.
Each of my Wordpress posts has a YouTube video ID attached to it, which is getting pulled back when I fetch the collection.
I am trying to work out the best point within the application to go out and parse the video ID to get the total video views.
This is code that is fetching the collection model:
parse: function(response) {
return response.posts;
}
And the following code is then rendering the appropriate view.
this.getCollection().each(function(model) {
var view = new App.Thumbnail.View({model: model});
var item = $(view.render().el);
this.container.append(item);
});
At some point in this process, I need the thumbnails to assign themselves the video count. This is the code I have for grabbing the YouTube view count:
function getYoutubeViewCount(videoID) {
$.ajax({
url: "http://gdata.youtube.com/feeds/api/videos/" + videoID + "?v=2&alt=json",
dataType: "jsonp",
success: function (data) { console.log(data.entry.yt$statistics.viewCount); }
});
}
So my question is, where do you think the best place to fetch the view count is? Should I create a sub-model that fetches the count? Or do it outside of backbone.js?
Any help would be beyond appreciated!
Thanks in advance,
Charlie.
The viewCount should be an attribute on your Video model subclass. You can load both the wordpress data for the video and the youtube count in parallel before instantiating your model, or you can instantiate your model with the data from wordpress while the youtube data is being fetched and latered applied. Once you get the view count from youtube, set it on the corresponding model instance. Have your view bind to the change:viewCount event on the model and re-render itself (or at least shove the view count into the appropriate element in the DOM) once this data is loaded.
As to WHEN you do this, probably you should start fetching the view count(s) in the background as soon as you have your basic Video model instance created and populated with its basic attributes from your wordpress data source. Or you can choose to load view counts later lazily when the video is played or scrolled into the viewport or moused over or whatever.

Ajax state history in coldfusion page

I'm confused as to how to accomplish this. I have a page which, has a popup filter, which has some input elements and an "Apply" button (not a submit). When the button is clicked, two jquery .get() calls are made, which load a graph, a DataTables grid, photos, and miscellaneous info into four separate tabs. Inside the graph, if one clicks on a particular element, the user is taken to another page where the data is drilled down to a finer level. All this works well.
The problem is if the user decides to go back to the original page, but with the ajax generated graph/grid/photos etc. Originally I thought that I would store a session variable with the filter variables used to form the original query, and on returning to the page, if the session var was found, the original ajax call would be made again, re-populating the tabs.
The problem that I find with this method is that Coldfusion doesn't recognize that the session variable has been set when returning to the page using the browser's back button. If I dump out the session var at both the original and the second page, I can see the newly set var at the second page, and I can see it if I go to the original page through the navigation menu, but NOT if I use the back button.
SO.... from reading posts on here about ajax browser history plugins, it seems that there are various jquery plugins which help with this, including BBQ. The problem that I see with this approach is that it requires the use of anchor elements to trigger it, and then modifies the query string using the anchors' href attributes. I suppose that I could modify the page to include a hidden anchor.
My question, at long last is: is an ajax history plugin like BBQ the best way to accomplish this, or is there a way to make Coldfusion see the newly created session var when returning to the page via the back button? Or, should I consider re-architecting the page so that the ajax calls are replaced by a form submission back to the page instead?
Thanks in advance, as always.
EDIT: some code to help clarify things:
Here's the button that makes the original ajax calls:
<button id="applyFilter">APPLY</button>
and part of the js called on #applyFilter, wrapped in $(document).ready():
$('#applyFilter').click(function(){
// fill in the Photos tab
$.get('tracking/listPhotos.cfm',
{
id: id,
randParam: Math.random()
},
function(response){
$('#tabs-photos').html(response);
}
);
});
Finally, when the user calls the drill-down on the ajax generated graph, it uses the MaintAction form which has been populated with the needed variables:
function DrillDown() {
//get the necessary variables and populate the form inputs
document.MaintAction.action = "index.cfm?file=somepage.cfm&Config=someConfig";
document.MaintAction.submit();
}
and that takes us to the new page, from which we'd like to return to the first page but with the ajax-loaded photos.
The best bet is to use the BBQ method. For this, you don't have to actually include the anchor tags in your page; in fact, doing so would cause problems. This page: http://ajaxpatterns.org/Unique_URLs explains how the underlying process works. I'm sure a jQuery plugin would make the actual implementation much easier.
Regarding your other question, about how this could be done with session variables - I've actually done something similar to that, prior to learning about the BBQ method. This was specifically to save the state of a jqGrid component, but it could be easily changed to support any particular Ajax state. Basically, what I did was keep a session variable around for each instance of each component that stored the last parameters passed to the server via AJAX requests. Then, on the client side, the first thing I did was run a synchronous XHR request back to the server to fetch the state from that session variable. Using the callback method for that synchronous request, I then set up the components on my page using those saved parameters. This worked for me, but if I had to do it again I would definitely go with the BBQ method because it is much simpler to deal with and also allows more than one level of history.
Some example code based on your update:
$('#applyFilter').click(function(){
var id = $("#filterid").val(); // assumes the below id value is stored in some input on the page with the id "filterid"
// fill in the Photos tab
$.get('tracking/listPhotos.cfm',
{
id: id // I'm assuming this is what you need to remember when the page is returned to via a back-button...
//randParam: Math.random() - I assume this is to prevent caching? See below
},
function(response){
$('#tabs-photos').html(response);
}
);
});
/* fixes stupid caching behavior, primarily in IE */
$.ajaxSetup({ cache: false });
$.ajax({
async: false,
url: 'tracking/listPhotosSessionKeeper.cfm',
success: function (data, textStatus, XMLHttpRequest)
{
if (data.length)
{
$("#filterid").val(data);
$('#applyFilter').trigger('click');
}
}
});
This is what you need on the client-side to fetch the state of the photo list. On the server side, you'll need to add this modification to tracking/listPhotos.cfm:
<cfset session.lastUsedPhotoFilterID = URL.id>
And add this new one-line file, tracking/listPhotosSessionKeeper.cfm:
<cfif IsDefined("session.lastUsedPhotoFilterID")><cfoutput>#session.lastUsedPhotoFilterID#</cfoutput></cfif>
Together these changes will keep track of the last ID used by the user, and will load it up each time the page is rendered (whether via a back button, or simply by the user revisiting the page).

Resources