transform in function javascript - javascript

Hello and I could do with this one function?
I am new to javascript.
I need to encapsulate the code below in a function like:
ConfirmDelete function () {
};
that does the same as this:
$('.btn-danger').on('click', function (e, confirmed) {
if (!confirmed) {
e.preventDefault();
bootbox.confirm("Are you sure?", function (response) {
if (response) {
$('.btn-danger').trigger('click', true);
}
});
}
});

I have been over your code and the jQuery version is your best bet. You can't get the same functionality from inline handlers connected to the button.
You will want to move to the submit event of the form as click on a single button is unreliable (e.g. when using keyboard). e.g. You would want to change it to something like:
$('form:has(.btn-danger)').on('submit', function (e, confirmed) {
var $form = $(this);
if (!confirmed) {
e.preventDefault();
bootbox.confirm("Are you sure?", function (response) {
if (response) {
$form.trigger('submit', true);
}
});
}
});

Related

Jquery on Blur and on input conflict

I created a small AutoComplete object and list my results as a list of li elements. I have an this.on('input', function () {}); event that handles when you choose an item in the list and works fine. Now I want to add an blur event to hide results. Adding the blur events stops the input event from working.
$.fn.autoComplete = function () {
this.on('input', function () {
AutoComplete(self.val());
});
this.on('blur', function () {
$('#' + settings.resultsDivId).hide();
});
function AutoComplete(term) {
// ajax call
});
};
This worked in the following JSFiddle - it looks like you have an error after your AutoComplete function (it ends with ");"): https://jsfiddle.net/ek5v59t6/
$(function() {
$('input').autoComplete();
});
$.fn.autoComplete = function () {
this.on('input', function () {
console.log('input fired');
AutoComplete($(this).val());
});
this.on('blur', function () {
console.log('blur fired');
$('#results').hide();
});
function AutoComplete(term) {
$('#results').show();
}
};

nesting ajax post in json get

function test() {
$.getJSON("/Home/GetAp", function (result) {
$.each(result, function () {
if (this.is_disabled == "False") {
var a = $("#MainDiv")
.append('<div id="imagewrap"><img id="infobutton" src="/Content/information%20icon.png" /></div>')
.val(this.id);
} else if (this.is_disabled == "True") {
var a = $("#MainDiv")
.append('<div id="imagewrap"><img id="infobutton2" src="/Content/information%20icon.png" /></div>')
.val(this.id);
} else {
return null;
}
})
})
}
How would I nest and ajax function be able to POST the a.val() so that when a user clicks on any $("#infobutton") they will be able to use the val of that button which would be an id specific to that button
$("#infobutton").click(function () {
$.ajax({
type: "POST",
contentType: 'application/json; charset=utf-8',
url: "/Home/setID",
data: JSON.stringify({ id: this.id }),
success: function (result) {
}
});
});
Do not make your logic depend on duplicate ids of DOM elements, use class instead.
Use event delegation to register event handlers for elements that exist at the time of event registration and for elements that will be created later.
.append('<div id="imagewrap"><img class="infobutton" src="/Content/information%20icon.png" /></div>')
$(document).on("click",".infobutton",function () {
$.ajax({
...
});
});
No need to nest ajax call. Just ensure click events bind to new elements appended and get the id in click event handler. Similar example (without ajax call)
$(document).ready(function(){
$(document).on('click', '.info', function(e) { alert("clicked div # " + $(e.target).text()); });
setTimeout(function(){ $("#d1").append("<div class='info'>Click info 1.</div>"); }, 1000);
setTimeout(function(){ $("#d1").append("<div class='info'>Click info 2.</div>"); }, 2000);
setTimeout(function(){ $("#d1").append("<div class='info'>Click info 3.</div>"); }, 3000);
});
<div id="d1">
</div>
Let me know if you need more details or example with ajax call.
For id you can use
$(document).on('click', '.info', function(e) { alert("clicked div # " + e.target.id); });

How can i call a function within a js file?

