jQuery append icon only once - append

I'd like to append an icon on a table row data, but only once on window resize. The problem is that whenever I resize the window its appends the icon multiple times. This is the code I have, that works when the window is resized once.
$(window).on('resize', function(e) {
if ($(window).width() < 600) {
$('td.sorting').append('<i class="fa fa-chevron-right pull right fa-2x"></i>');
}
});
Does anyone have a better solution please?
Thank you.

//You must add a mark when youYou must add a mark when you've added the icon
$(window).on('resize', function(e) {
if ($(window).width() < 600) {
if(!$(this).data('addedIcon')) {
$('td.sorting').append('<i class="fa fa-chevron-right pull right fa-2x"></i>');
$(this).data('addedIcon', true);
}
}
});

Related

Customizing fullpage.js to skip section(s) dynamically

The question is simple but i'm not able to make a script by myself for what i need...
I am actually using a script ( fullpage.js ) who toggle some classes into a container ( in my case switching from fp-viewing-1 to fp-viewing-x ) when you scroll down/up between sections.
I need to make a script that listen from this container and toggle a new class into a div ONLY when a class ( in my case fp-viewing-3 ) is added to this container ( from the fullpage.js script of course ).
Any way to make it?
I need to make a script that listen from this container
That's not the way to go for it.
If you want to use the status class, then just create a new class based on the previous ones as explained in this fullpage.js tutorial.
Create a conditional CSS class that will only get applied when its parent class matches your requirement.
Something like this, for example, would only apply the red color to element with myClass when you are in section 1 slide 0.
.fp-viewing-1-0 .myClass{
color: red;
}
Having:
<div id="fullpage">
<div class="section"></div>
<div class="section myClass"></div>
<div class="section"></div>
<div>
If for some other reason (use of plugins etc) you really need to add the class dynamically, then go for fullpage.js callbacks onLeave or afterLoad:
$('#fullpage').fullpage({
onLeave: function(index, nextIndex, direction){
var destination = $('.section').eq(nextIndex - 1);
destination.find('.my-element').addClass('myClass');
}
});
This is the solution to my problem.
Fullpage works as intended except for section 2.
Section 2 will be usable only scrolling down, the script ignore it when scrolling up.
$(document).ready(function() {
$('#application').fullpage({
onLeave: function(index, nextIndex, direction){
var destinationToIgnore = $('.fp-section').hasClass('ignore');
if(destinationToIgnore && direction =='up'){
var destination = nextIndex = 1
$.fn.fullpage.moveTo(destination);
}
},
afterLoad: function(anchorLink, index){
var loadedSection = $(this);
if(index !== 1){
$('.section-intro').removeClass('ignore');
}
if(index == 3){
$('.section-intro').addClass('ignore');
}
}
});
});

Jquery Accordion choosing correct selector

