Related
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()
})
I have recently started using JsFormValidatorBundle to validate my forms on symfony. The only issue is that i need to send these forms with Ajax and unfortunately for some reason the JsFormValidatorBundle forces the form to be sent by reloading the page.
So now i am trying to override that function which looks like:
function FpJsCustomizeMethods() {
...
this.submitForm = function (event) {
//noinspection JSCheckFunctionSignatures
FpJsFormValidator.each(this, function (item) {
var element = item.jsFormValidator;
if (event) {
event.preventDefault();
}
element.validateRecursively();
if (FpJsFormValidator.ajax.queue) {
if (event) {
event.preventDefault();
}
FpJsFormValidator.ajax.callbacks.push(function () {
element.onValidate.apply(element.domNode, [FpJsFormValidator.getAllErrors(element, {}), event]);
if (element.isValid()) {
item.submit();
}
});
} else {
element.onValidate.apply(element.domNode, [FpJsFormValidator.getAllErrors(element, {}), event]);
if (element.isValid()) {
item.submit();
}
}
});
};
....
}
if i remove the item.submit() it works perfectly.
So how can override this?
full script
You just need to make a new function and extend the parent via its prototype.
Perhaps this code block can explain what you need to do.
function Parent() {
this.a = function() {
alert("i am here");
}
this.submitForm = function() {
alert("i am wrong one here");
}
}
function Child () {
//we need to override function submitForm with right one
this.submitForm = function() {
alert("i am right one here");
}
}
Child.prototype = new Parent;
var c = new Child();
//other parent methods are still accessible.
c.a();
//method submitForm is overriden with the one we defined
c.submitForm();
see it in action here
As I suggested you actually don't want to overwrite the FpJsFormValidator.customizeMethods.submitForm function just to be able to submit your forms via Ajax instead of default. Doing so will result in:
code duplication as you would be forced to restore all of the validation parts in your own function
and if part of your solution would be getting rid of the item.submit() bits then you would also lose any other events bound to be driggered by that submit as a by product.
I would instead simply create a handler for the submit event on that item which would call event.preventDefault() and do the Ajax request. As you tagged your question with jQuery, something like:
$("#your_fav_form_selector").submit(function (e) {
e.preventDefault();
// fetch form data and send it off with $.ajax etc
});
There's 2 ways of doing that.
As far as I know, the function you want to override isn't a jQuery function. I kept the 2 examples so that you can decide which one fits in your code.
If it's a JavaScript function (custom or native)
First of all, I saw the function you're using and I find that it's hard to override a specific part of it, so I wrote it again and removed (or commented out) the "submit call" and then I've overridden the function. When calling FpJsFormValidator, the following function will be called NewFpJsCustomizeMethods.
<script type="text/javascript">
FpJsFormValidator = function() {
return NewFpJsCustomizeMethods();
}
function NewFpJsCustomizeMethods() {
this.init = function (options) {
FpJsFormValidator.each(this, function (item) {
if (!item.jsFormValidator) {
item.jsFormValidator = {};
}
for (var optName in options) {
switch (optName) {
case 'customEvents':
options[optName].apply(item);
break;
default:
item.jsFormValidator[optName] = options[optName];
break;
}
}
}, false);
return this;
};
this.validate = function (opts) {
var isValid = true;
//noinspection JSCheckFunctionSignatures
FpJsFormValidator.each(this, function (item) {
var method = (opts && true === opts['recursive'])
? 'validateRecursively'
: 'validate';
var validateUnique = (!opts || false !== opts['findUniqueConstraint']);
if (validateUnique && item.jsFormValidator.parent) {
var data = item.jsFormValidator.parent.data;
if (data['entity'] && data['entity']['constraints']) {
for (var i in data['entity']['constraints']) {
var constraint = data['entity']['constraints'][i];
if (constraint instanceof FpJsFormValidatorBundleFormConstraintUniqueEntity && constraint.fields.indexOf(item.name)) {
var owner = item.jsFormValidator.parent;
constraint.validate(null, owner);
}
}
}
}
if (!item.jsFormValidator[method]()) {
isValid = false;
}
});
return isValid;
};
this.showErrors = function (opts) {
//noinspection JSCheckFunctionSignatures
FpJsFormValidator.each(this, function (item) {
item.jsFormValidator.errors[opts['sourceId']] = opts['errors'];
item.jsFormValidator.showErrors.apply(item, [opts['errors'], opts['sourceId']]);
});
};
this.submitForm = function (event) {
//noinspection JSCheckFunctionSignatures
FpJsFormValidator.each(this, function (item) {
var element = item.jsFormValidator;
if (event) {
event.preventDefault();
}
element.validateRecursively();
if (FpJsFormValidator.ajax.queue) {
if (event) {
event.preventDefault();
}
FpJsFormValidator.ajax.callbacks.push(function () {
element.onValidate.apply(element.domNode, [FpJsFormValidator.getAllErrors(element, {}), event]);
if (element.isValid()) {
//item.submit();
}
});
} else {
element.onValidate.apply(element.domNode, [FpJsFormValidator.getAllErrors(element, {}), event]);
if (element.isValid()) {
//item.submit();
}
}
});
};
this.get = function () {
var elements = [];
//noinspection JSCheckFunctionSignatures
FpJsFormValidator.each(this, function (item) {
elements.push(item.jsFormValidator);
});
return elements;
};
//noinspection JSUnusedGlobalSymbols
this.addPrototype = function(name) {
//noinspection JSCheckFunctionSignatures
FpJsFormValidator.each(this, function (item) {
var prototype = FpJsFormValidator.preparePrototype(
FpJsFormValidator.cloneObject(item.jsFormValidator.prototype),
name,
item.jsFormValidator.id + '_' + name
);
item.jsFormValidator.children[name] = FpJsFormValidator.createElement(prototype);
item.jsFormValidator.children[name].parent = item.jsFormValidator;
});
};
//noinspection JSUnusedGlobalSymbols
this.delPrototype = function(name) {
//noinspection JSCheckFunctionSignatures
FpJsFormValidator.each(this, function (item) {
delete (item.jsFormValidator.children[name]);
});
};
}
</script>
If it's a jQuery function
First of all, I saw the function you're using and I find that it's hard to override a specific part of it, so I wrote it again and removed (or commented out) the "submit call" and then I've overridden the jQuery function. When calling FpJsFormValidator, the following function will be called NewFpJsCustomizeMethods.
Here's the code:
<script type="text/javascript">
(function(){
// Define overriding method
jQuery.fn.FpJsFormValidator = NewFpJsCustomizeMethods();
})();
function NewFpJsCustomizeMethods() {
this.init = function (options) {
FpJsFormValidator.each(this, function (item) {
if (!item.jsFormValidator) {
item.jsFormValidator = {};
}
for (var optName in options) {
switch (optName) {
case 'customEvents':
options[optName].apply(item);
break;
default:
item.jsFormValidator[optName] = options[optName];
break;
}
}
}, false);
return this;
};
this.validate = function (opts) {
var isValid = true;
//noinspection JSCheckFunctionSignatures
FpJsFormValidator.each(this, function (item) {
var method = (opts && true === opts['recursive'])
? 'validateRecursively'
: 'validate';
var validateUnique = (!opts || false !== opts['findUniqueConstraint']);
if (validateUnique && item.jsFormValidator.parent) {
var data = item.jsFormValidator.parent.data;
if (data['entity'] && data['entity']['constraints']) {
for (var i in data['entity']['constraints']) {
var constraint = data['entity']['constraints'][i];
if (constraint instanceof FpJsFormValidatorBundleFormConstraintUniqueEntity && constraint.fields.indexOf(item.name)) {
var owner = item.jsFormValidator.parent;
constraint.validate(null, owner);
}
}
}
}
if (!item.jsFormValidator[method]()) {
isValid = false;
}
});
return isValid;
};
this.showErrors = function (opts) {
//noinspection JSCheckFunctionSignatures
FpJsFormValidator.each(this, function (item) {
item.jsFormValidator.errors[opts['sourceId']] = opts['errors'];
item.jsFormValidator.showErrors.apply(item, [opts['errors'], opts['sourceId']]);
});
};
this.submitForm = function (event) {
//noinspection JSCheckFunctionSignatures
FpJsFormValidator.each(this, function (item) {
var element = item.jsFormValidator;
if (event) {
event.preventDefault();
}
element.validateRecursively();
if (FpJsFormValidator.ajax.queue) {
if (event) {
event.preventDefault();
}
FpJsFormValidator.ajax.callbacks.push(function () {
element.onValidate.apply(element.domNode, [FpJsFormValidator.getAllErrors(element, {}), event]);
if (element.isValid()) {
//item.submit();
}
});
} else {
element.onValidate.apply(element.domNode, [FpJsFormValidator.getAllErrors(element, {}), event]);
if (element.isValid()) {
//item.submit();
}
}
});
};
this.get = function () {
var elements = [];
//noinspection JSCheckFunctionSignatures
FpJsFormValidator.each(this, function (item) {
elements.push(item.jsFormValidator);
});
return elements;
};
//noinspection JSUnusedGlobalSymbols
this.addPrototype = function(name) {
//noinspection JSCheckFunctionSignatures
FpJsFormValidator.each(this, function (item) {
var prototype = FpJsFormValidator.preparePrototype(
FpJsFormValidator.cloneObject(item.jsFormValidator.prototype),
name,
item.jsFormValidator.id + '_' + name
);
item.jsFormValidator.children[name] = FpJsFormValidator.createElement(prototype);
item.jsFormValidator.children[name].parent = item.jsFormValidator;
});
};
//noinspection JSUnusedGlobalSymbols
this.delPrototype = function(name) {
//noinspection JSCheckFunctionSignatures
FpJsFormValidator.each(this, function (item) {
delete (item.jsFormValidator.children[name]);
});
};
}
</script>
Second of all, if you're looking to override some stuff in the function:
<script type="text/javascript">
(function(){
// Store a reference to the original method.
var originalMethod = jQuery.fn.FpJsFormValidator;
// Define overriding method.
jQuery.fn.FpJsFormValidator = function(){
// Execute the original method.
originalMethod.apply( this, arguments );
}
})();
</script>
Note:
You need to write this code after loading the original function.
I'm using a jquery plugin called quicksearch within Sharepoint 2010 and it works perfectly. Unfortunately were being forced to migrate onto sharepoint 2013 and it's stopped working. An error is shown saying that the function is undefined. I believe I've narrowed this down to the quicksearch function itself.
Here is the preliminary code:
_spBodyOnLoadFunctionNames.push("Load");
$('[name=search]').on('keyup', function(){
Load();
});
function Load() {
var searchArea = "#cbqwpctl00_ctl22_g_ca6bb172_1ab4_430d_ae38_a32cfa03b56b ul li";
var qs = $('input#id_search_list').val();
qs.quicksearch(searchArea);
$('.filter input').on('change', function(){
checkAndHide()
//$(searchArea).unhighlight();
});
function checkAndHide(){
var inputs = $('.filter input');
var i =0;
for (var i = 0; i < inputs.length; i++){
if (!inputs[i].checked){
$('.' + inputs[i].name).addClass('filter-hide');
} else {
$('.' + inputs[i].name).removeClass('filter-hide');
};
};
};
}
Here is an example of the quicksearch library I'm using:
(function($, window, document, undefined) {
$.fn.quicksearch = function (target, opt) {
var timeout, cache, rowcache, jq_results, val = '', e = this, options = $.extend({
delay: 300,
selector: null,
stripeRows: null,
loader: null,
noResults: 'div#noresults',
bind: 'keyup keydown',
onBefore: function () {
var ar = $('input#id_search_list').val()
if (ar.length > 2) {
var i=0;
var ar2 = $('input#id_search_list').val().split(" ");
for (i = 0; i < ar2.length; i++) {
$(searchArea + ':visible');
}
return true;
}
return false;
checkAndHide()
},
onAfter: function () {
return;
},
show: function () {
this.style.display = "block";
},
hide: function () {
this.style.display = "none";
},
prepareQuery: function (val) {
return val.toLowerCase().split(' ');
},
testQuery: function (query, txt, _row) {
for (var i = 0; i < query.length; i += 1) {
if (txt.indexOf(query[i]) === -1) {
return false;
}
}
return true;
}
}, opt);
this.go = function () {
var i = 0,
noresults = true,
query = options.prepareQuery(val),
val_empty = (val.replace(' ', '').length === 0);
for (var i = 0, len = rowcache.length; i < len; i++) {
if (val_empty) {
options.hide.apply(rowcache[i]);
noresults = false;
} else if (options.testQuery(query, cache[i], rowcache[i])){
options.show.apply(rowcache[i]);
noresults = false;
} else {
options.hide.apply(rowcache[i]);
}
}
if (noresults) {
this.results(false);
} else {
this.results(true);
this.stripe();
}
this.loader(false);
options.onAfter();
return this;
};
this.stripe = function () {
if (typeof options.stripeRows === "object" && options.stripeRows !== null)
{
var joined = options.stripeRows.join(' ');
var stripeRows_length = options.stripeRows.length;
jq_results.not(':hidden').each(function (i) {
$(this).removeClass(joined).addClass(options.stripeRows[i % stripeRows_length]);
});
}
return this;
};
this.strip_html = function (input) {
var output = input.replace(new RegExp('<[^<]+\>', 'g'), "");
output = $.trim(output.toLowerCase());
return output;
};
this.results = function (bool) {
if (typeof options.noResults === "string" && options.noResults !== "") {
if (bool) {
$(options.noResults).hide();
} else {
$(options.noResults).show();
}
}
return this;
};
this.loader = function (bool) {
if (typeof options.loader === "string" && options.loader !== "") {
(bool) ? $(options.loader).show() : $(options.loader).hide();
}
return this;
};
this.cache = function () {
jq_results = $(target);
if (typeof options.noResults === "string" && options.noResults !== "") {
jq_results = jq_results.not(options.noResults);
}
var t = (typeof options.selector === "string") ? jq_results.find(options.selector) : $(target).not(options.noResults);
cache = t.map(function () {
return e.strip_html(this.innerHTML);
});
rowcache = jq_results.map(function () {
return this;
});
return this.go();
};
this.trigger = function () {
this.loader(true);
if (options.onBefore()) {
window.clearTimeout(timeout);
timeout = window.setTimeout(function () {
e.go();
}, options.delay);
}
return this;
};
this.cache();
this.results(true);
this.stripe();
this.loader(false);
return this.each(function () {
$(this).bind(options.bind, function () {
val = $(this).val();
e.trigger();
});
});
};
}(jQuery, this, document));
`
This is where the error comes up:
var qs = $('input#id_search_list').val();
qs.quicksearch(searchArea);
Any help would be appreciated
Turns out was a small issue in the code and major css as sharepoint plays differently in 2013
I hope that somebody can help me.
I want to redeclare js function by extension.
For example, there is the basic js function on website:
function foo(){
..something here..
}
i want to redeclare it by own function with the same name. how it will be easiest to do?
edit 1. i'll try to explain better.
there is a native code in website:
Notifier = {
debug: false,
init: function (options) {
curNotifier = extend({
q_events: [],
q_shown: [],
q_closed: [],
q_max: 3,
q_idle_max: 5,
done_events: {},
addQueues: curNotifier.addQueues || {},
recvClbks: curNotifier.recvClbks || {},
error_timeout: 1,
sound: new Sound('mp3/bb1'),
sound_im: new Sound('mp3/bb2')
}, options);
if (!this.initFrameTransport() && !this.initFlashTransport(options)) {
return false;
}
this.initIdleMan();
if (!(curNotifier.cont = ge('notifiers_wrap'))) {
bodyNode.insertBefore(curNotifier.cont = ce('div', {id: 'notifiers_wrap', className: 'fixed'}), ge('page_wrap'));
}
},
destroy: function () {
Notifier.hideAllEvents();
curNotifier.idle_manager.stop();
curNotifier = {};
re('notifiers_wrap');
re('queue_transport_wrap');
},
reinit: function () {
ajax.post('notifier.php?act=a_get_params', {}, {
onDone: function (options) {
if (options) {
curNotifier.error_timeout = 1;
this.init(options);
} else {
curNotifier.error_timeout = curNotifier.error_timeout || 1;
setTimeout(this.reinit.bind(this), curNotifier.error_timeout * 1000);
if (curNotifier.error_timeout < 256) {
curNotifier.error_timeout *= 2;
}
}
}.bind(this),
onFail: function () {
curNotifier.error_timeout = curNotifier.error_timeout || 1;
setTimeout(this.reinit.bind(this), curNotifier.error_timeout * 1000);
if (curNotifier.error_timeout < 256) {
curNotifier.error_timeout *= 2;
}
return true;
}.bind(this)
});
}
}
and function Sound
function Sound(filename) {
var audioObjSupport = false, audioTagSupport = false, self = this, ext;
if (!filename) throw 'Undefined filename';
try {
var audioObj = ce('audio');
audioObjSupport = !!(audioObj.canPlayType);
if (('no' != audioObj.canPlayType('audio/mpeg')) && ('' != audioObj.canPlayType('audio/mpeg')))
ext = '.mp3?1';
else if (('no' != audioObj.canPlayType('audio/ogg; codecs="vorbis"')) && ('' != audioObj.canPlayType('audio/ogg; codecs="vorbis"')))
ext = '.ogg?1';
else
audioObjSupport = false;
} catch (e) {}
// audioObjSupport = false;
if (audioObjSupport) {
audioObj.src = filename + ext;
var ended = false;
audioObj.addEventListener('ended', function(){ended = true;}, true);
audioObj.load();
this.playSound = function() {
if (ended) {
audioObj.load();
}
audioObj.play();
ended = false;
};
this.pauseSound = function() {
audioObj.pause();
};
} else {
cur.__sound_guid = cur.__sound_guid || 0;
var wrap = ge('flash_sounds_wrap') || utilsNode.appendChild(ce('span', {id: 'flash_sounds_wrap'})),
guid = 'flash_sound_' + (cur.__sound_guid++);
var opts = {
url: '/swf/audio_lite.swf?4',
id: guid
}
var params = {
swliveconnect: 'true',
allowscriptaccess: 'always',
wmode: 'opaque'
}
if (renderFlash(wrap, opts, params, {})) {
var swfObj = browser.msie ? window[guid] : document[guid],
inited = false,
checkLoadInt = setInterval(function () {
if (swfObj && swfObj.paused) {
try {
swfObj.setVolume(1);
swfObj.loadAudio(filename + ext);
swfObj.pauseAudio();
} catch (e) {debugLog(e);}
}
inited = true;
clearInterval(checkLoadInt);
}, 300);
self.playSound = function() {
if (!inited) return;
swfObj.playAudio(0);
};
self.pauseSound = function() {
if (!inited) return;
swfObj.pauseAudio();
};
}
}
}
Sound.prototype = {
play: function() {
try {this.playSound();} catch(e){}
},
pause: function() {
try {this.pauseSound();} catch(e){}
}
};
when i try to add injection with redeclaration function Sound it doesn't work.
if i create my own function, for example, xSound and сall it this way:
cur.sound = new xSound('mp3/bb1');
it's working.
You can do it like this, for example:
foo = function(args) {
// method body...
}
JavaScript is a programming language where functions are first-class citizens so you can manipulate them like other types.
UPDATE:
Make sure that this piece of code actually does the redefinition and not the first definition. (thanks to #jmort253)
function foo(){
// ..something else here..
}
Remember that an extension's Content Script code and the webpage code run in different execution contexts.
So if you want to redefine a function that exists in the webpage context, you'll have to inject your code into the webpage. Take a look at this answer by Rob W for different methods of doing that:
Insert code into the page context using a content script
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