Getting DIV ID on AJAX loaded content - html

I have div with unique id and I'm trying to get that div id with jQuery
<div class="quantity" id="UNIQUE_ID">Quantity</div>
Everything works good, but after loading div with ajax - I just can't get id from loaded div.
$('.quantity').click(function() {
$.post('quantity.php', { id: $(this).attr('id') }, function(output) {
$(this).html(output);
});
});
Any ideas?

This should work
$('.quantity').click(function() {
var that = this;
$.post('quantity.php', { quantityId: $(that).attr('id') }, function(data) {
$(that).html(data);
});
});
But this is how i'd write it
<div class="quantity" data-id='<?=$unique_id?>'>
Quantity
</div>
$('.quantity').on('click', function() {
var that = this;
$.post('quantity.php', { quantityId: $(that).data('id') }, function(data) {
$(that).html(data);
});
});
And for dynamic divs
<div class="quantity" data-id='<?=$unique_id?>'>
Quantity
</div>
$(document).on('click', '.quantity', function() {
var that = this;
$.post('quantity.php', { quantityId: $(that).data('id') }, function(data) {
$(that).html(data);
});
});

The onclick binding to your div won't work once the div has been refreshed (it binded on document.ready() right?). The solution will be either to rebind the function to your element every time you change it (a bad one) or use the on() function of jquery. Example code:
$(document).on('click', '.quantity', function(){
var id = $(this).attr('id');
$.post('quantity.php', { quantityId: id }, function(data){
$('#'+ id).html(data);
});
});
UPDATE: As discussed in comments, the on method should bind to the document as a whole and not the the class to actually work as the deprecated live() method.

Related

Is there a way to add a behavior(s) dynamically?

I want to add a behavior after a component/behavior already loaded or a certain function that will add a behevaior to its components.
Something like this:
<script>
// samplebehavior.html file
// this is the behavior file
samplebehavior = {
testAlert: function(){
alert('test');
}
};
</script>
// my-component.html
<script>
Polymer({
is: "my-component",
test: function() {
url = "samplebehavior.html";
var importHTML = new Promise(function(resolve, reject) {
Polymer.Base.importHref(url, function(e) {
resolve(e.target);
}, reject);
});
importHTML.then(function(element) {
// add a behavior here
// I know this script does not work
this.push('behaviors', samplebehavior);
});
}
});
</script>
So that I can access the testAlert() function.
How to I add a behavior dynamically?
To the best of knowledge it's not possible.
Behaviors are mixed in with the element definition when the prototype is built.
What you could do is generate the behaviors array dynamically
var behavior = {
properties: {
smth: {
value: 'initial value'
}
}
}
Polymer({
is: 'my-elem',
behaviors: getBehaviors()
});
function getBehaviors() {
return [ behavior ];
}
Remember though that getBehaviors will only ever be called once. After that you won't be able to change behaviors of your elements.
It's ugly but you can copy all members of your behavior in your object
<script>
// samplebehavior.html file
// this is the behavior file
samplebehavior = {
testAlert: function(){
alert('test');
}
};
</script>
// my-component.html
<script>
Polymer({
is: "my-component",
test: function() {
url = "samplebehavior.html";
var importHTML = new Promise(function(resolve, reject) {
Polymer.Base.importHref(url, function(e) {
resolve(e.target);
}, reject);
});
importHTML.then(function(element) {
for (let member in samplebehavior) {
this[member] = samplebehavior[member];
}
});
}
});
</script>
Or maybe you can call the internal method _prepBehavior() https://github.com/Polymer/polymer/blob/ff6e884ef4f309d41491333860a8bc9c2f178696/src/micro/behaviors.html#L111
But i don't know if that can do side effects
<script>
// samplebehavior.html file
// this is the behavior file
samplebehavior = {
testAlert: function(){
alert('test');
}
};
</script>
// my-component.html
<script>
Polymer({
is: "my-component",
test: function() {
url = "samplebehavior.html";
var importHTML = new Promise(function(resolve, reject) {
Polymer.Base.importHref(url, function(e) {
resolve(e.target);
}, reject);
});
importHTML.then(function(element) {
this.push('behaviors', samplebehavior);
this._prepBehaviors();
});
}
});
</script>
With introduction to new value for lazyRegister setting this has become partially possible.
By partially i mean you can only do this if you can edit the code of the element in which you want to add the behavior.
Three changes you'll require to add behavior dynamically are
Set lazyRegister setting to max
window.Polymer = {
lazyRegister:"max"
};
Just like #tomasz suggested, in the element you want to add behavior dynamically add behaviors using a function. This is so, because we won't be able to access the element from where we'll try to add new behavior dynamically(atleast i was not able to).
Polymer({
.
.
behaviors: getBehavior(),
.
.
});
function getBehavior(){
var myArr = [myBehavior];
document.addEventListener('add-behavior',function(e){
debugger;
myArr.push(e.detail);
});
return myArr;
}
From the element where you want to dynamically add the behavior use beforeRegister callback to dispatch an event adding the new behavior object
beforeRegister: function(){
var event = new CustomEvent('add-behavior',{
detail:{
func: function(){console.log(this.myProp,"!")}
}
});
document.dispatchEvent(event);
}
Here's a plunkr for working example.

