JS sortable POST start and update function together? - html

I would like to know how can I the current list and the sorted list sending together with POST?
I got the results well, put the posting sending only one list. The problem is the currentlist VAR is outside of UPDATE. How can I find it?
<script type="text/javascript">
$(".wrapper").sortable({
handle: ".draghandler",
connectWith: $('.wrapper'),
distance: 100,
opacity: 0.4,
cursor: 'move',
start: function (event, ui) {
var currentlist = new Array(); //Aktuális sorrend lista
$('.draghandler').each(function() {
currentlist.push($(this).attr("id"));
$('#currentlist').html(currentlist);
});
},
update: function (event, ui) {
var newsortedlist = new Array(); //Átrendezett lista
$('.draghandler').each(function() {
newsortedlist.push($(this).attr("id"));
});
$('#newsortedoutput').html(newsortedlist);
//$('#responsefromserver').html('Rendezés mentése folyamatban');
**//'currentid': currentlist is outside of update:function, it is in start:function, therefore it dosen't send.**
$.post('/megrendelesek/sortmouse.php',{'currentid': currentlist, 'sortid': newsortedlist}, function(theResponse){
$('#responsefromserver').html(theResponse);
});
}
});
$(".wrapper").disableSelection();
$(".draghandler").disableSelection();
</script>
<div id="currentlist"></div>
<div id="newsortedoutput"></div>
<div id="responsefromserver"> </div>

To do what you require you need to store currentlist within scope of both function handlers. A global variable would do this, but is bad practice.
A better approach would be to store the array in a data attribute on the relevant .wrapper container. Then you can access this wherever necessary.
Also note that you can use the map() function to simplify creating the array from the drag handle id attributes.
$(".wrapper").sortable({
handle: ".draghandler",
connectWith: $('.wrapper'),
distance: 10, // reduced to 10 to make this demo easier to use
opacity: 0.4,
cursor: 'move',
start: function(e, ui) {
var currentlist = $('.draghandler').map((i, el) => el.id).get();
$(e.target).closest('.wrapper').data('currentlist', currentlist);
$('#currentlist').html(currentlist);
},
update: function(e, ui) {
var currentlist = $(e.target).closest('.wrapper').data('currentlist');
var newsortedlist = $('.draghandler').map((i, el) => el.id).get();
$('#newsortedoutput').html(newsortedlist);
// Commented as the AJAX call will cause an error in an SO snippet...
/*
$.post('/megrendelesek/sortmouse.php', {
'currentid': currentlist,
'sortid': newsortedlist
}, function(theResponse) {
$('#responsefromserver').html(theResponse);
});
*/
}
});
$(".wrapper").disableSelection();
$(".draghandler").disableSelection();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://code.jquery.com/ui/jquery-ui-git.css" />
<div class="wrapper">
<div class="item">
Foo
<div class="draghandler" id="item-1">DRAG</div>
</div>
<div class="item">
Foo
<div class="draghandler" id="item-2">DRAG</div>
</div>
<div class="item">
Foo
<div class="draghandler" id="item-3">DRAG</div>
</div>
</div>
<br />
<div id="currentlist"></div>
<div id="newsortedoutput"></div>
<div id="responsefromserver"> </div>

Related

Sorting with isotope from external json rendered with handlebars