I'm struggling with plugging in the correct selector into jquery. When I plug in ".accordionButton" the entire div is clickable and the functionality works great. However, I want to make only the "h3.toggle a" clickable, but plugging that selector in doesn't work. Is there something else in the jquery I need to change here? Any advice is greatly appreciated. Thanks!
The HTML:
<div class="accordionButton">
<div class="case-top">
<div class="case-left"></div>
<div class="case-right">
<h3 class="toggle">Our Strategy and Results</h3>
</div>
</div><!--end case-top-->
</div><!--end button-->
<div class="accordionContent">sliding content here</div>
The JQUERY:
$(document).ready(function() {
//ACCORDION BUTTON ACTION (ON CLICK DO THE FOLLOWING)
$('.accordionButton h3.toggle a').click(function() {
//REMOVE THE ON CLASS FROM ALL BUTTONS
$('.accordionButton h3.toggle a').removeClass('on');
//NO MATTER WHAT WE CLOSE ALL OPEN SLIDES
$('.accordionContent').slideUp('normal');
//IF THE NEXT SLIDE WASN'T OPEN THEN OPEN IT
if($(this).next().is(':hidden') == true) {
//ADD THE ON CLASS TO THE BUTTON
$(this).addClass('on');
//OPEN THE SLIDE
$(this).next().slideDown('normal');
}
});
/*** REMOVE IF MOUSEOVER IS NOT REQUIRED ***/
//ADDS THE .OVER CLASS FROM THE STYLESHEET ON MOUSEOVER
$('.accordionButton h3.toggle a').mouseover(function() {
$(this).addClass('over');
//ON MOUSEOUT REMOVE THE OVER CLASS
}).mouseout(function() {
$(this).removeClass('over');
});
$('.accordionContent').hide();
});
You are using
$(this)
but you change the selector, you need to change all $(this) selectors to
$('.accordionButton')
FIDDLE
Ok, here is where I'm at... the buttons are now working correctly, but on click all the instances of .accordionContent open, not just next one. ( FYI, I removed the mouseover from this code snipped)
Jquery
$(document).ready(function() {
//ACCORDION BUTTON ACTION (ON CLICK DO THE FOLLOWING)
$('.accordionButton h3.toggle a').click(function() {
//REMOVE THE ON CLASS FROM ALL BUTTONS
$('.accordionButton h3.toggle a').removeClass('on');
//NO MATTER WHAT WE CLOSE ALL OPEN SLIDES
$('.accordionContent').slideUp('normal');
//IF THE NEXT SLIDE WASN'T OPEN THEN OPEN IT
if($('.accordionButton').next().is(':hidden') == true) {
//ADD THE ON CLASS TO THE BUTTON (correct)
$(this).addClass('on');
//OPEN THE SLIDE
$('.accordionButton').next().slideDown('normal');
}
});
I'm guessing the lines:
$('.accordionButton').next().slideDown('normal');
and
if($('.accordionButton').next().is(':hidden') == true) {
are the lines which need editing. I need these two lines to open and close just the "next" .accordionContent instances not all of the instances together.

Drag and Drop into Fabric.js canvas

How can I drop items (like image, or other object from other canvas) into canvas which is managed by fabricjs? I have found many examples how to move items inside canvas but I would like to drag and drop item from outer element into canvas.
Since you asked for an example and I haven't tried it out myself yet, here goes:
Example Fiddle
Markup
<div id="images">
<img draggable="true" src="http://i.imgur.com/8rmMZI3.jpg" width="250" height="250"></img>
<img draggable="true" src="http://i.imgur.com/q9aLMza.png" width="252" height="295"></img>
<img draggable="true" src="http://i.imgur.com/wMU4SFn.jpg" width="238" height="319"></img>
</div>
<div id="canvas-container">
<canvas id="canvas" width="800" height="600"></canvas>
</div>
JS Breakdown
1. Fabric.canvas instance
First we want our canvas, of course:
var canvas = new fabric.Canvas('c');
2. Feature Detection (optional)
Not sure this is necessary, since the fact that you have a canvas makes it very likely that the browser has Drag and Drop as well. Were you to use it, you can do so like this, using Modernizr:
if (Modernizr.draganddrop) {
// Browser supports HTML5 DnD.
// Bind the event listeners for the image elements
// Bind the event listeners for the canvas
} else {
// Replace with a fallback to a library solution.
alert("This browser doesn't support the HTML5 Drag and Drop API.");
}
3. Events
Again, unlike the source article I below, the source and target elements are different (in that articles's example, you just move divs around within the same parent container), so I failed to notice that some of the events are meant for the element being dragged, but most are bound to the element into which you are dropping.
NOTE: I know this is technically a question about Fabric.js, but it's really kind of a question about Drag and Drop in the context of adding objects to a <canvas> with Fabric.js, which is why I'm going a bit more in depth about the DnD stuff now.
For the <img>
dragstart (I added a class here to lower the opacity)
dragend (and removed that class here)
For #canvas-container:
dragenter (added a class to give the canvas container that nifty dotted line)
dragover: Here you can set the event.dataTransfer.dropEffect property to show one of the native cursor types. The default would be 'move' here, but I set it to 'copy' since I don't actually remove the <img> element (in fact in the fiddle you can, for example create several McClures).
dragleave (removed the dotted line here)
drop: The handler for this event creates and adds the fabric.Image object (see the fiddle).
if (Modernizr.draganddrop) {
// Browser supports HTML5 DnD.
// Bind the event listeners for the image elements
var images = document.querySelectorAll('#images img');
[].forEach.call(images, function (img) {
img.addEventListener('dragstart', handleDragStart, false);
img.addEventListener('dragend', handleDragEnd, false);
});
// Bind the event listeners for the canvas
var canvasContainer = document.getElementById('canvas-container');
canvasContainer.addEventListener('dragenter', handleDragEnter, false);
canvasContainer.addEventListener('dragover', handleDragOver, false);
canvasContainer.addEventListener('dragleave', handleDragLeave, false);
canvasContainer.addEventListener('drop', handleDrop, false);
} else {
// Replace with a fallback to a library solution.
alert("This browser doesn't support the HTML5 Drag and Drop API.");
}
Sources:
HTML5 Rocks - Native HTML5 Drag and Drop
Modernizr
Web Platform Docs > DOM > Properties - dropEffect
Web Platform Docs > DOM > Events
dragstart
dragend
dragenter
dragover
dragleave
drop
I had gone through fiddle of #natchiketa, And fixed the problem , just check this fiddle..
http://jsfiddle.net/Ahammadalipk/w8kkc/185/
window.onload = function () {
var canvas = new fabric.Canvas('canvas');
/*
NOTE: the start and end handlers are events for the <img> elements; the rest are bound to
the canvas container.
*/
function handleDragStart(e) {
[].forEach.call(images, function (img) {
img.classList.remove('img_dragging');
});
this.classList.add('img_dragging');
}
function handleDragOver(e) {
if (e.preventDefault) {
e.preventDefault();
}
e.dataTransfer.dropEffect = 'copy';
return false;
}
function handleDragEnter(e) {
this.classList.add('over');
}
function handleDragLeave(e) {
this.classList.remove('over');
}
function handleDrop(e) {
if (e.stopPropagation) {
e.stopPropagation(); // stops the browser from redirecting.
}
var img = document.querySelector('#images img.img_dragging');
var newImage = new fabric.Image(img, {
width: img.width,
height: img.height,
// Set the center of the new object based on the event coordinates relative
// to the canvas container.
left: e.layerX,
top: e.layerY
});
newImage.hasControls = newImage.hasBorders = false;
canvas.add(newImage);
return false;
}
function handleDragEnd(e) {
// this/e.target is the source node.
[].forEach.call(images, function (img) {
img.classList.remove('img_dragging');
});
}
if (Modernizr.draganddrop) {
var images = document.querySelectorAll('#images img');
[].forEach.call(images, function (img) {
img.addEventListener('dragstart', handleDragStart, false);
img.addEventListener('dragend', handleDragEnd, false);
});
var canvasContainer = document.getElementById("canvas-container");
canvasContainer.addEventListener('dragenter', handleDragEnter, false);
canvasContainer.addEventListener('dragover', handleDragOver, false);
canvasContainer.addEventListener('dragleave', handleDragLeave, false);
canvasContainer.addEventListener('drop', handleDrop, false);
} else {
alert("This browser doesn't support the HTML5 Drag and Drop API.");
}
}
Thanks
Well, the question is quite old^^
I have updateted the fiddle, no it will work in Firefox as well.
Fiddle
function handleDrop(e) {
// this / e.target is current target element.
e.preventDefault(); //I've altert this line for FireFox
As far as I understand, drag and drop is not already provided by fabricjs,
fiddling it will be quite interesting.
Well I m new to javascript and fabricJS but I think this fiddle might help
fiddle
html code
<div class="img_cont">
<img class="img" id="ele1" draggable="true" ondragstart="dragElement(event)" src="https://webkit.org/wp-content/uploads/STP-300x300.png">
<img class="img" id="ele2" draggable="true" ondragstart="dragElement(event)" src="https://webkit.org/wp-content/uploads/ephy-webkit-graphic.png">
<img class="img" id="ele3" draggable="true" ondragstart="dragElement(event)" src="https://res.cloudinary.com/css-tricks/image/upload/w_600,q_auto,f_auto/buysellads/uu/7/112766/1646327381-MC_CSSTricks_Logo_600x600-_1_.png">
<img class="img" id="ele4" draggable="true" ondragstart="dragElement(event)" src="https://miro.medium.com/max/1400/1*9hd_8qR0CMZ8L0pVbFLjDw.png">
</div>
<br>
<div id="canvas_cont" ondragover="allowDrop(event)" ondrop="dropElement(event)">
<canvas id="canvas" width="650" height="350" ></canvas>
</div>
javascript code
// allowDrop function called on ondragover event.
function allowDrop(e) {
e.preventDefault();
}
//dragElement function called on ondrag event.
function dragElement(e) {
e.dataTransfer.setData("id", e.target.id); //transfer the "data" i.e. id of the target dragged.
}
//Initializing fabric canvas on window load event.
var canvas;
window.onload = function(){
canvas = new fabric.Canvas(document.getElementById("canvas"));
}
//dropElement function called on ondrop event.
function dropElement(e) {
e.preventDefault();
var data = e.dataTransfer.getData("id"); //receiving the "data" i.e. id of the target dropped.
var imag = document.getElementById(data); //getting the target image info through its id.
var img = new fabric.Image(imag, { //initializing the fabric image.
left: e.layerX - 80, //positioning the target on exact position of mouse event drop through event.layerX,Y.
top: e.layerY - 40,
});
img.scaleToWidth(imag.width); //scaling the image height and width with target height and width, scaleToWidth, scaleToHeight fabric inbuilt function.
img.scaleToHeight(imag.height);
canvas.add(img);
}
The accepted answer no longer works.
This is for drag and drop from desktop using the dataTransfer interface.
canvas.on('drop', function(event) {
// prevent the file to open in new tab
event.e.stopPropagation();
event.e.stopImmediatePropagation();
event.e.preventDefault();
// Use DataTransfer interface to access the file(s)
if(event.e.dataTransfer.files.length > 0){
var files = event.e.dataTransfer.files;
for (var i = 0, f; f = files[i]; i++) {
// Only process image files.
if (f.type.match('image.*')) {
// Read the File objects in this FileList.
var reader = new FileReader();
// listener for the onload event
reader.onload = function(evt) {
// put image on canvas
fabric.Image.fromURL(evt.target.result, function(obj) {
obj.scaleToHeight(canvas.height);
obj.set('strokeWidth',0);
canvas.add(obj);
});
};
// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
}
}
});
Resources
https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/File_drag_and_drop

How to have multiple toggle at the same time for 2 different div?

I need to handle multiple slide toggle for 2 different divs using jquery.
example: when I click a button, it should slideLeft the 1st div and at the same time it should expand the 2nd div covering the whole area of the 1st div.
Thanks in advance.
Here the piece of code I have used:
$(document).ready(function() {
$('#foo').click(function() {
$('#accordian').toggle("slide", 300);
if ($(this).val() == "Hide Menu"){
$(this).val("Show Menu");
$('#area').css({"max-width":"960px"});
}else{
$(this).val("<< Hide Menu");
$('#area').css({"max-width":"730px"});
}
});

sort multiple items at once with jquery.ui.sortable

did somebody manage to sort multiple items at once with jquery.ui.sortable?
we are working on a photo managing app.
select multiple items
drag them to a new location.
thanx
I had a similar requirement, but the solution in the accepted answer has a bug. It says something like "insertBefore of null", because it removes the nodes.
And also i tried jQuery multisortable, it stacks the selected items on top of each other when dragging, which is not what i want.
So I rolled out my own implementation and hope it will save others some time.
Fiddle Link.
Source code:
$( "#sortable" ).sortable({
// force the cursor position, or the offset might be wrong
cursorAt: {
left: 50,
top: 45
},
helper: function (event, item) {
// make sure at least one item is selected.
if (!item.hasClass("ui-state-active")) {
item.addClass("ui-state-active").siblings().removeClass("ui-state-active");
}
var $helper = $("<li><ul></ul></li>");
var $selected = item.parent().children(".ui-state-active");
var $cloned = $selected.clone();
$helper.find("ul").append($cloned);
// hide it, don't remove!
$selected.hide();
// save the selected items
item.data("multi-sortable", $cloned);
return $helper;
},
stop: function (event, ui) {
// add the cloned ones
var $cloned = ui.item.data("multi-sortable");
ui.item.removeData("multi-sortable");
// append it
ui.item.after($cloned);
// remove the hidden ones
ui.item.siblings(":hidden").remove();
// remove self, it's duplicated
ui.item.remove();
}
});
There's a jQuery UI plugin for that: https://github.com/shvetsgroup/jquery.multisortable
jsFiddle: http://jsfiddle.net/neochief/KWeMM/
$('ul.sortable').multisortable();
... or just define a 'items' option to your multisortable that way (for example) :
$('table tbody').multisortable({
items: 'tr'
});
you can use shvetsgroup/jquery.multisortable
but it will create problem.. because, that js is designed only for tags...
but customize it to use it, its very simple i'll tell you how????
at first download that .js and use it in your program...
step 1. open the js file...now edit the following lines...
$.fn.multiselectable.defaults = {
click: function(event, elem) {},
mousedown: function(event, elem) {},
selectedClass: 'selected',
items: 'li'
};
the above are lines from 107 to 112....
there you can see "items: 'li'
in that use your tag which you are used to enclose those image like if you are using, or or anything you are using like this
$.fn.multiselectable.defaults = {
click: function(event, elem) {},
mousedown: function(event, elem) {},
selectedClass: 'selected',
items: 'div' // or any tag you want...
};
and 249 to 254
selectedClass: 'selected',
placeholder: 'placeholder',
items: 'li'
};
}(jQuery);
change the line " item:'li' " with your tag like this
selectedClass: 'selected',
placeholder: 'placeholder',
items: 'div' // or anything else
};
}(jQuery);
if you are working on textboxes inside those envelopes.. you have to get rid of these lines too
// If no previous selection found, start selecting from first selected item.
prev = prev.length ? prev : $(parent.find('.' + options.selectedClass)[0]).addClass('multiselectable-previous');
var prevIndex = prev.index();
after that comment line...
add a line code that search textbox or check box or any interaction element inside it...
like this..
// If no previous selection found, start selecting from first selected item.
item.children("input").focus(); // customize this code to get your element focus...
prev = prev.length ? prev : $(parent.find('.' + options.selectedClass)[0]).addClass('multiselectable-previous');
var prevIndex = prev.index();
and also to indicate selected tags or elements... use styles like this
div { margin: 2px 0; cursor: pointer; }
div.selected { background-color: orange }
div.child { margin-left: 20px; }
actually i used div.. instead of that you can use any tag you wish...
hope will help u.... if it is not... read again.. and ask again....
wishes