I have implemented kendo editor within it i have implemented kendo image browser.
I have implemented it the way it is guided in documentation with same backend controller.
I have implemented kendo confirmation box for other functionality too. I want kendo alert instead of javascript alert for confirmation when one delete image. so I have capture the delete event and using event.stopPropagation I manage stop the default delete behaviour and implemented kendo confirm box. on its ok button i have called backend destroy method of controller to delete image using ajax.
Fortunately it is successfully deleted from backend but from view side that is in image browser thumbnail it is not deleting, after refreshing the it goes from view side or remove from thumbnail . I have also try to manually delete the respective li it got deleted but as soon as I upload some new image that deleted li also comes up with deleted image although it has been deleted from backend.
Here is the code how I implemented image browser:
function createEditor(id)
{
//Kendo Editor for content
$(id).kendoEditor({
encoded: false,
tools: [
"bold",
"italic",
"underline",
"strikethrough",
],
imageBrowser: {
transport: {
read: "/ImageBrowser/Read",
destroy: {
url: '/ImageBrowser/Destroy',
type: "POST"
},
create: {
url: '/ImageBrowser/Create',
type: "POST"
},
thumbnailUrl: '/ImageBrowser/Thumbnail',
uploadUrl: '/ImageBrowser/Upload',
imageUrl: "../Content/article/" + userId + "/{0}"
},
}
});
//On click of imagebrowser icon of editor
$(".k-i-image").click(function () {
setTimeout(function () {
// Attach a select handler to the Upload embedded in the ImageBrowser.
$(".k-imagebrowser .k-upload").find("input").data("kendoUpload").bind("select",
function (e) {
// Prevent the event if the selected file is not of specified extension.
if (e.files[0].extension.toLowerCase() != ".jpg" && e.files[0].extension.toLowerCase() != ".jpeg" && e.files[0].extension.toLowerCase() != ".png" && e.files[0].extension.toLowerCase() != ".gif") {
e.preventDefault();
$("<div></div>").kendoAlert({
title: false,
content: "The file extension is not *.png,*.gif,*.jpg,*.jpeg.",
buttonLayout: "normal"
}).data("kendoAlert").open();
}
var s = e.files[0].size / Math.pow(1000, 2);
//Size validation
if (s > 5) {
e.preventDefault();
$("<div></div>").kendoAlert({
title: false,
content: "File size should not be more than 5 MB",
buttonLayout: "normal"
}).data("kendoAlert").open();
}
$('.k-reset.k-floats.k-tiles.k-widget.k-listview.k-selectable').children('li').each(function (index, value) {
// Prevent the event if the selected file is already exist.
if ($(this).children("strong").html() == e.files[0].name) {
e.preventDefault();
$("<div></div>").kendoAlert({
title: false,
content: "A file with name already exists in the current directory",
buttonLayout: "normal"
}).data("kendoAlert").open();
}
});
});
//Delete image from image browser
$(".k-toolbar-wrap>.k-button-icon").click(function (event) {
var type;
var name;
if ($(this).children().hasClass("k-i-close")) {
//alert();
//event.preventDefault();
event.stopPropagation();
var path = "";
var img;
$('.k-breadcrumbs-wrap').children('a').each(function (index, value) {
if ($(this).hasClass("k-link")) {
path = path + $(this).text() + "/";
}
});
$('.k-reset.k-floats.k-tiles.k-widget.k-listview.k-selectable').children('li').each(function (index, value) {
if ($(this).hasClass("k-tile k-state-selected")) {
img = $(this).attr("data-uid");
type = $(this).attr("data-type");
name = $(this).children("strong").html();
}
});
//alert(path);
window.OpenDeleteConfirm("Are you sure you want to delete this record?").then(function (e) {
$.ajax({
type: 'POST',
url: "/ImageBrowser/Destroy",
data: { "path": path, "type": type, "name": name },
success: function (response) {
//$(".k-reset.k-floats.k-tiles.k-widget.k-listview.k-selectable>.k-tile.k-state-selected").remove();
}
});
}, function () {
// window.myalert("You chose to Cancel action.");
});
}
else {
}
});
//End
});
});
}```
In short, kendoEditor has an internal ImageBrowser that has an internal ListView with the files that keeps the list of files in its dataSource, that it creates from your transport configuration. Your ajax call doesn't tell that dataSource that an item should be removed.
Since it's a poorly documented component of Kendo Professional, I suggest you file a ticket with Telerik.
Related
I am using https://www.dropzone.dev/js/ to upload images with the following script:
This is working if I upload an image. However when I capture an image with my phone (and someone else has had the same problem) although I see the preview on my .dropzone area the image never uploads. I have browsed my phone and actually don't see the image I have taken so am wondering if that is the problem but has anyone else managed to get images from a camera (where they're not saved) to upload with this script? Am I missing something?
$(".dropzone").dropzone({
url: base_url+'url/save',
acceptedFiles: 'image/*',
autoProcessQueue: false,
addRemoveLinks: true,
autoDiscover: false,
uploadMultiple: false,
init: function() {
var dzClosure = this;
$('#button[name="saveBtn"]').off('click').on('click',function(e){
e.preventDefault();
e.stopPropagation();
dzClosure.processQueue();
// Reload existing layer/view on datatable
setTimeout(function(){
MyAssets.ajax.reload(); // see notes at top
},500);
$('.modal:visible').modal('hide');
});
// When sending the data add our actual form contents too - note the formdata.append is crucial
dzClosure.on('sending', function (data, xhr, formData) {
var extra = getForm($('.modal:visible'));
formData.append(key,extra[key]);
});
// On removing files - if they are already there remove them!
dzClosure.on('removedfile',function(file) {
var params = {
fileContents: JSON.stringify(file),
assetID: $('.modal:visible').find('input[name="assetID"]').val(),
};
$.post(base_url+'url/remove',params);
})
// Preload existing image
dzClosure.addCustomFile = function(){
var thisFileBit = this;
// This is getting the SOURCE clicked VIEW link ...
// But its not ready yet
setTimeout(function(){
if (typeof $('#asset'+$('.modal:visible').find('input[name="assetID"]').val()).data('contents') != 'undefined'){
var origAsset = JSON.parse(atob($('#asset'+$('.modal:visible').find('input[name="assetID"]').val()).data('contents')));
} else {
var origAsset = {};
}
var file = {
accepted: true,
status: Dropzone.QUEUED,
size: origAsset.FileSize,
upload: {},
};
// Push file to collection
thisFileBit.files.push(file);
// Emulate event to create interface
thisFileBit.emit("addedfile", file);
// Add thumbnail url
if (origAsset.PublicImagePath != '' && typeof origAsset.PublicImagePath != 'undefined'){
thisFileBit.emit("thumbnail", file, origAsset.PublicImagePath);
}
// Add status processing to file
thisFileBit.emit("processing", file);
// Add status success to file AND RUN EVENT success from response
thisFileBit.emit("success", file,{
status: "success"
},false);
// Add status complete to file
thisFileBit.emit("complete", file);
},200);
}
// Includes test file above
dzClosure.on('addedfile',function (){
setTimeout(function(){
$('.dz-size span').data('dz-size');
$('.dz-details').remove();
$('.dz-image img').each(function(){
$(this).wrap('');
})
},1000);
});
dzClosure.addCustomFile();
}
});
I am performing an Ajax (JQuery) request on a php script which iterates. At each iteration I do an "echo" of the value of the loop counter, encoded in JSon. The goal is to manage the display of a progress bar.
By doing this I hoped to intercept and retrieve each of the counter values in a separate response thanks to the "progress" event.
Actually I only have one answer which contains all the counter values.
My research always leads me to information about downloading files, which is not my situation.
Maybe I should use the "onreadystatechange" event, but I don't see how to fit it into my code: $ Ajax parameter or separate function?
If anyone has an idea to solve my problem.
Here is my JS code
function DiffuseOffre(envoi, tab, paquet, dest) {
//$('#cover-spin').show(0);
$("#xhr-rep").css("display", "block");
var server = '/Admin/Offres/DiffuseOffre.php';
$.ajax({
url: server,
type: 'Post',
dataType: 'json',
data: {
envoi: envoi,
tab: tab,
paquet: paquet,
dest: dest
},
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var compteur = evt.text;
$("#xhr-rep").html(compteur);
}
}, false);
return xhr;
},
success: function(msg) {
//$('#cover-spin').css("display", "none");
$('#xhr-rep').css("display", "none");
if (msg.hasOwnProperty('erreur')) {
$("#dialog-erreur").html(msg.erreur);
$("#dialog-erreur").dialog("open");
$("#dialog-erreur").dialog({
width: '600px',
title: msg.title
})
} else {
$("#dialog-message").html(msg.message);
$("#dialog-message").dialog("open");
$("#dialog-message").dialog({
width: '600px',
title: msg.title
})
if (paquet == 1) {
$("#envoi_" + dest).remove();
$("#diffuser").remove();
}
if (msg.hasOwnProperty('encours')) {
$("#en_cours").html(msg.encours);
}
if (msg.hasOwnProperty('fieldset')) {
$("#" + msg.fieldset).remove();
}
}
}
})
}
I have a kendo dialog which I want to populate with a partial view but it's sort of not working.
I want to populate the dialog with the click of a button, so here's my code so far
<div id="dialog"></div>
function showDetails(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
var dialog = $("#dialog");
console.log("objId", dataItem.OBJECTID1)
$.ajax({
url: '#Url.Action("SavePartial", "SettlementContract")',
data: {
id: dataItem.OBJECTID1
},
success: function (result) {
if (result != null) {
dialog.html(result);
dialog.data("kendoDialog").open();
}
}
});
}
I tried removing the if condition inside the success, just in case but it's not working either. It returns the partial view, but not inside the kendo dialog, the dialog doesn't even open. What am I doing wrong?
We do this in our application and this is how we have set it up (I updated it to use your controller/actions/ids) - this is using the ASP.NET Core MVC wrappers:
#(Html.Kendo().Window()
.Name("dialog")
.Content("loading...")
.Draggable()
.Actions(actions => actions.Maximize().Close())
.Resizable()
.Modal(true)
.Visible(false)
.Events(e => e.Refresh("onDialogWindowRefresh"))
)
<script>
function showDetails(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
let win = $("#dialog").data("kendoWindow");
win.refresh({
url: "/SettlementContract/SavePartial/",
data: {
id: dataItem.OBJECTID1
}
});
}
function onDialogWindowRefresh(e) {
e.sender.center().open();
}
</script>
d3js (both v4 and also v3) charts in Drupal 7 with having click event attached to one of the svg text element using .attr("class", "ajax_button") and attaching Drupal behavior for that element. Problem is that click event is lost once tree gets collapsed and not get reattached on expand.
link : d3js + Drupal behavior
following is code for click element
(function($) {
Drupal.behaviors.listload = {
attach: function(context, settings) {
if (context == document) {
$('.ajax_button', context).once(function() {
$(this).click(function(e) {
e.preventDefault();
// https://stackoverflow.com/a/1369080
// to prevent collapsible function which is attached to parent element
e.stopPropagation();
var the_id = $(this).attr('href'); // contextual filter(nid) to views
noSlashes = the_id.replace(/\//g, '');
$.ajax({
url: Drupal.settings.basePath + 'views/ajax',
type: 'post',
data: {
view_name: 'candidate_list_er', //view name
view_display_id: 'candidate_list_block', //your display id
view_args: noSlashes, // your views arguments, //view contexuall filter
},
dataType: 'json',
success: function(response) {
//console.log(response);
if (response[1] !== undefined) {
//console.log(response[1].data); // do something with the view
var viewHtml = response[1].data;
$('#ajax-target .content').html(viewHtml);
//Drupal.attachBehaviors(); //check if you need this.
}
},
error: function(data) {
alert('An error occured!');
}
});
}); //click ends
}); //once ends
}
},
detach: function(context, settings, trigger) { //this function is option
$('.ajax_button').unbind(); //or do whatever you want;
}
};
})(jQuery);
I have some tabs (jQuery UI tabs) in the "index.php" of a page. This page not only shows content, but also retrieves the $_GET variable to show some other content below the tabs.
The problem is how to tell jQuery UI that the href (attr of the clicked ) is a value for the key "href" that has to send (GET) to the current index.php page, called in JS has window.location.pathname (I can't use PHP generated JavaScript).
The code is this, and i'm out of options for how to make things work.
jQuery('#front-tab').tabs({
spinner: "Loading...",
select: '#tab-one',
cache: true,
fx: { height: 'toggle', opacity: 'toggle' },
url: window.location.pathname,
ajaxOptions: {
type: 'get',
success: function(){alert('Sucess');},
error: function(){alert('I HAZ FAIL');};
},
dataType: 'html'
}
});
The HTML:
<div id="front-tab">
<ul>
<li><span>Home</span></li>
<li><span>Tab Content 1</span></li>
<li><span>Tab Content 2</span></li>
<li><span>Tab Content 3</span></li>
<li><span>Tab Content 4</span></li>
</ul>
<div id="tab-home">
content...
</div>
</div>
Yep, this gets me full of "I HAZ FAIL" every time I try to load other tabs. The first tab is inline HTML, but the rest is Ajax. url: window.location.pathname doesn't seems to work or point to the right direction. Well, I don't know if that does what I am looking for.
function initTabs(elementHref) {
jQuery('#front-tab').tabs({
spinner: "Loading...",
select: '#tab-one',
cache: true,
fx: { height: 'toggle', opacity: 'toggle' },
url: elementHref,
ajaxOptions: {
type: 'get',
success: function(){alert('Sucess');},
error: function(){alert('I HAZ FAIL');};
},
dataType: 'html'
}
});
}
jQuery('yourLink').on('click', function() {
initTabs(jQuery(this).attr('href'));
});
Well, after noting the inflexibility of jQuery UI Tabs I had to replicate the action on my own. Better yet, few lines of code compared to two plugins.
front_tab.click(function(e) {
// Content parent
tab_content = $('#tab-content');
// other variables
var tab_visible = tab_content.children('div.visible'),
span = $(this).children('span'),
span_value = span.html(),
value = $(this).attr('href'),
// This gets our target div (if exists)
target = tab_content.children(value);
// There is no anchor
e.preventDefault();
// Don't do nothing if we are animating or "ajaxing"
if (tab_content.children().is(':animated') || is_ajaxing) { return; };
// Put the "selected" style to the clicked tab
if (!$(this).hasClass('selected')) {
front_tab.removeClass('selected');
$(this).addClass('selected');
}
// If is target div, call it
if (target.length > 0) {
is_ajaxing = true;
span.html('Loading...');
tab_content.children().removeAttr('class');
tab_visible.slideUp('slow', 'swing', function(){
// Some timeout to slow down the animation
setTimeout(function() {
target.attr('class', 'visible').slideDown('slow');
if (value = '#tpopular') { update_postbox(); }
is_ajaxing = false;
span.html(span_value)
}, 400);
});
// So, the target div doesn't exists. We have to call it.
} else {
is_ajaxing = true;
span.html('Cargando...');
$.get(
window.location.pathname,
{ href : value },
function(data) {
tab_visible.slideUp('slow', 'swing', function(){
setTimeout(function() {
tab_content.children().removeAttr('class');
tab_content
.append(unescape(data))
.children(value)
.css('display', 'none')
.attr('class', 'visible')
.slideDown('slow');
if (value = '#tpopular') { update_postbox(); }
is_ajaxing = false;
span.html(span_value)
}, 800);
});
},
'html');
}
});
The next problem is to make a nice error warning, but that is the solution.