How to add this jQuery script to coffeescript - coffeescript

I am new to coffeescript and not sure how to add this code to it. How do I write it in coffeescript language?
$(function() {
YesClick.attach(document.body);
});
So far I have this but not compiling as same code:
$ ->
do YesClick = ->
YesClick.attach(document.body)
return

At first I had no idea what do was, but it turns out it is actually a thing, for anyone who doesn't know this. http://rzrsharp.net/2011/06/27/what-does-coffeescripts-do-do.html
Anyway, it's not necessary here, and the JS:
$(function() {
YesClick.attach(document.body);
});
Can be written as:
$ ->
YesClick.attach(document.body)

Related

Use babel transform with create-react-app

I am working on a javaScript / react playground (something like very simple codesandbox.io) and I'm trying to figure out how to transpile the code. I was thinking of using Babel transform but the app itself is built using create-react-app so I do not have access to Babel. My question is, if I do something like the following and install Babel, will it also override how create-rect-app currently transpiles the code for the app?
// transpile.js
const babelOptions = {
presets: [ "react", ["es2015", { "modules": false }]]
}
export default function preprocess(str) {
const { code } = Babel.transform(str, babelOptions);
return code;
}
EDIT:
I've since learned that I can use Babel standalone for exactly this use case! Now it's just to figure out how to configure it. I would still appreciate help but if I find a solution first I will post for others :)
Ok so I have figured this out but it is not straight forward. I will try to add some details here in case anyone else finds it helpful.
I first needed to load Babel standalone and so I used this answer to create a custom hook to load a script:
import { useEffect } from 'react';
const useScript = url => {
useEffect(() => {
const script = document.createElement('script');
script.src = url;
script.async = true;
document.body.appendChild(script);
console.log(`${url} script loaded`);
return () => {
document.body.removeChild(script);
console.log(`${url} script removed`);
}
}, [url]);
};
export default useScript;
then I used it in my component like this:
import useScript from '../../../hooks/useScript';
useScript("https://unpkg.com/#babel/standalone/babel.min.js");
then I later use the code I wrote in the initial question to transpile my code.

Ionic 3 loading Google Pay library

I'm trying to implement Google Pay to my Ionic app. As I didn't find any convenient library matching both, I tried to use what is described here
https://developers.google.com/pay/api/web/guides/tutorial#full-example.
Problem: loading the pay.js library
I don't know how to load the library pay.js in my Ionic project.
I hope that's pretty clear.
Thanks for your help.
You need to first include the pay.js library.
The preferred method is to include the script in your page:
<script src="https://pay.google.com/gp/p/js/pay.js" async></script>
Alternatively, if you need to load it with JavaScript you could dynamically load the script:
function loadScript(src) {
return new Promise(function(resolve, reject) {
let script = document.createElement('script');
script.src = src;
script.onload = () => resolve(script);
script.onerror = () => reject(new Error(`Script load error for ${src}`));
document.head.append(script);
});
}
loadScript('https://pay.google.com/gp/p/js/pay.js')
.then(() => getGooglePayPaymentsClient());
For code completion in supported editors, you can use the #types/googlepay package:
npm install --save-dev #types/googlepay

getJSON method issue (jquery mobile)

I want to get some json object from a remote server.
Here is the simplest html you can imagine:
<div id="getHotels" data-theme="e" data-role="button">Get hotels</div>
<ul id="bringHotels" data-role="listview"></ul>
and here is the javascript:
$("#getHotels").click(function(){
$.getJSON("/services/apexrest/Hotels", function(obj){
$.each(obj,function(key,value){
$("#bringHotels").append("<li>"+value.Hotel_Name__c+"</li>");
});
});
});
i have never used the getJSON method but it seems to be quite clear, despite that it doesnt work and I checked the directory - there really is JSON array. So, if I am doing it wrong, please correct me, thank you.
There are no enough informations about the problem to solve it...
It could be a problem in the URL you pass to getJSON. Try to change the first slash with a ./, or use other callbacks to obtain more debug infos:
$.getJSON("example.json", function() {
alert("success");
})
.success(function() { alert("second success"); })
.error(function() { alert("error"); })
.complete(function() { alert("complete"); });

inject a javascript function into an Iframe

This link (archived version) describes how to inject code from a script into an iframe:
function injectJS() {
var iFrameHead = window.frames["myiframe"].document.getElementsByTagName("head")[0];
var myscript = document.createElement('script');
myscript.type = 'text/javascript';
myscript.src = 'myscript.js'; // replace this with your SCRIPT
iFrameHead.appendChild(myscript);
}
That's ok, but what if I want to insert a function object into an iframe and get it executed in the iframe context? Let's say I have:
function foo () {
console.log ("Look at me, executed inside an iframe!", window);
}
and I want to insert foo's code inside an iframe? (function foo could be something loaded dynamically, I can't just wrap it in quotes)
I naively tried:
var scriptFooString = "<script>" + foo.toString() + "</script>"
to get the code inside function, but
I don't know how to insert it in the iframe HEAD (maybe with jquery?)
I don't know if it's the right way
I don't know what happens when if function is way more complex than that
I don't know what happens with double and single quotes in scriptFooString
Any hint?
First of all you can only accomplish this if your frame and the page displaying it is within the same domain (Due to cross-domain rules)
secondly you can manipulate dom and window objects of the frame directly through JS:
frames[0].window.foo = function(){
console.log ("Look at me, executed inside an iframe!", window);
}
to get your frame from a DOMElement object you can use:
var myFrame = document.getElementById('myFrame');
myFrame.contentWindow.foo = function(){
console.log ("Look at me, executed inside an iframe!");
}
Note that the scope in foo is NOT changed, so window is still the parent window etc. inside foo.
If you want to inject some code that needs to be run in the context of the other frame you could inject a script tag, or eval it:
frames[0].window.eval('function foo(){ console.log("Im in a frame",window); }');
Though the general consensus is to never use eval, I think its a better alternative than DOM injection if you REALLY need to accomplish this.
So in your specific case you could do something like:
frames[0].window.eval(foo.toString());
This code is the result of my research. The accepted answer also helped me a lot.
First of all, I create a simple iframe:
<iframe id="myiframe" width="200" height="200" srcdoc="<h1 id='title'>Hello from Iframe</h1><button type='button' id='fire'>Click Me!</button>
"></iframe>
For access to iframe's window and document I used this code.
const iframe = document.getElementById('myiframe');
const iframeWin = iframe.contentWindow || iframe;
const iframeDoc = iframe.contentDocument || iframeWin.document;
Finally I injected js codes into iframe:
var script = iframeDoc.createElement("script");
script.append(`
window.onload = function() {
document.getElementById("fire").addEventListener('click', function() {
const text = document.getElementById('title').innerText;
alert(text);
})
}
`);
iframeDoc.documentElement.appendChild(script);
Demo:
https://jsfiddle.net/aliam/1z8f7awk/2/
Here's my solution. I'm using jquery to insert the content, then using eval to execute the script tags in the context of that iframe:
var content = $($.parseHTML(source, document, true));
$("#content").contents().find("html").html(content);
var cw = document.getElementById("content").contentWindow;
[].forEach.call(cw.document.querySelectorAll("script"), function (el, idx) {
cw.eval(el.textContent);
});

can't tap on item in google autocomplete list on mobile

I'm making a mobile-app using Phonegap and HTML. Now I'm using the google maps/places autocomplete feature. The problem is: if I run it in my browser on my computer everything works fine and I choose a suggestion to use out of the autocomplete list - if I deploy it on my mobile I still get suggestions but I'm not able to tap one. It seems the "suggestion-overlay" is just ignored and I can tap on the page. Is there a possibility to put focus on the list of suggestions or something that way ?
Hope someone can help me. Thanks in advance.
There is indeed a conflict with FastClick and PAC. I found that I needed to add the needsclick class to both the pac-item and all its children.
$(document).on({
'DOMNodeInserted': function() {
$('.pac-item, .pac-item span', this).addClass('needsclick');
}
}, '.pac-container');
There is currently a pull request on github, but this hasn't been merged yet.
However, you can simply use this patched version of fastclick.
The patch adds the excludeNode option which let's you exclude DOM nodes handled by fastclick via regex. This is how I used it to make google autocomplete work with fastclick:
FastClick.attach(document.body, {
excludeNode: '^pac-'
});
This reply may be too late. But might be helpful for others.
I had the same issue and after debugging for hours, I found out this issue was because of adding "FastClick" library. After removing this, it worked as usual.
So for having fastClick and google suggestions, I have added this code in geo autocomplete
jQuery.fn.addGeoComplete = function(e){
var input = this;
$(input).attr("autocomplete" , "off");
var id = input.attr("id");
$(input).on("keypress", function(e){
var input = this;
var defaultBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(37.2555, -121.9245),
new google.maps.LatLng(37.2555, -121.9245));
var options = {
bounds: defaultBounds,
mapkey: "xxx"
};
//Fix for fastclick issue
var g_autocomplete = $("body > .pac-container").filter(":visible");
g_autocomplete.bind('DOMNodeInserted DOMNodeRemoved', function(event) {
$(".pac-item", this).addClass("needsclick");
});
//End of fix
autocomplete = new google.maps.places.Autocomplete(document.getElementById(id), options);
google.maps.event.addListener(autocomplete, 'place_changed', function() {
//Handle place selection
});
});
}
if you are using Framework 7, it has a custom implementation of FastClicks. Instead of the needsclick class, F7 has no-fastclick. The function below is how it is implemented in F7:
function targetNeedsFastClick(el) {
var $el = $(el);
if (el.nodeName.toLowerCase() === 'input' && el.type === 'file') return false;
if ($el.hasClass('no-fastclick') || $el.parents('.no-fastclick').length > 0) return false;
return true;
}
So as suggested in other comments, you will only have to add the .no-fastclick class to .pac-item and in all its children
I was having the same problem,
I realized what the problem was that probably the focusout event of pac-container happens before the tap event of the pac-item (only in phonegap built-in browser).
The only way I could solve this, is to add padding-bottom to the input when it is focused and change the top attribute of the pac-container, so that the pac-container resides within the borders of the input.
Therefore when user clicks on item in list the focusout event is not fired.
It's dirty, but it works
worked perfectly for me :
$(document).on({
'DOMNodeInserted': function() {
$('.pac-item, .pac-item span', this).addClass('needsclick');
}
}, '.pac-container');
Configuration: Cordova / iOS iphone 5