I've made a Chrome extension in which user saves their important links in extension and pastes that link by click on contextmenu of Chrome, but there is a bug: it is not working for Google forms .
When I do click on submit button, the site is giving me an error that you missed the field.
What's the reason for this bug ?
Full content script code from my extension :
var element = null ;
document.addEventListener("contextmenu", function(event){
element = event.target;
});
var types = [
"text",
"url",
"search",
"tel",
"password",
"email",
"number",
"textarea"
];
function getCaretPosition(element){
var caretPos = 0;
/* Chrome and Firefox support */
if(!document.selection && $.inArray(element.type, types) >= 0){
/* element.selectionStart for type email give error because their is a bug in chrome */
if( element.type == 'email' || element.type == 'number' ){
caretPos = 0 ;
}else{
caretPos = element.selectionStart;
}
}
else {
/* IE support */
if(document.selection){
element.focus();
var sel = document.selection.createRange();
sel.moveStart('character', -element.value.length);
caretPos = sel.text.length;
}
}
return caretPos;
}
$(document).ready(function (){
chrome.runtime.onMessage.addListener( function (response , sender , sendResponse) {
var caretposition = getCaretPosition(element);
var initvalue = element.value ;
var first_part = initvalue.substr(0, caretposition);
var last_part = initvalue.substr(caretposition);
if(element.type == 'email' || element.type =='number'){
element.value = response.requested_link + initvalue;
} else {
var selected_text = element.value.substring(element.selectionStart, element.selectionEnd);
if ( selected_text != ''){
last_part = initvalue.substr(caretposition + selected_text.length);
}
element.value = first_part + response.requested_link + last_part;
}
});
});
Bug : I am not sending keypress event when my extension pastes something in the input/Textarea field .
Soultion : I solved this bug by using sendkeyevent , you can read about how to trigger sendkey event here . .
Related
I've a form which has 6 controls(Id, Title, Genre.....) for user to add an entry. Have 2 buttons one of which will add the entry and other will cancel it.
I've written $setPristine() in my cancel button click event in my controller
$scope.reset = function () {
var master = { Movid: '' }; //Movid--> <input type="text" name="Movid"
var master1 = { MovTitle: '' };
var master2 = { MovGnre: '' };
var master3 = { MovClafictn: '' };
var master4 = { MovRate: '' };
var master5 = { MovDate: '' };
$scope.temp = angular.copy(master);
$scope.temp1 = angular.copy(master1);
$scope.temp2 = angular.copy(master2);
$scope.temp3 = angular.copy(master3);
$scope.temp4 = angular.copy(master4);
$scope.temp5 = angular.copy(master5);
$scope.adduserform.$setPristine();
}
But when i click the Cancel button, only validation messages have reset and the values which are in controls still present with them.
Version i'm using
/*
AngularJS v1.3.14
(c) 2010-2014 Google, Inc. http://angularjs.org
License: MIT
*/
Is anything error in my code?????
I need to find out if a page(browser tab) is partially/fully hidden.
The page visibility api allows me to find paritally visible/ fully visible, fully hidden.
I need some way to find if page is partially/fully hidden.
http://www.w3.org/TR/page-visibility/#sec-document-interface
This code may work
(function() {
var hidden = "hidden";
// Standards:
if (hidden in document)
document.addEventListener("visibilitychange", onchange);
else if ((hidden = "mozHidden") in document)
document.addEventListener("mozvisibilitychange", onchange);
else if ((hidden = "webkitHidden") in document)
document.addEventListener("webkitvisibilitychange", onchange);
else if ((hidden = "msHidden") in document)
document.addEventListener("msvisibilitychange", onchange);
// IE 9 and lower:
else if ('onfocusin' in document)
document.onfocusin = document.onfocusout = onchange;
// All others:
else
window.onpageshow = window.onpagehide
= window.onfocus = window.onblur = onchange;
function onchange (evt) {
var v = 'visible', h = 'hidden',
evtMap = {
focus:v, focusin:v, pageshow:v, blur:h, focusout:h, pagehide:h
};
evt = evt || window.event;
if (evt.type in evtMap)
document.body.id = evtMap[evt.type];
else
document.body.id = this[hidden] ? "hidden" : "visible";
}
})();
function getHiddenProp(){
var prefixes = ['webkit','moz','ms','o'];
// if 'hidden' is natively supported just return it
if ('hidden' in document) return 'hidden';
// otherwise loop over all the known prefixes until we find one
for (var i = 0; i < prefixes.length; i++){
if ((prefixes[i] + 'Hidden') in document)
return prefixes[i] + 'Hidden';
}
// otherwise it's not supported
return null;
}
For more details Plz refer this link
This is the markup I use:
<input type="text" form="myform" name="inp1" />
<form id="myform" name="myform">
...
</form>
Now I realized that it does not work for old IE and therefore I am searching for a HTML 5 polyfill.
Anyone aware of a certain polyfill which covers this HTML5 feature?
I wrote this polyfill to emulate such feature by duplicating fields upon form submission, tested in IE6 and it worked fine.
(function($) {
/**
* polyfill for html5 form attr
*/
// detect if browser supports this
var sampleElement = $('[form]').get(0);
var isIE11 = !(window.ActiveXObject) && "ActiveXObject" in window;
if (sampleElement && window.HTMLFormElement && (sampleElement.form instanceof HTMLFormElement || sampleElement instanceof window.HTMLFormElement) && !isIE11) {
// browser supports it, no need to fix
return;
}
/**
* Append a field to a form
*
*/
$.fn.appendField = function(data) {
// for form only
if (!this.is('form')) return;
// wrap data
if (!$.isArray(data) && data.name && data.value) {
data = [data];
}
var $form = this;
// attach new params
$.each(data, function(i, item) {
$('<input/>')
.attr('type', 'hidden')
.attr('name', item.name)
.val(item.value).appendTo($form);
});
return $form;
};
/**
* Find all input fields with form attribute point to jQuery object
*
*/
$('form[id]').submit(function(e) {
// serialize data
var data = $('[form='+ this.id + ']').serializeArray();
// append data to form
$(this).appendField(data);
}).each(function() {
var form = this,
$fields = $('[form=' + this.id + ']');
$fields.filter('button, input').filter('[type=reset],[type=submit]').click(function() {
var type = this.type.toLowerCase();
if (type === 'reset') {
// reset form
form.reset();
// for elements outside form
$fields.each(function() {
this.value = this.defaultValue;
this.checked = this.defaultChecked;
}).filter('select').each(function() {
$(this).find('option').each(function() {
this.selected = this.defaultSelected;
});
});
} else if (type.match(/^submit|image$/i)) {
$(form).appendField({name: this.name, value: this.value}).submit();
}
});
});
})(jQuery);
The polyfill above doesn't take into account the Edge browser. I have amended it to use feature detection, which I have tested in IE7+, Edge, Firefox (mobile/desktop), Chrome (mobile/desktop), Safari (mobile/desktop), and Android browser 4.0.
(function($) {
/**
* polyfill for html5 form attr
*/
// detect if browser supports this
var SAMPLE_FORM_NAME = "html-5-polyfill-test";
var sampleForm = $("<form id='" + SAMPLE_FORM_NAME + "'/>");
var sampleFormAndHiddenInput = sampleForm.add($("<input type='hidden' form='" + SAMPLE_FORM_NAME + "'/>"));
sampleFormAndHiddenInput.prependTo('body');
var sampleElementFound = sampleForm[0].elements[0];
sampleFormAndHiddenInput.remove();
if (sampleElementFound) {
// browser supports it, no need to fix
return;
}
/**
* Append a field to a form
*
*/
$.fn.appendField = function(data) {
// for form only
if (!this.is('form')) return;
// wrap data
if (!$.isArray(data) && data.name && data.value) {
data = [data];
}
var $form = this;
// attach new params
$.each(data, function(i, item) {
$('<input/>')
.attr('type', 'hidden')
.attr('name', item.name)
.val(item.value).appendTo($form);
});
return $form;
};
/**
* Find all input fields with form attribute point to jQuery object
*
*/
$('form[id]').submit(function(e) {
// serialize data
var data = $('[form='+ this.id + ']').serializeArray();
// append data to form
$(this).appendField(data);
}).each(function() {
var form = this,
$fields = $('[form=' + this.id + ']');
$fields.filter('button, input').filter('[type=reset],[type=submit]').click(function() {
var type = this.type.toLowerCase();
if (type === 'reset') {
// reset form
form.reset();
// for elements outside form
$fields.each(function() {
this.value = this.defaultValue;
this.checked = this.defaultChecked;
}).filter('select').each(function() {
$(this).find('option').each(function() {
this.selected = this.defaultSelected;
});
});
} else if (type.match(/^submit|image$/i)) {
$(form).appendField({name: this.name, value: this.value}).submit();
}
});
});
})(jQuery);
I improved patstuart's polyfill, such that:
a form can now be submitted several times, e.g. when using the target attribute (external fields were duplicated previously)
reset buttons now work properly
Here it is:
(function($) {
/**
* polyfill for html5 form attr
*/
// detect if browser supports this
var SAMPLE_FORM_NAME = "html-5-polyfill-test";
var sampleForm = $("<form id='" + SAMPLE_FORM_NAME + "'/>");
var sampleFormAndHiddenInput = sampleForm.add($("<input type='hidden' form='" + SAMPLE_FORM_NAME + "'/>"));
sampleFormAndHiddenInput.prependTo('body');
var sampleElementFound = sampleForm[0].elements[0];
sampleFormAndHiddenInput.remove();
if (sampleElementFound) {
// browser supports it, no need to fix
return;
}
/**
* Append a field to a form
*
*/
var CLASS_NAME_POLYFILL_MARKER = "html-5-polyfill-form-attr-marker";
$.fn.appendField = function(data) {
// for form only
if (!this.is('form')) return;
// wrap data
if (!$.isArray(data) && data.name && data.value) {
data = [data];
}
var $form = this;
// attach new params
$.each(data, function(i, item) {
$('<input/>')
.attr('type', 'hidden')
.attr('name', item.name)
.attr('class', CLASS_NAME_POLYFILL_MARKER)
.val(item.value).appendTo($form);
});
return $form;
};
/**
* Find all input fields with form attribute point to jQuery object
*
*/
$('form[id]').submit(function(e, origSubmit) {
// clean up form from last submit
$('.'+CLASS_NAME_POLYFILL_MARKER, this).remove();
// serialize data
var data = $('[form='+ this.id + ']').serializeArray();
// add data from external submit, if needed:
if (origSubmit && origSubmit.name)
data.push({name: origSubmit.name, value: origSubmit.value})
// append data to form
$(this).appendField(data);
})
//submit and reset behaviour
$('button[type=reset], input[type=reset]').click(function() {
//extend reset buttons to fields with matching form attribute
// reset form
var formId = $(this).attr("form");
var formJq = $('#'+formId);
if (formJq.length)
formJq[0].reset();
// for elements outside form
if (!formId)
formId = $(this).closest("form").attr("id");
$fields = $('[form=' + formId + ']');
$fields.each(function() {
this.value = this.defaultValue;
this.checked = this.defaultChecked;
}).filter('select').each(function() {
$(this).find('option').each(function() {
this.selected = this.defaultSelected;
});
});
});
$('button[type=submit], input[type=submit], input[type=image]').click(function() {
var formId = $(this).attr("form") || $(this).closest("form").attr("id");
$('#'+formId).trigger('submit', this); //send clicked submit as extra parameter
});
})(jQuery);
after reading thru the docs of webshim it seems it has a polyfill for that.
http://afarkas.github.io/webshim/demos/demos/webforms.html
I made a vanilla JavaScript polyfill based on the above polyfills and uploaded it on GitHub: https://github.com/Ununnilium/form-attribute-polyfill.
I also added a custom event to handle the case when submit is processed by JavaScript and not directly by the browser. I tested the code only shortly with IE 11, so please check it yourself before use. The polling should maybe be replaced by a more efficient detection function.
function browserNeedsPolyfill() {
var TEST_FORM_NAME = "form-attribute-polyfill-test";
var testForm = document.createElement("form");
testForm.setAttribute("id", TEST_FORM_NAME);
testForm.setAttribute("type", "hidden");
var testInput = document.createElement("input");
testInput.setAttribute("type", "hidden");
testInput.setAttribute("form", TEST_FORM_NAME);
testForm.appendChild(testInput);
document.body.appendChild(testInput);
document.body.appendChild(testForm);
var sampleElementFound = testForm.elements.length === 1;
document.body.removeChild(testInput);
document.body.removeChild(testForm);
return !sampleElementFound;
}
// Ideas from jQuery form attribute polyfill https://stackoverflow.com/a/26696165/2372674
function executeFormPolyfill() {
function appendDataToForm(data, form) {
Object.keys(data).forEach(function(name) {
var inputElem = document.createElement("input");
inputElem.setAttribute("type", "hidden");
inputElem.setAttribute("name", name);
inputElem.value = data[name];
form.appendChild(inputElem);
});
}
var forms = document.body.querySelectorAll("form[id]");
Array.prototype.forEach.call(forms, function (form) {
var fields = document.querySelectorAll('[form="' + form.id + '"]');
var dataFields = [];
Array.prototype.forEach.call(fields, function (field) {
if (field.disabled === false && field.hasAttribute("name")) {
dataFields.push(field);
}
});
Array.prototype.forEach.call(fields, function (field) {
if (field.type === "reset") {
field.addEventListener("click", function () {
form.reset();
Array.prototype.forEach.call(dataFields, function (dataField) {
if (dataField.nodeName === "SELECT") {
Array.prototype.forEach.call(dataField.querySelectorAll('option'), function (option) {
option.selected = option.defaultSelected;
});
} else {
dataField.value = dataField.defaultValue;
dataField.checked = dataField.defaultChecked;
}
});
});
} else if (field.type === "submit" || field.type === "image") {
field.addEventListener("click", function () {
var obj = {};
obj[field.name] = field.value;
appendDataToForm(obj, form);
form.dispatchEvent(eventToDispatch);
});
}
});
form.addEventListener("submit", function () {
var data = {};
Array.prototype.forEach.call(dataFields, function (dataField) {
data[dataField.name] = dataField.value;
});
appendDataToForm(data, form);
});
});
}
// Poll for new forms and execute polyfill for them
function detectedNewForms() {
var ALREADY_DETECTED_CLASS = 'form-already-detected';
var newForms = document.querySelectorAll('form:not([class="' + ALREADY_DETECTED_CLASS + '"])');
if (newForms.length !== 0) {
Array.prototype.forEach.call(newForms, function (form) {
form.className += ALREADY_DETECTED_CLASS;
});
executeFormPolyfill();
}
setTimeout(detectedNewForms, 100);
}
// Source: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent
function polyfillCustomEvent() {
if (typeof window.CustomEvent === "function") {
return false;
}
function CustomEvent(event, params) {
params = params || {bubbles: false, cancelable: false, detail: undefined};
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
return evt;
}
CustomEvent.prototype = window.Event.prototype;
window.CustomEvent = CustomEvent;
}
if (browserNeedsPolyfill()) {
polyfillCustomEvent(); // IE is missing CustomEvent
// This workaround is needed if submit is handled by JavaScript instead the browser itself
// Source: https://stackoverflow.com/a/35155789/2372674
var eventToDispatch = new CustomEvent("submit", {"bubbles": true, "cancelable": true});
detectedNewForms(); // Poll for new forms and execute form attribute polyfill for new forms
}
I take some time to send an update for this polyfill because it doesn't work with MS Edge.
I add 2 line to fix it :
var isEdge = navigator.userAgent.indexOf("Edge");
if (sampleElement && window.HTMLFormElement && sampleElement.form instanceof HTMLFormElement && !isIE11 && isEdge == -1) {
// browser supports it, no need to fix
return;
}
UPDATE: Edge now support it:
https://caniuse.com/#feat=form-attribute
Whilst in a html textarea input, I want the tab keyboard button to act like a Word processor-style indentation key rather than skipping to the next element.
How can this be done?
google is your friend! link
function insertTab(o, e)
{
var kC = e.keyCode ? e.keyCode : e.charCode ? e.charCode : e.which;
if (kC == 9 && !e.shiftKey && !e.ctrlKey && !e.altKey)
{
var oS = o.scrollTop;
if (o.setSelectionRange)
{
var sS = o.selectionStart;
var sE = o.selectionEnd;
o.value = o.value.substring(0, sS) + "\t" + o.value.substr(sE);
o.setSelectionRange(sS + 1, sS + 1);
o.focus();
}
else if (o.createTextRange)
{
document.selection.createRange().text = "\t";
e.returnValue = false;
}
o.scrollTop = oS;
if (e.preventDefault)
{
e.preventDefault();
}
return false;
}
return true;
}
<textarea onkeydown="insertTab(this, event);"></textarea>
I am using zoho for live chat in my website. How to get that pop up which usually comes in most of the website
its code is some thing like this...
<div style="height:300px; width:300px; padding-top:20px;"><iframe style='overflow:hidden;width:100%;height:100%;' frameborder='0' border='0' src='http://chat.zoho.com/mychat.sas?U=c36599f3bbee3974d1af8b95ee04001b&chaturl=helpdesk&V=********************Center&smiley=false'></iframe></div>
How to make sure that this iframe must be loaded in a pop up..
try using window.open
window.open("http://chat.zoho.com/mychat.sas?U=c36599f3bbee3974d1af8b95ee04001b&chaturl=helpdesk&V=********************Center&smiley=false","mywindow","location=1,status=1,scrollbars=1,width=100,height=150");
Add page onLoad event to popup.
<body onLoad="window.open('http://chat.zoho.com/mychat.sas?U=c36599f3bbee3974d1af8b95ee04001b&chaturl=helpdesk&V=********************Center&smiley=false','mywindow','location=1,status=1,scrollbars=1,width=100,height=150');">
`
Here is the complete solution that worked for me
HTML CODE:--- chat.html contains the code i got from zoho...
Clickhere to chat with us
this is the main thing to be noticed...
rel="popup console 350 350"
Javascript code...
function addEvent(elm, evType, fn, useCapture){if(elm.addEventListener){elm.addEventListener(evType, fn, useCapture);return true;}else if (elm.attachEvent){var r = elm.attachEvent('on' + evType, fn);return r;}else{elm['on' + evType] = fn;}}
var newWindow = null;
function closeWin(){
if (newWindow != null){
if(!newWindow.closed)
newWindow.close();
}
}
function popUpWin(url, type, strWidth, strHeight){
closeWin();
type = type.toLowerCase();
if (type == "fullscreen"){
strWidth = screen.availWidth;
strHeight = screen.availHeight;
}
var tools="";
if (type == "standard") tools = "resizable,toolbar=yes,location=yes,scrollbars=yes,menubar=yes,width="+strWidth+",height="+strHeight+",top=0,left=0";
if (type == "console" || type == "fullscreen") tools = "resizable,toolbar=no,location=no,scrollbars=no,width="+strWidth+",height="+strHeight+",left=0,top=0";
newWindow = window.open(url, 'newWin', tools);
newWindow.focus();
}
function doPopUp(e)
{
//set defaults - if nothing in rel attrib, these will be used
var t = "standard";
var w = "780";
var h = "580";
//look for parameters
attribs = this.rel.split(" ");
if (attribs[1]!=null) {t = attribs[1];}
if (attribs[2]!=null) {w = attribs[2];}
if (attribs[3]!=null) {h = attribs[3];}
//call the popup script
popUpWin(this.href,t,w,h);
//cancel the default link action if pop-up activated
if (window.event)
{
window.event.returnValue = false;
window.event.cancelBubble = true;
}
else if (e)
{
e.stopPropagation();
e.preventDefault();
}
}
function findPopUps()
{
var popups = document.getElementsByTagName("a");
for (i=0;i<popups.length;i++)
{
if (popups[i].rel.indexOf("popup")!=-1)
{
// attach popup behaviour
popups[i].onclick = doPopUp;
// add popup indicator
if (popups[i].rel.indexOf("noicon")==-1)
{
popups[i].style.backgroundImage = "url(pop-up.gif)";
popups[i].style.backgroundPosition = "0 center";
popups[i].style.backgroundRepeat = "no-repeat";
popups[i].style.paddingLeft = "3px";
}
// add info to title attribute to alert fact that it's a pop-up window
popups[i].title = popups[i].title + " [Opens in pop-up window]";
}
}
}
addEvent(window, 'load', findPopUps, false);