jQuery timeago usage - javascript

I have an <abbr> tag with class "timeago" in my HTML. When I set it value on page load, then call jQuery("abbr.timeago").timeago(); on document ready function it works.
My question is, what if I change abbr.timeago title dynamically from some javascript function, how can I make timeago plugin to do its magic on the updated abrr.timeago element?
Which function should I call? Should I remove jQuery("abbr.timeago").timeago(); from document ready function or leave it ? thank you
EDIT QUESTION:
#squiddy example works, updates the time only once and it just remains like that unchanged. For example if I put timeago to current time .. then it just stands like that it doesn't change?
BOUNTY UPDATE :
Please disregard previous question. In my website there is a link upon its click getJSON function is invoked which gets some information from server into a table.
Each row represents feedback from the server. Here is my getJSON pseudo code :
$.getJSON("feedback/" + feedbackId, function(data) {
var column ... declared variable in which column selector
.... some logic that populates table(irrelevant)
//Store last checked time in title
column.attr("title", iso8601(new Date()));
//invoke timeago on this title
column.html(jQuery.timeago(iso8601(new Date())));
....iso8601 is date format function
});
So this getJSON is invoked for every feedback I get from the server(n times). And when json completes the appropriate column in table is populated with last updated time.
But it seems that timeago is not reading the changed title value, it does not recognize updated DOM. I put a console.log(element.attr("title")) for each feedback from server for debugging purposes just to see if I set the title attribute to current time, and it does indeed but the timeago picks up the initially loaded title value.
What should I do I also tried this version :
$.getJSON("feedback/" + feedbackId, function(data) {
var column ... declared variable in which column selector
.... some logic that populates table(irrelevant)
//Store last checked time in title
column.attr("title", iso8601(new Date()));
//invoke timeago on this title
$(column).livequery(function() {
$(this).timeago(iso8601(new Date()));
console.log($(this).attr("title"));
});
});
I've spent few hours trying several possible solution .. like a function called every n seconds, to call the timeago function but always the same results

UPDATE 2: Same trick works here. The element column was previously converted by timeago once, when that happend, timeago placed a 'timeago' data field on the element. When this data field is present timeago won't bother with it, so you have to clear it. The code would look somethink like this:
$.getJSON("feedback/" + feedbackId, function(data) {
var column
// ... declared variable in which column selector
// ... some logic that populates table(irrelevant)
// Store last checked time in title
column.attr("title", iso8601(new Date()));
// invoke timeago on this title
column.data("timeago",null).timeago();
// ... iso8601 is date format function
});
UPDATE: corrected, tested, the trick was, that timeago plugin marks the elements which were already turned, and dont let them turn again, unless the mark is cleared
When you change the value in abbr.timeago, you should run the timeago() function only on that element again. I would recommend some function for this:
$.fn.changeTimeago = function(isotime) {
return $(this).attr("title",isotime).data("timeago",null).timeago();
}
// usage:
$("abbr.timeago").changeTimeago("2004-07-17T09:24:17Z");
Hope this is what you needed!

As of v1.1.0, jquery.timeago.js now provides an update action that can be used:
From: https://github.com/rmm5t/jquery-timeago/pull/115
$(column).livequery(function() {
$(this).timeago('update', iso8601(new Date()));
});

don't add any javascript or jquery code except this;
$('.timeago').timeago();
and then add 'Z' (or including T). for more information go to this link
<abbr class='timeago' title='2011-09-09 10:10:10Z'></abbr>
http://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations

I couldn't get it to work after changing the value in the title attribute, but timeago supports a direct approch like this:
jQuery.timeago(new Date()); //=> "less than a minute ago"
jQuery.timeago("2008-07-17"); //=> "2 years ago"
jQuery.timeago(jQuery("abbr#some_id")); //=> "2 years ago" [title="2008-07-20"]
So when changing an element, update the html yourself:
jQuery("abbr.timeago").html(jQuery.timeago("2010-07-17T09:24:17Z"));

If you wish to update the timeago element with a new date. The simplest way to do is as follows -
$('abbr.timeago').timeago('update',(new Date()).toISOString());
It works like a charm. I don't understand why it is not documented anywhere. You can find this function by looking at timeago javascript code.

Related

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.

BIRT Using Date parameter in script

