Skip to content
Snippets Groups Projects
Commit af08c397 authored by Robert Goldmann's avatar Robert Goldmann
Browse files

#419 - upload images with ajax

parent 43c92d3e
No related branches found
No related tags found
No related merge requests found
...@@ -5,6 +5,11 @@ import org.slf4j.Logger; ...@@ -5,6 +5,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.Optional;
@Service @Service
public class ImageService implements Resetable public class ImageService implements Resetable
...@@ -46,6 +51,32 @@ public class ImageService implements Resetable ...@@ -46,6 +51,32 @@ public class ImageService implements Resetable
// setAsDefaultAccount(account.getID()); // setAsDefaultAccount(account.getID());
// LOGGER.debug("Created default account"); // LOGGER.debug("Created default account");
} }
}
@Transactional
public void saveImageFile(MultipartFile file) throws IOException
{
Byte[] byteObjects = new Byte[file.getBytes().length];
int i = 0;
for(byte b : file.getBytes())
{
byteObjects[i++] = b;
}
final Optional<String> fileExtensionOptional = getFileExtension(file.getOriginalFilename());
if(fileExtensionOptional.isEmpty())
{
throw new IllegalArgumentException("Could not determine file extension from file name: " + file.getOriginalFilename());
}
final Image image = new Image(byteObjects, fileExtensionOptional.get());
imageRepository.save(image);
}
private Optional<String> getFileExtension(String filename) {
return Optional.ofNullable(filename)
.filter(f -> f.contains("."))
.map(f -> f.substring(filename.lastIndexOf(".") + 1));
} }
} }
package de.deadlocker8.budgetmaster.images; package de.deadlocker8.budgetmaster.images;
import com.google.gson.JsonObject;
import de.deadlocker8.budgetmaster.controller.BaseController; import de.deadlocker8.budgetmaster.controller.BaseController;
import de.deadlocker8.budgetmaster.utils.Mappings; import de.deadlocker8.budgetmaster.utils.Mappings;
import de.thecodelabs.utils.util.Localization;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
@Controller @Controller
@RequestMapping(Mappings.MEDIA) @RequestMapping(Mappings.MEDIA)
public class MediaController extends BaseController public class MediaController extends BaseController
...@@ -31,9 +32,27 @@ public class MediaController extends BaseController ...@@ -31,9 +32,27 @@ public class MediaController extends BaseController
} }
@PostMapping("uploadImage") @PostMapping("uploadImage")
public String handleImagePost(@RequestParam("file") MultipartFile file) @ResponseBody
public String uploadImage(@RequestParam("file") MultipartFile file)
{
boolean success = true;
String localizedMessage = Localization.getString("upload.image.success");
try
{ {
imageService.saveImageFile(file); imageService.saveImageFile(file);
return "redirect:/accounts"; }
catch(IOException e)
{
e.printStackTrace();
success = false;
localizedMessage = Localization.getString("upload.image.error", e.getMessage());
}
final JsonObject data = new JsonObject();
data.addProperty("isUploadSuccessful", success);
data.addProperty("localizedMessage", localizedMessage);
return data.toString();
} }
} }
...@@ -139,6 +139,8 @@ notification.settings.saved=Einstellungen gespeichert ...@@ -139,6 +139,8 @@ notification.settings.saved=Einstellungen gespeichert
notification.settings.update.available=BudgetMaster Update "{0}" verfügbar notification.settings.update.available=BudgetMaster Update "{0}" verfügbar
notification.settings.database.delete.success=Datenbank erfolgreich gelöscht notification.settings.database.delete.success=Datenbank erfolgreich gelöscht
notification.settings.database.import.success=Import erfolgreich: {0} Konten, {1} Buchungen, {2} Kategorien, {3} Vorlagen und {4} Diagramme notification.settings.database.import.success=Import erfolgreich: {0} Konten, {1} Buchungen, {2} Kategorien, {3} Vorlagen und {4} Diagramme
upload.image.success=Erfolgreich hochgeladen
upload.image.error=Fehler: {0}
# WARNING # WARNING
warning.text.account.delete=Das Konto "{0}" kann nicht gelöscht werden, da mindestens ein Konto existieren muss. Um dieses Konto zu löschen musst du zuerst ein neues anlegen. warning.text.account.delete=Das Konto "{0}" kann nicht gelöscht werden, da mindestens ein Konto existieren muss. Um dieses Konto zu löschen musst du zuerst ein neues anlegen.
......
...@@ -139,6 +139,8 @@ notification.settings.saved=Settings saved ...@@ -139,6 +139,8 @@ notification.settings.saved=Settings saved
notification.settings.update.available=BudgetMaster update "{0}" available notification.settings.update.available=BudgetMaster update "{0}" available
notification.settings.database.delete.success=Successfully deleted database notification.settings.database.delete.success=Successfully deleted database
notification.settings.database.import.success=Import successful: {0} accounts, {1} transactions, {2} categories, {3} templates and {4} charts notification.settings.database.import.success=Import successful: {0} accounts, {1} transactions, {2} categories, {3} templates and {4} charts
upload.image.success=Upload successful
upload.image.error=Error: {0}
# WARNING # WARNING
warning.text.account.delete=The account "{0}" could not be deleted, because at least one account must exist at all time. You have to create a new account in order to delete this one. warning.text.account.delete=The account "{0}" could not be deleted, because at least one account must exist at all time. You have to create a new account in order to delete this one.
......
...@@ -56,6 +56,11 @@ $(document).ready(function() ...@@ -56,6 +56,11 @@ $(document).ready(function()
{ {
openSelectAccountIconModal(this); openSelectAccountIconModal(this);
}); });
$('#button-upload-new-image').click(function()
{
uploadImage();
});
}); });
function openSelectAccountIconModal(item) function openSelectAccountIconModal(item)
...@@ -91,3 +96,36 @@ function selectIcon(item) ...@@ -91,3 +96,36 @@ function selectIcon(item)
item.classList.add('selected'); item.classList.add('selected');
} }
function uploadImage()
{
let formID = 'form-upload-account-image';
let form = document.getElementById(formID);
$.ajax({
url: form.action,
enctype: 'multipart/form-data',
type: 'post',
processData: false,
contentType: false,
cache: false,
data: new FormData(form),
success: function(response)
{
let parsedData = JSON.parse(response);
let isUploadSuccessful = parsedData['isUploadSuccessful']
M.toast({
html: parsedData['localizedMessage'],
classes: isUploadSuccessful ? 'green' : 'red'
});
},
error: function(response)
{
let parsedData = JSON.parse(response);
M.toast({
html: parsedData['localizedMessage'],
classes: 'red'
});
}
});
}
\ No newline at end of file
<#import "/spring.ftl" as s>
<#import "../helpers/header.ftl" as header> <#import "../helpers/header.ftl" as header>
<#macro modalAccountIconSelect> <#macro modalAccountIconSelect>
...@@ -32,7 +33,8 @@ ...@@ -32,7 +33,8 @@
</#macro> </#macro>
<#macro uploadImageForm> <#macro uploadImageForm>
<form id="form-upload-account-image" method="POST" action="/media" enctype="multipart/form-data"> <form></form>
<form id="form-upload-account-image" method="post" action="<@s.url '/media/uploadImage'/>" enctype="multipart/form-data">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
<div class="file-field input-field col s12"> <div class="file-field input-field col s12">
<div class="container"> <div class="container">
...@@ -41,10 +43,10 @@ ...@@ -41,10 +43,10 @@
${locale.getString("account.new.icon.upload.choose.file")} ${locale.getString("account.new.icon.upload.choose.file")}
<input id="inputUploadFile" type="file" accept="image/png, image/jpeg" name="file"> <input id="inputUploadFile" type="file" accept="image/png, image/jpeg" name="file">
</div> </div>
<div class="file-path-wrapper" id="abc"> <div class="file-path-wrapper">
<input id="def" class="file-path validate" type="text"> <input class="file-path validate" type="text">
</div> </div>
<@header.buttonSubmit name='action' icon='upload' localizationKey='account.new.icon.upload' classes="right"/> <@header.buttonLink url='' icon='upload' localizationKey='account.new.icon.upload' id='button-upload-new-image' classes='right' noUrl=true/>
</div> </div>
</div> </div>
</form> </form>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment