mootools load content with function - html

I am using mootools and i want to load in a div (named response) content.
The div content i pass in javascript with $('response').set('html', content) where content is variable. in the content variable i have some html code with buttons and want to create a event handle ( click ).
the content I load with a json request and pass to the element:
<div id="undo">
<ul>
<li> <button value="1">foo</button> </li>
<li> <button value="2">bar</button> </li>
</ul>
</div>
my javascript looks like
$('undo').addEvents({
'click:relay(button)': function(ev, element){
alert('a button clicked!');
}
});
but I don't know why the event didn't work.
I think the problem is that $('undo') doesn't exist when the dom object is ready but i don't know how to fix this.

Delegate further up the dom tree to an element that is there at the time of domready block running. eg, if you have <div id=content>... </div> (or response if it's static)
document.id('content').addEvents({
'click:relay(#undo button)': function(event, element){
event.stop();
console.log(element.get('value'));
}
});
given that you inject your data there later on, this will work fine.

Related

JQuery populate div with link content but also need to move (like anchor link) to area where div located

I have unordered list of links. Using JQuery, when clicked, the link's contents (a div with image and text) are loaded into the section specified. This all works beautifully. But I'm wondering how to also get the onclick function to move the view to the div's location on the page similarly to how anchor tag works. Here is the site where you can see the div being populated, but not moving down to view it. https://www.thecompassconcerts.com/artists.php
My JQuery knowledge is not awesome (I'm being generous).
I followed Osama's suggestion to add event listener and I got almost correct results. Upon first click...contents are loaded but do not move. But on every successive click, it functions perfectly: Contents loaded and move to div (like an anchor link) works! BUT...not on Safari or Mobile Safari.
Here is my jQuery. I assume if first click is not working that I must add listener before the first click?? Can the event listeners be added on page load BEFORE the function to prevent default click, etc.?
<script>
// BEGIN FUNCTION TO CAPTURE AND INSERT CONTENT
$(document).ready(function () {
// PREVENT DEFAULT LINK ACTION
$('.bio').click(function (e) {
e.preventDefault();
// ADD LISTENER TO EACH ITEM BY CLASS
var list = document.getElementsByClassName("bio");
for (let i = 0; i < list.length; i++) {
list[i].onclick = moveToDiv;
}
// FUNCTION TO MOVE TO LOCATION
function moveToDiv() {
document.location = "#performbio";
}
// STORE the page contents
var link = $(this).attr("href");
// load the contents into #performbio div
$('#performbio').load(link);
});
});
</script>
Here is the HTML with links in unordered list
<!-- CONTRIBUTING ARTISTS LIST AND BIOS -->
<section id="artists">
<h2>Contributing Artists</h2>
<ul class="cols">
<li><a class="bio" href="performers/first-last.html">First Last</a></li>
<li><a class="bio" href="performers/first-last.html">First Last</a></li>
<li><a class="bio" href="performers/first-last.html">First Last</a></li>
</ul>
</section>
Here is HTML of Section where code is being inserted by function
<!-- Performer Bios Dynamically updated -->
<section id="performbio">
</section>
Here is div contents that are being inserted
<div class="artistbio">
<p class="artistname">First Last</p>
<img class="artistimg" src="performers/img/name.jpg">
<p>lots of text here</p>
</div>
If I understand it right, you want to scroll to the section where the details appear on clicking any item in the list but through js and not HTML. In that case, you would add an onclick listener on to the list elements like so:
listElement.onclick = moveToDiv;
The function:
function moveToDiv() {
document.location = "#performbio";
}
A simple way to add a listener to all of the elements:
var list = document.getElementsByClassName("bio");
for (let i = 0; i < list.length; i++) {
list[i].onclick = moveToDiv;
}
For the edited post, you need to move the function definition out of the document.ready function. you would change the script to:
// FUNCTION TO MOVE TO LOCATION
function moveToDiv() {
document.location = "#performbio";
}
$(document).ready(function () {
// PREVENT DEFAULT LINK ACTION
$('.bio').click(function (e) {
e.preventDefault();
// ADD LISTENER TO EACH ITEM BY CLASS
var list = document.getElementsByClassName("bio");
for (let i = 0; i < list.length; i++) {
list[i].onclick = moveToDiv;
}
// STORE the page contents
var link = $(this).attr("href");
// load the contents into #performbio div
$('#performbio').load(link);
});
});
Another Solution: Using scrollIntoView
First, get all the elements into a variable using querySelectorAll
var elements = document.querySelectorAll(".bio");
Then create a function, for the scrolling part:
function scroll(element) {
element.scrollIntoView();
}
Then just add the onclick listener:
for (let i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', function() {
scroll(elements[i]);
});
}
I found it very frustrating to try to accomplish these two tasks so instead of a jQuery solution I opted for a CSS solution.
I populated my DIV with all the php includes, gave them unique id's for the anchors to work and then used CSS to hide them by default until clicked and it works like a charm....shows only what I need to show and goes there like an anchor is supposed to.
I must thank Ghost for all of your help and efforts to try and solve this via jQuery. You were very kind and generous.
Here is the code I used:
My collection of links.
<li><a class="bio" href="#artist-name1">Name 1</a></li>
<li><a class="bio" href="#artist-name2">Name 2</a></li>
which anchors to these divs
<div class="bio-container" id="artist-name1">
<?php include('performers/name-lastname.html'); ?>
</div>
<div class="bio-container" id="artist-name2">
<?php include('performers/name-lastname.html'); ?>
</div>
Then I use this CSS to hide those divs until the anchors are clicked.
I'm using [id*="artist-"] to target only links with such text...very easy. Not ideal for a massive list...but mine is not so large so it will do for this situation.
[id*="artist-"] {display: none;}
[id*="artist-"]:target {display: block;}

