Hi I'm using the jQuery countdown from Keith Wood (http://keith-wood.name/countdownRef.html) and I would like to know how I reset the counter when someone refreshes the page.
So every time someone enters the page he must see: 00days 3hours 13min 19sec
I'm a complete newbie with jQuery. I make use of jquery.countdown.min.js file.
Please help.
I have this now as JS:
/* jQuery countdown init */
$('#countdown').countdown({
layout: '<div class="span3 counter-block"><span id="days-num">{dn}</span><h4 id="days-desc">{dl}</h4></div>' +
'<div class="span3 counter-block"><span id="hours-num">{hn}</span><h4 id="hours-desc">{hl}</h4></div>' +
'<div class="span3 counter-block"><span id="min-num">{mn}</span><h4 id="min-desc">{ml}</h4></div>' +
'<div class="span3 counter-block"><span id="sec-num">{sn}</span><h4 id="sec-desc">{sl}</h4></div>',
until: '+00d +3h +13m +19s')
});
});
and HTML:
<div id="countdown" class="row"></div>
But it is not showing
What am I doing wrong?
Assuming you always want 3hrs, 13min, 19sec from now use:
$(selector).countdown({until: '+3h +13m +19s'});
Related
I'm trying to create a new Custom Component in pentaho. It is just a menu for every dashboard that I need to use, with some buttons and a text input.
I have in my solutions/system/pentaho-cdf-dd/resources/custom/components my ControlComponent folder, with component.xml and control-implementation.js. I have too in amd-components, the same folder but with ControlComponent.js.
In CDE, I can use it, but every time I run my dashboard, come the error from javascript.
define(['cdf/components/BaseComponent', 'cdf/lib/jquery'],
function(BaseComponent, $) {
return BaseComponent.extend({
update: function() {
if(this.htmlObject){
var ph = $("#" + this.htmlObject);
} else{
var ph = $("<div id='ControlDefault'></div>").appendTo("body");
}
var content = '<div id="Control" class="row clearfix">'+
'<div class="col-xs-6-last">'+
'<div>'+
'<div class="row clearfix">'+
'<div class="col-xs-1">'+
'<div id="Left" title="left">'+
+
'</div>'+
'</div>'+
'</div>'+
'</div>'+
'</div>'+
'</div>';
ph.append(content);
}
});
});
The error is:
require.js:8 Uncaught Error: Script error for:
cde/components/ControlComponent
http://requirejs.org/docs/errors.html#scripterror
at C (require.js:8)
at HTMLScriptElement.onScriptError (require.js:30)
Thanks in advance.
Check that the tag in component.xml is named controlComponent to match your js file name. RequireJS uses the IName tag value to reference the js file name instead of the Code tag src attribute.
Also, the Implementation tag needs attribute supportsAMD="true".
I'm trying to use Twitter's typeahead.js in a Vue component, but although I have it set up correctly as tested out outside any Vue component, when used within a component, no suggestions appear, and no errors are written to the console. It is simply as if it is not there. This is my typeahead setup code:
var codes = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('code'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: contextPath + "/product/codes"
});
$('.typeahead').typeahead({
hint: true,
highlight: true,
minLength: 3
},
{
name: 'codes',
display: 'code',
source: codes,
templates: {
suggestion: (data)=> {
return '<div><strong>' + data.code + '</strong> - ' + data.name + '</div>';
}
}
});
I use it with this form input:
<form>
<input id="item" ref="ttinput" autocomplete="off" placeholder="Enter code" name="item" type="text" class="typeahead"/>
</form>
As mentioned, if I move this to a div outside Vue.js control, and put the Javascript in a document ready block, it works just fine, a properly formatted set of suggestions appears as soon as 3 characters are input in the field. If, however, I put the Javascript in the mounted() for the component (or alternatively in a watch, I've tried both), no typeahead functionality kicks in (i.e., nothing happens after typing in 3 characters), although the Bloodhound prefetch call is made. For the life of me I can't see what the difference is.
Any suggestions as to where to look would be appreciated.
LATER: I've managed to get it to appear by putting the typeahead initialization code in the updated event (instead of mounted or watch). It must have been some problem with the DOM not being in the right state. I have some formatting issues but at least I can move on now.
The correct place to initialize Twitter Typeahead/Bloodhound is in the mounted() hook since thats when the DOM is completely built. (Ref)
Find below the relevant snippet: (Source: https://digitalfortress.tech/js/using-twitter-typeahead-with-vuejs/)
mounted() {
// configure datasource for the suggestions (i.e. Bloodhound)
this.suggestions = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('title'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
identify: item => item.id,
remote: {
url: http://example.com/search + '/%QUERY',
wildcard: '%QUERY'
}
});
// get the input element and init typeahead on it
let inputEl = $('.globalSearchInput input');
inputEl.typeahead(
{
minLength: 1,
highlight: true,
},
{
name: 'suggestions',
source: this.suggestions,
limit: 5,
display: item => item.title,
templates: {
suggestion: data => `${data.title}`;
}
}
);
}
You can also find a working example: https://gospelmusic.io/
and a Reference Tutorial to integrate twitter typeahead with your VueJS app.
I have an XTemplate and I would like to add some actual EXT widgets inside the template so that I have template code rendered above and below the widgets. Let's say I have a "dataview" with the following itemTpl defined:
itemTpl: [
'<tpl for=".">',
'<div class="song-page-header">',
' <div class="artwork"><img src="{artwork}"/></div>',
' <h1>{title}</h1>',
' <h2>{artist}</h2>',
' <h3>Genre: {genre}</h3>',
' <p>{copyright}</p>',
'</div>',
/* Ext.Button should go here */
'<tpl for="offers">',
' <p>{offer_id}: {offer_type}, {price}</p>',
'</tpl>',
'</tpl>'
]
Is it possible to define a real Ext.Button there (and not just some HTML approximating the behavior of an Ext.Button)? I don't care if it has to be applied after the fact, but I can't seem to find the correct event handler to use to be able to insert a button there. The Sencha documentation sucks so any help would be greater appreciated.
Actually you can do this, you just have to be a little bit creative.
Check out my blog post here: http://jakes-hackerblog.herokuapp.com/blog/2013/05/23/a-fresh-rails-blog/
Essentially, you put some dynamic div element in your template
'<div id="box-holder">' +
'<div id="box-{schoolpersonid}"></div>'+
'</div>'+
Then you use the use "renderTo" within your button config, calling it in a refresh funciton:
listeners: {
'refresh': function(records) {
var storeRecords = records._store._data.items;
for(var i = 0; i < storeRecords.length; i++){
var data = storeRecords[i].data;
var renderTo = this.element.select('#box-' + data.schoolpersonid).elements[0];
var button1 = new Ext.Button({
action: 'doPresent',
xtype: 'button',
align: 'right',
text: 'Present',
ui: 'present',
renderTo: renderTo,
schoolpersonid: data.schoolpersonid
});
}
}
},
I think XTemplate does not support this feature due to managment and performance of Sencha Touch framework.
Secondly, you cannot do like that because basically you're trying to merge between HTML and javascript inside your itemTpl when sencha template only allow html structure.
In order to address this scenario, you may take a look at Component Dataview
I know that InfiniteScroll and Masonry work well together. But I am using the Infinite Scroll Extension of Yii (called yiinfinite-scroll) and tried to apply Masonry on it. Infinite Scroll for itself works perfectly, Masonry for itself too. But after InfiniteScroll tries to load a new set of images (I've got an image page), the callback part of InfiniteScroll doesn't seem to fire, because the newly appended elements don't have any masonry code in it and appear behind the first visible items. (I know that this bug is reported often, but the solutions I found so far didn't work for me).
My structure for showing the picture looks like this:
<div class="items">
<div class="pic">...</pic>
<div class="pic">...</pic>
...
</div>
The first page load looks like this
<div class="items masonry" style="...">
<div class="pic masonry-brick" ...></div>
<div class="pic masonry-brick" ...></div>
...
</div> // everything's fine, masonry is injected into the code
After infinite scroll dynamically loads new images these look like this:
<div class="items masonry" ...></div>
<div class="pic masonry-brick" ...></div>
...
// appended pics:
<div class="pic"></div>
<div class="pic"></div>
</div> // so no masonry functionality was applied
My Masonry Code:
$(function (){
var $container = $('.items');
$container.imagesLoaded(function(){
$container.masonry({
itemSelector: '.pic',
columnWidth: 405
});
});
});
$container.infinitescroll({
// normally, the options are found here. but as I use infinitescroll as a Yii extension, the plugin is already initiated with options
}
},
// trigger Masonry as a callback
function( newElements ) {
// hide new items while they are loading
var $newElems = $( newElements ).css({ opacity: 0 });
// ensure that images load before adding to masonry layout
$newElems.imagesLoaded(function(){
// show elems now they're ready
$newElems.animate({ opacity: 1 });
$container.masonry( 'appended', $newElems, true );
});
});
});
I also tried to copy and replace the current InfiniteScroll-min.js file in the extension folder by the newest one. Same effect...
Best regards,
Sebastian
Okay I found a solution. I post it here if somebody else has the same issue:
I just modified the YiinfiniteScroller Class from the Yiinfinite Scroll Yii Extension and added the callback part for Infinite Scroll which was missing:
private function createInfiniteScrollScript() {
Yii::app()->clientScript->registerScript(
uniqid(),
"$('{$this->contentSelector}').infinitescroll(".$this->buildInifiniteScrollOptions().", ".$this->callback.");"
);
}
At the beginning of the class I added the line
public $callback;
to use it later in the method.
Then you can call the Widget with an additional option callback, for example like this:
'callback' => 'function( newElements ) {
// hide new items while they are loading
var $newElems = $( newElements ).css({ opacity: 0 });
// ensure that images load before adding to masonry layout
$newElems.imagesLoaded(function(){
// show elems now theyre ready
$newElems.animate({ opacity: 1 });
$(".items").masonry( "appended", $newElems, true );
});
}',
Works like charm.
I'm opening a simple modal and making an Ajax call with the following function.
function TransactionModal($id, $s) {
jQuery("#dialog").load("/chat/rejoin", { 'id': +$id, 's': +$s }, function()
{
jQuery("#dialog").modal({
overlay:80,
autoResize:false,
containerCss: {width: "490px", height: "538px"},
overlayCss: {backgroundColor:"#000"}
});
});
}
Because I have some Javascript running in the page I want to load, I need to use iframes, so the rejoin page has the following in it.
<IFRAME SRC="/chat/join/id/<?php echo $id; ?>/cid/<?php echo $cid;?>" width="500" height="535">
<!-- Alternate content for non-supporting browsers -->
Upgrade Browser to support iframes
</IFRAME>
That all works great.
The problem that I'm having is that when I click on the close button, it is resubmitting form data.
I have no idea why but it's driving me nuts.
If I refresh the page the modal goes away and doesn't resubmit.
If I click the X image to close it it does resubmit.
Please help if you have any idea why it's doing this!
function rejoinModal($id) {
var src = '/chat/join/id/'+$id ;
jQuery.modal('<iframe src="' + src + '" height="555" width="510" style="border:0">', {
containerCss:{
backgroundColor:"#000",
height:555,
width:510,
overFlow: "hidden",
},
});
}
i solved it by not calling the iframe from withing the ajax call.
it is working now.