I have a JavaScript file AppForm.js, which I wish to reinitialize after a successful ajax post response.
The file itself contains, among others
(function(namespace, $) {
"use strict";
var AppForm = function() {
// Create reference to this instance
var o = this;
// Initialize app when document is ready
$(document).ready(function() {
o.initialize();
});
};
var p = AppForm.prototype;
p.initialize = function() {
// Init events
this._enableEvents();
this._initRadioAndCheckbox();
this._initFloatingLabels();
this._initValidation();
};
p._enableEvents = function () {
//blah blah blah
e.preventDefault();
};
p._initRadioAndCheckbox = function () {
};
p._initFloatingLabels = function () {
};
p._initValidation = function () {
};
window.materialadmin.AppForm = new AppForm;
}(this.materialadmin, jQuery)); // pass in (namespace, jQuery):
How can I do that?
$.ajax({
url: path, type: "POST", cache: "false",
dataType: "html",
contentType: "application/json; charset=utf-8",
traditional: true,
data: JSON.stringify(postData)
}).success(function (data) {
$("#products-list").html(data);
//**PERFORM INIT OF JS FILE**
}).error(function (data) {
});
Thanks to Dan's answer the solution is pretty close but the events are not working since e.preventDefault(); is called.
And here is the full script
(function(namespace, $) {
"use strict";
var AppForm = function() {
// Create reference to this instance
var o = this;
// Initialize app when document is ready
$(document).ready(function() {
o.initialize();
});
};
var p = AppForm.prototype;
// =========================================================================
// INIT
// =========================================================================
p.initialize = function() {
// Init events
this._enableEvents();
this._initRadioAndCheckbox();
this._initFloatingLabels();
this._initValidation();
};
// =========================================================================
// EVENTS
// =========================================================================
// events
p._enableEvents = function () {
var o = this;
// Link submit function
$('[data-submit="form"]').on('click', function (e) {
e.preventDefault();
var formId = $(e.currentTarget).attr('href');
$(formId).submit();
});
// Init textarea autosize
$('textarea.autosize').on('focus', function () {
$(this).autosize({append: ''});
});
};
// =========================================================================
// RADIO AND CHECKBOX LISTENERS
// =========================================================================
p._initRadioAndCheckbox = function () {
// Add a span class the styled checkboxes and radio buttons for correct styling
$('.checkbox-styled input, .radio-styled input').each(function () {
if ($(this).next('span').length === 0) {
$(this).after('<span></span>');
}
});
};
// =========================================================================
// FLOATING LABELS
// =========================================================================
p._initFloatingLabels = function () {
var o = this;
$('.floating-label .form-control').on('keyup change', function (e) {
var input = $(e.currentTarget);
if ($.trim(input.val()) !== '') {
input.addClass('dirty').removeClass('static');
} else {
input.removeClass('dirty').removeClass('static');
}
});
$('.floating-label .form-control').each(function () {
var input = $(this);
if ($.trim(input.val()) !== '') {
input.addClass('static').addClass('dirty');
}
});
$('.form-horizontal .form-control').each(function () {
$(this).after('<div class="form-control-line"></div>');
});
};
// =========================================================================
// VALIDATION
// =========================================================================
p._initValidation = function () {
if (!$.isFunction($.fn.validate)) {
return;
}
$.validator.setDefaults({
highlight: function (element) {
$(element).closest('.form-group').addClass('has-error');
},
unhighlight: function (element) {
$(element).closest('.form-group').removeClass('has-error');
},
errorElement: 'span',
errorClass: 'help-block',
errorPlacement: function (error, element) {
if (element.parent('.input-group').length) {
error.insertAfter(element.parent());
}
else if (element.parent('label').length) {
error.insertAfter(element.parent());
}
else {
error.insertAfter(element);
}
}
});
$('.form-validate').each(function () {
var validator = $(this).validate();
$(this).data('validator', validator);
});
};
// =========================================================================
// DEFINE NAMESPACE
// =========================================================================
window.materialadmin.AppForm = new AppForm;
}(this.materialadmin, jQuery)); // pass in (namespace, jQuery):
UPDATE 1
I added window.materialadmin.AppForm.Initilize at the ajax response but the events are not working
UPDATE 2
And here is the code that does not work after the postback.
$(".ProductOnlyForDemonstation, .IncludeInMainPage, .Active")
.on('click', 'button', function(){
$('.sweet-overlay').toggle();
if (jQuery("#FORM").valid()) {
var id = $(this).attr("data-id");
$.post("/product/DemoIncludeActive", {
"Id": id,
"ProductOnlyForDemonstation": $("#ProductOnlyForDemonstation-" + id).is(':checked'),
"IncludeInMainPage": $("#IncludeInMainPage-" + id).is(':checked'),
"Active": $("#Active-" + id).is(':checked'),
},
function (data) {
}).success(function (data) {
}).error(function () {
});
}
});
You can wrap your code in a global function.
(function(namespace, $) {
"use strict";
window.main = function() {
var AppForm = function () {
// ...
};
};
window.main(); // you can initialize it here
)(this.materialadmin, jQuery);
And execute it if the response is successful.
.success(function (data) {
$("#products-list").html(data);
//**PERFORM INIT OF JS FILE**
window.main();
}).error(function (data) {
});
Edit: It looks like you're exposing the initialize method on a global object. You can just call that init method when the AJAX response completes.
.success(function (data) {
$("#products-list").html(data);
//**PERFORM INIT OF JS FILE**
window.materialadmin.AppForm.initialize();
}).error(function (data) {
});
Related to UPDATE 2
Try to register your events with delegation:
$(document).on(
'click',
'.ProductOnlyForDemonstation button, .IncludeInMainPage button, .Active button',
function() {
// Your code
}
);
I suppose you're loading something and render new page content after response, so previously registered events are not attached to new elements. With delegation you'll get your events working even after elements were added to DOM dynamically (if they match with delegating selector), because events are attached to document and bubbled from your buttons. You can attach event deeper in the DOM than document itself, but to the element containing your dynamic content (in other words: to closest element that will not be overriden after completing request).
PS. You can also add some unique class to all .ProductOnlyForDemonstation button, .IncludeInMainPage button, .Active button and delegate events to that class (shorter definition)
some checks for the events to work after postback
1)using $("#products-list").html(data) will remove all the events attached to child elements of #products-list.
So either a)attach events once on "#products-list" only with event-delegation In jQuery, how to attach events to dynamic html elements?
or b)reattach events on every child after using $("#products-list").html(data)
2) dont use .html() because it also removes all jquery data and events on children. update independent children elements instead.
I had experienced same issue like you. After reinitializing events,all events are not working properly.
I have tried lots and finally i have found issue.when i am reinitializing all control, all events are rebind.
so they are not fired properly.
so please unbind all events related to your control and then init all control agian and bind all event.
Updated answer
if you are using jQuery 1.7 or onwarads then add following code:
$(".ProductOnlyForDemonstation, .IncludeInMainPage, .Active").off();
$('[data-submit="form"]').off('click');
$('textarea.autosize').off('focus');
$('.floating-label .form-control').off('keyup change');
//-----------------
//**PERFORM INIT OF JS FILE**
before this line.
//**PERFORM INIT OF JS FILE**
and you are using jquery below 1.7 then use following code:
$(".ProductOnlyForDemonstation, .IncludeInMainPage, .Active").unbind();
$('[data-submit="form"]').unbind('click');
$('textarea.autosize').unbind('focus');
$('.floating-label .form-control').unbind('keyup change');
//-----------------
//**PERFORM INIT OF JS FILE**
before this line.
//**PERFORM INIT OF JS FILE**
for more help related to unbind click here.
for more help related to off click here.
i hope this will help.
In order to call a function you should take into account the following points below:
The function should be defined in the same file or one loaded before the attempt to call it.
The function should be in the same or greater scope then the one trying to call it.
So, the following example should work:
You declare function fnc1 in first.js, and then in second you can just have fnc1();
first.js :
function fnc1 (){
alert('test');
}
second.js :
fnc1();
index.html :
<script type="text/javascript" src="first.js"></script>
<script type="text/javascript" src="second.js"></script>
You could add the line namespace.initialize = p.initialize; at the end of your code :
(function(namespace, $) {
"use strict";
/* ....... */
// =================================================
// DEFINE NAMESPACE
// =================================================
namespace.AppForm = new AppForm;
namespace.initialize = p.initialize;
}(this.materialadmin, jQuery)); // pass in (namespace, jQuery):
Then, p.initialize becomes available globally as materialadmin.initialize, and you can call it from another file like this :
materialadmin.initialize();
Maybe two solutions
First solution
Create a file js with your functions who will reload.
<script language="text/javascript">
function load_js()
{
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.src= 'source_file.js';
head.appendChild(script);
}
</script>
And in your success :
.success(function (data) {
$("#products-list").html(data);
load_js();
}).error(function (data) {
});
2nd Solution
Like the first solution : Create a file js with your functions who will reload.
Use use getScript instead of document.write - it will even allow for a callback once the file loads.
Description: Load a JavaScript file from the server using a GET HTTP
request, then execute it.
So you can try this :
.success(function (data) {
$.getScript('your-file.js', function() {
}).error(function (data) {
});
or simply :
jQuery.getScript('my-js.js');
You will try, and tell me if that helps.
It should be simple by printing content of this at top of your ajax url script :
<script src="your-js-to-be-initialized.js"></script>
Your jquery ajax code will remain the same. You just need to print the script on each request so that it is reinitialized and binds to your elements.
$.ajax({
url: path.php, type: "POST", cache: "false",
dataType: "html", contentType: "application/json; charset=utf-8",
traditional: true,
data: JSON.stringify(postData)
}).success(function (data) {
$("#products-list").html(data);
//**PERFORM INIT OF JS FILE**
//path.php should echo/print the <script src="your-js-to-be-initialized.js">
}).error(function (data) {
});
I looked at your edit history and saw you did
p._enableEvents = function () {
var o = this;
// Link submit function
$('[data-submit="form"]').on('click', function (e) {
e.preventDefault();
var formId = $(e.currentTarget).attr('href');
$(formId).submit();
});
// Init textarea autosize
$('textarea.autosize').on('focus', function () {
$(this).autosize({append: ''});
});
};
If this is still how you enable your events, I suspect the cause might be you have more than one subscription on form click and textarea focus after reinitializing on your ajax callback. I suggest try only do other init tasks, and exclude event bindings in your callback function.
Try make it like this:
(function($) {
"use strict";
var materialadmin = {};
var AppForm = function() {
//closure
var self = this;
(function(){
//todo: init events
};)();
//<your AppForm class's props here...>
};
materialadmin.Init = function(){
//create instance of AppForm calss for materialadmin object
materialadmin.appForm = new AppForm();
}
return materialadmin;
//*}(jQuery)); // syntax mistake, i'm sorry)).*
})(jQuery);
$(document).ready(function(){
materialadmin.Init();
});
$.ajax({
url: path,
type: "POST",
cache: "false",
dataType: "html",
contentType: "application/json; charset=utf-8",
traditional: true,
data: JSON.stringify(postData),
success: function (data) {
$("#products-list").html(data);
materialadmin.Init();
},
error: function(){
alert('error')}
});
As you're using jQuery validator, you can use Validator's resetForm method in order to reset your form.
For this purpose, you can expose a reset method like follows:
p.reset = function () {
// Reset managed form
$('.form-validate').data('validator').resetForm();
// Reset custom stuff
this._initRadioAndCheckbox();
this._initFloatingLabels();
};
Note that in order to reset your form correctly after posting your request, you need to isolate event binding from the init stuff, for instance the following event binding should move from _initFloatingLabels to _enableEvents:
// Link submit function
$('[data-submit="form"]').on('click', function (e) {
e.preventDefault();
var formId = $(e.currentTarget).attr('href');
$(formId).submit();
});
Finally, you just have to call window.materialadmin.AppForm.reset() in your POST request's callback.

Jquery widget triggered event not being handled or fired

I have a very simple widget outlined that appears to fire an event via _trigger that I cant seem to bind to:
; (function ($) {
$.widget('testspace.ftpWidget', {
options: {},
widgetEventPrefix: 'ftpwidget:',
_create: function () {
var that = this;
that.paused = ko.observable(false);
},
_triggerPlayerInitialized: function () {
console.log("player initialized");
this._trigger("testeventname", null, null);
console.log("player testeventname supposedly fired");
},
pause: function () {
this.paused(!this.paused());
console.log("player paused");
this._triggerPlayerInitialized();
},
_destroy: function () { },
_setOption: function (key, value) { }
});
}(jQuery));
In an html file:
<script>
jQuery(document).ready(function ($) {
$('#videoA').ftpWidget();
var widget = $('#videoA').data("testspace-ftpWidget");
console.log(widget);
$(widget).on("ftpwidget:testeventname", function (event, data) {
console.log("widget initialized");
});
widget.pause();
});
And console output:
Why is this event not being handled / or is it not even being fired? How can I debug this?
Update:
This answer, though not my problem, gave me a hint. The OP is calling the on binding from an element body. So I changed
$(widget).on("ftpwidget:testeventname", function (event, data) {
to
$("body").on("ftpwidget:testeventname", function (event, data) {
and it worked, so does
$("#video").on("ftpwidget:testeventname", function (event, data) {
So now I have it working but don't really understand why. Is it a scope "thing"?
I was thinking
"I want to register for the testeventname on widget"
What's going on here?
_trigger itself can actually call your function. In the first parameter you're specifying the name of the callback function you want to trigger. So if you were to change:
$('#videoA').ftpWidget();
to
$('#videoA').ftpWidget({
testeventname: function (event, data) {
console.log("widget initialized");
}
});
that would also work.
Jquery-UI: How to Use the Widget Factory

pub/sub API does not work

I wrote following code to implement simple pub/sub API.
(function ($) {
var o = $({});
$.each({
trigger: 'trigger',
on: 'listen',
off: 'stopListen'
}, function (key, val) {
jQuery[val] = function () {
//console.log(o[key]);
o[key].apply(o, arguments);
}
});
})(jQuery);
$.trigger('watch');
$.listen('watch', function (e, data) {
alert('Watch it');
});
However, above code does not alert Watch it. Why it does not work and how can I fix it?
You have to listen to the event before you trigger it. Try executing in this order:
$.listen('watch', function (e, data) {
alert('Watch it');
});
$.trigger('watch');

Categories