live function with out arguments in jQuery - javascript

I wanna select some item by jQuery which has been added after loading page,so I wanna use live() function.I used it before for clicking like following code:
$("selector").live('click')
but now when I wanna use it in another function.
but It will not work with out argument,like it live()
for e.g followin code will alert test (work)
var pos_eq=Math.abs($('.myList').css("left").replace("px","")/$('.myList').children('li').eq(0).css('width').replace("px","")) + 1;
alert("test");
but this will not.
var pos_eq=Math.abs($('.myList').live().css("left").replace("px","")/$('.myList').live().children('li').eq(0).css('width').replace("px","")) + 1;
alert("test");
how can I solve it?

You want a function, not a variable. It looks like you are trying to keep pos_eq up to date after elements have been added to the page. Having a variable auto-update when the DOM changes in the way you are trying to do is not possible with JavaScript. What you can do is use a function instead of a variable. This way whenever the value is accessed you are getting the latest value because it is computed on demand:
function pos_eq() {
var list = $('.myList');
var left = parseInt(list.css("left"));
var width = parseInt(list.children('li').eq(0).css('width'));
return Math.abs(left / width) + 1;
}
I broke your code up into multiple statements to make it more readable. You would use this function the same as you used the variable, but instead add parens to the end to invoke the function:
alert(pos_eq);
alert(pos_eq());

To get a set of objects at the time you need them, just do $("selector"). That will do a query at that time and get the set of objects. There is no need to use .live() in order to query objects on the page. It does not matter whether the objects were part of the original page or were added dynamically later. When you do $("selector"), it will search the contents of the current page and get you the objects that are currently in the page that match the selector.
There is no way to do a live selector query and save it and have it automatically update in jQuery or any other library I know of. The way you solve that issue with a dynamic page is that you just do a new query when you need current results.

The description of live() is: Attach a handler to the event for all elements which match the current selector, now and in the future. It does not give you a live node list despite its name. jQuery does not have any method that returns a live node list(such as those returned by getElementsByTagName etc.) as far as I know.

Related

textContent returns undefined

I have a table in which I want to extract the text of the active item. I do this with the following code:
var addedWorkout = $("#custDropDownMenuA").find(".dropdown-item.active");
console.log(addedWorkout);
addedWorkout = addedWorkout.textContent;
console.log(addedWorkout);
The problem is that I keep getting undefined. I checked the console and it indeed finds the element I want without fail.
I am relatively new to Javascript, but after over an hour of Googling I could not find the issue and I don't understand why. I know that I can get the text element if I hardcore it using the following line:
document.querySelector("#selectiona1").textContent
but not with:
$("#selectiona1").textContent
What is the difference between these 2? I read that textContent is part of the DOM, to my understanding it relates to objects and according to my console i think it is an object. I made some crazy attempts like putting the object I got into the querySelector, but nothing works.
With this line:
var addedWorkout = $("#custDropDownMenuA").find(".dropdown-item.active");
you're using jQuery to select the .dropdown-item.active inside #custDropDownMenuA, and when you select with jQuery, you get a jQuery object in response. So, addedWorkout is a jQuery object, and jQuery objects generally do not have the same properties/methods as standard HTMLElements. (querySelector is the vanilla Javascript method to retrieve an element)
Either select the [0]th item in the jQuery collection to get to the first matching element:
var addedWorkout = $("#custDropDownMenuA").find(".dropdown-item.active")[0];
Or use the jQuery method to get the text of the first matching element, which is .text():
var addedWorkoutText = addedWorkout.text();
(note the use of a new variable - you will likely find it easier to read and debug code when you create new variables rather than reassigning old ones, when possible)
Your var 'addedWorkout' is a Jquery object, not a html element.
To show the text use:
addedWorkout.text();
Alternatively, you can change the 'addedWorkout' to a html element by adding the index [0], like this:
addedWorkout[0].textContent;

How to apply css styles to dynamic JavaScript array?

