Windows Metro: links in img tag won't work - windows-8

I am developing an app in Metro using HTML+Javascript. My links are not working when they are used to create a link in a img tag:
<h4>Go to child page</h4>
<img src="/images/home/child.jpg" />
The first link works OK and the second does not. When I click the image, it blocks the app.
For the links, I'm using a Application.PageControlNavigator as suggested in the documentation. My JS has:
(function () {
"use strict";
function linkClickEventHandler(eventInfo) {
eventInfo.preventDefault();
var link = eventInfo.target;
WinJS.Navigation.navigate(link.href);
}
WinJS.UI.Pages.define("/pages/home/home.html", {
ready: function (element, options) {
WinJS.Utilities.query("a").listen("click", linkClickEventHandler, false);
WinJS.UI.processAll();
}
});
})();

The problem is that the link.href returns the src string instead of the href string when having the tag used inside the tag . In your case the link.href returns "/images/home/child.jpg". I asssume this is a bug and not a feature. The workaround is not to use the href.link.

You can do this:
Use the onclick property of the <a> tag and call a handler() function as shown below:
<a onclick="handler();"><img src="/images/home/child.png" /></a>
Body of the handler function is as shown below:
function handler()
{
WinJS.Navigation.navigate('/pages/childpage.html');
}
Worked fine for me.

By blocks, I assume you mean "hang"? Is it calling your linkClickEventHandler when you click the image?

Related

How to embed codepen as HTML in vue.js

