I have different "Profiles" in a Json-File. In an index.html different profile cards are shown and filled with the information of the Json-File. When you click on a Profil (Profil-Card) a detailed profile.html will be loaded and the function initateProfile will be executed.
$(document).on("click", ".profile-card", function () {
$('#page-content').load("sections/profile.html", function () {
initiateProfile($(this).data("profileid"));
});
});
I want to transmit the content of the profileid-class, which is the index for the Json-File.
function initiateProfile(id) {
var profile_data;
$.getJSON('data/profiles.json', function (data) {
profile_data = data[id];
$('.trn-name').text(profile_data.name);
$('.trn-studies').text(profile_data.studies);
$('.trn-stage').text(profile_data.stage);
});
}
Unfortunatly the id-variable is undefined. So the function can't get the information of the Json-File. What's the problem?
Thx
The issue is because this within the load() callback handler function is not the element which raised the event. It runs under a different scope. To fix this you need to save the element reference to a variable in the scope of the click handler, and use that within the callback, something like this:
$(document).on("click", ".profile-card", function () {
var profileId = $(this).data('profileid');
$('#page-content').load("sections/profile.html", function () {
initiateProfile(profileId);
});
});
Assuming that the data-profileid attribute is defined on the element which has the class .profile-card:
Your problem is this.
$(document).on("click", ".profile-card", function () {
$('#page-content').load("sections/profile.html", function () {
initiateProfile($(this).data("profileid")); // "this" points to the element with id "page-content"
});
});
One solution would be to use event.currentTarget:
$(document).on("click", ".profile-card", function (event) {
$('#page-content').load("sections/profile.html", function () {
initiateProfile($(event.currentTarget).data("profileid"));
});
});
Related
I have a table in which I can click the rows () with the class .details. This will show a div with id="details" with extra information about the element in the row.
I have the following code.
$('.details').click(function () {
$('#details').slideUp('slow');
$('#details').load($(this).data('url'), { id: $(this).data('id') }, function () {
$(this).slideDown('slow');
});
});
However I would like the loading (.load()) to happen after the .slideUp() due to the fact that the load starts while the element is sliding up (which looks wierd). I have tried to add it as a callback function the following way:
$('#details').slideUp('slow', function () {
$('#details').load($(this).data('url'), { id: $(this).data('id') }, function () {
$(this).slideDown('slow');
});
});
However that stops the code from working. Does anyone have an idea on how to solve this?
Thanks.
EDIT:
My table row looks as follows:
<tr class="details" data-id="#item.VehicleID" data-url="#Url.Action("Details", "Vehicle")">
</tr>
My div looks as follows:
<div id="details"></div>
One problem i see with your code is, you are using $(this).data('url') to get the url data attribute value set to the tr which was clicked. but $(this) is actually the $('#details') there because you are accessing it inside the slideUp of $('#details'), which does not have the url data attribute. So you must be getting an error
The solution is to assign the $(this) (clicked row) to a local variable and use that inside your other callback function.
This should work.
$(function () {
$('.details').click(function () {
var _this = $(this);
$('#details').slideUp('slow', function () {
$('#details').load(_this.data('url'), { id: _this.data('id') }, function () {
$('#details').slideDown('slow');
});
});
});
});
I have a panel widget with a button. Clicking the button should execute some global actions related to all such widgets and after that execute some local actions related to this widget instance only. Global actions are binded in a separate javascript file by CSS class like this:
var App = function ()
{
var handleWidgetButton = function ()
{
$('.widgetBtn').on('click', function (e)
{
// do smth global
});
return {
init: function ()
{
handleWidgetButton();
}
};
}
}();
jQuery(document).ready(function()
{
App.init();
});
And in the html file local script is like this:
$("#widgetBtn1234").click(function (e)
{
// do smth local
});
Currently local script is executed first and global only after while I want it to be the opposite. I tried to wrap local one also with document.ready and have it run after global but that doesn't seem to change the execution order. Is there any decent way to arrange global and local jQuery bindings to the same element?
The problem you're having comes from using jQuery's .ready() function to initialize App, while you seem to have no such wrapper in your local code. Try the following instead:
var App = function ()
{
var handleWidgetButton = function ()
{
$('.widgetBtn').on('click', function (e)
{
// do smth global
});
return {
init: function ()
{
handleWidgetButton();
}
};
}
}();
$(function()
{
App.init();
});
Then in your local JS:
$(function() {
$("#widgetBtn1234").click(function (e)
{
// do smth local
});
});
Note that $(function(){}) can be used as shorthand for $(document).ready(function(){});. Also, make sure your JS file is located before your local JS, as javascript runs sequentially.
Alternatively, you can use setTimeout() to ensure everything's loaded properly:
(function executeOnReady() {
setTimeout(function() {
// Set App.isInitialized = true in your App.init() function
if (App.isInitialized) runLocalJs();
// App.init() hasn't been called yet, so re-run this function
else executeOnReady();
}, 500);
})();
function runLocalJs() {
$("#widgetBtn1234").click(function (e)
{
// do smth local
});
};
How about this instead:
var widget = $("#widgetBtn1234").get(0);//get the vanilla dom element
var globalHandler = widget.onclick; //save old click handler
// clobber the old handler with a new handler, that calls the old handler when it's done
widget.onclick = function(e){
//do smth global by calling stored handler
globalHandler(e);
//afterward do smth local
};
There might be a more jqueryish way to write this, but I hope the concept works for you.
-------VVVV----keeping old answer for posterity----VVVV--------
Why not something like this?
var App = function ()
{
var handleWidgetButton = function ()
{
$('.widgetBtn').on('click', function (e)
{
// do smth global
if(this.id === 'widgetBtn1234'){
//do specific things for this one
}
});
return {
init: function ()
{
handleWidgetButton();
}
};
}
}();
Please excuse any syntax errors I might have made as I haven't actually tested this code.
Check out my simple JQ extension I created on jsbin.
http://jsbin.com/telofesevo/edit?js,console,output
It allows to call consequentially all defined personal click handlers after a global one, handle missed handlers case if necessary and easily reset all personal handlers.
Say I have a javascript function for a hover event like this:
hoverFunc = function (HoverElement, AnimatedElement) {
HoverElement.on({
mouseenter: function () {
AnimatedElement.hide();
}
});
}
The tricky part is I want to keep AnimatedElement dynamic, and be able to use it as a reference of HoverElement's "this".
Here's an example of how I'd want AnimatedElement to function:
hoverFunc = function (HoverElement, AnimatedElement) {
HoverElement.on({
mouseenter: function () {
$(this).find("img").hide(); //this being a reference to HoverElement
}
});
}
So I'd like AnimatedElement to be able to be a "this" reference to HoverElement. I've tried writing it like this:
hoverFunc($("div"), $(this).find("img"));
But obviously the "this" will not reference the first parameter. Is there a way to achieve this? Thanks
instead of this use event.target and pass event in mouseenter function call
mouseenter: function (event) {
$(event.target).find("img").hide(); //this being a reference to HoverElement
}
Use bind() to do this
hoverFunc = function (HoverElement, AnimatedElement) {
HoverElement.on({
mouseenter: function () {
$(this).find("img").hide(); //this being a reference to HoverElement
}.bind(HoverElement)
});
}
fnc.bind() Description
From your example,
hoverFunc = function (HoverElement, AnimatedElement) {
HoverElement.on({
mouseenter: function () {
$(this).find("img").hide(); //this being a reference to HoverElement
}
});
}
Here this withing mouseenter event is actually HoverElement's this. As you're binding the mouseenter on HoverElement, so withing event callback this is actually HoverElement.
DEMO
I want to call a function with a namespace based on its name.
Perhaps some background: What I want is, dynamically bind pages via $.mobile.loadPage(inStrUrl, { showLoadMsg: false }); and then, based on the current page, invoke a function within a loaded page. For example: each page has a showFilter function, the Event is attached to a main.html - page which should call the matching function in the current page.
I also tried some solutions, with jquery too, but nothing works for me.
This is my function code:
function namespace() { }
namespace.showFilter = function () {
alert("Test");
}
And want to "invoke" or "call" it via its name.
This is what i tried at least.
$(document).ready(function() {
var fn = window["namespace.showFilter"];
fn();
});
I get error TypeError: fn is not a function
Here is a fiddle http://jsfiddle.net/xBCes/1/
You can call it in the following way:
$(document).ready(function() {
window["namespace"]["showFilter"]();
});
or
$(document).ready(function() {
window["namespace"].showFilter();
});
or
$(document).ready(function() {
window.namespace.showFilter();
});
I found that I had to manually set it to window.
window.namespace = function() { }
window.namespace.showFilter = function () {
alert("Test");
};
$(document).ready(function() {
var fn = window["namespace"]["showFilter"];
fn();
});
http://jsfiddle.net/xBCes/4/
Like this:
$(function() {
window.namespace.showFilter();
});
P.S. I shortened the $(document).ready(...)
function namespace() {}
namespace.showFilter = function () {
alert("Test");
}
$(document).ready(function() {
var fn = namespace.showFilter();
fn();
});
http://jsfiddle.net/xBCes/3/
I have a block of code like so:
function doSomething() {
someVar.on("event_name", function() {
$('#elementId').click(function(e) {
doSomething();
});
});
}
// and on document ready
$(function () {
$('#anotherElemId').click(function () {
doSomething();
});
});
The problem that I'm encountering is that when I call doSomething() from anotherElemId click event(that is binded on document ready) it works as expected, but calling it recursively from elementId click doesn't work.
Any ideas? Thinking is something trivial that I'm missing.
Is someVar an actual jQuery reference to a dom element? (e.g. $('#someitem'))
The second problem is you cant put a .click event inside a function that you would like to instantiate later on. If you are trying to only allow #elementId to have a click event AFTER some previous event, try testing if a tester variable is true:
var activated = false;
$(function () {
$('#anotherElemId').click(function () {
activated = true;
});
$('#secondElemId').on("event_name", function() {
if (activated) {
// code that happens only after #anotherElemId was clicked.
}
});
});