I'm trying to apply CSS styles to input elements that are added to the HTML DOM dynamically via a JSON object.
Essentially an Ajax call receives a JSON payload with an array of data. Some KnockoutJS code then foreach's over the DOM to dynamically add rows.
I'm trying to add styles to inputs where a value is less than a required value. The bottom line is, I know the elements are dynamic to the DOM, and I'm having trouble accessing them so I can apply the style. I've tried both jQuery and pure JavaScript, and I can't access the newly added fields.
How would I do this?
I have a very complex fiddle created that creates the inputs. But I can't figure out how to style those inputs whose values are less than the current year.
I'm trying to add the .k-invalid style to the NextPaymentDate input whose value is less than the current year.
var $incomeWrapper = $("#income-wrapper");
$incomeWrapper.find("input#iNextPaymentDate_" + i).removeClass("k-valid").addClass("k-invalid");
The above doesn't work.
http://jsfiddle.net/kahanu/rdb00n76/9/
You could add a filter function to your selector like this:
$('input[id^="iNextPaymentDate_"]').filter(function(index) {
return parseInt($(this).val().split('/')[2]) < new Date().getFullYear();
}).addClass('k-invalid');
Fiddle: http://jsfiddle.net/rdb00n76/10/
The above code selects all inputs whose ids start with iNextPaymentDate_, then applies a filter that evaluates the current element against the current full year. To do this I split the date string on / and take the 3rd item which should be the year. Then I cast the value to int and compare the the current year.
Your actual filter function should probably be a lot more solid than the one above. For example, you could include moment.js for comparisons.
I think the forEach loop inside ListDateValidation is being executed too soon. If my understanding from your jsfiddle is correct, you're running it as soon as you instantiate the FinancialViewModel, but even though the call comes after everything else, Knockout may not have updated the DOM by this point.
There are several ways you could check this and if correct, guard against this.
But for now, to check if this is the case, I would suggest placing some logic immediately prior to the self.ListDateValidation() method call: in this logic you should just have a quick and dirty way of determining if any of those elements are present - can you temporarily (just for debugging) give these elements id attributes (just increment an int) and then run something like
if (document.getElementById("test-id-1") !== null) {
console.log("element found");
}
This will tell you if you're running the date validation too soon.
If you need a method of determining when the elements have been added then search for "javascript poll dom element added". If you can't be bothered, here's a crude method:
var elmnt,
elmntId = "YOUR ELEMENT'S ID HERE",
tmr = window.setInterval(function() {
elmnt = document.getElementById(elmntId);
if (elmnt) {
window.clearInterval(tmr); // stop the search
// do something
}
}, 15);
This method polls the DOM every 15ms, then stops when it finds that the element with the specified ID is present. 15ms corresponds to the minimum tie increment in which a browser will run - if this has since been lowered then great, but no-one would notice the difference in this context.

setting default root element in jquery

jQuery currently uses window as its default element so any call like $('div') will look for div tags inside window.
Is there any way to change defaults on jQuery like:
$.defaultRoot = $('.anyOtherRootElement');
$('div').text("Hello");
this will select any div inside the elements containing .anyOtherRootElement class.
Thanks in advance
Upate
just an update refining the question a bit more here:
I would like to perform the actions above based on external queries coming from external script which won't know what defaultRoot is so they can still be calling what is supposed to be the current base, so in this instance, I'm afraid adding the a second parameter wouldn't be an option, unfortunately.
And at the same time creating a function which returns defaultRoot.find(el) would prevent me of using first-level methods such $.trim, $.each, etc… so unfortunately that would not be possible as well.
Ideally (for performance reasons) you'd want to use find()
$.defaultRoot.find("div");
Otherwise you can use the 2 argument form that sets a context
$("div", $.defaultRoot);
In general you don't want to do these types of things implicitly since someone else could easily end up thoroughly confused when having to work with your code later. If you want to do it consistently and make it shorter you should create your own function to do so like:
var $s = function(selector) {
return $.defaultRoot.find(selector);
}
and then you'd just be able to use
$s("div")
or you could also do a scoped higher order function with something like
var withScope = function(scope$) {
return function(selector) {
return scope$.find(selector);
}
}
var $s = withScope($.defaultRoot);
$s("div")
If for some reason you really want to screw around with the default state for client code (begging for chaos IMO), you should look at the functional practice: currying.
$('SELECTOR', 'CONTEXT')
You can use context. As in your case $('div', '.anyOtherRootElement')
For more details, visit http://api.jquery.com/jQuery/
Given that you can pass the context as a second argument, you can easily overwrite the $() operator in Javascript with a version which internally calls JQuery using jQuery.noConflict(); and always passes your new root as the second argument.
I don't think jQuery provide such method or variable. But you can pass second parameter in jQuery method to set context.
$.defaultRoot = $('.anyOtherRootElement');
$('div', $.defaultRoot ).text("Hello"); // all div inside $('.anyOtherRootElement')
$('div' ).text("Hello"); //all div inside body tag