What is the angular way for cloning buttons?

I have a follow button for a particular user that should change its text to followed after it's clicked and vice versa. This follow button can show up in different modules on the page. When it's clicked, the follow button for this particular users should update in all of these modules. However, the buttons are in different scopes. What is the angular way of making sure the cloned buttons are in the same state?
My current solution is to use an universal jQuery selector to update all the buttons on click.
You should store the state in a service.
example:
app.factory('SharedService', function() {
this.buttonState = null;
this.setButtonState= function(value) {
this.buttonState = value;
}
this.getButtonState= function() {
return this.buttonState ;
}
return this;
});
Read: AngularJS Docs on services
or check this Egghead.io video
You can use $rootScope.$broadcast to do this. when any of button gets clicked you fire an event using $rootScope.$broadcast and then listen to it using $scope.$on and toggle the status of buttons. and you can also update state inside the service too, so you can fetch current value later if needed.
See the below example:
var app = angular.module('app', []);
app.controller('ctrl1', function($scope) {
$scope.label1 = "First Button";
});
app.controller('ctrl2', function($scope) {
$scope.label2 = "Second Button";
});
app.controller('ctrl3', function($scope) {
$scope.label3 = "Third Button";
});
// updating state in service too.
app.service('fButtons', function($rootScope) {
var buttonState = false;
this.getCurrentState = function() {
return buttonState;
};
this.updateCurrentState = function() {
buttonState = !buttonState;
};
});
app.directive('followButton', function($rootScope, $timeout, fButtons) {
return {
restrict: 'E',
scope: {
label: '='
},
template: '<button ng-click="buttonClick()" ng-class="{red: active}">{{label}}</button>',
controller: function($scope) {
$scope.$on('button.toggled', function() {
$scope.active = !$scope.active;
});
$scope.buttonClick = function() {
fButtons.updateCurrentState();
$rootScope.$broadcast('button.toggled');
console.log(fButtons.getCurrentState());
}
}
};
});
.red {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="ctrl1">
<follow-button label="label1"></follow-button>
</div>
<hr/>
<div ng-controller="ctrl2">
<follow-button label="label2"></follow-button>
</div>
<hr/>
<div ng-controller="ctrl3">
<follow-button label="label3"></follow-button>
</div>
</div>
see console for service state.
$broadcast docs

jquery sidebar putting next to each other

I have put together a sidebar with hover-delay animation, but I can't seem to exactly copy the column to place next to the first. This is my first problem.
The second is that I would like to use the jspanel plugin, so that a dragable window will pop up when I click on a sub-item in the sidebar.
I hope this can be brought to a working state.
Thank you very much for responses in advance!
Here's [a link] (http://jsfiddle.net/chrisoutwright/tc4d9t6d/)!
$('#categories').corner("top keep");
$(document).ready(function(){
$("#foo").click(function(){
$().jsPanel().show();
});
});
$( "#navigation ul.sub-level" ).corner("").css( "border", "3px double blue" );
jQuery.fn.hoverWithDelay = function(inCallback,outCallback,delay) {
this.each(function() {
var timer, $this = this;
$(this).hover(function(){
timer = setTimeout(function(){
timer = null;
inCallback.call($this);
}, delay);
},function() {
if (timer) {
clearTimeout(timer);
timer = null;
} else
outCallback.call($this);
});
});
};
var hovering = {mainMenu: false, categories: false};
function closeSubMenus() {
$('ul.sub-level').css('display', 'none');
}
closeSubMenus();
function closeMenuIfOut() {
setTimeout(function(){
if (!hovering.mainMenu && !hovering.categories) {
$('#navigation').fadeOut('fast',closeSubMenus);
}
},100);
}
$('ul.top-level li').hoverWithDelay(function() {
$(this).find('ul').show();
}, function() {
$(this).find('ul').fadeOut('fast', closeMenuIfOut);
}, 500);
$('#categories').hoverWithDelay(function() {
$('#navigation').show();
hovering.categories = true;
},
function(){
hovering.categories = false;
closeMenuIfOut();
},500);
$('#navigation').hover(function() {
hovering.mainMenu = true;
}, function() {
hovering.mainMenu = false;
});
I can see at least one error in line 4 where you try to generate/open the jsPanel.
Which jsPanel version do you use? Version 1.x or Version 2.x? The two versions differ on how to use the jsPanel() command.
version 1.x: $( selector ).jsPanel( config );
version 2.x: $.jsPanel( config );
Do you get any error messages?

Inserting a block as a last child inside a selected tag using JQuery

I am working on a commenting module which is auto-refreshed every 5 seconds. The code is like this:
jQuery Part:
$(document).ready(function(){
var refreshId = setInterval(function(){
$.getJSON('process.php?fooId=1', function(data){
$.each(data, function(key,val){
$('#abc:last-child').prepend('<div>some text</div>');
});
});
}, 5000);
});
HTML part:
<div id="abc"></div>
What I need is, when someone comment, the comment must append into the div (id="abc").
Any solutions?
use insertAfter()
official Documentation : http://api.jquery.com/insertAfter/
$('<div>some text</div>').insertAfter($('#abc:last-child'));
Try this one:
$(document).ready(function(){
var refreshId = setInterval(function(){
$.getJSON('process.php?fooId=1', function(data){
$.each(data, function(key,val){
$('#abc').last().append(val);
});
});
}, 5000);
});

Mootools set className

I have got a list of events, onClick the elements expand and they SHOULD do the opposite on a second click. That is the part of my little script that does not work. WHY NOT??
window.addEvent('load',function() {
$$('.eventlistitempassive').each(function(item) {
item.addEvent('click',function() {
$$('.eventlistitemactive').set('class', 'eventlistitempassive block');
item.set('class', 'eventlistitemactive block');
});
});
$$('.eventlistitemactive').each(function(item) {
item.addEvent('click',function() {
item.set('class', 'eventlistitempassive block');
});
});
});
See the script in action at
http://hoch3.cc/index.php/aktuelles.html
Thanks,
PB
how about
window.addEvent('domready', function(){
$$('.eventlistitempassive').addEvent('click', function(){
this.toggleClass('bar');
});
});
http://jsfiddle.net/tofu/aUPtw/
The problem here is that there is no active element on window.load, so your second selector to add click events on each active item is not finding anything. So try this:
window.addEvent('load',function() {
$$('.eventlistitempassive').each(function(item) {
item.addEvent('click',function() {
$$('.eventlistitemactive').set('class', 'eventlistitempassive block');
item.set('class', (item.get('class') == 'eventlistitemactive block' ? 'eventlistitempassive block') : 'eventlistitemactive block');
});
});
});
greatings from austria ;)