I have certain form inputs that are only displayed depending on other input's value. I am trying to control when inputs fadeOut() and fadeIn() with, I think, a promise() but it seems the call-stack still runs everything synchronously - maybe I am not configuring the promise correctly?
Here is some pseudo code. The catch here is one of my inputs, input3 needs to be removed, then re-added to correct some JQuery validation and JQuery automcomplete rules, so I am trying to create the function to do that, every time that function is called to fadeIn().
function display_input1() {
return new Promise(function (resolve) {
resolve(hide_input3())
var new_element = `...`
$(new_element)
.hide()
.insertAfter(
$("#input0")
)
$("new_element").fadeIn("fast")
})
}
function hide_input1() {
$("#input1")
.fadeOut("fast", function () {
$("#input1").remove()
})
}
function display_input2(data) {
var new_element = `...`
$(new_element)
.hide()
.insertAfter(
$("#input0")
)
$("new_element").fadeIn("fast")
}
function hide_input2() {
$("#input2")
.fadeOut("fast", function () {
$("#input2").remove()
})
}
function display_input3(search_type) {
return new Promise(function (resolve) {
resolve(hide_input1(), hide_input3())
if (search_type == "some_varible") {
var new_element = `...`
} else if (search_type == "some_variable") {
var new_element - `...`
}
$(new_element)
.hide()
.insertAfter(
$("#input2")
)
$("new_element").fadeIn("fast")
})
}
function hide_input3() {
if ($("#input3").length) {
$("#input3")
.fadeOut("fast", function () {
$("#input3").remove()
})
}
}
$(document).on("change", "#input0", function (e) {
var option = $(this).find("option:selected")
var data = AJAX response
if (data["some_attr"]) {
display_input2(data)
hide_input1()
} else {
hide_input2()
if (data["some_attr"]) {
if (!$("#input1").length) {
display_input1()
}
} else {
hide_input1()
}
}
})
$(document).on("change", "input2", function (e) {
var option = this
if (option.value === "input1") {
display_input1()
} else if (["input2", "input3"].includes(option.value)) {
if (option.value === "input2") {
var search_type = "some_varible"
} else {
var search_type = "some_varibale"
}
display_input3(search_type)
}
})
$(document).on("click", "button.cancel", function (e) {
hide_input1()
hide_input2()
hide_input3()
$(form).validate().resetForm()
})
UPDATE
Based on comments, I've reflected my code block for better understanding. I've consolidated functions in hopes to make the code more malleable.
function display_form_input(input_type, search_type = null, data = null) {
if (input_type == "input_var1") {
var new_element = `...`
$(new_element)
.hide()
.insertAfter(
$("#input1")
)
$("#input1").fadeIn("fast")
} else if (input_type == "input_var2") {
var new_element = `...`
$(new_element)
.hide()
.insertAfter(
$("#input0")
)
$("#input2").fadeIn("fast")
} else if (input_type == "input_var3") {
if (search_type == "some_var1") {
var new_element = `...`
} else if (search_type == "some_var2") {
var new_element = `...`
}
$(new_element)
.hide()
.insertAfter(
$("#input3")
)
$("#input3").fadeIn("fast")
}
}
function hide_form_input(input_type) {
return new Promise(function (resolve) {
if (input_type == "input_var1") {
$("#input1")
.fadeOut("fast", function () {
$("#input1").remove()
resolve()
})
} else if (input_type == "input_var2") {
$("#input2")
.fadeOut("fast", function () {
$("#input2").remove()
resolve()
})
} else if (input_type == "input_var3") {
$("#input3")
.fadeOut("fast", function () {
$("#input3").remove()
resolve()
})
}
})
}
$(document).on("change", "#input0", function (e) {
var option = $(this).find("option:selected")
$.ajax({
...
success: function (data) {
if (data["key1"]) {
hide_form_input("input_var1")
display_form_input(
"input_var2",
null,
(data = data["key1"]),
)
} else {
hide_form_input("input_var2")
if (data["key2"] && !$("#input1").length) {
display_form_input("input_var1")
}
}
},
})
})
$(document).on("change", "#input2", function (e) {
var option = this
if (option.value === "value1") {
var search_form = hide_form_input("input_var3")
search_form
.promise()
.done(display_form_input("input_var1"))
} else if (["value2", "value3"].includes(option.value)) {
if (option.value === "value2") {
var search_type = "value22"
} else {
var search_type = "value33"
}
hide_form_input("input_var1")
var search_form = hide_form_input("input_var3")
search_form
.promise()
.done(display_form_input("input_var3", search_type))
}
})
$(document).on("click", "button.cancel", function (e) {
var items = ["input_var1", "input_var2", "input_var3"]
items.forEach(function (item) {
hide_form_input(item)
})
$(form).validate().resetForm()
})
You are creating a promise in display_input1, but where you are calling display_input1 you are not capturing the promise or ever resolving it. So your promise isn't doing anything
if (option.value === "input1") {
var p = display_input1();
//here you can call p.then(function(resolve, reject) { ... } or
var res = await p; (if you mark the function that await is in async)
Thanks to #Bergi and #ControlAltDel for walking me through understanding .promise(). I now have a working example I was trying to achieve! Thank you guys so much for your patience.
Here is my working example in pseudo code. I made some improvements too on a function based #Bergi comments (always strive for DRY code)
function display_form_input(input_type, search_type = null, data = null) {
/*
create_form_input: Display the form input for a given input_type.
Args:
input_type (str): The type of input to create.
Optional Args:
search_type (str): The type of results expected from this search.
Returns:
None
*/
if (input_type == "input_var1") {
var new_element = `...`
$(new_element)
.hide()
.insertAfter(
$("#input0").closest("div.row").children(),
)
$("#input1").parents(":eq(1)").fadeIn("fast")
} else if (input_type == "input_var2") {
var new_element = `...`
$(new_element)
.hide()
.insertAfter($("#input0").closest("div.row"))
$("#input2").parents(":eq(2)").fadeIn("fast")
} else if (input_type == "input_var3") {
if (search_type == "some_var1") {
var new_element = `...`
} else if (search_type == "some_var2") {
var new_element = `...`
}
$(new_element)
.hide()
.insertAfter($("#input2").closest("div.row").children())
$("#input3").parents(":eq(1)").fadeIn("fast")
}
}
function hide_form_input(input_type) {
/*
hide_form_input: Hide the form input for a given input_type.
Args:
input_type (str): The type of input to hide.
Returns:
JQuery Promise.
*/
if (input_type == "input_var1") {
var form_element = $("#input1").parents(":eq(1)")
} else if (input_type == "input_var2") {
var form_element = $("#input2").parents(":eq(2)")
} else if (input_type == "input_var3") {
var form_element = $("#input3").parents(":eq(1)")
}
return form_element
.fadeOut("fast")
.promise()
.then(function () {
form_element.remove()
})
}
$(document).on("change", "#input0", function (e) {
/*
Event Handler: Trigger what form field to display when a the input0
changes.
*/
var option = $(this).find("option:selected")
$.ajax({
...
success: function (data) {
if (data["key1"]) {
hide_form_input("input_var1").then(function () {
if (!$("#input2").length) {
display_form_input(
"input_var2",
null,
data["key1"],
)
}
})
} else {
hide_form_input("input_var2")
if (data["key2"] && !$("#input1").length) {
display_form_input("input_var1")
} else if (!data["key2"]) {
hide_form_input("input_var2")
}
}
},
})
})
$(document).on("change", "#input2", function (e) {
/*
Event Handler: Trigger what form field to display when a the input2
changes.
*/
var option = this
if (option.value === "value1") {
hide_form_input("input_var3").then(function () {
display_form_input("input_var1")
})
} else if (["value2", "value3"].includes(option.value)) {
if (option.value === "value2") {
var search_type = "some_var1"
} else {
var search_type = "some_var2"
}
hide_form_input("input_var1")
hide_form_input("input_var3").then(function () {
display_form_input("input_var3", search_type)
})
}
})
$(document).on("click", "button.cancel", function (e) {
/*
Event Handler: Make form back to default state.
*/
var button = this
var form = $($(button).closest("form"))
var items = ["input_var1", "input_var2", "input_var3"]
items.forEach(function (item) {
hide_form_input(item)
})
$(form).validate().resetForm()
})
Related
I m trying to check a if condition and do a click if its true, but it returns me a error 'eachOperator.toEqual is not a function'
var selectDropdownbyNum = function (element, optionNum) {
var opt = element.all(by.tagName('option'));
opt.each(function (eachOperator) {
eachOperator.toEqual('-').then(function (subtract) {
if (subtract) {
eachOperator.click();
}
});
});
};
Do you try it or?
var selectDropdownbyNum = function (element, optionNum) {
var opt = element.all(by.tagName('option'));
opt.each(function (eachOperator) {
eachOperator.getAttribute('value').then(function (value) {
if (value === '-') {
eachOperator.click();
}
});
});
};
I am using the excellent onlinejs (https://github.com/PixelsCommander/OnlineJS) library for checking that my app has a live internet connection. However, I don't need it to fire regularly, but rather upon the manual calling of the main function.
I would like to modify this code so that it is not firing on a timer, and know the name of the function to call for manual firing, which assume is just getterSetter.
My previous attempts to modify the code below have broken the script as I'm no expert at JavaScript. I appreciate any help in adapting this very useful code.
function getterSetter(variableParent, variableName, getterFunction, setterFunction) {
if (Object.defineProperty) {
Object.defineProperty(variableParent, variableName, {
get: getterFunction,
set: setterFunction
});
}
else if (document.__defineGetter__) {
variableParent.__defineGetter__(variableName, getterFunction);
variableParent.__defineSetter__(variableName, setterFunction);
}
}
(function (w) {
w.onlinejs = w.onlinejs || {};
//Checks interval can be changed in runtime
w.onLineCheckTimeout = 5000;
//Use window.onLineURL incapsulated variable
w.onlinejs._onLineURL = "http://lascelles.us/wavestream/online.php";
w.onlinejs.setOnLineURL = function (newURL) {
w.onlinejs._onLineURL = newURL;
w.onlinejs.getStatusFromNavigatorOnLine();
}
w.onlinejs.getOnLineURL = function () {
return w.onlinejs._onLineURL;
}
getterSetter(w, 'onLineURL', w.onlinejs.getOnLineURL, w.onlinejs.setOnLineURL);
//Verification logic
w.onlinejs.setStatus = function (newStatus) {
w.onlinejs.fireHandlerDependOnStatus(newStatus);
w.onLine = newStatus;
}
w.onlinejs.fireHandlerDependOnStatus = function (newStatus) {
if (newStatus === true && w.onLineHandler !== undefined && (w.onLine !== true || w.onlinejs.handlerFired === false)) {
w.onLineHandler();
}
if (newStatus === false && w.offLineHandler !== undefined && (w.onLine !== false || w.onlinejs.handlerFired === false)) {
w.offLineHandler();
}
w.onlinejs.handlerFired = true;
};
w.onlinejs.startCheck = function () {
setInterval("window.onlinejs.logic.checkConnectionWithRequest(true)", w.onLineCheckTimeout);
}
w.onlinejs.stopCheck = function () {
clearInterval("window.onlinejs.logic.checkConnectionWithRequest(true)", w.onLineCheckTimeout);
}
w.checkOnLine = function () {
w.onlinejs.logic.checkConnectionWithRequest(false);
}
w.onlinejs.getOnLineCheckURL = function () {
return w.onlinejs._onLineURL + '?' + Date.now();
}
w.onlinejs.getStatusFromNavigatorOnLine = function () {
if (w.navigator.onLine !== undefined) {
w.onlinejs.setStatus(w.navigator.onLine);
} else {
w.onlinejs.setStatus(true);
}
}
//Network transport layer
var xmlhttp = new XMLHttpRequest();
w.onlinejs.isXMLHttp = function () {
return "withCredentials" in xmlhttp;
}
w.onlinejs.isXDomain = function () {
return typeof XDomainRequest != "undefined";
}
//For IE we use XDomainRequest and sometimes it uses a bit different logic, so adding decorator for this
w.onlinejs.XDomainLogic = {
init: function () {
xmlhttp = new XDomainRequest();
xmlhttp.onerror = function () {
xmlhttp.status = 404;
w.onlinejs.processXmlhttpStatus();
}
xmlhttp.ontimeout = function () {
xmlhttp.status = 404;
w.onlinejs.processXmlhttpStatus();
}
},
onInternetAsyncStatus: function () {
try {
xmlhttp.status = 200;
w.onlinejs.processXmlhttpStatus();
} catch (err) {
w.onlinejs.setStatus(false);
}
},
checkConnectionWithRequest: function (async) {
xmlhttp.onload = w.onlinejs.logic.onInternetAsyncStatus;
var url = w.onlinejs.getOnLineCheckURL();
xmlhttp.open("GET", url);
w.onlinejs.tryToSend(xmlhttp);
}
}
//Another case for decoration is XMLHttpRequest
w.onlinejs.XMLHttpLogic = {
init: function () {
},
onInternetAsyncStatus: function () {
if (xmlhttp.readyState === 4) {
try {
w.onlinejs.processXmlhttpStatus();
} catch (err) {
w.onlinejs.setStatus(false);
}
}
},
checkConnectionWithRequest: function (async) {
if (async) {
xmlhttp.onreadystatechange = w.onlinejs.logic.onInternetAsyncStatus;
} else {
xmlhttp.onreadystatechange = undefined;
}
var url = w.onlinejs.getOnLineCheckURL();
xmlhttp.open("HEAD", url, async);
w.onlinejs.tryToSend(xmlhttp);
if (async === false) {
w.onlinejs.processXmlhttpStatus();
return w.onLine;
}
}
}
if (w.onlinejs.isXDomain()) {
w.onlinejs.logic = w.onlinejs.XDomainLogic;
} else {
w.onlinejs.logic = w.onlinejs.XMLHttpLogic;
}
w.onlinejs.processXmlhttpStatus = function () {
var tempOnLine = w.onlinejs.verifyStatus(xmlhttp.status);
w.onlinejs.setStatus(tempOnLine);
}
w.onlinejs.verifyStatus = function (status) {
return status === 200;
}
w.onlinejs.tryToSend = function (xmlhttprequest) {
try {
xmlhttprequest.send();
} catch(e) {
w.onlinejs.setStatus(false);
}
}
//Events handling
w.onlinejs.addEvent = function (obj, type, callback) {
if (window.attachEvent) {
obj.attachEvent('on' + type, callback);
} else {
obj.addEventListener(type, callback);
}
}
w.onlinejs.addEvent(w, 'load', function () {
w.onlinejs.fireHandlerDependOnStatus(w.onLine);
});
w.onlinejs.addEvent(w, 'online', function () {
window.onlinejs.logic.checkConnectionWithRequest(true);
})
w.onlinejs.addEvent(w, 'offline', function () {
window.onlinejs.logic.checkConnectionWithRequest(true);
})
w.onlinejs.getStatusFromNavigatorOnLine();
w.onlinejs.logic.init();
w.checkOnLine();
w.onlinejs.startCheck();
w.onlinejs.handlerFired = false;
})(window);
Looking at the source, I believe you can simply call onlinejs.logic.checkConnectionWithRequest(false) to get the status synchronously. This function will return either true or false.
PS: I am sure there are better libraries for this task out there, I really do not like the way it's written and clearly, the author doesn't know JS very well. E.g., the following code taken from the library makes no sense at all.
w.onlinejs.stopCheck = function () {
clearInterval("window.onlinejs.logic.checkConnectionWithRequest(true)", w.onLineCheckTimeout);
}
I am trying to render a pdf in chrome using PDFJS
This is the function I am calling:
open: function pdfViewOpen(url, scale, password) {
var parameters = {password: password};
if (typeof url === 'string') { // URL
this.setTitleUsingUrl(url);
parameters.url = url;
} else if (url && 'byteLength' in url) { // ArrayBuffer
parameters.data = url;
}
if (!PDFView.loadingBar) {
PDFView.loadingBar = new ProgressBar('#loadingBar', {});
}
this.pdfDocument = null;
var self = this;
self.loading = true;
getDocument(parameters).then(
function getDocumentCallback(pdfDocument) {
self.load(pdfDocument, scale);
self.loading = false;
},
function getDocumentError(message, exception) {
if (exception && exception.name === 'PasswordException') {
if (exception.code === 'needpassword') {
var promptString = mozL10n.get('request_password', null,
'PDF is protected by a password:');
password = prompt(promptString);
if (password && password.length > 0) {
return PDFView.open(url, scale, password);
}
}
}
var loadingErrorMessage = mozL10n.get('loading_error', null,
'An error occurred while loading the PDF.');
if (exception && exception.name === 'InvalidPDFException') {
// change error message also for other builds
var loadingErrorMessage = mozL10n.get('invalid_file_error', null,
'Invalid or corrupted PDF file.');
//#if B2G
// window.alert(loadingErrorMessage);
// return window.close();
//#endif
}
var loadingIndicator = document.getElementById('loading');
loadingIndicator.textContent = mozL10n.get('loading_error_indicator',
null, 'Error');
var moreInfo = {
message: message
};
self.error(loadingErrorMessage, moreInfo);
self.loading = false;
},
function getDocumentProgress(progressData) {
self.progress(progressData.loaded / progressData.total);
}
);
}
This is the call:
PDFView.open('/MyPDFs/Pdf2.pdf', 'auto', null);
All I get is this:
If you notice, even the page number is retrieved but the content is not painted in the pages. Can´t find why.. Is the any other function I should call next to PDFView.open?
Found the solution...!
This is the code that does the work.
$(document).ready(function () {
PDFView.initialize();
var params = PDFView.parseQueryString(document.location.search.substring(1));
//#if !(FIREFOX || MOZCENTRAL)
var file = params.file || DEFAULT_URL;
//#else
//var file = window.location.toString()
//#endif
//#if !(FIREFOX || MOZCENTRAL)
if (!window.File || !window.FileReader || !window.FileList || !window.Blob) {
document.getElementById('openFile').setAttribute('hidden', 'true');
} else {
document.getElementById('fileInput').value = null;
}
//#else
//document.getElementById('openFile').setAttribute('hidden', 'true');
//#endif
// Special debugging flags in the hash section of the URL.
var hash = document.location.hash.substring(1);
var hashParams = PDFView.parseQueryString(hash);
if ('disableWorker' in hashParams)
PDFJS.disableWorker = (hashParams['disableWorker'] === 'true');
//#if !(FIREFOX || MOZCENTRAL)
var locale = navigator.language;
if ('locale' in hashParams)
locale = hashParams['locale'];
mozL10n.setLanguage(locale);
//#endif
if ('textLayer' in hashParams) {
switch (hashParams['textLayer']) {
case 'off':
PDFJS.disableTextLayer = true;
break;
case 'visible':
case 'shadow':
case 'hover':
var viewer = document.getElementById('viewer');
viewer.classList.add('textLayer-' + hashParams['textLayer']);
break;
}
}
//#if !(FIREFOX || MOZCENTRAL)
if ('pdfBug' in hashParams) {
//#else
//if ('pdfBug' in hashParams && FirefoxCom.requestSync('pdfBugEnabled')) {
//#endif
PDFJS.pdfBug = true;
var pdfBug = hashParams['pdfBug'];
var enabled = pdfBug.split(',');
PDFBug.enable(enabled);
PDFBug.init();
}
if (!PDFView.supportsPrinting) {
document.getElementById('print').classList.add('hidden');
}
if (!PDFView.supportsFullscreen) {
document.getElementById('fullscreen').classList.add('hidden');
}
if (PDFView.supportsIntegratedFind) {
document.querySelector('#viewFind').classList.add('hidden');
}
// Listen for warnings to trigger the fallback UI. Errors should be caught
// and call PDFView.error() so we don't need to listen for those.
PDFJS.LogManager.addLogger({
warn: function () {
PDFView.fallback();
}
});
var mainContainer = document.getElementById('mainContainer');
var outerContainer = document.getElementById('outerContainer');
mainContainer.addEventListener('transitionend', function (e) {
if (e.target == mainContainer) {
var event = document.createEvent('UIEvents');
event.initUIEvent('resize', false, false, window, 0);
window.dispatchEvent(event);
outerContainer.classList.remove('sidebarMoving');
}
}, true);
document.getElementById('sidebarToggle').addEventListener('click',
function () {
this.classList.toggle('toggled');
outerContainer.classList.add('sidebarMoving');
outerContainer.classList.toggle('sidebarOpen');
PDFView.sidebarOpen = outerContainer.classList.contains('sidebarOpen');
PDFView.renderHighestPriority();
});
document.getElementById('viewThumbnail').addEventListener('click',
function () {
PDFView.switchSidebarView('thumbs');
});
document.getElementById('viewOutline').addEventListener('click',
function () {
PDFView.switchSidebarView('outline');
});
document.getElementById('previous').addEventListener('click',
function () {
PDFView.page--;
});
document.getElementById('next').addEventListener('click',
function () {
PDFView.page++;
});
document.querySelector('.zoomIn').addEventListener('click',
function () {
PDFView.zoomIn();
});
document.querySelector('.zoomOut').addEventListener('click',
function () {
PDFView.zoomOut();
});
document.getElementById('fullscreen').addEventListener('click',
function () {
PDFView.fullscreen();
});
document.getElementById('openFile').addEventListener('click',
function () {
document.getElementById('fileInput').click();
});
document.getElementById('print').addEventListener('click',
function () {
window.print();
});
document.getElementById('download').addEventListener('click',
function () {
PDFView.download();
});
document.getElementById('pageNumber').addEventListener('change',
function () {
PDFView.page = this.value;
});
document.getElementById('scaleSelect').addEventListener('change',
function () {
PDFView.parseScale(this.value);
});
document.getElementById('first_page').addEventListener('click',
function () {
PDFView.page = 1;
});
document.getElementById('last_page').addEventListener('click',
function () {
PDFView.page = PDFView.pdfDocument.numPages;
});
document.getElementById('page_rotate_ccw').addEventListener('click',
function () {
PDFView.rotatePages(-90);
});
document.getElementById('page_rotate_cw').addEventListener('click',
function () {
PDFView.rotatePages(90);
});
//#if (FIREFOX || MOZCENTRAL)
//if (FirefoxCom.requestSync('getLoadingType') == 'passive') {
// PDFView.setTitleUsingUrl(file);
// PDFView.initPassiveLoading();
// return;
//}
//#endif
//#if !B2G
PDFView.open(file, 0);
//#endif
});
The system must be initialized first before PDFView.open call!
Thanks
It's simple validation module. Now, i can't understand why my functions (validateEmail) can't call successful. I have no js errors, but browser do postback with my form thorought validation code
<script type="text/javascript">
var Validation;
(function (Validation) {
var FormValidator = (function () {
function FormValidator(formid) {
this.emailPattern = /^[a-zA-Z0-9._-]+#[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
this.formID = formid;
}
FormValidator.prototype.Validate = function () {
var errorsSum;
$('#' + this.formID).find('input[type="text"][validate], textarea[validate]').each(function (index, item) {
var validateType = $(item).attr('validate');
switch(validateType) {
case 'text':
case 'password': {
errorsSum += FormValidator.prototype.validateText(item);
break;
}
case 'email': {
errorsSum += FormValidator.prototype.validateEmail(item);
break;
}
}
});
return errorsSum == 0;
};
FormValidator.prototype.validateGeneric = function (element, validationFunc) {
var jqElement = $(element);
alert('tested element = ' + jqElement);
if(validationFunc(jqElement.val())) {
alert('tested element error = ' + jqElement.val());
element.removeClass('error');
return 0;
} else {
element.addClass('error');
}
alert('tested element success = ' + jqElement.val());
return 1;
};
FormValidator.prototype.validateEmail = function (element) {
return FormValidator.prototype.validateGeneric(element, function (elementValue) {
return FormValidator.prototype.emailPattern.test(elementValue);
});
};
FormValidator.prototype.validateText = function (element) {
return FormValidator.prototype.validateGeneric(element, function (elementValue) {
return elementValue != '';
});
};
return FormValidator;
})();
Validation.FormValidator = FormValidator;
})(Validation || (Validation = {}));
</script>
This is my form
#using (Html.BeginForm("Register", "Account", FormMethod.Post, new { #id = "register-form", #class = "form-horizontal"}))
{
...
#Html.TextBoxFor(m => m.Email, new { #placeholder = #L("Email"), #name = "email", #validate = "email" })
...
}
This is validation code
<script type="text/javascript">
$(function () {
$('#register-form').submit(function() {
return (new Validation.FormValidator('register-form').Validate());
});
});
</script>
I don't understand js so deep
You need to catch the submit event and prevent it from firing, validate the form, then submit if it was valid. Right now you are running the javascript as soon as it's submitted, but it just keeps submitting anyway since you don't stop the http request from being made.
On a related note, this is a huge mess. You don't need anything close to that much code just to validate emails and text presence on your form. This is all you need:
var validate = function(form){
var form_valid = true;
form.find('input[validate], textarea').each(function(index, el){
var type = el.attr('validate');
if (type == 'email') {
if (!el.match(/^[a-zA-Z0-9._-]+#[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/)) { form_valid = false; el.addClass('error'); }
}
if (type == 'text') {
if (!el.val() == '') { form_valid = false; el.addClass('error'); }
}
});
return form_valid
}
$('#register-form').on('submit', function(){
validate($(this)) && $(this).submit()
});
Hope this helps...
Edit: made the example a bit more modular
I am getting error when using the script below in vm mynxx template by rockettheme in virtuemart Joomla 1.5 -
It works fine outside of mynxx
User inputs data into a html form- presses "Get Price" button and a price is returned to same form. Problem is that user is unable to submit to cart
firebug error -
callback is not a function callback(this.responseText);
my ajax script
function Ajax() {
this.instance = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
this.request = function(url, callback) {
this.instance.open('GET', url, true);
this.instance.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
callback(this.responseText);
}
}
this.instance.send(null);
}
}
function validate(form) {
(new Ajax).request('testform.php?width65=' + form.width65.value + '&length65=' + form.length65.value, function(respons) {
var prices = eval(respons);
form.price.value = prices[0];
form.otherprice.value = prices[1];
});
}
I think I have tracked the file down to theme.js and require some code to validate the function.
I am new at this and this is way above me - any help would be appreciated
Theme.js code - was packed - ie eval(function(p,a,c,k,e,r){e=function(c)...... I have unpacked it
var RokVM = {};
RokVM.autoHide = 3; // seconds before auto closing the Panel
RokVM.Base=
{
uri:window.templatePath,start:function()
{
RokVM.Base.quantityBox();
RokVM.Cart.init()
}
,featuredHeight:function(b)
{
b=$(b);
if(!b)
{
return RokVM.Base
}
var c=b.getElements(".home-featured-inner");
var d=0;
c.each(function(a)
{
d=Math.max(a.getSize().size.y,d)
}
);
c.setStyle("height",d)
}
,quantityBox:function()
{
var h=$$(".cart-quantity-box, .home-featured-cartblock");
if(h.length)
{
h.each(function(b)
{
var c=b.getElement(".quantity_box_button_up");
var d=b.getElement(".quantity_box_button_down");
var f=b.getElement(".inputboxquantity");
if(!c||!d||!f)
{
return
}
var g=f.getValue().toInt();
f.addEvent("keyup",function(e)
{
e=(new Event(e)).stop();
var a=this.value;
if(a<0)
{
a=0
}
if(isNaN(a))
{
this.value=1;
a=1
}
if(e.key=="up")
{
if($type(this.getValue().toInt())=="number")
{
this.value=++a
}
}
if(e.key=="down")
{
if(a>0&&$type(this.getValue().toInt())=="number")
{
this.value=--a
}
}
}
);
f.addEvent("mousewheel",function(e)
{
e=(new Event(e)).stop();
var a=this.value;
if(a<0)
{
a=0
}
if(isNaN(a))
{
this.value=1;
a=1
}
if(e.wheel==1)
{
if($type(this.getValue().toInt())=="number")
{
this.value=++a
}
}
if(e.wheel==-1)
{
if(a>0&&$type(this.getValue().toInt())=="number")
{
this.value=--a
}
}
}
);
c.addEvent("click",function(e)
{
(new Event(e)).stop();
if($type(f.getValue().toInt())=="number")
{
f.value=++f.value
}
}
);
d.addEvent("click",function(e)
{
(new Event(e)).stop();
if(f.getValue().toInt()>0&&$type(f.getValue().toInt())=="number")
{
f.value=--f.value
}
}
)
}
)
}
}
};
RokVM.Cart=
{
init:function()
{
RokVM.Cart.cartPanel=$("cart-panel");
RokVM.Cart.cartButton=$("cart-button");
RokVM.Cart.cartSurround=$("cart-panel-surround");
if(!RokVM.Cart.cartPanel||!RokVM.Cart.cartButton||!RokVM.Cart.cartSurround)
{
return RokVM.Cart
}
if(!RokVM.Cart.Fx)
{
RokVM.Cart.Fx=(new(Fx.Slide)(RokVM.Cart.cartPanel,
{
duration:400,transition:Fx.Transitions.Expo.easeOut
}
)).hide()
}
RokVM.Cart.cartSurround.setStyle("visibility","visible");
RokVM.Cart.cartButton.getFirst("a").addEvent("click",function(e)
{
(new Event(e)).stop();
if(!RokVM.Cart.cartPanel.getText().length&&!window.webkit)
{
return
}
if(!RokVM.Cart.cartPanel.innerHTML.clean().length&&window.webkit)
{
return
}
var a=RokVM.Cart.cartButton.getElement("strong");
if(!a||!a.getText().toInt()&&(!RokVM.Cart.cartPanel.getText().length&&!window.webkit))
{
return
}
RokVM.Cart.clicked=true;
if(window.fontFx&&window.fontFx.open)
{
window.fontFx.toggle()
}
if(window.loginFx&&window.loginFx.open)
{
window.loginFx.toggle()
}
RokVM.Cart.Fx.toggle()
}
);
RokVM.scrollWindow=new(Fx.Scroll)(window);
RokVM.Cart.getShortList();
RokVM.Cart.XHRify()
}
,XHRify:function()
{
var b=$$(".addtocart_form");
if(!b.length)
{
return RokVM.Cart
}
b.each(function(a)
{
a.addEvent("submit",RokVM.Cart.add.bindWithEvent(a,true))
}
)
}
,add:function(e,c)
{
(new Event(e)).stop();
(new Ajax(this.getProperty("action"),
{
data:$(this),evalScripts:true,onComplete:function(r)
{
var a=new Element('div').setHTML(r);
var b=a.getElement('.shop_tip');
RokVM.Cart.getShortList((r.length&&b)?r:false);
RokVM.Cart.clicked=c||false
}
}
)).request()
}
,getShortList:function(b)
{
var c=
{
onComplete:function(a)
{
RokVM.Cart.update(a,b)
}
,evalScripts:true,data:
{
only_page:1,page:"shop.basket_short",option:"com_virtuemart"
}
};
(new Ajax(RokVM.Base.uri+"index2.php",c)).request()
}
,handleError:function(a)
{
var b=RokVM.Cart.cartPanel;
var c=new Element('div').setHTML(a);
var d=b.getElement('.show-cart-button');
var e=c.getElement('.shop_tip').inject((d)?d:b,(d)?'before':'inside')
}
,update:function(a,b)
{
RokVM.Cart.cartPanel.setHTML(a);
var c=RokVM.Cart.cartPanel.getElement(".total_products"),total=0;
if(c)
{
total=c.innerHTML.split(" ")[0].toInt()
}
if(!total)
{
RokVM.Cart.cartButton.getFirst().setProperty("class","cart-button-desc")
}
else
{
RokVM.Cart.cartButton.getFirst().setProperty("class","cart-button-desc-full")
}
RokVM.Cart.cartButton.getElement("strong").setText(total);
if(b)RokVM.Cart.handleError(b);
if(RokVM.Cart.clicked&&a.length||b)
{
if(window.fontFx&&window.fontFx.open)
{
window.fontFx.toggle()
}
if(window.loginFx&&window.loginFx.open)
{
window.loginFx.toggle()
}
RokVM.scrollWindow.toTop();
RokVM.Cart.show();
RokVM.Cart.hide.delay(RokVM.autoHide*1000)
}
RokVM.Cart.clicked=false
}
,show:function()
{
RokVM.Cart.Fx.slideIn()
}
,hide:function()
{
RokVM.Cart.Fx.slideOut()
}
};
window.addEvent("domready",RokVM.Base.start);
window.addEvent(window.webkit?"load":"domready",function()
{
RokVM.Base.featuredHeight("home-featured")
}
);
var live_site = RokVM.Base.url;
Then following - this in the same theme.js file (this is not packed)
/// Following is VM stuff, kept for compatibility
/**
* This file holds javascript functions that are used by the templates in the Theme
*
*/
// AJAX FUNCTIONS
function loadNewPage( el, url ) {
var theEl = $(el);
var callback = {
success : function(responseText) {
theEl.innerHTML = responseText;
if( Lightbox ) Lightbox.init();
}
}
var opt = {
// Use POST
method: 'get',
// Handle successful response
onComplete: callback.success
}
new Ajax( url + '&only_page=1', opt ).request();
}
function handleGoToCart() { document.location = live_site + '/index.php?option=com_virtuemart&page=shop.cart&product_id=' + formCartAdd.product_id.value ; }
function handleAddToCart( formId, parameters ) {
formCartAdd = document.getElementById( formId );
var callback = function(responseText) {
updateMiniCarts();
// close an existing mooPrompt box first, before attempting to create a new one (thanks wellsie!)
/*if (document.boxB) {
document.boxB.close();
clearTimeout(timeoutID);
}
document.boxB = new MooPrompt(notice_lbl, responseText, {
buttons: 2,
width:400,
height:150,
overlay: false,
button1: ok_lbl,
button2: cart_title,
onButton2: handleGoToCart
});
setTimeout( 'document.boxB.close()', 3000 );*/
}
var opt = {
// Use POST
method: 'post',
// Send this lovely data
data: $(formId),
// Handle successful response
onComplete: callback,
evalScripts: true
}
new Ajax(formCartAdd.action, opt).request();
}
/**
* This function searches for all elements with the class name "vmCartModule" and
* updates them with the contents of the page "shop.basket_short" after a cart modification event
*/
function updateMiniCarts() {
var callbackCart = function(responseText) {
carts = $$( '.vmCartModule' );
if( carts ) {
try {
for (var i=0; i<carts.length; i++){
carts[i].innerHTML = responseText;
try {
color = carts[i].getStyle( 'color' );
bgcolor = carts[i].getStyle( 'background-color' );
if( bgcolor == 'transparent' ) {
// If the current element has no background color, it is transparent.
// We can't make a highlight without knowing about the real background color,
// so let's loop up to the next parent that has a BG Color
parent = carts[i].getParent();
while( parent && bgcolor == 'transparent' ) {
bgcolor = parent.getStyle( 'background-color' );
parent = parent.getParent();
}
}
var fxc = new Fx.Style(carts[i], 'color', {duration: 1000});
var fxbgc = new Fx.Style(carts[i], 'background-color', {duration: 1000});
fxc.start( '#222', color );
fxbgc.start( '#fff68f', bgcolor );
if( parent ) {
setTimeout( "carts[" + i + "].setStyle( 'background-color', 'transparent' )", 1000 );
}
} catch(e) {}
}
} catch(e) {}
}
}
var option = { method: 'post', onComplete: callbackCart, data: { only_page:1,page: "shop.basket_short", option: "com_virtuemart" } }
new Ajax( live_site + '/index2.php', option).request();
}
/**
* This function allows you to present contents of a URL in a really nice stylish dhtml Window
* It uses the WindowJS, so make sure you have called
* vmCommonHTML::loadWindowsJS();
* before
*/
function fancyPop( url, parameters ) {
parameters = parameters || {};
popTitle = parameters.title || '';
popWidth = parameters.width || 700;
popHeight = parameters.height || 600;
popModal = parameters.modal || false;
window_id = new Window('window_id', {className: "mac_os_x",
title: popTitle,
showEffect: Element.show,
hideEffect: Element.hide,
width: popWidth, height: popHeight});
window_id.setAjaxContent( url, {evalScripts:true}, true, popModal );
window_id.setCookie('window_size');
window_id.setDestroyOnClose();
}
I dont really know this template but in my opinion function callback() is something that should be specified in it's code to make an reaction when there is a positive response from the server (HTTP 200), so can you also give us:
that function
it's localization (ie. if it is located in the same file or not)
and when it's loaded to the DOM: before or after function Ajax() {}