So I have a dropzone file uploader. each successfull upload returns the following
File: {
"upload": {
"uuid": "f89f409b-7e49-4503-98d8-dc060e75b874",
"progress": 0,
"total": 5017004,
"bytesSent": 0,
"filename": "20190902_115950.jpg"
},
"status": "error",
"previewElement": {},
"previewTemplate": {},
"accepted": false,
"dataURL": "data:image/jpeg;base64,/9j/4XGiRXh/WU8GGXVL5BHN5PW...",
"width": 3024,
"height": 4032
}
I have a laravel backend with a request validation for this:
rules = [
...
'featured_image' => 'image',
]
However, my laravel backend returns that the featured image field must be an image. So I'm not sure what format the backend expects.
My dropzone component looks like this:
<template>
<div
class="dropzone mb-3 dz-clickable"
:class="[multiple ? 'dropzone-multiple' : 'dropzone-single']"
>
<div class="fallback">
<div class="custom-file">
<input
type="file"
class="custom-file-input"
id="projectCoverUploads"
:multiple="multiple"
/>
<label class="custom-file-label" for="projectCoverUploads"
>Choose file</label
>
</div>
</div>
<div
class="dz-preview dz-preview-single"
v-if="!multiple"
:class="previewClasses"
ref="previewSingle"
>
<div class="dz-preview-cover">
<img class="dz-preview-img" data-dz-thumbnail />
</div>
</div>
<ul
v-else
class="dz-preview dz-preview-multiple list-group list-group-lg list-group-flush"
:class="previewClasses"
ref="previewMultiple"
>
<li class="list-group-item px-0">
<div class="row align-items-center">
<div class="col-auto">
<div class="avatar">
<img class="avatar-img rounded" data-dz-thumbnail />
</div>
</div>
<div class="col ml--3">
<h4 class="mb-1" data-dz-name>...</h4>
<p class="small text-muted mb-0" data-dz-size>...</p>
</div>
<div class="col-auto">
<button data-dz-remove="true" class="btn btn-danger btn-sm">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
</li>
</ul>
</div>
</template>
<script>
export default {
name: "dropzone-file-upload",
props: {
options: {
type: Object,
default: () => ({}),
},
value: [String, Object, Array],
url: {
type: String,
default: "http://",
},
multiple: Boolean,
previewClasses: [String, Object, Array],
},
model: {
prop: "value",
event: "change",
},
data() {
return {
currentFile: null,
files: [],
showList: false,
};
},
methods: {
async initDropzone() {
let Dropzone = await import("dropzone");
Dropzone = Dropzone.default || Dropzone;
Dropzone.autoDiscover = false;
let preview = this.multiple
? this.$refs.previewMultiple
: this.$refs.previewSingle;
let self = this;
let finalOptions = {
...this.options,
url: this.url,
thumbnailWidth: null,
thumbnailHeight: null,
previewsContainer: preview,
previewTemplate: preview.innerHTML,
maxFiles: !this.multiple ? 1 : null,
acceptedFiles: !this.multiple ? "image/*" : null,
init: function () {
this.on("addedfile", function (file) {
if (!self.multiple && self.currentFile) {
// this.removeFile(this.currentFile);
}
self.currentFile = file;
});
},
};
this.dropzone = new Dropzone(this.$el, finalOptions);
preview.innerHTML = "";
let evtList = [
"drop",
"dragstart",
"dragend",
"dragenter",
"dragover",
"addedfile",
"removedfile",
"thumbnail",
"error",
"processing",
"uploadprogress",
"sending",
"success",
"complete",
"canceled",
"maxfilesreached",
"maxfilesexceeded",
"processingmultiple",
"sendingmultiple",
"successmultiple",
"completemultiple",
"canceledmultiple",
"totaluploadprogress",
"reset",
"queuecomplete",
];
evtList.forEach((evt) => {
this.dropzone.on(evt, (data) => {
this.$emit(evt, data);
if (evt === "addedfile") {
this.files.push(data);
this.$emit("change", this.files);
} else if (evt === "removedfile") {
let index = this.files.findIndex(
(f) => f.upload.uuid === data.upload.uuid
);
if (index !== -1) {
this.files.splice(index, 1);
}
this.$emit("change", this.files);
}
});
});
},
},
async mounted() {
this.initDropzone();
},
};
</script>
<style></style>
Related
here my goal is to create a tree on button click one popup modal has to opent where i have to input the values and and has to store in database and as well show in the tree,and also in the context menu which node we select there also an popup modal to open and get node ,delete node and renaming has to happen
here its my controller view
public class HomeController : Controller
{
private readonly ApplicationDbContext _db;
public HomeController(ApplicationDbContext db)
{
_db = db;
}
public IActionResult Index()
{
return View();
}
//[HttpPost]
//public IActionResult Index(string selectedItems)
//{
// List<TreeViewModel> items=JsonConvert.DeserializeObject<List<TreeViewModel>>(selectedItems);
// return RedirectToAction("Index");
//}
public IActionResult GetTree()
{
List<TreeViewModel> nodes = new List<TreeViewModel>();
foreach (ParentClass type in _db.parent)
{
nodes.Add(new TreeViewModel
{
id = type.Id.ToString(),
parent = "#",
text = type.ParentName
});
}
foreach (ChildClass list in _db.child)
{
nodes.Add(new TreeViewModel
{
id = list.Id.ToString(),
parent = list.parentId.ToString(),
text = list.ChildName
});
}
return Json(nodes);
}
[HttpGet]
public IActionResult Create()
{
ParentClass parent = new ParentClass();
return PartialView("_HomePartial",parent);
}
[HttpPost]
public IActionResult Create(ParentClass parent)
{
if (ModelState.IsValid)
{
_db.parent.Add(parent);
_db.SaveChanges();
return PartialView("_HomePartial", parent);
}
return RedirectToAction("Index");
}
}
and my index view where i am giving button for popup modal to insert tree node in my code it taking only parent
<div class="container" id="placeHolder">
<div class="row">
<div class="col-3">
<div class="row pt-3">
<div class="col-6">
<p class="text-primary text-light">File Structure
</p>
</div>
<div class="col-6 text-end">
<button type="button" class="btn btn-primary"
data-toggle="ajax-modal" data-bs-target="#Addnode"
data-url="#Url.Action("Create")"><i class="bi
bi-plus-square-fill"></i></button>
</div>
</div>
<div id="simpleJsTree">
</div>
</div>
<div class="col=9">
</div>
</div>
</div>
javacript for tree view
$(document).ready(function () {
$.ajax({
async: true,
type: "GET",
url: "https://localhost:44376/Home/GetTree",
dataType: "json",
success: function (json) {
createJSTree(json);
}
});
});
function createJSTree(jsondata) {
$('#simpleJsTree').jstree({
"core": {
"check_callback": true,
'data': jsondata
},
"plugins": ["contextmenu"],
"contextmenu": {
"items": function ($node) {
var tree = $("#simpleJsTree").jstree(true);
return {
"Create": {
"separator_before": false,
"separator_after": true,
"label": "Create",
"action": function (obj) {
tree.create_node($node);
}
},
"Rename": {
"separator_before": false,
"separator_after": false,
"label": "Rename",
"action": function (obj) {
tree.edit($node);
}
},
"Remove": {
"separator_before": false,
"separator_after": false,
"label": "Remove",
"action": function (obj) {
tree.delete_node($node);
}
},
"Upload": {
"seperator_beore": false,
"seperator_after": false,
"label": "Upload"
}
};
}
}
}).bind('create_node.jstree', function (e, data) {
$.ajax({
url: "/Home/Create",
method: "POST",
data: data,
success: function (data) {
console.log(data);
}
});
});
}
here binding of create function to context menu is not working
this is the partial view where i m calling modal popup to take parent node
#model ParentClass
<div class="modal fade" id="Addnode">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title"id="Addnode">Add Node</h4>
<button type="button" class="close" data-bs-
dismiss="modal">
<span>X</span>
</button>
</div>
<div class="modal-body">
<form asp-controller="Home" asp-action="Create"
method="post">
#Html.HiddenFor(m=>m.Id)
<div class="form-group">
<label asp-for="ParentName"></label>
<input asp-for="ParentName"class="form-
control" />
<span asp-validation-
for="ParentName"class="text-danger"></span>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary"
data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary"
data-save="modal">Save</button>
</div>
</div>
</div>
</div>
and site.js file to show modal popup
$(function () {
var placeElement = $('#placeHolder');
$('button[data-toggle="ajax-modal"]').click(function (event) {
var url = $(this).data('url');
$.get(url).done(function (data) {
placeElement.html(data);
placeElement.find('.modal').modal('show');
});
});
placeElement.on('click', '[data-save="modal"]', function
(event) {
var form = $(this).parents('.modal').find('form');
var actionUrl = form.attr('action');
var sendData = form.serialize();
$.post(actionUrl, sendData).done(function (data) {
placeElement.find('.modal').modal('hide');
});
});
});
You are making ajax call with the codes:
var sendData = form.serialize();
$.post(actionUrl, sendData)
controller in MVC project read data from request form by default,So you need to add
[FromBody]
[HttpPost]
public IActionResult Create([FromBody]ParentClass parent)
{
_db.parent.Add(parent);
_db.SaveChanges();
return PartialView("_HomePartial", parent);
}
if you have further issue on the case,please show more details of the error
As you can see below, I have a modal that should be validated then send a request to the server. The problem is that if I try to submit for the first time, that validation is worked properly but for the second time it won't work. When I debug the codes I found out that validationCheck() worked fine but the resolve() doesn't return any result to the add() in certificate-manager file.
request.js
let insert = function (isPost = false, url, data, reloadLocation = false, table = null,
modal = null, ponds) {
let request = null;
if (isPost) {
let uploadNotify = uploadNotification();
//step 3
let config = {
onUploadProgress: function (progressEvent) {
let percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
console.log(percentCompleted);
uploadNotify.update('message', '<strong>Uploading</strong> ' + percentCompleted + ' %');
uploadNotify.update('progress', percentCompleted);
},
headers: {
'content-type': 'multipart/form-data'
}
};
//step 4
request = axios.post(url, data, config)
} else {
//step 4
request = axios.get(url, {
params: data
});
}
request.then(function (response) {
console.log(response);
let data = response['data'];
if (data['status'] === 200) {
let content = {
'title': 'Done!',
'message': data['message']
};
notification(content, 1);
if (reloadLocation)
location.reload();
if (table) {
table.ajax.reload();
clearModal('.inp', ponds);
}
}
})
.catch(function (error) {
console.log(error);
let data = error['data'];
let content = {
'title': 'Error!',
'message': data['message']
};
notification(content, 0);
})
.then(function () {
if (modal)
closeModal(modal);
});
};
utilities.js
async function validationCheck (id, rules) {
jQuery.validator.addMethod('passwordCheck', function (value, element, param) {
//Your Validation Here
let oldPass = jQuery('#input-old-password').val();
let confirmPass = jQuery('#input-confirm-password').val();
return oldPass != null && confirmPass === value;
// return bool here if valid or not.
}, 'Your error message!');
jQuery.validator.addMethod('phoneNumber', function (value, element, param) {
value = value.replace(/\s+/g, "");
return this.optional(element) || value.length > 9 &&
value.match(/\(?([0-9]{3})\)?([ .-]?)([0-9]{3})\2([0-9]{4})/);
}, 'Please specify a valid phone number');
jQuery.validator.addMethod('startDate', function (value, element, param) {
return (parseInt(value) > 2000)
}, 'Please specify a valid year');
jQuery.validator.addMethod('endDate', function (value, element, param) {
return (parseInt(value) >= parseInt(jQuery('#input-start-time').val()) ||
jQuery('#input-current').is(":checked"))
}, 'Please specify a valid year');
jQuery.validator.addMethod('uendDate', function (value, element, param) {
return (parseInt(value) >= parseInt(jQuery('#input-update-start-time').val()) ||
jQuery('#input-update-current').is(":checked"))
}, 'Please specify a valid year');
return new Promise((resolve, reject)=> {
jQuery(id).validate({
// define validation rules
rules: rules,
errorPlacement: function (error, element) {
let group = element.closest('.input-group');
if (group.length) {
group.after(error.addClass('invalid-feedback'));
} else {
element.after(error.addClass('invalid-feedback'));
}
},
// messages: {
// username: {
// required: "Username is required"
// }
// },
//display error alert on form submit
invalidHandler: function (event, validator) {
// let alert = jQuery('#kt_form_1_msg');
// alert.removeClass('kt--hide').show();
KTUtil.scrollTo(id, -200);
reject(false);
},
submitHandler: function (form) {
resolve(true);
//form[0].submit(); // submit the form
}
});
});
}
certificate-manager.js
let add = async function () {
let check = await validationCheck("#form", {
title: {
required: true
},
company: {
required: true
},
start: {
required: true,
date: true,
digits: true,
minlength: 4,
maxlength: 4,
startDate: true
},
end: {
date: true,
digits: true,
minlength: 4,
maxlength: 4,
endDate: true
},
description: {
required: true
}
}).then(value => {
console.log(value)
insert(
false,
'/api/add/certificate',
getInputsData(),
false,
table,
"#kt_modal")
}, reason => {
console.log(reason)
}).catch(reason => {
console.log(reason)
});
}
<!--begin:: insert Modal-->
<div class="modal fade" id="kt_modal" tabindex="-1" role="dialog"
aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">New Certificate</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
</button>
</div>
<div class="modal-body">
<form id="form">
<div class="row">
<div class="col-12">
<div class="form-group">
<label for="input-title"
class="form-control-label">Title</label>
<input type="text" class="inp form-control"
name="title"
id="input-title">
</div>
<div class="form-group">
<label for="input-company-institute"
class="form-control-label">Company/Institute</label>
<input type="text" class="inp form-control" name="company" id="input-company-institute">
</div>
<div class="row">
<div class="form-group col-6">
<label for="input-start-time"
class="form-control-label">From Year</label>
<input type="text" class="inp form-control" name="start" id="input-start-time">
</div>
<div class="form-group col-6">
<label for="input-end-time"
class="form-control-label">To Year</label>
<input type="text" class="inp form-control" name="end" id="input-end-time">
<div class="mt-2">
<label for="input-current" class="kt-checkbox kt-checkbox--brand col-6">
<input type="checkbox" id="input-current"> Current
<span></span>
</label>
</div>
</div>
</div>
<div class="form-group">
<label for="input-description"
class="form-control-label">Description</label>
<textarea class="inp form-control" name = "description" id="input-description"></textarea>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button id="add-btn" onclick="add()" type="submit" class="btn btn-primary" >Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
<!--end::insert Modal-->
the order of the files is:
'../../../assets/adminPanel/js/utilities.js',
'../../../assets/adminPanel/js/request.js',
'../../../assets/adminPanel/js/pages/resume/certificate-manager.js'
I have made and AngularJs app and made Form in HTML/CSS. The form takes 2 Dates. StartDate and endDate. For validations, I used the AngularJs Ng-messages. I created a custom validation function to check that endDate should not be before startDate. But the function is not invoking. Things i have checked.
Include Ng-messages file in start.
Add the function to Scope.
add the customer function name in input Tag of HTML.
Checked the spelling issue.
But nothing has worked for me. So, here I am to show it to you guys.
Layout = null;
}
<form name="newTenatForm" class="flex-fill" ng-submit="newTenatForm.$valid && onAddEditTenantSubmitForm(newTenatForm)" novalidate>
<div class="row">
<div class="col-lg-6 offset-lg-3">
<div class="card mb-0">
<div class="card-body">
<div class="text-center mb-3">
<i class="icon-stack icon-2x text-success border-success border-3 rounded-round p-3 mb-3 mt-1"></i>
<h5 class="mb-0">#ViewBag.title</h5>
<span class="d-block text-muted">Fields with * are required</span>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group form-group-feedback form-group-feedback-right">
<input type="text" class="form-control" placeholder="Name *" name="tenantName" ng-minlength="5" ng-model="state.tenantModel.name" required>
<ng-messages class="form-text text-danger-400"
ng-if="newTenatForm.$submitted || newTenatForm.tenantName.$touched"
for="newTenatForm.tenantName.$error">
<div ng-message="minlength">Tenant name is too short.</div>
<div ng-message="required">Tenant name is required</div>
</ng-messages>
<div class="form-control-feedback">
<i class="icon-user-check text-muted"></i>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group form-group-feedback form-group-feedback-right">
<input type="text" class="form-control" placeholder="Identifier *" name="tenantIdentifier" ng-minlength="5" ng-model="state.tenantModel.identifier" required>
<ng-messages class="form-text text-danger-400"
ng-if="newTenatForm.$submitted || newTenatForm.tenantIdentifier.$touched"
for="newTenatForm.tenantIdentifier.$error">
<div ng-message="minlength">Tenant Identifier is too short.</div>
<div ng-message="required">Tenant identifier is required</div>
</ng-messages>
<div class="form-control-feedback">
<i class="icon-user-check text-muted"></i>
</div>
</div>
</div>
</div>
<div class="form-group form-group-feedback form-group-feedback-right">
<input type="text" class="form-control" placeholder="Connection String" ng-model="state.tenantModel.connectionString">
<div class="form-control-feedback">
<i class="icon-user-plus text-muted"></i>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group form-group-feedback form-group-feedback-right">
<input type="date" class="form-control" placeholder="Start Date" id="anytime-date" name="tenantStartDate" ng-model="state.tenantModel.startFrom" required>
<ng-messages class="form-text text-danger-400"
ng-if="newTenatForm.$submitted || newTenatForm.tenantStartDate.$touched"
for="newTenatForm.tenantStartDate.$error">
<div ng-message="required">Tenant start date is required</div>
</ng-messages>
<div class="form-control-feedback">
<i class="icon-user-lock text-muted"></i>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group form-group-feedback form-group-feedback-right">
<input type="date" class="form-control" placeholder="End Date" id="tenantEndDate" name="tenantEndDate" ng-model="state.tenantModel.endOn" required compareWithStartDate>
<ng-messages class="form-text text-danger-400"
ng-if="newTenatForm.$submitted || newTenatForm.tenantEndDate.$touched"
for="newTenatForm.tenantEndDate.$error">
<div ng-message="required">Tenant end date is required</div>
<div ng-message="checkEndDate">End date cannot be before start date.</div>
</ng-messages>
<div class="form-control-feedback">
<i class="icon-user-lock text-muted"></i>
</div>
</div>
</div>
</div>
<div class="form-group form-group-feedback form-group-feedback-right">
<div class="form-group row">
<label class="col-form-label col-lg-2">Tenant Type *</label>
<div class="col-lg-10">
<select class="form-control" id="tenantType" name="tenantType" ng-model="state.tenantModel.tenantType" required>
<option value="1">Trial</option>
<option value="2">Standard</option>
</select>
<ng-messages class="form-text text-danger-400"
ng-if="newTenatForm.$submitted || newTenatForm.tenantType.$touched"
for="newTenatForm.tenantType.$error">
<div ng-message="required">Pleas select tenant type.</div>
</ng-messages>
</div>
</div>
</div>
<button type="submit" value="Submit" class="btn bg-teal-400 btn-labeled btn-labeled-right"><b><i class="icon-plus3"></i></b> #if (ViewBag.title == "Update Tenant")
{<span>Update Acccount</span> }
else
{ <span>Create account </span>} </button>
</div>
</div>
</div>
</div>
</form>```
and this is Js code.
```(function () {
var app = angular.module('app');
app.controller('MultiTenantController', ['$scope', '$window', '$filter', 'TenantServices', function ($scope, $window, $filter, TenantServices) {
var objectA = {}
var state = {
tenantModel: {
addedOn: '',
connectionString: '',
createdBy: '',
endOn: '',
id: '',
identifier: '',
isDisabled: '',
items: [{
isDisabled: '',
tenantType: '',
endOn: '',
startFrom: '',
}],
name: '',
startFrom: '',
tenantType: '',
userId: '',
},
};
var init = function (id) {
if (id) { tenantEdit(id); };
$(document).ready(function () {
tenantTable = $('#table_Tenants').DataTable({
ajax: {
url: 'API/MultiTenant/Pagged',
method: 'POST'
},
columns: [
{ data: 'name' },
{ data: 'identifier' },
{ data: 'connectionString' },
{
data: 'startFrom',
render: function (startFrom) {
return $filter('date')(startFrom, 'medium');
}
},
{
data: 'addedOn',
render: function (addedOn) {
return $filter('date')(addedOn, 'medium');
}
},
{
data: 'endOn',
render: function (endOn) {
return $filter('date')(endOn, 'medium');
}
},
{
data: 'isDisabled',
render: function (isDisabled) {
return !isDisabled ?'<span class="badge badge-success">Active</span>':'<span class="badge badge-danger">Inactive</span>';
}
},
{
data: function (data) {
return data;
},
orderable: false,
render: function (data) {
return `<div class="list-icons">
<div class="dropdown">
<a href="#" class="list-icons-item" data-toggle="dropdown">
<i class="icon-menu9"></i>
</a>
<div class="dropdown-menu dropdown-menu-right">
<i class="icon-database-upload"></i>Create Database
<i class="icon-database-edit2"></i>Edit
<i class="icon-database-remove"></i>Delete
</div>
</div>
</div>`;
}
},
]
});
tenantTable.on('click', '.createTenantDatabase', function () {
const $row = $(this).closest('tr');
const rowData = tenantTable.row($row).data();
addTenantDatabase(rowData);
});
tenantTable.on('click', '.deleteTenant', function () {
const $row = $(this).closest('tr');
const rowData = tenantTable.row($row).data();
deleteTenant(rowData);
});
})
};
const onAddEditTenantSubmitForm = function (newTenatForm) {
if (!state.tenantModel.userId) {
addTenant(newTenatForm);
}
else {
updateTenant(newTenatForm);
}
};
var addTenant = function (newTenatForm) {
state.isLoading = true;
TenantServices.addTenant(state.tenantModel).then(
function () {
swalInit.fire({
title: 'Success',
text: 'Tenant has been created',
type: 'success'
});
},
function (errorResponse) {
if (errorResponse.status === 400) {
swalInit.fire({
title: 'Server Error',
text: 'An server error occurred while adding tenant.',
type: 'error 400'
});
}
else if (errorResponse.status === 500) {
swalInit.fire({
title: 'Server Error',
text: 'An server error occurred while adding tenant.',
type: 'error 500'
});
}
}
)
.finally(() => state.isLoading = false);
};
var addTenantDatabase = function (rowObj) {
state.isLoading = true;
TenantServices.createTenantDatabase(rowObj.i).then(
function () {
swalInit.fire({
title: 'Success',
text: 'Tenant Database has been created',
type: 'success'
});
table_Tenants.ajax.reload();
},
function (errorResponse) {
if (errorResponse.status === 400) {
swalInit.fire({
title: 'Server Error',
text: 'An server error occurred while creating database tenant.',
type: 'error 400'
});
}
else if (errorResponse.status === 500) {
swalInit.fire({
title: 'Server Error',
text: 'An server error occurred while creating database tenant.',
type: 'error 500'
});
}
}
)
.finally(() => state.isLoading = false);
};
var updateTenant = function (rowObj) {
state.isLoading = true;
TenantServices.updateTenant(state.tenantModel).then(
function () {
swalInit.fire({
title: 'Success',
text: 'Tenant Updated!',
type: 'success'
});
tenantTable.ajax.reload();
},
function (errorResponse) {
if (errorResponse.status === 500) {
swalInit.fire({
title: 'Server Error',
text: 'An server error occurred while Updating Tenant.',
type: 'error'
});
}
else if (errorResponse.status === 404) {
swalInit.fire({
title: 'Server Error',
text: 'Tenant not found on Server.',
type: 'error'
});
}
}
)
.finally(() => state.isLoading = false);
};
var deleteTenant = function (rowObj) {
state.isLoading = true;
TenantServices.deleteTenant(rowObj.id).then(
function () {
swalInit.fire({
title: 'Success',
text: 'Tenant Deleted!',
type: 'success'
});
tenantTable.ajax.reload();
},
function (errorResponse) {
if (errorResponse.status === 500) {
swalInit.fire({
title: 'Server Error',
text: 'An server error occurred while Deleting Tenant.',
type: 'error'
});
}
else if (errorResponse.status === 404) {
swalInit.fire({
title: 'Server Error',
text: 'Tenant not found on Server.',
type: 'error'
});
}
}
)
.finally(() => state.isLoading = false);
};
var tenantEdit = function (id) {
TenantServices.getTenantById(id).then(function (data) {
var startDate = new Date(data.found.startFrom + "Z");
var endDate = new Date(data.found.endOn + "Z");
state.tenantModel = data.found;
state.tenantModel.startFrom = startDate;
state.tenantModel.endOn = endDate;
if(state.tenantModel.tenantType == 1)
{
$(function () {
$('#tenantType').val('1');
});
} else if (state.tenantModel.tenantType == 2)
{
$(function () {
$('#tenantType').val('2');
});
}
});
};
var compareWithStartDate = function () {
if (state.tenantModel.startFrom == state.tenantModel.endOn) {
newTenatForm.tenantEndDate.$setValidity('checkEndDate', true);
}
else {
newTenatForm.tenantEndDate.$setValidity('checkEndDate', false);
}
};
$scope.onAddEditTenantSubmitForm = onAddEditTenantSubmitForm;
$scope.tenantEdit = tenantEdit;
$scope.compareWithStartDate = compareWithStartDate;
$scope.state = state;
$scope.init = init;
}]);
})();```
My mistake here was not making the directive for the custom validation.
I need to get the URL of a picture to show my img :src tag. I tryied:
<img class="card-img-top" :src="noticia.Fotos.Link" alt="Card image cap">
This is my HTML:
<div class="col-lg-4" v-for="noticia in noticias">
<div class="row">
<div class="card mt-3 col-lg-10 offset-lg-1">
<img class="card-img-top" :src="noticia.Fotos.Link" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">{{noticia.Titulo}}</h5>
<p class="card-text text-center">
{{noticia.Descricao}}
</p>
</div>
</div>
</div>
</div>
This is my script:
<script>
new Vue({
el: '#noticia',
data: {
UnidadeId: "",
Identificador: "",
Tipo: "",
},
data() {
return {
noticias: [],
}
},
mounted() {
var self = this
axios.get('URL', {
params: this.axiosParams
})
.then(response => {
console.log(response);
self.noticias = response.data
})
.catch(error => {
console.log(error);
})
},
computed: {
axiosParams() {
const params = new URLSearchParams();
params.append('UnidadeId', '31');
params.append('Identificador', '0');
params.append('Tipo', '1');
return params;
}
},
})
</script>
The response:
[
{
"ItemId": 902,
"Titulo": "Noticia",
"Descricao": "Noticia",
"Data": "/Date(1590593442191)/",
"QtdeCurtidas": 0,
"QtdeComentarios": 0,
"Curtido": false,
"Observacao": null,
"Fotos": [
{
"FotoId": 1508,
"Link": "http://agro.aloapp.com.br/Imagens/cVV4S0dINGRESm9IN3IxM2swYXVjZz09/Item/bg_carousel_2.jpg"
}
],
"Videos": [],
"IsVideo": false
}
]
You're trying to retrieve an element from an array (not an ArrayList) which means you need to specify which element in the array you want. In Javascript, this works by specifying the index of the element in brackets after the array name. If you want the first element, you can do noticia.Fotos[0].Link.
My html code is
I also need to add sez which is in array format and also i need to add multiple images, need to provide add image and when clicking on it, need to add images as needed by the client
<form method="POST" enctype="multipart/form-data" v-on:submit.prevent="handleSubmit($event);">
<div class="row">
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Name</label>
<input type="text" class="form-control" v-model="name">
</div>
</div>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Alias</label>
<input type="text" class="form-control" v-model="alias">
</div>
</div>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Sex</label>
<select class="form-control" v-model="sex" id="level">
<option value="Male">Male</option>
<option value="female">Female</option>
</select>
</div>
</div>
</div>
<div class="row" v-for="(book, index) in sez" :key="index">
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Date </label>
<input type="date" class="form-control" v-model="book.date">
</div>
</div>
<div class="col-md-8">
<div class="form-group label-floating">
<label class="control-label"> Details</label>
<input type="text" class="form-control" book.details>
</div>
</div>
</div>
<a #click="addNewRow">Add</a>
<div class="card-content">
<div class="row">
<div class="col-md-4">
<div class="button success expand radius">
<span id="save_image_titlebar_logo_live">Signature</span>
<label class="custom-file-upload"><input type="file" name="photo" accept="image/*" />
</label>
</div>
</div>
<div class="col-md-4">
<div class="button success expand radius">
<span id="save_image_titlebar_logo_live">Recent Photograph</span>
<label class="custom-file-upload">
<input type="file" name="sign"/>
</label>
</div>
</div>
</div>
</div>
</form>
My vue js code is
addForm = new Vue({
el: "#addForm",
data: {
name: '',
alias: '',
sex: '',
sez: [{
date: null,
details: null,
}, ],
photo: '',
sign: '',
},
methods: {
addNewRow: function() {
this.seziure.push({
date: null,
details: null,
});
},
handleSubmit: function(e) {
var vm = this;
data = {};
data['sez'] = this.sez;
data['name'] = this.name;
data['alias'] = this.alias;
data['sex'] = this.sex;
//how to add images
$.ajax({
url: 'http://localhost:4000/save/',
data: data,
type: 'POST',
dataType: 'json',
success: function(e) {
if (e.status) {
vm.response = e;
alert("success")
} else {
vm.response = e;
console.log(vm.response);
alert("Registration Failed")
}
}
});
return false;
},
},
});
This is my code. I have no idea about how to add images in this case.
Can anyone please help me pass this data.
How to pass this data along with images to the backend?
I don't want to use base64 encoding. I need to just pass this image in this ajax post request along with other data
Using axios:
Template
...
<input type="file" name="photo" accept="image/*" #change="setPhotoFiles($event.target.name, $event.target.files) />
...
Code
data () {
return {
...
photoFiles: [],
...
}
},
...
methods: {
...
setPhotoFiles (fieldName, fileList) {
this.photoFiles = fileList;
},
...
handleSubmit (e) {
const formData = new FormData();
formData.append('name', this.name);
formData.append('alias', this.alias);
formData.append('sex', this.sex);
...
this.photoFiles.forEach((element, index, array) => {
formData.append('photo-' + index, element);
});
axios.post("http://localhost:4000/save/", formData)
.then(function (result) {
console.log(result);
...
}, function (error) {
console.log(error);
...
});
}
}
I'm not sure where would you like the extra images to appear, but I added them after this column:
<div class="col-md-4">
<div class="button success expand radius">
<span id="save_image_titlebar_logo_live">Recent Photograph</span>
<label class="custom-file-upload">
<input type="file" name="sign"/>
</label>
</div>
</div>
And here's the column I added — "add images": (You can try this feature here, with the updates)
<div class="col-md-4">
<ul class="list-group" :if="images.length">
<li class="list-group-item" v-for="(f, index) in images" :key="index">
<button class="close" #click.prevent="removeImage(index, $event)">×</button>
<div class="button success expand radius">
<label class="custom-file-upload">
<input type="file" class="images[]" accept="image/*" #change="previewImage(index, $event)">
</label>
</div>
<div :class="'images[' + index + ']-preview image-preview'"></div>
</li>
</ul>
<button class="btn btn-link add-image" #click.prevent="addNewImage">Add Image</button>
</div>
And the full Vue JS code (with jQuery.ajax()):
addForm = new Vue({
el: "#addForm",
data: {
name: '',
alias: '',
sex: '',
sez: [{
date: null,
details: null
}],
// I removed `photo` and `sign` because (I think) the're not necessary.
// Add I added `images` so that we could easily add new images via Vue.
images: [],
maxImages: 5,
// Selector for the "Add Image" button. Try using (or you should use) ID
// instead; e.g. `button#add-image`. But it has to be a `button` element.
addImage: 'button.add-image'
},
methods: {
addNewRow: function() {
// I changed to `this.sez.push` because `this.seziure` is `undefined`.
this.sez.push({
date: null,
details: null
});
},
addNewImage: function(e) {
var n = this.maxImages || -1;
if (n && this.images.length < n) {
this.images.push('');
}
this.checkImages();
},
removeImage: function(index) {
this.images.splice(index, 1);
this.checkImages();
},
checkImages: function() {
var n = this.maxImages || -1;
if (n && this.images.length >= n) {
$(this.addImage, this.el).prop('disabled', true); // Disables the button.
} else {
$(this.addImage, this.el).prop('disabled', false); // Enables the button.
}
},
previewImage: function(index, e) {
var r = new FileReader(),
f = e.target.files[0];
r.addEventListener('load', function() {
$('[class~="images[' + index + ']-preview"]', this.el).html(
'<img src="' + r.result + '" class="thumbnail img-responsive">'
);
}, false);
if (f) {
r.readAsDataURL(f);
}
},
handleSubmit: function(e) {
var vm = this;
var data = new FormData(e.target);
data.append('sez', this.sez);
data.append('name', this.name);
data.append('alias', this.alias);
data.append('sex', this.sex);
// The `data` already contain the Signature and Recent Photograph images.
// Here we add the extra images as an array.
$('[class~="images[]"]', this.el).each(function(i) {
if (i > vm.maxImages - 1) {
return; // Max images reached.
}
data.append('images[' + i + ']', this.files[0]);
});
$.ajax({
url: 'http://localhost:4000/save/',
data: data,
type: 'POST',
dataType: 'json',
success: function(e) {
if (e.status) {
vm.response = e;
alert("success");
} else {
vm.response = e;
console.log(vm.response);
alert("Registration Failed");
}
},
cache: false,
contentType: false,
processData: false
});
return false;
},
},
});
Additional Notes
I know you're using Node.js in the back-end; however, I should mention that in PHP, the $_FILES variable would contain all the images (so long as the fields name are properly set); and I suppose Node.js has a similar variable or way of getting the files.
And in the following input, you may have forgotten to wrap book.details in v-model:
<input type="text" class="form-control" book.details>
<input type="text" class="form-control" v-model="book.details"> <!-- Correct -->
UPDATE
Added feature to limit number of images allowed to be selected/uploaded, and added preview for selected image. Plus the "send images as array" fix.
If you're using HTML5, try with a FormData object ; it will encode your file input content :
var myForm = document.getElementById('addForm');
formData = new FormData(myForm);
data: formData
Use below templete to show/upload the image:
<div v-if="!image">
<h2>Select an image</h2>
<input type="file" #change="onImageUpload">
</div>
<div v-else>
<img :src="image" />
<button #click="removeImage">Remove image</button>
</div>
Js code:
data: {
image: '',
imageBuff: ''
},
methods: {
onImageUpload(e) {
var files = e.target.files || e.dataTransfer.files;
if (!files.length)
return;
this.createImage(files[0]);
},
createImage(file) {
var image = new Image();
var reader = new FileReader();
this.imageBuff = file;
reader.onload = (e) => {
this.image = e.target.result;
};
reader.readAsDataURL(file);
},
removeImage: function(e) {
this.image = '';
},
handleSubmit(e) {
const formData = new FormData();
formData.append('name', this.name);
formData.append('alias', this.alias);
formData.append('sex', this.sex);
formData.append('image', this.imageBuff);
...
// Ajax or Axios can be used
$.ajax({
url: 'http://localhost:4000/save/',
data: formData,
processData: false, // prevent jQuery from automatically transforming the data into a query string.
contentType: false,
type: 'POST',
success: function(data) {
console.log(data);
...
}
});
}
}