Data binding for dynamically generated HTML in Polymer?

When I write the following inside my <template>-tag, everything works fine:
<ul id="breadcrumbList" class="breadcrumb">
<li><a on-click="{{breadcrumbClick}}">{{overviewName}}</a></li>
</ul>
I dynamically generated a new <li>-element of the same structure, like this:
crumb = document.createElement("li");
crumb.innerHTML = '<a on-click="{{breadcrumbClick}}">'+category+'</a>';
But when I click this element, the event-handler isn't called.
The event-handler looks like this:
breadcrumbClick: function(event, detail, sender) {
/*reaction*/
}
I did not find any documentation about whether it's possible or impossible to use data binding for dynamically generated content.
This is possible with injectBoundHTML(). We haven't documented it yet, but you can see the method signature and demo here: https://github.com/Polymer/docs/issues/607
Example:
<li id="myli></li>
this.injectBoundHTML('<a on-click="{{breadcrumbClick}}">...</a>', this.$.myli);

DOM manipulation by angularjs direction

I read that Angularjs directives require a different approach than jquery. I am new to angularjs, so it will be great if somebody can explain how to use directives for this simple example. If you click on bottom div, then it moves (re-parent) the top image to the bottom div. I could add this jquery code on ng-click... but is there a better way?
JQUERY INTENT:
$("#bottom").click(function(){
$("#myimage").appendTo("#bottom");
});
ANGULARJS:
<div ng-app="myapp">
<div data-ng-controller="mycontroller">
<div id="top" style="background-color:red;width:200px;height:200px">
<img id="myimage" src="//placehold.it/150x150">
</div>
<div id="bottom" style="background-color:green;width:200px;height:200px">
</div>
</div>
</div>
Instead of listening for a click in jQuery, you can use Angular's ng-click directive to specify a function to call when the element is clicked and you can use the ng-if directive to add/remove the image, for example...
<div ng-click="appendImage()" id="bottom" style="background-color:green;width:200px;height:200px">
<img ng-if="showImage" id="myimage" src="//placehold.it/150x150">
</div>
Then in your controller...
angular.controller('myController', function ($scope) {
$scope.showImage = false;
$scope.appendImage = function (event) {
$scope.showImage = true;
};
});
A key difference between plain jQuery and Angular is that in jQuery you have to write code to manipulate the DOM yourself (like appending the image). If you use directives properly in Angular, you simply make changes to the $scope and directives will update the DOM for you automatically

Event binding not working on div

I have a structure like this:
<ul id="container">
<li>
<div tabindex="1" class="selectThis">
<div>
<div>
<span class="textToEdit" contenteditable="true"></span>
</div>
</div>
</div>
</li>
<ul>
Where it works to bind an event to the contenteditable span:
$("#container").on("keydown", ".textToEdit", function (e) {
alert("yes");
});
But the div itself doesn't react:
$("#container").on("keydown", ".selectThis", function () {
alert("no");
});
Using .on because the whole thing is dynamically generated, besides the container. I'm using jquery UI's sortable on said container. What is wrong with the binding? I've tried giving the ul and li a tabindex too, but the div still won't give me an alert.
The problem was that the div wasn't being focused after sortable is called on the ul--manually calling $(".selectThis").focus() makes it work. Thanks to Pilgerstorfer Franz for making me aware of this!

How to interconnect (listener/action) separate elements in Mootools 1.4?

I have a little issue with mootools 1.4 and interaction between multiple separate elements. I have a menu like this :
<div id="links">
<a class="readmore" href="#1" title="1">Read More</a>
<a class="readmore" href="#2" title="2">Read More</a>
<a class="readmore" href="#2" title="3">Read More</a>
...
</div>
And an other element like this :
Code PHP:
<div id="content">
<div id="1">Lorem Ipsum</div>
<div id="2">Lorem Ipsum</div>
<div id="3">Lorem Ipsum</div>
...
</div>
Both are the same length (each link of the menu have a correspondant div element). What I need to do is to create a listener on each menu link so when it’s click it display the div. And that’s where my problem is because for the moment I use the title of the menu link to open the div that have the same ID. I don’t think that is the most performant, maybe I can do all this in one loop with the index ?
Other little question (not as important at all) : How to put add the same event on 2 element in one line of code (to avoid the multiplication of line of code to do exactly the same thing if the user click on different button) ?
Thanks a lot !
several things can be done.
- event delegation
idea: attach a single event to parent of menu items which fires dependent on the child el that has matched the event condition
so:
document.id('links').addEvent('click:relay(a.readmore)', function(event, element){
var id = element.get('title');
// do something.
});
downside is that you need to read the id but you can remove the ids from the target els if they are in the right order.
(function() {
var els = document.getElements('#content div');
document.id('links').addEvent('click:relay(a.readmore)', function(event, element){
var id = element.get('title'),
hint = els[id-1];
showHint(hint);
});
}());
that's about it. less events attached.
- looping to attach the events has a reference to index, which will match target
(function() {
var els = document.getElements('#content div'),
clickHandler = function(trigger, target){
};
document.getElements('#links a').each(function(element, index){
element.addEvent('click', function(event) {
event.stop();
clickHandler(this, els[index]));
});
});
}());
upside to that is, you don't need ids on hint els and no title tags or anything on source. downside, each link has its own click event.