I am using BIRT and am trying to modify the text on a chart based on an end date report parameter, which I've assigned a default value and of course, Date datatype. SQL queries also use this parameter. To test passing of value, I write the below script.
function beforeDrawLegendItem( lerh, bounds, icsc )
{
var endDate = new Date(params["rptEndDate"].value);
}
However, when I try to preview the chart, it is blank, indicating that there is something wrong with my script. When I comment out the var endDate line, it renders as normal. I've tried other ways to get the value like:
var endDate = new Date();
Which works, but when I try to assign the parameter value:
endDate = params["rptEndDate"].value;
It fails again. Removing the .value part also fails. Also fails when I try to use reportContext to get the parameter value. According to other sources my script should be correct. Is there anything I am missing?
This is due to the specifity of the chart engine: "params" object is not made available in chart scripts, use "getParameterValue" instead. It will work like this:
function beforeDrawLegendItem( lerh, bounds, icsc )
{
var endDate = new Date(getParameterValue("rptEndDate"));
}
The Previewer tends to offer less then optimally formated or fully functional design. Open the report in the format/tool that will be used in the final delivery for true testing durring design. Personally I have Apache on my test server and do all of my preview testing as a web page.

Coffeescript: Dynamically update time with moment js with coffeescript

I am having trouble dynamically seeing the time update with moment js. It shows the correct time but I have to refresh my browser to get the time update. I would like it to update it in real time. Like momentjs.com main page.
I've tried using setInterval and setTimeout but for some reason I get the below digits that don't even update.
Here's what I have so far code-wise. Pretty simple as far as moment goes and all I want is seconds to keep counting...
update = ->
time = moment().format('hh:mm:ss a')
clock = setInterval update, 1000
console.log(clock) //output: 53296
Any ideas are immensely appreciated.
You should put the output inside of the update method and everthing will work as expected.
The method setInterval won't return the result of the repeatedly called method but an identifier which can be used with clearInterval to stop the execution.
Just a small working example to print the time every seconds and stop after 10 seconds:
update = ->
console.log(moment().format('hh:mm:ss a'))
x = setInterval update, 1000;
setTimeout (-> clearInterval(x)), 10000
If you want to use that time as content of some DOM-Element you can use the following code inside your update function (assuming you have an element (e.g. div) with id "time"):
JQuery:
$("#time").text(moment().format('hh:mm:ss a'))
Plain JS:
document.getElementById("time").firstChild.data = moment().format('hh:mm:ss a')
Try this. If u are dont have to use meomentJS.
https://github.com/furkankaynak/countdown

live function with out arguments in jQuery

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.

select value not changing after ajax call

I have written a piece of code to generate a chart by values generated by an ajax call.
The problem is, the select (years) is not changing its value after the call is done loading. The weird thing is, i can see its value changing (if i alert its current value) but it simply won't change.
The code:
http://pastebin.com/RNfLmdWy
The $.load_x function is a custom loader but it behaves the same as a regular $.getJson call.
Found it! This part is responsible:
var option = $(this).attr('id').split('option_');
$('#'+option[1]).val(String($cur_val));
setTimeout(function(){$('#'+option[1]).val(String($cur_val))}, 1000);
I don't know what were you trying to do here, but basically, the option variable becomes a array ["", "years"], and in the next step you are setting $("#"+option[1]) value to $cur_val variable which is anything found in the #option_years input.
Soooo to wrap it up. To get rid of the "my select is not changing its value" issue in this case just get rid of those lines or at least let me know what you wanted to do there :)
EDIT: Here's the example that works for me: http://pastebin.com/sFRT3GJa (tested on FF and Chrome). As you can see it the source I use jQuery 1.6.1, jQuery UI 1.8.16 and jqPlot 1.0.0b2_r792. Other than that I've moved the callback function of $.load_x and named it handleJSON. Then I passed the JSON data you've pasted in your question to mock the successfull response of the $.load_x function.
Before you make get_port_graph call, give some time for select box to change the dropdown since its heavy call. It will work.
function year_chart(year)
{
settTimeout(function(){
var d = new Date();
get_port_graph("Uitporteringen "+year,d.getMonth(), year,'outport', 'chart1', 'bar');
}, 100);
}

Categories

Resources