How to disable drag and drop with jquery.shapeshift? - javascript

I'm using this plugin grid system with drag and drop functionality:
https://github.com/McPants/jquery.shapeshift.
You can call the shapeshift function and pass it the parameters to enable and disable the drag and drop functionality.
$(".container").shapeshift({
enableDrag: true,
});
I want to be able to turn on and off this feature. I used this code:
var dragState = 0;
$(".switch").on("click", function() {
if(dragState == 0) {
options = {
enableDrag: true,
}
dragState = 1;
} else {
options = {
enableDrag: false,
}
dragState = 0;
}
$(".container").shapeshift(options);
});
When I run this code I can turn on drag and drop but not back off again.
Does anyone have any suggestions or experience with this plugin?

Use http://mcpants.github.io/jquery.shapeshift/ as a reference.
Basicaly all you need to do is:
$(function(){
var sso = {
minColumns: 3,
enableDrag: false
};
var ss = $(".container").shapeshift(sso);
$('button').click(function () {
sso.enableDrag = true;
ss.trigger('ss-destroy');
ss.shapeshift(sso);
});
});
I simplified the example to show what needs to be done in this fiddle:
http://jsfiddle.net/carisch19/hDm4e/2/
Added enable and disable buttons:
http://jsfiddle.net/carisch19/hDm4e/4/

Sorry for answering on such an old question but i was just going through shapeshift.js and understand that for disabling drag and drop we can destroy it but not in such a long way and there is no need to take it to variable.
Hope you will interested in this short way and update your codes.
Below is the code
$('div').trigger("ss-destroy");
Above code is sufficient for destroying and also a very clean and convenient way according to me.
Try once!

Related

Remember JavaScript with cookie

I’m working on a left menu bar that expands on a button click.
I want to save the state of the menu, if it is expanded or not.
When it refreshes the class must still be added.
$('#menu-action').click(function() {
$('.sidebar').toggleClass('active');
$('.main').toggleClass('active');
$(this).toggleClass('active');
if ($('.sidebar').hasClass('active')) {
$(this).find('i').addClass('fa-close');
$(this).find('i').removeClass('fa-bars');
} else {
$(this).find('i').addClass('fa-bars');
$(this).find('i').removeClass('fa-close');
}
});
// Add hover feedback on menu
$('#menu-action').hover(function() {
$('.sidebar').toggleClass('hovered');
});
Try Local Storage:
$(document).ready(function() {
if(localStorage.getItem("active")) {
$('.sidebar').addClass("active")
}
});
$(window).unload(function() {
localStorage.setItem("active", $('.sidebar').hasClass("active"));
});
Local storage is not supported by all browsers. See the link above. You can use extensions like store.js to support old browsers.
Another option is to use cookie plugin as mentioned here.
Since you have not yet made it clear on how you want to read or write cookies, I'd recommend using js-cookie to make handling a little easier. Handling cookies with plain JS is possible, but a rather cumbersome task.
A solution using the mentioned library would work like this (Expecting you have added js.cookie.js before your code to your HTML)
// Store references to reusable selectors
var $menuAction = $('#menu-action');
var $menuActionI = $menuAction.find('i'); // the <i> inside #menu-action
var $sidebar = $('.sidebar');
var activeClass = 'active';
// Docs: https://github.com/js-cookie/js-cookie/tree/v2.1.0#basic-usage
var isActive = Cookies.get('site-menu-active') || false;
function toggleMenu() {
$sidebar.toggleClass('active', isActive);
$('.main').toggleClass('active', isActive);
$menuAction.toggleClass('active', isActive);
$menuActionI.toggleClass('fa-close', isActive);
$menuActionI.toggleClass('fa-bars', isActive);
isActive = !isActive;
Cookies.set('site-menu-active', isActive, { expires: 7 });
}
// Calling immediately to set to state read from cookie
toggleMenu();
// Add click interaction
$menuAction.click(toggleMenu);
// Add hover feedback on menu
$menuAction.hover(function() {
$sidebar.toggleClass('hovered');
});
The Html5 storage is the best option for these scenario. Here you can change the localStorage to sessionStorage based on the requirement:
1)localStorage - even close the browser the data is alive
2)sessionStorage - while close the browser the data is removed
We can also remove the stored data
$('#menu-action').click(function() {
$('.sidebar').toggleClass('active');
$('.main').toggleClass('active');
$(this).toggleClass('active');
localStorage.setItem("active", $('.sidebar').hasClass('active'));
if ($('.sidebar').hasClass('active')) {
$(this).find('i').addClass('fa-close');
$(this).find('i').removeClass('fa-bars');
} else {
$(this).find('i').addClass('fa-bars');
$(this).find('i').removeClass('fa-close');
}
});
$(document).ready(function(){
if(localStorage.getItem("active")){
$('.sidebar').addClass('active');
$('.main').addClass('active');
$('#menu-action').find('i').addClass('fa-close');
$('#menu-action').find('i').removeClass('fa-bars');
}
});

