Dropzone specifying a droppable area in form - dropzone.js

I was wondering if there is a way to specify an area within a form that has been initialzed as a dropzone element.
I have this markup
<form class="vertical-flow vertical-flow--mini" id="new-support-ticket-form" method="post" enctype="multipart/form-data">
//Have removed all other mark up for brevity
<div class="catalogue__upload">
<div class="file-upload placeholder">
<label class="is-hidden--text">#BackendText.Global_UploadFiles</label>
<div class="file-upload__inner" aria-hidden="true" role="presentation">
<div class="file-upload__icon" aria-hidden="true" role="presentation">
<svgicon iconid="page-upload"></svgicon>
</div>
<div class="file-upload__content">
<h3 class="heading heading--quaternary file-upload__heading">#BackendText.Global_DragAndDropFile</h3>
<p class="file-upload__sub-heading">
#BackendText.Global_Or_Lowercase <label id="file-upload-browse" class="file-upload__label">#BackendText.Global_Browse_Lowercase</label>
</p>
</div>
</div>
</div>
</div>
<br/>
<div class="button-group button-group--right">
<button class="button button--color-orange button--medium" type="submit">Create ticket</button>
</div>
</form>
I create the dropzone programmically via.
var dz = $("#new-support-ticket-form").dropzone({
// The configuration we've talked about above
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 100,
maxFiles: 100,
previewTemplate: '<div style="display:none"></div>',
url: "#Url.Action("NewTicket")",
clickable: "#file-upload-browse",
// The setting up of the dropzone
init: function() {
var myDropzone = this;
}
});
I know the clickable option allows to have multiple elements or single one to bring up the file browser. However im wondering if there is a way to specify an element that is the "droppable" for files instead of the whole form. The element I would like is the div with the class catalogue__upload
The reason I have the whole form as the dropzone is that I want to upload additional data along with the file(s). The mark up for this is removed for the question, but its basically a bunch of selects and textboxes.

Instead of using whole form as the dropzone, it would be better to make just the element as dropzone and add additional data to the request using a sending event handler.

Related

Alpinejs property bound to x-show not defined

I'm building a form in Laravel's Blade syntax, and using AlpineJs for some interactivity stuff like showing and hiding content.
My code is here:
<div class="flex items-center" x-data="destinationBuilder">
<x-label required="true" class="mr-5">Destination:</x-label>
<x-basic-input #change="handleDestinationChange" ::value="destination" placeholder="https://google.com"/>
<x-buttons.primary class="ml-5" #check="validateDestination">Check</x-buttons.primary>
</div>
<div class="mt-4">
<button type="button"
class="p-5 w-full text-sm grid grid-cols-[min-content_min-content_auto_min-content] items-center gap-x-3 font-light text-gray-400 hover:bg-gray-300 rounded-full"
#click.camel="toggleAdvancedOptions">
<i class="lni lni-cog"></i>
<span class="whitespace-nowrap">Advanced options</span>
<div class="h-px w-full bg-gray-400"></div>
<i class="lni lni-chevron-down"></i>
</button>
<div x-show="advanced" x-transition x-cloak>
{{-- <x-links.get-parameter-form/>--}}
</div>
</div>
#push('footer-scripts')
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('destinationBuilder', () => ({
destination: '',
advanced: false,
handleDestinationChange() {
if (this.validateDestination()) {
// emit constructed destination up
}
},
validateDestination() {
// check url is in a legit form (with https)
// basic is just url input
// advanced dropdown with get parameters, fragment, http protocol and port
},
toggleAdvancedOptions() {
this.advanced = !this.advanced;
}
}));
})
</script>
#endpush
I'm using a property named advanced to bind to x-show for another component.
When I look in my browser I get the following message: app.js:434 Uncaught ReferenceError: advanced is not defined
I'm not sure if this is due to a weird collision with blade or if I'm missing something fundamental with Alpinejs. I tried renaming the variable to showAdvanced but that didn't work either. I would expect advanced to be recognised as a property and bind to x-show as expected. What am I doing wrong here?
You have the following HTML structure:
<div x-data="destinationBuilder">
...
</div>
<div>
<div x-show="advanced">
...
</div>
</div>
As you see, the second div is not a child element of the first one where the x-data is defined, so it's outside of the scope of destinationBuilder component. Just create a common div (or similar) element that embeds both divs and apply the component x-data there, so each div will have access to the component's scope.

Autosave content of TinyMce editor on change event (with laravel 7)?

