Why can't Jquery access an imported element on my page - javascript

I have a change that lists records from a database, my main page uses a second page to load information from it. I want the user to be able to click an 'x' and be able to delete the record.
So i have my main page 'index.php' and i have the loader page that is called 'get_results.php'
So when i load index.php, the JS loads and then goes to get_results.php and then displays the output on the screen, however, when i click the 'x' to try and delete a section it doesn't work. To add to that, i have run the JS script on the get_result.php page and the deleting works just fine.
I can't figure out how to get around this, i assume that it's because the new data (get_results) is being loaded after the index.php document is loaded.
I thought about changing when this data is load but i will still have the same problem because users can click a button and it gets rid of the data and puts new data there.
When the doc is read i run this:
$(".search_results_container").load("get_results.php?service_type=auto #results_output");
This loads the new data into it's container.
Then when the clicks the X it should run this code:
$(".delete_result").on("click", function( e ){
e.preventDefault();
var result_id = $(this).data("delete-id");
// post data to delete page
$.post("delete_results.php?action=delete&result_id=" + result_id, function( data ){
// Out delete data
console.log(data);
// Refresh list
} );
});
And this is the HTML that is being loaded into the container
<ul class="data_list" id="result_list">
<li>
<div class="result_info">
<a href="?action=edit_result&result_id=5" class="update_links">
<h2>
Test data 1
<small>Testing</small>
</h2>
</a>
</div>
<div class="result_delete_icon">
<a href="?result_id=5&action=delete" class="delete_result" data-delete-id="5">
<i class="fa fa-times" style="float: right;"></i>
</a>
</div>
</li>
<div class="result_info">
<a href="?action=edit_result&result_id=5" class="update_links">
<h2>
Test data 1
<small>Testing</small>
</h2>
</a>
</div>
<div class="result_delete_icon">
<a href="?result_id=5&action=delete" class="delete_result" data-delete-id="5">
<i class="fa fa-times" style="float: right;"></i>
</a>
</div>
</li>
I really don't know how to get this working, i'm thinking maybe something needs to be refreshed because it seems like Jquery isn't finding the elements in the dom, but i thought that if i reference the element each time, instead of storing it in a var it would walk through the DOM again to get it.

