I'm trying to achieve a file drag-and-drop with knockout.js.
This is my html:
<div type="text" id="filedrag" class="" data-bind="event: {drop: function (data,e) { $root.insertFile(e,data);} }">
<div id="messages"></div>
</div>
And this my JS:
self.insertFile = function(e, data) {
console.log("insertfile called");
var files = e.target.files || e.dataTransfer.files;
console.log(files);
};
I copied the code from a jsfiddle. I don't quite see the difference between that one and mine. What am I doing wrong?
This is because you need to have a dragover event where you cancel the default behaviour.
The cancellation of the dragover event is needed to allow drop.
See https://developer.mozilla.org/en-US/docs/Web/Events/dragover.
I have created a fiddle with your code, updated with an dragover event where you cancel default behaviour.
Fiddle: http://jsfiddle.net/JBJd2/10/
HTML:
<div type="text" id="filedrag" class="drop_zone" data-bind="event: {
drop: function (data,e) { $root.insertFile(e,data);},
dragover: function(data, e){ $root.dragover(e);}
}">
<div id="messages"></div>
</div>
JS:
self.insertFile = function(e, data) {
e.preventDefault();
console.log("insertfile called");
var files = e.target.files || e.dataTransfer.files;
console.log(files);
};
self.dragover = function(e){
e.preventDefault();
}
Related
I have tried a few things currently from what I could search online however I, unfortunately, haven't found anything.
enter image description here
I would like to disable the pagination when I click on the replace button. Since it's loading with a spinner and there is a wait I thought it would make sense to disable it but not remove it. I know how to remove, both on the css side and angularjs. However, in all honesty, I am unsure how to disable this particular feature compared to other works that I have done.
HTML:
<button class="btn btn-blue" ng-click="handleLoadAndDeactivate()"
ng-show="'Load' == importAction && 0 == errors"
title="Load">
Replace
</button>
AngularJS (Button):
$scope.handleLoadAndDeactivate = function () {
$scope.onCompleteData.targetBody.withDeactivation = true;
onComplete($scope.onCompleteData, $scope.handleLoadAndDeactivateCompleted);
};
AngularJS (Table):
$scope.operationsPreloadCompletedTableOptions = new NgTableParams({}, {
dataset: importLog
});
html
Here's how you could achive this:
(function () {
"use strict";
const app = angular.module("app", []);
app.controller("app.AppCtrl", ($scope, $timeout) => {
$scope.disablePagination = false;
$scope.handleReplace = () => {
$scope.disablePagination = true;
//Your replace logic goes here
$timeout(() => {
$scope.disablePagination = false;
}, 2000);
};
}
);
})();
body {
margin: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="app" ng-controller="app.AppCtrl">
<button ng-disabled="disablePagination"><</button>
<button ng-disabled="disablePagination">1</button>
<button ng-disabled="disablePagination">2</button>
<button ng-disabled="disablePagination">></button>
<button ng-click="handleReplace();">Replace</button>
</div>
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/
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
}
}
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>
I've got a jQuery code, which
$("a.reply").click(function() {
//code
});
When I click the link with .reply class the first time, nothing happens. The second time I click, the code inside the click function works.
The link is being inserted on the page using PHP from a mysql database. so it's not being inserted dynamically.
Why is this happening? Any solution?
The BadASS Code:
$(function(){
//TextArea Max Width
var textmaxwidth = $('#wrapper').css('width');
//Initialize Focus ids To Different Initially
var oldcommentid = -1;
var newcommentid = -2;
//End Of initialization
$("a.reply").click(function() {
newcommentid = $(this).attr('id');
if (newcommentid == oldcommentid)
{
oldcommentid=newcommentid;
$("#comment_body").focus();
}
else
{
$('#comment_form').fadeOut(0, function(){$(this).remove()});
var commetformcode = $('<form id="comment_form" action="post_comment.php" method="post"><textarea name="comment_body" id="comment_body" class="added_comment_body" rows="2"></textarea> <input type="hidden" name="parent_id" id="parent_id" value="0"/> <div id="submit_button"> <input type="submit" value="Share"/><input type="button" id="cancelbutton" value="Cancel"/></div></form>');
commetformcode.hide().insertAfter($(this)).fadeIn(300);
//
var id = $(this).attr("id");
$("#parent_id").attr("value", id);
oldcommentid=newcommentid;
//dynamicformcreation function
dynarun();
//
}
return false;
});
dynarun();
function dynarun()
{
//Form Re-Run Functions
$('#comment_body').elastic();
texthover();
$("#comment_form input, select, button").uniform();
textareasizer();
$("#comment_body").focus();
$("abbr.timestamp").timeago();
return false;
}
//TextArea Resizer Function
function textareasizer(){$("#comment_body").css('max-width', textmaxwidth);return false;}
//Other Miscellaneous Functions
$('.comment-holder').hover(
function(event) {
$(this).addClass('highlight');
},
function(event) {
$('.comment-holder').removeClass('highlight');
}
);
function texthover()
{
$('.added_comment_body').hover(
function(event) {
$(this).parent().parent().addClass('highlight');
},
function(event) {
$('.comment-holder').removeClass('highlight');
}
);
return false;
}
});
This is a longshot, but are you running some sort of tracking script? Like webtrends or coremetrics (or even some of your own script, that's globally looking for all clicks)? I ran into a similar problem a while ago, where the initial-click was being captured by coremetrics. Just a thought.
Does it still happen if you comment out all your code and simply have an alert("hi") inside the click function?
Update
I think Sarfaz has the right idea, but I would use the document ready function like so
$(document).ready(function(){
$("a.reply").click(function() {
//code
});
});
I just ran into same problem and I resolved my problem by removing:
<script src="bootstrap.js"></script>
you can use bootstrap.min.js
Use Inline CSS for hiding div and use JS/jQuery to show . This way Jquery Click Event will Fire On First Click
<div class="about-block">
<div class="title">About us</div>
<div class="" id="content-text" style="display:none;">
<p>Show me.</p>
</div>
</div>
<script>
var x = document.getElementById("content-text");
jQuery( '.about-block' ).click(function() {
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
});
</script>