I can't figure out how to embed a codepen using the recommended HTML method i a Vue application.
As <script> tag cannot be part of a Vue component template, I tried to add it to index.html where my Vue application is injected without luck. However, when I tried to paste the html code outside the div where Vue resides, the code got turned into an iFrame as it should.
Here is the HTML embed:
<p data-height="265" data-theme-id="0" data-slug-hash="JyxKMg" data-default-tab="js,result" data-user="sindael" data-embed-version="2" data-pen-title="Fullscreen image gallery using Wallop, Greensock and Flexbox" class="codepen">See the Pen Fullscreen image gallery using Wallop, Greensock and Flexbox by Dan (#sindael) on CodePen.</p>
And the script:
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
Embedding an iFrame directly works fine, but I wonder. Is there a way how to get the html working?
Look into the https://static.codepen.io/assets/embed/ei.js, then you will see it executes two steps:
check document.getElementsByClassName if exists, create it if not.
one IIFE to execute the embed.
So one hacky way as below simple demo:
copy the source codes from https://static.codepen.io/assets/embed/ei.js
copy the codes of first step then wrap it as one function = _codepen_selector_contructor
copy the codes of second step and remove () from the end, then wrap it as one function = _codepen_embed_method
create one vue-directive (I prefer using the directive to support the features which directly process Dom elements, you can use other solutions), then execute _codepen_selector_contructor and _codepen_embed_method
Probably you want to replace document inside _codepen_embed_method with el instead, then execute _codepen_embed_method(el). so that it will not affects other elements.
Below demo uses the hook='inserted', you could use other hooks if inserted can't meet your requirements.
let vCodePen = {}
vCodePen.install = function install (Vue) {//copy from https://static.codepen.io/assets/embed/ei.js
let _codepen_selector_contructor = function () {
document.getElementsByClassName||(document.getElementsByClassName=function(e){var n,t,r,a=document,o=[];if(a.querySelectorAll)return a.querySelectorAll("."+e);if(a.evaluate)for(t=".//*[contains(concat(' ', #class, ' '), ' "+e+" ')]",n=a.evaluate(t,a,null,0,null);r=n.iterateNext();)o.push(r);else for(n=a.getElementsByTagName("*"),t=new RegExp("(^|\\s)"+e+"(\\s|$)"),r=0;r<n.length;r++)t.test(n[r].className)&&o.push(n[r]);return o})
}
let _codepen_embed_method = //copy from https://static.codepen.io/assets/embed/ei.js then removed `()` from the end
function(){function e(){function e(){for(var e=document.getElementsByClassName("codepen"),t=e.length-1;t>-1;t--){var u=a(e[t]);if(0!==Object.keys(u).length&&(u=o(u),u.user=n(u,e[t]),r(u))){var c=i(u),l=s(u,c);f(e[t],l)}}m()}function n(e,n){if("string"==typeof e.user)return e.user;for(var t=0,r=n.children.length;t<r;t++){var a=n.children[t],o=a.href||"",i=o.match(/codepen\.(io|dev)\/(\w+)\/pen\//i);if(i)return i[2]}return"anon"}function r(e){return e["slug-hash"]}function a(e){for(var n={},t=e.attributes,r=0,a=t.length;r<a;r++){var o=t[r].name;0===o.indexOf("data-")&&(n[o.replace("data-","")]=t[r].value)}return n}function o(e){return e.href&&(e["slug-hash"]=e.href),e.type&&(e["default-tab"]=e.type),e.safe&&("true"===e.safe?e.animations="run":e.animations="stop-after-5"),e}function i(e){var n=u(e),t=e.user?e.user:"anon",r="?"+l(e),a=e.preview&&"true"===e.preview?"embed/preview":"embed",o=[n,t,a,e["slug-hash"]+r].join("/");return o.replace(/\/\//g,"//")}function u(e){return e.host?c(e.host):"file:"===document.location.protocol?"https://codepen.io":"//codepen.io"}function c(e){return e.match(/^\/\//)||!e.match(/https?:/)?document.location.protocol+"//"+e:e}function l(e){var n="";for(var t in e)""!==n&&(n+="&"),n+=t+"="+encodeURIComponent(e[t]);return n}function s(e,n){var r;e["pen-title"]?r=e["pen-title"]:(r="CodePen Embed "+t,t++);var a={id:"cp_embed_"+e["slug-hash"].replace("/","_"),src:n,scrolling:"no",frameborder:"0",height:d(e),allowTransparency:"true",allowfullscreen:"true",allowpaymentrequest:"true",name:"CodePen Embed",title:r,"class":"cp_embed_iframe "+(e["class"]?e["class"]:""),style:"width: "+p+"; overflow: hidden;"},o="<iframe ";for(var i in a)o+=i+'="'+a[i]+'" ';return o+="></iframe>"}function d(e){return e.height?e.height:300}function f(e,n){if(e.parentNode){var t=document.createElement("div");t.className="cp_embed_wrapper",t.innerHTML=n,e.parentNode.replaceChild(t,e)}else e.innerHTML=n}function m(){"function"==typeof __CodePenIFrameAddedToPage&&__CodePenIFrameAddedToPage()}var p="100%";e()}function n(e){/in/.test(document.readyState)?setTimeout("window.__cp_domReady("+e+")",9):e()}var t=1;window.__cp_domReady=n,window.__CPEmbed=e,n(function(){new __CPEmbed})}
let defaultProps = {class: 'codepen', 'data-height':265, 'data-theme-id':0, 'data-slug-hash':'', 'data-default-tab':'js,result', 'data-user':'sindael', 'data-embed-version':'2', 'data-pen-title':''}
Vue.directive('code-pen', {
inserted: function (el, binding, vnode) {
let options = Object.assign({}, defaultProps, binding.value)
Object.entries(options).forEach((item) => {
el.setAttribute(item[0], item[1])
})
setTimeout(() => {
_codepen_selector_contructor()
_codepen_embed_method() //_codepen_embed_method(el); you can pass el to take place of `document`
}, 100)
},
componentUpdated: function (el, binding, vnode) {
}
})
}
Vue.use(vCodePen)
Vue.config.productionTip = false
app = new Vue({
el: "#app",
data: {
keyword: '',
},
mounted: function () {
},
methods: {
}
})
<script src="https://unpkg.com/vue#2.5.16/dist/vue.js"></script>
<div id="app">
<p v-code-pen="{class: 'codepen', 'data-height':'265', 'data-theme-id':0, 'data-slug-hash':'JyxKMg', 'data-default-tab':'js,result', 'data-user':'sindael', 'data-embed-version':'2', 'data-pen-title':'Test'}">
</p>
</div>

Riot JS unmount all tags in a page and then mount only one tag is not working

I am using Riot JS and in my index.html, I have 3 custom tags - header, login-panel and candidates-panel inside my body. In my main app.js, in the callback function of $(document).ready, I execute the current route and also register a route change handler function. In my switchView, I unmount all custom tags and then try to mount only the tag pertaining to the current view being switched. Here is my code. If I do unmount, then nothing is displayed on the page
index.html
<body>
<header label="Hire Zen" icon="img/user-8-32.png"></header>
<login-panel class="viewTag" id="loginView"></login-panel>
<candidates-panel id="candidatesView" class="viewTag"></candidates-panel>
<script src="js/bundle.js"></script>
</body>
app.js
function switchView(view) {
if(!view || view === '') {
view = 'login'
}
//unmount all other panels and mount only the panel that is required
//TODO: unmount all view panels and mounting only required panel is not working
//riot.unmount('.viewTag')
riot.mount(view+'-panel')
$('.viewTag').hide()
$(view+'-panel').show()
}
$(document).ready(function () {
RiotControl.addStore(new AuthStore())
RiotControl.addStore(new CandidatesStore())
riot.mount('header')
//register route change handler
riot.route(function (collection, id, action) {
switchView(collection)
})
riot.route.exec(function (collection, id, action) {
switchView(collection)
})
})
Answer for riot.js v2.1.0:
The function
riot.unmount(...)
is not available as far as I know. However, you can unmount saved tags.
mytag.unmount(true)
Source
The trick is to remember the mounted tags to be able to unmount them later:
var viewTag = riot.mount(document.getElementById('viewTag'))
viewTag.unmount(true)
You can store all those view tags in an object and loop them to unmount all and mount only the active one.
Source
Answer for 2.3.18
Based on the previous answer and this tutorial I have created following concept:
app.currentPage = null;
var goTo = function(page){
if (app.currentPage) {
app.currentPage.unmount(true); //unmount and keep parent tag
}
app.currentPage = riot.mount(page)[0]; //remember current page
};
riot.route(function() {
console.info("this page is not defined");
//do nothing (alternatively go to 404 page or home)
});
riot.route('/inventory', function(){
goTo('inventory');
});
riot.route('/options', function() {
goTo('options');
});
I think you are looking for riot.util.tags.unmountAll(tags)
How to achieve the goal?
index.html
var tags = [];
some.tag.html
var some = this;
tags.push(some);
unmountAllTags.js
riot.util.tags.unmountAll(tags);

Disable the escape key in dojo

I have a requirement to disable the escape key when the dialog is open.currently when i click the escape button the dialog closes and the transaction is submitting.I tried the following code snippet but its not working chrome.
dojo.connect(dialog, "onKeyPress", function(e){
var key = e.keyCode || e.charCode;
var k = dojo.keys;
if (key == k.ESCAPE) {
event.preventDefault();
d.stopEvent(event);
}
});
Could you please help on this..i have searched a lot and havent found a suitable solution for my problem.
Thanks inadvance..
Dojo uses the _onKey event for accessibility. You can override it by using:
dialog._onKey = function() { }
I wrote an example JSFiddle, hitting the Escape key should not work anymore.
In the event you want to override the escape key in all dialogs (rather than a particular instance), you can use dojo/aspect:
require(['dojo/aspect', 'dijit/Dialog'], function (Aspect, Dialog) {
Aspect.around(Dialog.prototype, '_onKey', function (original) {
return function () { }; // no-op
});
});
You can create an extension for the Dialog widget like this in a new file:
define(["dojo/_base/declare", "dijit/Dialog"],
function(declare, Dialog){
return declare(Dialog, {
//Prevents the 'ESC' Button of Closing the dialog
_onKey: function() { }
});
});
save the file into dojo Directory (say: dojo/my/my_dialog.js),
and instead of calling: 'dijit/Dialog', just call: 'my/my_dialog'.
this will save you the hard work of editing each Dialog call,
And the same thing to the "dojox/widget/DialogSimple" Widget.

Disqus Plugin Explanation of Dynamic Tags

So I am using the Disqus Plugin v2.65. I am trying to edit the dsq-global-toolbar at the top of the Disqus comments.
The following tags are in disqus-comment-system/comments.php
<div id="disqus_thread">
<?php if (!get_option('disqus_disable_ssr')): ?>
<?php
// if (is_file(TEMPLATEPATH . '/comments.php')) {
// include(TEMPLATEPATH . '/comments.php');
// }
?>
<div id="dsq-content">
<ul id="dsq-comments">
however on my site there are mulitple tags (the disqus-global-toolbar div) that seem to be dynamically appended between the dsq-content div and the dsq-comments ul. Where is this coming from and where can I edit this? Any help would be greatly appreciated.
I think it is coming somewhere around line 3140 in disqus.js
You can use this code to wait for the document to finish loading completely then do your changes (client side):
$(document).ready(function() {
window.disqus_no_style = true;
$.getScript('http://sitename.disqus.com/embed.js', function() {
var loader = setInterval(function() {
if($('#disqus_thread').html().length) {
clearInterval(loader);
disqusReady();
}
}, 1000);
});
function disqusReady() {
//whatever you can imagine
}
});
window.diqus_no_style can be deleted as well as the $.getsript wrapper.
Is that what you are looking for?
Something like this (use livequery instead of live):
function disqusReady() {
$('#dsq-global-toolbar').livequery(function() {
//$(this) will refer to object
});
}
Not sure what plug-in you're talking about, but if it's WordPress, I've done the same thing. Modify wp-content/plug-ins/disqus-comment-system/comments.php by adding an event handler for 'afterRender' (fires when the content ready in the DOM, but still hidden), eg. around line 70:
config.callbacks.afterRender.push(myFunctionToModifyDisqusOutput);

jCaptcha - Refresh only image not whole page

I'm using jCaptcha (http://jcaptcha.sourceforge.net/) on our website. The problem is sometimes it's very difficult to read the image. So, we are planning to provide a button named 'REFRESH' next to the jcaptcha image and upon clicking REFRESH button, it has to refresh only the jcaptcha image not the entire page/portlet. How can we do that?
This is how I solved it using JQuery, it will replace the image. The alert() is just there to show off the new filename and can of course be removed. The code is using the jquery plugin in grails but shows what to do in jquery to refresh the image.
<div>
<jcaptcha:jpeg name="captchaImage"/>
Refresh captcha
<jq:jquery>
$("#refreshCaptcha").click(function() {
$("#captchaImage").fadeOut(500, function() {
var captchaURL = $("#captchaImage").attr("src");
captchaURL = captchaURL.replace(captchaURL.substring(captchaURL.indexOf("=")+1, captchaURL.length), Math.floor(Math.random()*9999999999));
alert(captchaURL);
$("#captchaImage").attr("src", captchaURL);
});
$("#captchaImage").fadeIn(300);
});
</jq:jquery>
</div>
Make this changes in JSP :
<img src="jcaptcha" id="captcha_image"/> Refresh
Add the Javascript function like :
function reloadCaptcha(){
var d = new Date();
$("#captcha_image").attr("src", "jcaptcha?"+d.getTime());
}
You would have to load the image and the refresh button into . Than you should be able to refresh just the iframe. But the I don't know how you are performing your validation so.
Set an id for the img tag and let it call a javascript function:
<img src="jcaptcha.jpg" id="captchaImage"/>
javascript function:
<script type="text/javascript">
function refresh()
{
var captchaImage=document.getElementById("captchaImage");
captchaImage.src="jcaptcha.jpg";
}
</script>
this works fine because i implemented this one in my project just create one button on clicking that button it will come to below menctiond block of code like that you do
<script type="text/javascript">
function refresh()
{
var image=document.getElementById("kaptchaImage");
image.src="<%=request.getContextPath()%>/kaptcha.jpg?"+Math.floor(Math.random()*100)
}
</script>