I am new in javascript and jquery.
I have created a class having some functions in javascript.
My javascript class is written in a .js file.
common.js
var myGeneralClass = {
_show : function() {
console.log("showing some divs here");
},
_hide : function() {
console.log("hiding some divs here");
}
}
_show() and _hide() functions are bind to some events.
Now I have jsp file, from where final html is rendered.
myGeneralClass methods are called from various jsp files.
Some jsp script want to add some code in _show() and _hide() methods according to there need.
for eg :
employee.jsp
<script>
//want to add some lines of js code to _show() method plus its default code.
// intercept _show() method
_interceptShow : function() {
console.log("this line is custom for employee");
},
// override _show() method
_overrideShow : function() {
console.log("this line is custom for employee");
console.log("showing some divs here");
}
</script>
Can I override OR intercept methods in javascript?
Can it be possible ?
If yes then how?
For adding more code in method:
use this:
var temp = myGeneralClass._show;
myGeneralClass._show = function(){
temp();
// more code
}
for overriding:
myGeneralClass._show = function(){
// new code
}
Related
I put all my .js files in one. So one page will use less than 10% of the functions there.
eg, page1.php need only .func1, but now I have func 2, 3, 4...
$(document).on("click", ".func1", function() { /* ... */ });
$(document).on("click", ".func2", function() { /* ... */ });
$(document).on("click", ".func3", function() { /* ... */ });
$(document).on("click", ".func4", function() { /* ... */ });
$(document).click(function(){ /* ... */ });
... fun20, func30.
Is it ok? I need only func1 but all this others listeners are working too. any thing I need or should do?
There's nothing wrong with your code but definitely it can get better.
There are some ways in order to do that :
1. Use a code bundler like webpack
Using webpack would be a good Idea specially for it's new feature Code Splitting that let's you to import different modules dynamically.
2. Using Modular design patterns like Revealing Module Pattern
There are someways to do this and it's so easy. I put some example codes for you down below :
// Self Invoke function
var Module1 = (function(){
// Configurations
var config = {
body : '.body',
header : '.header',
...
}
// Functions
function bodyHandler(){
...
}
function headerHandler(){
...
}
// Bind Events
$(document).on('click', config.body , bodyHandler);
$(document).on('click', config.header , headerHandler);
})()
You can separate your JavaScript code into various modules and use them in different pages.
Also you can config each module dynamically from outside (In html page for instance) like so :
(function(){
var Page = {
// Init the Module with your own configuration
init(conf){
this.config = conf;
this.bindEvents()
},
// Bind Events
bindEvents(){
$(document).on('click', this.config.body , this.bodyHandler);
$(document).on('click', this.config.header , this.headerHandler);
},
bodyHandler(){
...
},
headerHandler(){
...
},
}
// You can Init the module whereever you want
Page.init({
body : '.body',
header : '.header',
// Other options ...
})
})()
I currently have a similar process when it comes to JavaScript. All functions I write go into one large file. I then have a single function that runs when the DOM is ready that binds events onto specific elements.
By doing it that way a) I know where all the event binding is happening and b) Only events that are specific to the content of the page are actually bound
for example....
(function() {
function fnFunctionA() { ... }
function fnFunctionB() { ... }
function fnFunctionC() { ... }
$('.containerA').on('click', '.subElementA', fnFunctionA);
$('.containerB').on('click', '.subElementB', fnFunctionB);
$('.containerC').on('click', '.subElementC', fnFunctionC);
}());
Function A is only ever bound when containerA actually exists on the page and so on and so forth
I am trying to write a delete function in Dropzone.js. In order to do that I need the id of the file the way it was uploaded.
I tried to get a property of an object with no success. Now I am trying to use jQuery to get the value or text content of the span that has it.
this is the screenshot of the structure. The jQuery code I am trying is:
var loooot = $(".dz-filename").parents('span').text();
To be more specific I am trying to get the number 1_1477778745352 (which is a time stamp).
The Dropzone code is as follows:
<script>
var listing_id = "1";
// these are the setting for the image upload
Dropzone.options.pud = {
acceptedFiles: ".jpeg,.jpg,.png,.gif",
uploadMultiple: false,
paramName: "file", // The name that will be used to transfer the file
maxFilesize: 1, // MB
addRemoveLinks: true,
maxFiles: 10,
renameFilename: function (filename) {return listing_id + '_' + new Date().getTime();},
init: function()
{
this.on("removedfile", function(file)
{
var loooot = $("span", ".dz-filename").html();
alert(loooot);
});
}
};
</script>
Try this use JQuery's .text(); to get inner text
Update: use this with DOM .ready() like that.
Deep selector
$(document).ready(function(){
var fname = $("#pud .dz-filename span [data-dz-name]").text();
});
OR (if your form is dynamic)
function get_fname(){
return $("#pud .dz-filename span [data-dz-name]").text();
}
Then use get_fname();
It becomes undefined because dropzone works dynamicly, use this:
$('body').find(".dz-filename").find('span').text();
Best way to do this is to declare dropzone:
//first declare somewhere variable
var my_drop;
// then on creating dropzone:
my_drop = new Dropzone('.dropzone', {
/* your setup of dropzone */
});
Then you can retreive information about files with this:
my_drop.files[0].name
The [0] represent's first file, you can loop through them if there's more then one.
Use:
var loooot = $("span", ".dz-filename").html();
Working Demo.
var loooot = $("span", ".dz-filename").html();
alert(loooot);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="dz-filename">
<span>Test</span>
</div>
EDIT
Since you are setting the text dynamically it may happens that jquery read the HTML before that you set it, to prevent this you have to call this function after the timestamp as a callback (i can't help you without seeing how you set the span text).
So do something like:
function setSpan(callback) {
// Set your stuffs
// Call the callback
callback();
}
function getText() {
// I'm the callback witch get the html
}
//Onload
setSpan(getText());
EDIT
For dropzone you can use queuecomplete that start a function after the queue, i'm not an dropzone expert but i suppose:
init: function () {
this.on("queuecomplete", function (file) {
//Get span html
alert("All files have uploaded ");
});
}
The working solution I found is this:
init: function()
{
this.on("removedfile", function(file)
{
var loooot = $(file.previewElement).find('[data-dz-name]').text();
alert(loooot);
});
}
i want to create a flexible jquery plugin for handling forms, here's my markup + code:
<div id="myform" validate="1">form</div>
<script>
(function ($) {
$.fn.myForm = function()
{
var me = this;
if(me.attr("validate"))
{
me.validate();
}
};
})(jQuery);
// code from external file eg. myform_validate.js
$.fn.myplugin.validate = function () {
// form validation here
alert("validate");
};
$(document).ready(function(){
$('#myform').myForm();
});
</script>
what i want to achieve is somekind of plugin-in-plugin structure which means myForm is the base plugin for each project and if required i would add extra functionality/methods like form validation or an image uploader to the plugin (by loading additional external scripts).
this should be dont without instantiation, directly inside the plugin.
as you might expect, the above code doesn't work .. :/
any ideas if this is possible?
thanks
There are probably numerous ways to achieve expected results. Here, checks if validate method from "external file" is defined, if yes, sets validate as property of myForm ; utilizes Function.prototype.call to set this within validate
(function($) {
function myForm() {
me = this;
if (me.attr("validate")) {
if (myForm.validate) {
myForm.validate.call(me)
.text(me.text() + " validated")
.css("color", "green");
}
};
return me
};
try {
if (validate && typeof validate === "function") {
myForm.validate = validate
}
// catch `ReferenceError` if `validate` is not defined
} catch (e) {
alert(e.message)
}
$.fn.myForm = myForm;
})(jQuery);
// code from external file eg. myform_validate.js
$(document).ready(function() {
$("#myform").myForm();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<script>
// external file
function validates() {
// form validation here
console.log(this)
alert("validate");
// `this` : `#myform`
return this
};
</script>
<div id="myform" validate="1">form</div>
I have a prototype.js class that I would like to extend to both add some new functions and override a couple of the functions already there.
in the example below I would like to add initAutocompleteNew and edit initAutocomplete to alert "new".
Varien.searchForm = Class.create();
Varien.searchForm.prototype = {
initialize : function(form, field, emptyText){
this.form = $(form);
this.field = $(field);
this.emptyText = emptyText;
Event.observe(this.form, 'submit', this.submit.bind(this));
Event.observe(this.field, 'focus', this.focus.bind(this));
Event.observe(this.field, 'blur', this.blur.bind(this));
this.blur();
},
//////more was here
initAutocomplete : function(url, destinationElement){
alert("old");
},
}
someone suggested but that doesn't work I think it's jQuery?
$.extend(obj_name.prototype, {
newfoo : function() { alert('hi #3'); }
}
This article should help out: http://prototypejs.org/learn/class-inheritance
It looks like you're defining your classes the 'old' way as described in the first example on that page. Are you using 1.7?
Assuming you are using 1.7, if you wanted to override or add methods to your class, you can use Class.addMethods:
Varien.searchForm.addMethods({
initAutocomplete: function(url, destinationElement) {
// Your new implementation
// This will override what was previously defined
alert('new');
},
someNewMethod: function() {
// This will add a new method, `someNewMethod`
alert('someNewMethod');
}
});
Here's a fiddle: http://jsfiddle.net/gqWDC/
I know that I can create custom jQuery plugins by using the $.fn.myFunction constructor, and the calling the custom function in JavaScript as $('selector').myFunction().
However, for a project I'm currently working on, I need to be able to define a function that does not require a selector to work.This is actually for a MessageBox plugin, which will act in a similar manner to C#'s MessageBox class. As such, I would ideally like to create the function as MessageBox, and then call it as follows:
var myMessage = $.MessageBox(); and then in turn myMessage.Show();
Notice the lack of selector brakets in the jQuery reference at the beginning of the function call.
Any advice on the best practice for this would be gratefully received.
This should work:
jQuery.MessageBox = function() {
var show = function() {
// something...
}
var hide = function() {
// something...
}
return {
show: show,
hide: hide
}
}
relipse has a good point - as you are cluttering the main namespace. A solution if you have more objects than just eg. MessageBox is to create your own namespace like this:
jQuery.myLib = {
MessageBox: function() {
var show = function() {
// something...
}
var hide = function() {
// something...
}
return {
show: show,
hide: hide
}
}
}
That means you are only taking one place in the main namespace (the name of your library, in this case myLib). You'd call it like this:
jQuery.myLib.MessageBox.show()
(function ($) {
$.MessageBox = function () {
var show = function () {
// something...
}
var hide = function () {
// something...
}
return {
show: show,
hide: hide
}
}
})(Jquery);
I think you better scope to Immediate invocation function to avoid collision with namespaces.