Skip disabled buttons when tabbing - keynav

Using ExtJS 4.2 Is there a simple way to skip over disabled buttons when tabbing?
I started implementing a whole custom keynav to get around this but it's growing into a monstrosity to handle any other type of component that could get tabbed onto.
I googled around and couldn't find anything though it seems like it would be a normal thing not to tab onto disabled (unfocusable) buttons. Has anyone else implemented something like this?
Seems like ExtJS buttons have a child element btnEl that gets missed when disabled state is set, I worked out some overrides to handle this:
// force disabled buttons to be untabbable
Ext.override(Ext.button.Button, {
afterRender: function() {
var me = this;
if (me.disabled) {
me.btnEl.dom.removeAttribute('tabIndex');
}
},
enable: function(silent) {
var me = this;
me.callParent(arguments);
me.removeClsWithUI('disabled');
if (me.rendered) {
me.el.dom.setAttribute('tabIndex', me.tabIndex);
me.btnEl.dom.setAttribute('tabIndex', me.tabIndex);
}
return me;
},
disable: function(silent) {
var me = this;
me.callParent(arguments);
me.addClsWithUI('disabled');
me.removeClsWithUI(me.overCls);
if (me.rendered) {
me.el.dom.removeAttribute('tabIndex');
me.btnEl.dom.removeAttribute('tabIndex');
}
if (me.btnInnerEl && Ext.isIE7m) {
me.btnInnerEl.repaint();
}
return me;
}
});

Accept Image in Filefield ExtJs

I have a filefield componente in my application and I want to restrict it to only image files. I've found this question on stackoverflow:
How to restrict file type using xtype filefield(extjs 4.1.0)?
Add accept="image/*" attribute to input field in ExtJs
I'm using this code:
{
xtype:'filefield',
listeners:{
afterrender:function(cmp){
cmp.fileInputEl.set({
accept:'audio/*'
});
}
}
}
But this code only works the first time I click on "Examine" button, when I click again on it, the restriction dissapears. I've been looking for other events like onclick to write this code in that event, but I don't find the best way to do it, Anyone has any idea?
Greetings.
This is happening because when you submit form, it calls Ext.form.field.File#reset().
You should override reset() method like this, to keep you accept property:
{
xtype:'filefield',
reset: function () {
var me = this,
clear = me.clearOnSubmit;
if (me.rendered) {
me.button.reset(clear);
me.fileInputEl = me.button.fileInputEl;
me.fileInputEl.set({
accept: 'audio/*'
});
if (clear) {
me.inputEl.dom.value = '';
}
me.callParent();
}},
listeners:{
afterrender:function(cmp){
cmp.fileInputEl.set({
accept:'audio/*'
});
}
}
}

How to implement a delegator using ExtJS 4.1