Can't seem to get Isotope sort to work :(
On the client side of a webpage I'm displaying data which comes from an external json with a template using handlebars.js.
I want the users to be able to sort, filter and search the data that is displayed. I've seen that with Isotope can this be achieve successfully. I did manage to get filtering to work.
However I'm stuck with sorting in targeting the class of the object with the getSortData option which value comes from the json.
Example of the JSON structure with the price:
Here is the code trying to sort by price, first my menu:
<ul id="sort">
<li>original order</li>
<li>number</li>
</ul>
Then my handlebars template, where I want to reach the p.class = number:
<div id="mcContainer"></div>
<script id="mcTemplate" type="text/x-handlebars-template">
{{#each this}} {{#annoncer}}
<article class="mc_item {{category}} {{year}}">
<a data-single href="{{id}}">
<h3>{{brand}} {{model}}</h3>
<img src={{images.0.small}} />
<h4 class="mc_aar">ÅR: {{year}}, {{km}} km</h4>
<p>{{category}}</p>
<p class="mc_pris number">{{price}},-</p>
<hr>
</a>
</article>
{{/annoncer}} {{/each}}
</script>
And my javascript file:
(function ($) {
"use strict";
// javascript code here. i.e.: $(document).ready( function(){} );
$(document).ready(function ($) {
var $container = $('#mcContainer');
$.ajax({
url: "http://diegovega.dk/kea/2semester/json-eks/json-eks.json",
method: "GET",
dataType: 'json',
success: function (response) {
var template = $('#mcTemplate').html();
var renderer = Handlebars.compile(template);
var result = response;
$('#mcContainer').html(renderer(result));
runIsotope();
}
});
function runIsotope() {
var $items = $('.mc_item');
$items.isotope({})
$items.isotope('reloadItems')
.isotope({
itemSelector: '.mc_item',
layoutMode: 'fitRows',
fitRows: {
gutter: 20
},
getSortData: {
number: '.number parseInt'
},
});
// Sort based on price
$('#sort').on('click', function () {
if ($(this).hasClass('checked')) {
$(this).removeClass('checked');
.isotope({
sortBy: 'original-order'
});
} else {
$('#sort').removeClass('checked');
var sortValue = $(this).attr('data-sort-value');
console.log($(this).attr('data-sort-value'));
.isotope({
sortBy: sortValue
});
$(this).addClass('checked');
}
});
} //RUN ISOTOPE
}); // END DOCUMENT READY
})(jQuery); // END use strict
Any help is greatly appreciated :)
Initialize Isotope on the container, not the items
Use data-sort attribute on the links click

html2canvas render high res image

I want to render 4k high res images using html2canvas but it not render.
please advise.
var element = $("#html-content-holder"); // global variable
var getCanvas; // global variable
$("#btn-Preview-Image").on('click', function () {
html2canvas(element, {
onrendered: function (canvas) {
$("#previewImage").append(canvas);
getCanvas = canvas;
}
});
});
$("#btn-Convert-Html2Image").on('click', function () {
var imgageData = getCanvas.toDataURL("image/png");
// Now browser starts downloading it instead of just showing it
var newData = imgageData.replace(/^data:image\/png/, "data:application/octet-stream");
$("#btn-Convert-Html2Image").attr("download", "your_pic_name.png").attr("href", newData);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="https://files.codepedia.info/files/uploads/iScripts/html2canvas.js"></script>
</head>
<body>
<div id="html-content-holder">
<img
width="400" height="auto"src="https://www.wallpaperup.com/uploads/wallpapers/2016/06/24/991808/9ab236cccae5470451c20329ca43ec6b-1000.jpg">
</div>
<input id="btn-Preview-Image" type="button" value="Preview"/>
<br/>
<h3>Preview :</h3>
<div id="previewImage">
</div>
preview not working please advise.
thank you

Mootools delete event not working after Drag + droppable event

I need to fix a few things here:
The delete button does not work after the drop event. The delete only works on items not in the dropzone. Not sure what is wrong here.
also, it would be better to add the delete button to each dropped item instead of cloning it.
I need to be able sort the dropped items.
sortable is not included in the current demo below.
HTML:
<div id="items">
<div class="item"><span>Item 111111</span>
<span class="delete"><button>Delete Line</button></span>
</div>
<div class="item"><span>Item 222222</span>
<span class="delete"><button>Delete Line</button></span>
</div>
<div class="item"><span>Item 333333</span>
<span class="delete"><button>Delete Line</button></span>
</div>
</div>
<div style="" id="cart">
<div class="info">Drag Items Here</div>
</div>
<div class=""><span>test delete works here but not after a drag event</span>
<span class="delete"><button>Delete Line</button></span>
</div>
Here is the DomReady event:
$$('.item').addEvent('mousedown', function (event) {
event.stop();
// `this` refers to the element with the .item class
var item = this;
var clone = item.clone().setStyles(item.getCoordinates()).setStyles({
opacity: 0.7,
position: 'absolute'
}).inject(document.body);
var drag = new Drag.Move(clone, {
droppables: $('cart'),
onDrop: function (dragging, cart) {
dragging.destroy();
item.removeClass('item');
item.addClass('item_dz');
if (cart != null) {
item.clone().inject(cart);
cart.highlight('#4679BD', '#FFF');
item.removeClass('item_dz');
item.addClass('item');
}
},
onEnter: function (dragging, cart) {
cart.tween('background-color', '#FFF04F');
},
onLeave: function (dragging, cart) {
cart.tween('background-color', '#FFF');
},
onCancel: function (dragging) {
dragging.destroy();
}
});
drag.start(event);
});
$$('.delete').addEvents({
click: function () {
this.getParent().destroy();
this.destroy();
},
mouseover: function () {
this.tween('opacity', '1');
this.getPrevious(['.item_dz']).fade(0.3);
this.getPrevious(['.item_dz']).tween('background-color', '#fff', '#f00');
},
mouseleave: function () {
this.tween('opacity', '0.5');
this.getPrevious(['.item_dz']).fade(1);
this.getPrevious(['.item_dz']).tween('background-color', '#f00', '#fff');
}
});
Current Jsfiddle code demo
Please help...
There are 2 things you are missing.
The first is that this code starting here
$$('.item').addEvent('mousedown', function (event){
event.stop();
is preventing this one to fire (since .delete is descendent of .item):
$$('.delete').addEvents({
click: function () {
this.getParent().destroy();
this.destroy();
},
This can be fixed by adding this line between the two I posted, to ignore the drag if the click was in the button
if (event.target == this.getParent().getElement('.delete button')) return;
The second problem is that you need to delegate the click event on the dropped element. You could do this like:
window.addEvent('click:relay(.delete)', function (){
this.getParent().destroy();
this.destroy();
})
So changing that you get this: http://jsfiddle.net/m6xDt/
About the sorting part I didn't get what you wanted. If you explain that better I will try to help with that also.
To make the cart sortable:
Start a new sortable class and then add each new item to it inside the onDrop event:
var mySortables = new Sortables('', {
clone: true,
opacity: 0.7
});
and then inside the onDrop:
mySortables.addLists(cart);
http://jsfiddle.net/m6xDt/

clearInterval() not working after stop button click

i am trying to Refresh div using java script . setInterval() and clearInterval (), its working fine, but i want stop Refresh process for single div when i clicked stop button ..clear Interval not working herer
<script type ="text/javascript">
$(document).ready(function () {
$('.output').click(function () {
var id = $(this).closest('.g').attr('id');
Go(id);
})
$('.bt').click(function () {
var id = $(this).closest('.g').attr('id');
stop(id)
});
function Go(id) {
id = setInterval(function () {
Chat_msg('Ch04', id, u)
}, 3000);
};
function stop(id) {
clearInterval(id);
}
})
</script>
</head>
<body>
<div id="a" class='g'>
<div class="output"></div>
<input id="Button1" type="button" value="stop" class="bt" />
</div>
<div id="b">
<div class="output"></div>
<input id="Button2" type="button" value="stop" class="bt"/>
</div>
<div id="c">
<div class="output"></div>
<input id="Button3" type="button" value="stop" class="bt" />
</div>
</body>
</html>
Use a global variable for your interval.
var interv = null;
interv = setInterval(function { ... }, 5000);
$('#btn').on('click', function(){
if (interv) clearInterval(intev);
})
It's likely the reference you associated with setInterval is not within the scope of your stop-button handler.
$("#start").on("click", function(){
var interv = setInterval(function(){ /*...*/ }, 1000);
});
$("#stop").on("click", function(){
clearInterval(interv);
});
In the code above, our interv variable is not within the scope of our #stop button handler. We could change this by moving it up another level:
var interv;
$("#start").on("click", function(){
interv = setInterval(function(){ /*...*/ }, 1000);
});
$("#stop").on("click", function(){
clearInterval(interv);
});
Now both handlers have access to the interv variable.
Looks like a combination of a scoping issue, and interchangeably using id DOM attributes with setInterval response values.
<script type ="text/javascript">
$(document).ready(function () {
var timeouts = {};
$('.output').click(function () {
var id = $(this).closest('.g').attr('id');
go(id);
});
$('.bt').click(function () {
var id = $(this).closest('.g').attr('id');
stop(id);
});
function go(id) {
timeouts[id] = setInterval(function () {
Chat_msg('Ch04', id, u)
}, 3000);
}
function stop(id) {
clearInterval(timeouts[id]);
}
});
</script>
The way I have gone about this in the past is using a function that uses a set timeout to call itself.
var stop = false
function caller () {
if (stop === true){
//do something
setTimeout(caller() , 1000);
}
else{
//do something after button has been click and stop is set to true
}
}

How to use HTML5 drag and drop in combination with KnockoutJS?

I can't seem to bind to html5 drag and drop events.
Here's an example of from a template:
<script id="tabsTemplate" type="text/html">
<div class="dropzone" for="tab"
data-bind="event:{dragover: function(event){event.preventDefault();},
dragenter: function(event){event.target.addClass('dragover'); event.preventDefault();},
dragleave: function(event){event.target.removeClass('dragover'); event.preventDefault();}}
drop: function(event){console.log('blahblah!')}"></div>
<h1 class="tab" draggable="true"
data-bind="attr: {selected: $data.name === $item.selected()},
click: function(){$item.selected($data.name)},
event:{ dragstart: function(event){console.log('blah!!')},
dragend: function(event){document.getElementsByClassName('dragover')[0].removeClass('dragover')}}">
${name}
<img src="icons/close-black.png" class="close button" role="button"
data-bind="click: function(e){$item.close($data)}">
</h1>
</script>
What I have should work as expected... and it does as long as I make them normal inline ones. However, then the other bindings don't work!
I am getting this error message:
Uncaught SyntaxError: Unexpected token '||' jquery-tmpl.js:10
What's going on here? Is there something I'm doing wrong?
OK, I have worked it out. It seems I missed in the documentation where it said that in knockout, by default it makes all events prevent default / return false. So all I had to do was make my dragstart handler return true, and now it works. Phew!!
For those (like me) who need a SSCCE working; the solution follow's [cybermotron] suggestion, also fixes an issue where handlers expect prarameters data and event.
http://jsfiddle.net/marrok/m63aJ/
HTML
<script type="application/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<ul id="people" data-bind='template: { name: "personTmpl", foreach: people }'>
</ul>
<div class="trash" data-bind ="visible:dragging, event:{
dragover: function(data, event){
event.preventDefault();
},
drop: function(data, event){
console.log('trash', $root.drag_start_index())
$root.trash($root.drag_start_index())
event.preventDefault();
}
}"> <span>DELETE</span> </div>
<script id="personTmpl" type="text/html">
<li class="draggable" draggable="true" data-bind="event:{
dragstart: function(data, event){
$(event.target).addClass('dragSource')
$root.drag_start_index($index());
return $(event.target).hasClass('draggable');},
dragend: function(data, event){
$root.drag_start_index(-1);
$(event.target).removeClass('dragSource')
return true;
},
dragover: function(data, event){event.preventDefault();},
dragenter: function(data, event){
$root.drag_target_index($index());
var element = $(event.target)
if(element.hasClass('draggable'))
element.toggleClass('dragover');
event.preventDefault();
},
dragleave: function(data, event, $index){
var element = $(event.target)
if(element.hasClass('draggable'))
element.toggleClass('dragover');
event.preventDefault();
},
drop: function(data, event){
$(event.target).removeClass('dragover');
console.log('swap', $root.drag_start_index(), $root.drag_target_index() )
$root.swap($root.drag_start_index(), $root.drag_target_index())
}
}">
<span data-bind='text: name'></span>
</li>
</script>
Knockout
var Person = function(name) {
this.name = ko.observable(name);
};
var PeopleModel = function() {
var self = this;
self.drag_start_index = ko.observable();
self.drag_target_index = ko.observable();
self.dragging = ko.computed(function() {
return self.drag_start_index() >= 0;
});
self.people = ko.observableArray([
new Person("Oleh"), new Person("Nick C."), new Person("Don"), new Person("Ted"), new Person("Ben"), new Person("Joe"), new Person("Ali"), new Person("Ken"), new Person("Doug"), new Person("Ann"), new Person("Eve"), new Person("Hal")]);
self.trash = function(index) {
self.people.splice(index, 1)
}
self.swap = function(from, to) {
if (to > self.people().length - 1 || to < 0) return;
var fromObj = self.people()[from];
var toObj = self.people()[to];
self.people()[to] = fromObj;
self.people()[from] = toObj;
self.people.valueHasMutated()
}
};
ko.applyBindings(new PeopleModel());​
You might have the same problem as mentioned here, although it refers to nested templates:
Warning
If you are passing templateOptions to the template binding from a nested template (so, specifying a template binding from within a template), then pay special attention to your syntax. You will encounter a problem, if your binding looks like this:
<div data-bind="template: { name: 'items', data: newItems, templateOptions: { header: “New Items!”}}"></div>
The jQuery Templates plugin gets confused by the }} at the end of your binding, since that is part of its syntax. Adding a space between your braces will work fine. Hopefully this prevents someone from a little unnecessary frustration.
<div data-bind="template: { name: 'items', data: newItems, templateOptions: { header: “New Items!”} }"></div>