I want to autosave the content of tinyMce editor
I'm using tinmce version 5.2.2 with laravel V7
tinymce configuration in app.js
require('./bootstrap');
require('tinymce/themes/silver');
require('tinymce/plugins/image');
require('tinymce/plugins/code');
require('tinymce/plugins/save');
import tinymce from 'tinymce';
tinymce.init({
selector:'textarea#inputQuestionTitle',
height:400,
setup: function(editor) {
editor.on('Change Keyup', function () {
editor.save();
//tinyMCE.triggerSave() <-- also tried
});
}
With following View
#extends('dashboard.layout')
#section('content')
<form id='addQ' action="{{route('questions.store')}}" method="post" enctype="multipart/form-data" >
#csrf
<div class="form-row align-items-center " >
<div class="col-md-12">
<label class="sr-only" for="inputQuestionTitle">Title</label>
<textarea name="title" class="form-control mb-2 " id="inputQuestionTitle" placeholder="Question Title"> </textarea>
</div>
</div>
<div class="form-row">
<button type="submit" class="btn btn-primary mb-2">Add new category </button>
</div>
</form>
<script type="text/javascript" src="{{asset('js/app.js')}}"></script>
<script type="text/javascript">
$(function(){
$('#addQ').submit(function(e){
e.preventDefault();
var frmdata = $(this).serialize();
console.log(frmdata);
});
});
</script>
#endsection
Outputs
I had using jquery to show input request with console.log
As showed in output title field does not returns any value
Please tell me how i autosave the content of tinymce editor and send it with input request ..
I had also tried to tinymce.triggerSave() before serialize() method of ajax so that input request will take tinymce content but not works
Instead of trying to update the textarea via the triggerSave() or save() methods while someone is editing the content I would just place tinymce.triggerSave() at the very beginning of the function that submits the page. This will ensure that the triggerSave() is called directly before you grab the content from the textarea.

Dropzone opens file chooser twice

I have set up dropzone with a clickable element. Clicking the button causes dropzone to open the file chooser twice, instead of just once, the second coming immediately after the first file has been chosen.
The init code is:
Dropzone.autoDiscover = false;
$(document).ready(function(){
// Remove the template from the document.
var previewNode = document.querySelector("#template");
previewNode.id = "";
var previewTemplate = previewNode.parentNode.innerHTML;
previewNode.parentNode.removeChild(previewNode);
$("div#photo").dropzone({
url: "/blackhole/",
thumbnailWidth: 240,
thumbnailHeight: 240,
parallelUploads: 1,
maxFiles:1,
maxFilesize: 5,
uploadMultiple: false,
previewTemplate: previewTemplate,
autoProcessQueue: true,
previewsContainer: "#photoPreview",
clickable: ".fileinput-button",
init: function() {
this.on("maxfilesexceeded", function(file) {
this.removeAllFiles();
this.addFile(file);
});
}
});
And the page elements are:
<div class="table table-striped" class="files">
<div id="photo">
<div id="actions" class="row">
<div class="col-lg-7">
<button type="button" class="btn btn-success fileinput-button">
<i class="glyphicon glyphicon-plus"></i>
<span>Choose file...</span>
</button>
</div>
</div>
</div>
<div class="files dropzone-previews" id="photoPreview">
<div id="template" class="file-row">
<div>
<span class="preview"><img data-dz-thumbnail /></span>
</div>
<div>
<p class="name" data-dz-name></p>
<strong class="error text-danger" data-dz-errormessage></strong>
</div>
<div>
<p class="size" data-dz-size></p>
<div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
<div class="progress-bar progress-bar-success" style="width:0%;" data-dz-uploadprogress></div>
</div>
</div>
<div>
<button data-dz-remove type="button" class="btn btn-warning cancel">
<i class="glyphicon glyphicon-ban-circle"></i>
<span>Cancel</span>
</button>
</div>
</div>
</div>
</div>
</div>
Strangely, even though I have added code to replace the any existing file with a later one (so only one file can be uploaded), the second file chooser dialog lets me add a second file.
Its like dropzone has been initialized twice, but I checked that it is only initialized once, and also added the autoDiscover = false option for good measure.
Can anyone spot my mistake?
The problem seems to be in how we initialized dropzone:
$("div#photo").dropzone({
...
}
Doing it the non-jquery way solved the problem:
var myDropZone = new Dropzone("#photo",{
...
}
This was on dropzone 3.11.1.
An issue has been created on github/dropzone:
https://github.com/enyo/dropzone/issues/771
This happens for me when more than one dropzone exists on the page with the same class for a browse trigger, it seems that dropzone attaches the event to any element on the page and not just within its own container
In the issue opened for this, maliayas said:
This bug happens when your clickable element is already an
input[type=file]. Dropzone injects another one and now you have two.
Either dropzone should handle this case or documentation should
mention not to use an input[type=file] for the clickable element.
Changing my dropzone element to something other than an input[type=file] fixed the issue for me.
Attach dropzone to the parent, not the input.
In Chrome if you inspect and look at the eventListeners. You will see that once you attach dropzone to your input, you have an additional click eventListener.
Say you have a list of uploads for documents with a child input element.
<li class="upload drag-and-drop">
<input type="file"/>
</li>
Code:
$('input').dropzone();
Will attach an event listener to an already clickable element. So you have 2 event listeners. One from the browser. One from dropzone. Hence 2 dialogs...
If you attach it to the parent:
$('li.upload').dropzone();
You'll now had the listener at the parent. This allows the bubble up behavior to hit the correct element when you drag and drop and not inadvertently effect the input.

ajax script onclick alert to popup message box

I found this voting script online and was wondering instead of a onclick alert(You already voted) can i change it to a popup message that i can style with css... i have only submitted a part of the code if you need to see more let me know. thanks in advance
function addVotData(elm_id, vote, nvotes, renot) {
// exists elm_id stored in ivotings
if(ivotings[elm_id]) {
// sets to add "onclick" for vote up (plus), if renot is 0
var clik_up = (renot == 0) ? ' onclick="addVote(this, 1)"' : ' onclick="<a type="button" class="btn" style="width:100%;" href="#test_modal" data-toggle="modal">alert</a>"';
// if vot_plus, add code with <img> 'votplus', else, if vot_updown1/2, add code with <img> 'votup', 'votdown'
if(ivotings[elm_id].className == 'vot_plus') { // simple vote
ivotings[elm_id].innerHTML = '<h6>'+ vote+ '</h6><span><img src="'+votingfiles+'arrow.png" alt="1" title="vote"'+ clik_up+ '/></span>';
};
}
}
You can use Bootstrap modal pop up instead of alert.
This is well explained example
If you need more help let me know
Update
html for model pop up:
<div class="modal fade" id="test_modal"> <div class="modal-header">
<a class="close" data-dismiss="modal">×</a> <h3>Modal Header</h3> </div>
<div class="modal-body"> <p>Test Alert</p> </div> <div class="modal-footer">
Close </div> </div>
Html for Button
<input type="Button" Text="ShowModal" Id="MyButton"/>
javaScript:
$( "#MyButton" ).click(function() {
$('#modalName').modal('show');
});

What is the proper way to edit items in a listview when using Kendo UI Mobile & MVVM?

What is the proper way to edit items in a listview when using Kendo UI Mobile & MVVM?
I don't get the expected results when using the following:
HTML
<div id="itemsView"
data-role="view"
data-model="vm">
<ul data-role="listview" data-bind="source: items"
data-template="itemsTemplate">
</ul>
<script id="itemsTemplate" type="text/x-kendo-template">
<li>
#=Name#
</li>
</script>
<input type="text" data-bind="value: newValue" />
<button data-role="button" data-bind="click: update">update</button>
</div>​
JavaScript
var vm = kendo.observable({
items: [{
Name: "Item1"}],
newValue: '',
update: function(e) {
var item = this.get("items")[0];
item.set("Name", this.get("newValue"));
//adding the follwoing line makes it work as expected
kendo.bind($('#itemsView'), vm);
}
});
kendoApp = new kendo.mobile.Application(document.body, {
transition: "slide"});​
I expect the listview to reflect the change to the Name property of that item. Instead, a new item is added to the listview. Examining the array reveals that there is no additional item, and that the change was made. (re)Binding the view to the view-model updates the list to reflect the change. Re-Binding after a change like this doesn't seem to make any sense.
Here is the jsfiddle:
http://jsfiddle.net/5aCYp/2/
Not sure if I understand your question properly: but this is how I did something similar with Kendo Web UI, I expect mobile is not so different from Web UI from API perspective.
$element.kendoListView({
dataSource: list,
template: idt,
editTemplate: iet,
autoBind: true
});
The way I bind the listview is different, but I guess you can get similar results with your method as well.
I pass two templates to the list view, one for displaying and one for editing.
Display template contains a button (or any element) with css class k-edit to which kendo will automatically bind the listview edit action.
display template:
<div class="item">
# if (city) { #
#: city #<br />
# } #
# if (postCode) { #
#: postCode #<br />
# } #
<div class="btn">
<span class="k-icon k-edit"></span>Edit
<span class="k-icon k-delete"></span>Delete
</div>
</div>
Edit template
<div class="item editable">
<div>City</div>
<div>
<input type="text" data-bind="value: city" name="city" required="required" validationmessage="*" />
<span data-for="city" class="k-invalid-msg"></span>
</div>
<div>Post Code</div>
<div>
<input type="text" data-bind="value: postCode" name="postCode" required="required" validationmessage="*" />
<span data-for="postCode" class="k-invalid-msg"></span>
</div>
<div class="btn">
<span class="k-icon k-update"></span>Save
<span class="k-icon k-cancel"></span>Cancel
</div>
</div>
Clicking that element will put the current element on edit mode using the editTemplate.
Then on the editTemplate there is another button with k-update class, again to which kendo will automatically bind and call the save method on the data source.
Hopefully this will give you more ideas on how to solve your issue.
The problem was caused by the <li> in the template. The widget already supplies the <li> so the additional <li> messes up the rendering. This question was answered by Petyo in the kendo ui forums

Resources