This isn't doing what you think it's doing:
$(".delete_result").on("click", function( e ){
This is invoking the selector ".delete_result" once, identifying the elements which exist at that time, and attaching the click handler to those elements. Handlers are attached to elements, not to selectors. So any elements added to the page after this code executes won't have click handlers attached to them.
Instead, you're looking to do this:
$(document).on("click", ".delete_result", function( e ){
This still executes only once, but attaches the handler to document (which is unchanging during the life of the DOM). Indeed, any common unchanging parent element in the hierarchy will work in place of document. The second selector, ".delete_result", is used on each event to filter events from selected child elements. Thus, any element added to the document later in the life of the DOM will still "bubble up" its click event to document and be identified by that second selector.
For more examples and information, I've written about this before.

You need to delegate your event http://learn.jquery.com/events/event-delegation/
$(document).on("click", ".delete_result",function( e ){...

Related

data-contenturl attribute in <a> tag

Working on one project and find this interesting attribute [data-contenturl] and did not find any information about it.
The main sense of this code is that the action of the controller returns a partial view. This link is part of the tabs widget and should insert content from a partial view to the #tab-body-id element. This partial view contains jquery widget with initializing spec and data-bind. The main issue is that on first load everything works great but on the second and subsequent old jquery objects try to send request to data-bind request but the element is one that`s why causes errors in console. I tried to destroy these elements, unbind them, insert empty content to #tab-body-id before the second tab load but nothing helps.
Could someone please explain how this attribute works? I could forget about something. I`ll be glad for any ideas!
<a href="#tab-body-id" data-toggle="tab" data-contenturl="#Url.Action("actionName", "controllerName",
new{ argument })">
And one more moment as additional information.
When i remove this attribute from and insert code
<div id="tab-body-id">
#{ Html.RenderPartial("route to my partial", Model.Id); }
</div>
directly to my #tab-body-id all works fine, becouse it is only one request during initialization of view...

How can I call a function at a click of a button?

I recently started playing around with javascript for fun.
I worked myself through the most of w3schools tutorial (including jquery ofc).
The point where i got stuck is simply calling a function at a click of a button.
My code (edited to provide a Minimal, Complete, and Verifiable example)
$("#linkId1").on("click", function(){
setTimeout(function(){
function decryptText() {
alert( "decrypted!" );
}
$("tableId").append('<a id="decryptID" class="button">decrypt</a>');
$("#decryptID").on("click", decryptText);
}, 500);
});
HTML:
<a id="linkId1">firstLink</a>
<table>
<tbody>
<tr>
<td id="tableId">
<a id="button1" class="button"></a>
<a id="button2" class="button"></a>
</td>
</tr>
</tbody>
</table>
Here's what i've already tried:
Different approaches to calling the function
Making the function decryptText() global or local
- Adding an eventListener to the button after creating it (because I read on another post that it's better to use the eventListener
than putting the onclick attribute in the HTML-tag). ~I mixed
basic js with jQuery methods here - BIG mistake.
The browser console does not give me any errors - when I changed to code a bit, I got: Reference Error: decryptText() not defined
S.
EDIT:
I tried doing it all in jQuery only, the selectors and the event handling.
As you can see, I changed the example code to the beginning of a simple encrypt and decrypt script - the core problem still stays the same though.
Checking with Firefox' inspector tool, this time the element does not have any event bound to it.
A probably important piece of information is that the table you can see in the HTML does not exist before an onclick ajax handler is called from the element #linkId1 and inserts the whole div containing the tables into the html.
I solved it!
(Thanks to Cbroe & Se0ng11)
Code before:
$("#tableId").append('<a id="decryptID" class="button">decrypt</a>');
$("#decryptID").on("click", decryptText);
Code after:
$("#tableId").append('<a class="button">decrypt</a>');
$(".button:contains('decrypt')").on("click", decryptText);
The problem was created by the static ID i assigned to the hyperlink element I append() in line 1.
Removing the ID and changing the jQuery selector in line 2 worked!
I'm going to provide an alternative solution to your problem. If you create the element as a fully fledged jQuery before you append it to the table you can bind the click event directly to this without having to find it again:
var newA = $('<a\>').addClass('button').text('decrypt');
newA.on("click", decryptText);
$("#tableId").append(newA);
$('<a\>') will create the DOM element as a variable before you append it to the DOM. The main advantage here over your current code is this will guarantee that that click is bound to that <a> tag, even if you have multiple elements with the same text(decrypt). I'm mainly saying this becuase the selector you use ".button:contains('decrypt')" is pretty vague and could match things that your not expecting or event bind a handler twice if you run the same code twice.
Another option is to bubble the events using delegation:
$("#tableId").on('click', '.button', decryptText);
the event handler is now bound to the static item tableId but it's listening for events that match the underlying class button. This is covered comprehensibly here Event binding on dynamically created elements?
With the above you can happily add as many new <a> as you want safe in the knowledge that the event binding is already dealt with, i.e. you don't have to bind the event on creation.
Try this, you was missing few things, $(document).ready(function () {} and $("tableId").append(...); should be using # $("#tableId").append(...); because tableId is id of the element not element itself. It will work with W3c as well it is not like you should not use this or that because of you are beginner. you can use any where.
$(document).ready(function () {
$("#linkId1").on("click", function () {
setTimeout(function () {
function decryptText() {alert("decrypted!");
}
$("#tableId").append('<a id="decryptID" class="button">decrypt</a>');
$("#decryptID").on("click", decryptText);}, 500);});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table><tr><td>
<a id="linkId1">firstLink</a></td>
</tr>
<tr><td id="tableId">
<a id="button1" class="button"></a>
<a id="button2" class="button"></a>
</td>
</tr>
</table>

Change status when I click in the child of an element (+AngularJS)

The goal
Change status when I click in the child (<i>) of an element (<li>)
The problem
Nothing happens when I click in <i>, that is child of <li>.
Details
I'm using AngularJS with ng-click. See:
<li ng-click="openNavigator($event)">
<i class="ico ico-home"></i>
</li>
Update
Guys, you are right — it's working! The problem, actually, is a little bit further.
See this jsFiddle. If you click exactly on the button, the console retrieves back to you a specific result; otherwise, if you click exactly on the icon, you get another response from $event.target.
This behavior isn't good for me — it's flimsy. In my real application I need to work with parents, siblings, etc. and that incosistence unleashes expected, but unwanted, results.
Can you all see my problem? If so, ideas?
Thanks in advance!
HTML
<div ng-app='currentApp' ng-controller='ACtrl'>
<li class="btn btn-primary">
<i class="fa fa-phone" ng-click="openNavigator($event)"></i>
</li>
</div>
CONTROLLER
currentApp.controller('ACtrl', ['$scope', function ($scope, $event) {
$scope.openNavigator = function($event) {
var target = $event.target['parentElement' || 'patentNode'];
console.log('li parent', target);
}
}]);
Since the i tag is a child of the li and the click event is inconsistent, then I suggest you target the i tag on click and then grab the parent. You can say it's the bubbling down, which is correct, So to fix it target the i and it won't bubble up.
The main reason this is an issue is because AngularJS doesn't have event delegation functionality like jQuery does, so you can't specifically target the li tag.
The fiddles been updated too!
JSFIDDLE
It should work. Here is a plunker

Jquery toggleClass loses the class once links is clicked or page is refreshed

When the link is not pointing to anywhere (href="#") my toggleClass works as it is suppose to. But as soon as I fill in the "href" with an URL it doesnt work anymore. I suspect it is because the page is refreshed? But I'm quite new to JS. If this is the problem how can I work around it? and if it's not, then what have I done wrong?
So this is my current javascript using jquery:
$(document).ready(function()
{
$('.button').click(function()
{
$('.buttonselected').removeClass('buttonselected');
$(this).toggleClass('buttonselected');
});
});
And this is my HTML code:
<nav>
<ul>
<li>
<a class="button" href="?page=frontpage"> HOME </a>
</li>
</ul>
</nav>
There are more links in the list, but that is irrelevant for this question.
Yes, I'm using PHP include.
Also, how can I set a link to "toggleClass" when the page loads so that it gets that class when someone first enters the website.
Thank you for the help!
You are right. The class goes away because the page is reloaded. If you need a specific link to have a specific class when the page loads, you'll need to hard code something to that link. Either manually put the class on the link with php or distinguish it in some other way so that JavaScript can find it.
If the link that should have the class is different based on which link you clicked previously, you will have to use a cookie or the localStorage object to retain that information.
Better yet, you should try to figure out a way to pass this information around that doesn't involve reloading the page. That would be ideal as, in most cases, users don't like to have a page reload on them when they're not expecting it.
EDIT:
The answer by #pszaba is great if you don't need to utilize query string variables.
You can use event.preventDefault()
$('.button').click(function( event )
{
event.preventDefault(); // default action of the event will not be triggered.
$('.buttonselected').removeClass('buttonselected');
$(this).toggleClass('buttonselected');
});
EDIT:
If you want to load your frontpage (as in your link) and give it a "buttonselected" class
than you need to use PHP.
Something like this
if( isset($_POST['page']) ){
$selectedPage = $_POST['page'];
}
View
<a class="button <?php echo ($selectedPage=='frontpage')?' buttonselected':'' ?>" href="?page=frontpage"> HOME </a>

How can I select an img placed within a span with appendChild?

I'm using picturefill.js (Scott Jehl): https://github.com/scottjehl/picturefill/blob/master/picturefill.js
Here's how I have it setup, (some code omitted b/c it was just more media query stuff) using span tags and data attributes as in his documentation:
<figure>
<a href='http://www.casaromeromexican.com'>
<span id="picture" data-picture data-alt="Casa Romero Mexican website">
<span data-src="img/casa-romero-mexican.jpg"></span>
<span data-src="img/casa-romero-mexican#2x.jpg" data-media="(min-device-pixel-ratio: 2.0)"></span>
<span data-src="img/casa-romero-mexican-md.jpg" data-media="(min-width: 768px") </span>
// and so on...
The correct img is being loaded and placed on the page, as expected. Here's is a snippet of the generated HTML:
<span data-src="img/casa-romero-mexican-md.jpg" data-media="(min-width: 768px)"><img alt="Casa Romero Mexican website" src="img/casa-romero-mexican-md.jpg"></span>
What I'd like to do is add a class to whichever img tag ends up getting generated.
However, I'm not even able to select the img that is appended! Here's what I'm working with:
alert(($('#picture').children().find('img').size()));
This returns 0, even though the image is on the page. I am expecting it to return a size of 1, b/c based on the media queries, 1 of the images is appended to the page with picturefill.
Just to be sure that there wasn't issues with the DOM loading, I placed picturefill.js in the header (even though JS should go in footer most of the time), and even did this:
$(document).ready(function() {
alert('ready!');
alert(($('#picture').children().find('img').size()));
});
Still doesn't seem to find the img.
http://learn.jquery.com/using-jquery-core/document-ready/
After reading this, I understood why jQuery was not finding the img. In this case, it was necessary to use $( window ).load(function() { ... }). This will not run the script until the entire page is loaded, as opposed to $( document ).ready(), which only waits for the DOM.
In other words, $( document ).ready() is fine most of the time, but not when waiting on media elements that may take longer to load and/or need to be fetched with a request!

Categories

Resources