Using $.data() in jQuery to store flag on element

I am authoring a simple jQuery plugin that turns an input tag into a time-formatted element (on blur it will change 245p into 2:45 pm).
Since I do not want to apply the time format events to the same element twice, I need a way to detect that the specific element in the list provided has not already had the format applied.
This is the relevant part of the code:
var methods = {
init : function(sel) {
var $this = $(sel);
return $this.each(function(){
var data = $(this).data('time_formatted');
if (data) {
return;
} else {
$(this).data('time_formatted', true);
I have heard that using $(sel).data() in a plugin is not a good idea; instead, use $.data(). I don't know why, that's just what I've heard; honestly, I don't know what the difference is.
So my question is, is this the way to accomplish checking if a specific element has had the time formatter applied to it in a plugin?
If you care to see the plugin in it's current development state, see http://jsfiddle.net/userdude/xhXCR/.
Thanks!
Jared
Where have you heard that using .data() is not good? jQuery's plugin autoring page says:
Often times in plugin development, you may need to maintain state or check if your plugin has already been initialized on a given element. Using jQuery's data method is a great way to keep track of variables on a per element basis. However, rather than keeping track of a bunch of separate data calls with different names, it's best to use a single object literal to house all of your variables, and access that object by a single data namespace.
So it should be perfectly fine.

Jquery Replace with return value of Javascript function

OK I am just starting out with jQuery.
I have a page with a table of date-values. Each is wrapped in a tag which I can find with
$('mytag').
<mytag>2009-10-31</mytag>
How, using Jquery, would I
take each of the source values and
pass it to a Javascript function
then replace that source value within the table with the result of the function calculation.
So <mytag>2009-10-31</mytag>would be replaced with <mytag>Very Late</mytag>
I have the Javascript function written. My question is the jQuery syntax to pass the individual value.
Firstly, you will need an element selector, e.g.
$('table')
Will select all <table> elements in your html. So,
$('mytag')
will give you your elements. You will get a jQuery object (not a DOM object) returned. See http://docs.jquery.com/Selectors
Then you want to call a function for each of your elements. For this we call the .each function, and pass the function to call for each element:
$('mytag').each(function(){
//function code goes here
});
(See http://docs.jquery.com/Utilities/jQuery.each)
The function in this case is called an Anonymous function
Then you want to reference the current object in the iteration, so we use the DOM this item and wrap it into a jquery object. To get the value, we use the .text() function (http://docs.jquery.com/Attributes/text)
$('mytag').each(function(){
$(this).text()
});
Note: if it were an input element then you would have used .val()
Passing it to a function is easy:
...
MyFunction($(this).text());
...
The text() function has an overloaded implementation which allows you to set the text if you pass a value:
$(this).text(someval);
So, we can factor this into our code
...
$(this).text(MyFunction($(this).text()));
...
Making our final code block:
$('mytag').each(function(){
$(this).text(MyFunction($(this).text()));
});
$('mytag').each(function (index,tag) {
$(tag).text( myFunc($(tag).text()) );
});
$("mytag").each(function() {
$(this).html("Very Late");
});
$('mytag').each(function() {
$(this).text(someFunction($(this).text()));
});
But, from the sound of your problem, you might be better served by the jQuery-timeago plugin. For your particular case, you'd possibly want to allow dates in the future:
jQuery.timeago.settings.allowFuture = true;
...and you'd want to create your own language override. See the language override examples. You could define several "late" and "very late" values. You can also pass a function to each one to change the value depending on how many days ago a timestamp was.

Categories

Resources