I use a Greasemonkey script in Firefox to intercept a submit process in order to modify a certain post variable. I save the old submit routine to call it later and overwrite HTMLFormElement.prototype.submit with my interception (modification) function.
The problem I am currently facing is that something drops the post variable post=Submit and calling the (old) submit function after the modification takes me back to the current page.
var intercept_complete = false;
window.addEventListener('submit', function (e) {
e.stopPropagation();
e.preventDefault();
interceptor(e);
}, true);
function interceptor_setup() {
HTMLFormElement.prototype.real_submit = HTMLFormElement.prototype.submit;
HTMLFormElement.prototype.submit = interceptor;
}
function interceptor(e) {
var frm = e ? e.target : this;
if (!interceptor_onsubmit(frm)) {
return false;
}
if (!intercept_complete) {
ModifyAndPost(frm);
return false;
} else {
HTMLFormElement.prototype.real_submit.apply(frm);
return true;
}
}
function interceptor_onsubmit(f) {
return !f.onsubmit || f.onsubmit();
}
function ModifyAndPost(f) {
var attrs = new Array('name', 'type', 'value');
for (var i = 0; i < f.elements.length; i++) {
for (var a = 0; a < attrs.length; a++) {
if (attrs[a] == 'name') {
if (f.elements[i][attrs[a]] == "message") {
var current_message = f.elements[i][attrs[a + 2]];
if (current_message.indexOf("hello") != -1) {
var do_replace = confirm("Detected hello, would you like to replace that with bye?");
if (do_replace) {
f.elements[i][attrs[a + 2]] = current_message.replace("hello", "bye");
}
}
}
}
}
}
PerformSubmit(f);
}
function PerformSubmit(f) {
HTMLFormElement.prototype.real_submit.apply(f);
}
interceptor_setup();
Basically the script works and modifies the post variables successfully but when calling HTMLFormElement.prototype.real_submit.apply(f); to submit the modified form the request is missing the Post=Submit variable and the submit fails.
I tried removing e.stopPropagation() and e.preventDefault() and then it worked sometimes, but still dropped that post variable once in a while.
Would be great if anyone could point me in the right direction on this one. ;)
Related
How can I override (or hook) the function Liferay.Util.focusFormField in Liferay 7.0?
The method is defined in frontend-js-aui-web (portal-src\modules\apps\foundation\frontend-js\frontend-js-aui-web\src\main\resources\META-INF\resources\liferay\util.js).
The only way I could think of is to just overwrite it somewhere in a js-file, like so:
Liferay.Util.focusFormField = function(el) {
var doc = $(document);
var interacting = false;
el = Util.getDOM(el);
el = $(el);
doc.on(
'click.focusFormField',
function (event) {
interacting = true;
doc.off('click.focusFormField');
}
);
if (!interacting && Util.inBrowserView(el)) {
var form = el.closest('form');
var focusable = !el.is(':disabled') && !el.is(':hidden') && !el.parents(':disabled').length;
if (!form.length || focusable) {
el.focus(false); // modified
}
else {
var portletName = form.data('fm-namespace');
Liferay.once(
portletName + 'formReady',
function () {
el.focus(false); // modified
}
);
}
}
}
All I actually want is to disable the scrolling that happens whenever a form is submitted.
Does someone know what to do best to achieve this?
Another thing I found on the web is this: https://alloyui.com/api/files/alloy-ui_src_aui-form-validator_js_aui-form-validator.js.html#l216
But I cannot find it in liferay-7.0-source-files and no explanation how to override it.
I need help in javascript, my code in woocomerce (checkout) is:
<script type="text/javascript">
document.getElementById("billing_city").onkeyup = function validarDistrito(event){
// do stuff
var billinginfo = document.getElementsByName("billing_city")[0].value;
var distritoArray= ["Barranco","Breña","Jesús María","La Victoria","Lince","Miraflores","Pueblo Libre","San Borja","San Isidro","San Luis","San Miguel","Surco","Surquillo","Callao","La Molina","Lima Cercado","Magdalena", "Rimac", "Lima Metropolitana"];
console.log(billinginfo);
for (i = 0; i < distritoArray.length; i++) {
if(distritoArray[i].toUpperCase() == billinginfo.toUpperCase()){
document.getElementById('payment_method_bacs').disabled = false;
alert('igual');
}else{
document.getElementById('payment_method_bacs').disabled = true;
}
}
event.preventDefault();
}
</script>
The code work very good, but then a few seconds later it updated and returns to a previous state. And I use the method preventDefault (); but it does not work in wordpress.
PD: the same holds true using jquery.
Thanks!
You are using e.preventDefault(); when it must be event.preventDefault();
take a look at validarDistrito(event), you named event the variable
try this code
<script>
document.getElementById("billing_city").onkeyup = function validarDistrito(event){
// do stuff
var billinginfo = document.getElementsByName("billing_city")[0].value;
var distritoArray= ["Barranco","Breña","Jesús María","La Victoria","Lince","Miraflores","Pueblo Libre","San Borja","San Isidro","San Luis","San Miguel","Surco","Surquillo","Callao","La Molina","Lima Cercado","Magdalena", "Rimac", "Lima Metropolitana"];
console.log(billinginfo);
for (i = 0; i < distritoArray.length; i++) {
if(distritoArray[i].toUpperCase() == billinginfo.toUpperCase()){
document.getElementById('payment_method_bacs').disabled = false;
return;
}else{
document.getElementById('payment_method_bacs').disabled = true;
}
}
event.preventDefault();
}
</script>
the thing is that distroArray will keep validating the rest of it, so if the input value is equal to one of the values of the array, you need to stop validating
I have three URLs that return different JSON responses (say user mobiles, addresses and emails) being populated from different beans.
url='/mobile.do?username=x&password=y'
url='/email.do?username=x&password=y'
url='/address.do?username=x&password=y'
For the following autocomplete plugin (fcbkcomplete):
<script type="text/javascript">
$(document).ready(function(){
$("#mySelect").fcbkcomplete({
json_url: "?!!",
});
});
</script>
Now I want to use these URLs to populate and add data to a single field rather than three different fields. Hence, somehow I need to mix these URL or something like this.
I was wondering what is the best way for this? Can we set more than one URLs or something?
You could modify the plugin, by changing the function load_feed. This isn't tested, so might need some tweeking.
function load_feed(etext) {
counter = 0;
if (options.json_url_list && maxItems()) {
if (options.cache && json_cache_object.get(etext)) {
addMembers(etext);
bindEvents();
} else {
getBoxTimeout++;
var getBoxTimeoutValue = getBoxTimeout;
setTimeout(function () {
if (getBoxTimeoutValue != getBoxTimeout) return;
var count = 0;
var all_data = [];
var finished = function () {
if (!isactive) return; // prevents opening the selection again after the focus is already off
json_cache_object.set(etext, 1);
bindEvents();
};
for (var i = 0; i < options.json_url_list.length; i++) {
$.getJSON(options.json_url_list[i], {
"tag": xssDisplay(etext)
}, function (data) {
addMembers(etext, data);
count += 1;
if (count === options.json_url_list.length) finished();
});
}
}, options.delay);
}
} else {
addMembers(etext);
bindEvents();
}
}
I am trying to modify an existing web page which looks like this
<script type="text/javascript" src="s1.js"></script>
s1.js has something like this
window.onDomReady = DomReady;
function DomReady(fn)
{
if(document.addEventListener)
{
document.addEventListener("DOMContentLoaded", fn, false);
}
else
{
document.onreadystatechange = function(){chState(fn);};
}
}
function chState(fn)
{
if(document.readyState == "interactive" || document.readyState == "complete")
fn();
}
window.onDomReady(addHndlrs);
function addHndlrs()
{
var forms = document.getElementsByTagName("form");
for(var i = 0; i < forms.length; i++)
{
var form = forms[i];
if(form.addEventListener)
{
form.addEventListener("submit", DoValidate, false);
}
else if (form.attachEvent)
{
form.attachEvent("onsubmit", DoValidate);
}
Other stuff.
}
When I click Submit on the form, DoValidate does called.
I am trying to modify this page to add another submit handler which is called after the first one.
I copied the above code, changed function names & put into s2.js.
window.onDomReady = DReady;
function DReady(fn)
{
if(document.addEventListener)
{
document.addEventListener("DOMContentLoaded", fn, false);
}
else
{
document.onreadystatechange = function(){Chk1State(fn);};
}
}
function Chk1State(fn)
{
if(document.readyState == "interactive" || document.readyState == "complete")
fn();
}
window.onDomReady(myready);
function myready()
{
var forms = document.getElementsByTagName("form");
for(var i = 0; i < forms.length; i++)
{
var form = forms[i];
if(form.addEventListener)
{
form.addEventListener("submit", mynewhandler, false);
}
else if (form.attachEvent)
{
form.attachEvent("onsubmit", mynewhandler);
}
}
}
In the form html, I added a reference to it
<script type="text/javascript" src="s1.js"></script>
<script type="text/javascript" src="s2.js"></script>
My new submit handler never gets called. I debugged it through firebug - I see DReady being called and my DOM Ready handler being registered. However myready never gets called, so my submit handler never gets registered.
What am I missing here? I tried changing order of inclusion of s1.js and s2.js but that doesn't seem to help. I want to do this without modifying s1.js
The code you provided seems to be fine! Have checked in Chrome 25, FireFox 19 and IE 10!
Normally I find it easier to just modify the code at runtime (not the source file), thanks to JavaScript being dynamic typed, you could overwrite the DoValidate function with your own, passing it the original DoValidate through closure in the s2.js:
var originalValidate = DoValidate;
DoValidate = function () {
originalValidate();
alert("my handler");
};
I have some jQuery plugin that changes some elements, i need some event or jQuery plugin that trigger an event when some text input value changed.
I've downloaded jquery.textchange plugin, it is a good plugin but doesn't detect changes via external source.
#MSS -- Alright, this is a kludge but it works:
When I call boxWatcher() I set the value to 3,000 but you'd need to do it much more often, like maybe 100 or 300.
http://jsfiddle.net/N9zBA/8/
var theOldContent = $('#theID').val().trim();
var theNewContent = "";
function boxWatcher(milSecondsBetweenChecks) {
var theLoop = setInterval(function() {
theNewContent = $('#theID').val().trim();
if (theOldContent == theNewContent) {
return; //no change
}
clearInterval(theLoop);//stop looping
handleContentChange();
}, milSecondsBetweenChecks);
};
function handleContentChange() {
alert('content has changed');
//restart boxWatcher
theOldContent = theNewContent;//reset theOldContent
boxWatcher(3000);//3000 is about 3 seconds
}
function buttonClick() {
$('#theID').value = 'asd;lfikjasd;fkj';
}
$(document).ready(function() {
boxWatcher(3000);
})
try to set the old value into a global variable then fire onkeypress event on your text input and compare between old and new values of it. some thing like that
var oldvlaue = $('#myInput').val();
$('#myInput').keyup(function(){
if(oldvlaue!=$('#myInput').val().trim())
{
alert('text has been changed');
}
});
you test this example here
Edit
try to add an EventListner to your text input, I don't know more about it but you can check this Post it may help
Thanks to #Darin because of his/her solution I've marked as the answer, but i have made some small jQuery plugin to achieve the same work named 'txtChgMon'.
(function ($) {
$.fn.txtChgMon = function (func) {
var res = this.each(function () {
txts[0] = { t: this, f: func, oldT: $(this).val(), newT: '' };
});
if (!watchStarted) {
boxWatcher(200);
}
return res;
};
})(jQuery);
var txts = [];
var watchStarted = false;
function boxWatcher(milSecondsBetweenChecks) {
watchStarted = true;
var theLoop = setInterval(function () {
for (var i = 0; i < txts.length; i++) {
txts[i].newT = $(txts[i].t).val();
if (txts[i].newT == txts[i].oldT) {
return; //no change
}
clearInterval(theLoop); //stop looping
txts[i].f(txts[i], txts[i].oldT, txts[i].newT);
txts[i].oldT = $(txts[i].t).val();
boxWatcher(milSecondsBetweenChecks);
return;
}
}, milSecondsBetweenChecks);
}