I am new to javascript, but I've been hired to give maintenance to an application which is developed in Sencha ExtJS 4. One of the modules I've been asked to modify, is of a component in which I show a tooltip whenever I hover over it. This component can be present in more than one view, it is something like "Customer Details" that is present in many screens of the application. If I hover over this data, I need to show a tooltip, this tooltip shows information retrieved by server (REST). I implemented some logic, but this logic involves the use of many listeners in each of the components that will show the information. For instance, I added a listener in all of the views that requires showing the tooltip:
this.listeners = {
boxready: {
fn: this.onAfterRender,
scope: this
}
And I had to implement this method for every view as well, which is a mess and, for sure, a very bad practice:
/**
* This method is executed after panels are rendered in order to set ToolTip listeners on
* users and workgroups.
*
* #param {Object} scope
*/
onAfterRender: function(scope) {
Ext.defer(function() {
var usElements = Ext.get(Ext.query('.usertooltip', scope.el.dom));
usElements.on({
click: function (e) {
var item = Ext.get(e.target);
if (Ext.isEmpty(item.dom.innerHTML.trim())) {
item.removeCls('usertooltip');
return;
}
if (item.hasCls('usertooltip-clicked')) {
return;
}
item.addCls('usertooltip-clicked');
var user = item.getAttribute('data-info');
UserInfo.getUserInfo(user, false);
if (UserInfo.errorResponse) {
UserInfo.getWGroupInfo(user);
}
UserInfo.displayToolTip(this);
}
});
var wgElements = Ext.get(Ext.query('.wgtooltip', scope.el.dom));
wgElements.on({
click : function (e) {
var item = Ext.get(e.target);
if (Ext.isEmpty(item.dom.innerHTML.trim())) {
item.removeCls('wgtooltip');
return;
}
if (item.hasCls('wgtooltip-clicked')) {
return;
}
item.addCls('wgtooltip-clicked');
var wgroup = item.getattribute('data-info');
WGroupInfo.getWGroupInfo(wgroup, false);
if (UserInfo.errorResponse) {
WGroupInfo.getUserInfo(wgroup);
}
WGroupInfo.displayToolTip(this);
}
});
}, 1000, this);
},
What I do is simply detect if the item is selected based a css class, if so, I handle the events and proceed with logic. But I've been doing some research and I think this can be achieved using a "delegator" but I am not sure how to implement this for my scenario.
What I've been thinking of, so far is to create a "js" class which have a method like an "observer" and whenever listen to someone asking for this tooltip functionality, delegate it to the executing object. But since I am new to javascript and this Sencha ExtJS, my tries have been frustrated. If someone can help me I would really appreciate it.
Thanks in advance.
Best regards.
The best way would be to declare a plugin:
Ext.define('TipPlugin', {
alias: 'plugin.tip',
init: function(c) {
c.on('boxready', this.onBoxReady, this);
},
onBoxReady: function(c) {
var els = this.el.select('.usertooltip');
// Do stuff!
}
});
var c = new Ext.Component({
plugins: ['tip']
});

How to implement toggle functionality on JQuery UI Selectable?

I'm using JQuery UI - Selectable. I want to deselect the element if it has been pressed and it has already been selected (toggle)
Could you help me to add this functionality please !
Because of all the class callbacks, you're not going to do much better than this:
$(function () {
$("#selectable").selectable({
selected: function (event, ui) {
if ($(ui.selected).hasClass('click-selected')) {
$(ui.selected).removeClass('ui-selected click-selected');
} else {
$(ui.selected).addClass('click-selected');
}
},
unselected: function (event, ui) {
$(ui.unselected).removeClass('click-selected');
}
});
});
You already have that functionality with jQuery UI selectable if you're holding down the Ctrl key while clicking.
If you really need that as the default functionality, you don't need to use selectable, you can do it just as a simple onclick handler, like what nolabel suggested.
Or... you might as well edit jquery.ui.selectable.js and add an option which does just what you need. Shouldn't be too hard, there are 4 places where event.metaKey is checked, make sure if your option is set, just run the codepaths as if event.metaKey was always true.
As the selectables could use some more customisation, you could also make a feature request for jQuery UI developers to include it in the next official version.
You have to inject two simple elements in the code to achieve what you want. This just inverts the metaKey boolean, whenever you need inverted/toggle functionality.
options: {
appendTo: 'body',
autoRefresh: true,
distance: 0,
filter: '*',
tolerance: 'touch',
inverted: false /* <= FIRST*/
},
_mouseStart: function(event) {
var self = this;
this.opos = [event.pageX, event.pageY];
if (this.options.disabled)
return;
var options = this.options;
if (options.inverted) /* <= SECOND*/
event.metaKey = !event.metaKey; /* <= SECOND*/

Categories