Javascript CallBack with same function name in multiple pages - javascript

My objective is to perform Auto-Complete feature of the same context in multiple pages/Views, for same input having the same class name (i.e. Client Name to be auto complete for many pages like Create and Edit View and others).
Since I need to call the jquery's autocomplete() in each page, I had written in
Views\Shared_Layout.cshtml
page of my project so the auto complete feature will available where required. The code I had written in _Layout.cshtml is as follows:
<script>
$(document).ready(function () {
//common
$('.form-control.salescode').autocomplete({
minLength: 4,
source: '#Url.Action("GetAccountManager", "AccountManager")',
select: callBackSalesCodeLookUp
});
});
</script>
Then any View (Create or Edit) which requires, the auto-complete feature have this code called:
<script>
function callBackSalesCodeLookUp(event, ui)
{
event.preventDefault();
var selectedArr = ui.item.value.split("|");
var accountManagerID = selectedArr[0];
var accountManagerName = selectedArr[1];
$('.form-control.salescode').val(accountManagerID);
}
</script>
However, when I ran the project, I am getting an error for pages which have not having the following code, which is as expected:
function callBackSalesCodeLookUp(event, ui)
{
event.preventDefault();
var selectedArr = ui.item.value.split("|");
var accountManagerID = selectedArr[0];
var accountManagerName = selectedArr[1];
$('.form-control.salescode').val(accountManagerID);
}
The error I am getting, is in Chrome as :
jquery-3.1.1.js:3855 Uncaught ReferenceError: callBackSalesCodeLookUp
is not defined
at HTMLDocument. (Login?ReturnUrl=%2FAccountOpeningRegister%2FCreate:393)
at mightThrow (jquery-3.1.1.js:3570)
at process (jquery-3.1.1.js:3638)
I want to less the code, and which is the reason I made up something like this. I will be glad to know if there is any better way of coding this.
Thank You

Check if the function exists in the window before calling it.
<script>
if (typeof callBackSalesCodeLookUp == 'function') {
$(document).ready(function () {
//common
$('.form-control.salescode').autocomplete({
minLength: 4,
source: '#Url.Action("GetAccountManager", "AccountManager")',
select: callBackSalesCodeLookUp
});
});
}
</script>

Related

Multiple Dropzone in a single page

I'm using Dropzone without creating a dropzone form. It works great for me in this way.
But in this case I can not create another instance of Dropzone in my page.
var myDropzone1 = new Dropzone(
document.body,
{
url : "upload1"...
.
.
. some parameters
};
var myDropzone2 = new Dropzone(
document.body,
{
url : "upload'"...
.
.
. some parameters
};
When I do this, I'm getting the error Dropzone already attached.
It's possible, but you can't bind a second dropdzone on the same element, as you did. 2 Dropzones on one element makes no sense. 2x document.body in your solution atm. Try this...
HTML:
<form action="/file-upload" class="dropzone" id="a-form-element"></form>
<form action="/file-upload" class="dropzone" id="an-other-form-element"></form>
JavaScript:
var myDropzoneTheFirst = new Dropzone(
//id of drop zone element 1
'#a-form-element', {
url : "uploadUrl/1"
}
);
var myDropzoneTheSecond = new Dropzone(
//id of drop zone element 2
'#an-other-form-element', {
url : "uploadUrl/2"
}
);
I want to add something here because I have experienced problems with multiple dropzones on the same page.
In your init code you must remember to include var if putting a reference otherwise it isn't dealing with this instance of the dropzone rather trying to access/relate to the others.
Simple javascript but makes a big difference.
init: function(){
var dzClosure = this;
$('#Btn').on('click',function(e) {
dzClosure.processQueue();
});
Note: I'm not using Ajax in order to upload the image on server. For Ajax, One can use url. Attaching the doc DropzoneDoc. It's works like action.( Something like that. Check my solution you can get some idea to do it in your case.
When I working we dropzone, I faced a similar issue working with the Meteor framework.
In the case of Meteor Framework, dropzone is initialized in the below code. This will look different to you, it's the way to initialize in the Meteor framework.
In your case, you can find similarities when using the dropzone library.
Params are added as
params='{name: "Image1"}'
{{> dropzone url=getDropZoneImageUploadURL id='candidate-identity-photo-proof'
init=initFunction params='{name: "Image1"}'
acceptedMimeTypes= 'image/jpeg,image/png,image/jpg' maxFiles=1
success=uploadSuccessHandler maxFilesize=2 dictDefaultMessage= "Photo
ID Proof Photo"
previewsContainer='#upload-photo-id-holder'
previewTemplate=previewTemplateString}}
when the file is getting uploaded check "this" context as mentioned below code. You can use the params value to distinguish the image.
var initFunction = function () {
this.on("addedfile", function () {
if (this.files[1] != null) {
this.removeFile(this.files[0]);
}
});
this.on("sending", function (file, xhr, formData) {
console.log(this); // Here you can get the value
formData.append("type", "image");
});
this.on("error", function (fileInfo, errorMessage) {
var message = "ERROR";
showNotification("error", { message: message }, {});
});
};

Why a JavaScript function with some specific name is not working while others are?

A very interesting problem I am facing these days is regarding one of my JavaScript function. My JavaScript function with some specific name is not working but if I change its name to anything else then it is working. Have a look -
// function to retain the jquery ui css for toolbar
function retain_css() {
alert('hi');
$( "#new_sort_options" ).buttonset();
}
// new sort
$(document).on("click", ".new_sort_button", function() {
var order = $(this).val();
var make_id = $('#new_make_id').val();
$.ajax({
beforeSend : start_loader(),
type : 'POST',
url : '/ajax/new-sort.php',
data : 'order='+order+'&make_id='+make_id,
dataType : 'json',
success : function(data) {
$("#new_results_toolbar").html(data.toolbar);
$("#new_results").html(data.models);
retain_css();
end_loader();
}
});
});
But retain_css() is not working at all. Even alert() is not firing. But if i change its name to anything such as my_fun() then the code works. I don't understand why it is happening so? Any idea? Don't worry about end_loader() function as it has nothing to deal with my problem. I also changed the order of code when retain_css() was being used but didn't work.
Try not to create global functions because it may collide with other frameworks or libraries.
//define private namespace
window.user3779493Functions = {};
//define method
user3779493Functions.retain_css = function() { ... }
//call method
user3779493Functions.retain_css();
Some functions are already programmed like 'alert('hi');', that is a function called alert:
function alert() {
/* do something */
}
That function also doesn't work.

Accessing function from within another with Javascript

I'm trying to get the jquery loadmask addon to work that will mask elements (for loading content). I'm using knockout.js, and when if I mask an element outside of my viewmodel it works, but I want to mask it upon submitting a POST request, and then unmask when I receive it. I'm getting an "object has no method mask" error from this. I'm not quite sure how to go about setting up an object to access it.
This works, but it's not what I want. I noted in the code where I would like to call mask from
<div id = "register_container">
<div data-bind="visible: register()">
<div id = "register_form"> <!--this is the div I want to mask -->>
<button data-bind="click: submitRegistration">Submit</button>
</div>
</div>
</div>
function MyViewModel(){
self.submitRegistration = function(){
//I want to mask here. When I try it says Object[object object] has no method mask
$.post....{
if(data.result == success){
// andunmask here
}
}
}
}
$("#register_form").mask("Waiting..."); //the masking works when I place it here, but it's always enabled and I want it inside the viewmodel where I noted so it only works when the POST request is in process
That's great and all, but I want to mask something from inside the viewmodel where I noted. How can I accomplish this?
I see several things that could be the problem.
Frist, you're doing assignment as opposed to comparison in the if statement. Use this instead:
if(data.result == success){
or even
if(data.result === success){
Second is the fact that I don't quite understand your code self.submitRegistration(){, which typically looks more like this:
var MyViewModel = function () {
var self = this;
self.submitRegistration = function() {
};
};
Then, if I mock the $.post call, it would work like this:
var MyViewModel = function () {
var self = this;
self.register = ko.observable(true);
self.submitRegistration = function() {
$("#register_form").mask("Waiting...");
// Mock $.post
window.setTimeout(function () {
if (1 == 1) {
// andunmask here
$("#register_form").unmask();
}
}, 3000);
}
};
ko.applyBindings(new MyViewModel());
See this fiddle for a demo.
You could even have Knockout help you find the element to look for:
See this updated fiddle for a demo of that.
// Use the "event" parameter to find the element...
self.submitRegistration = function(data, event) {
$(event.target).closest('#register_form').mask("Waiting...");
Hope it helps.

Trouble calling JavaScript function on page load

I have a javascript function that i have named refreshProjects(), what it does is filter a dropdownlist depending on what was selected in a previous dropdownlist. But i need to also filter my list direcktly after the page has finishd loading.
I have tried using the code window.onload = refreshProjects(id) with no sucsses, but onload workes when i use window.onload = alert('This page has finished loading!'), so i know that part off the script works. So how do i call a javascript function on load, i thought that it would be simple but evrything i tried have failed.
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
window.onload = refreshProjects(id); <-- Problem
$("#ddCustomers").change(function () {
refreshProjects($(this).val());
});
function refreshProjects(id) {
var projects = $("#ddProjects");
$.get('#Url.Action("FilterProjects","TimeEntry")', { customerId: id },
function (result) {
// clear the dropdown
projects.empty();
//Add a deafult "null" value
$("#ddProjects").get(0).options[0] = new Option("[ - No project - ]", "-1");
// rebuild the dropdown
$.each(result, function (i, e) {
projects.append($('<option/>').text(e.Text).val(e.Value));
});
});
}</script>
}
This is for MVC 4.5.
Try changing window.onload = refreshProjects(id); to:
window.onload = function() { refreshProjects($("#ddCustomers").val()); };
Onload expects a callback function. You were directly executing refreshProjects() and setting the return value as the onload.
But since you seem to be using jQUery, you could do the following:
$(function() {
refreshProjects($("#ddCustomers").val());
});
This will execute refreshProjects when the document is ready (which actually is before window load).
You can also try to use the following:
$(document).ready(function () {
refreshProjects(id);
});
This should work aswell if you are using jQuery.

How to place a jQuery snippet into a global file

I have a JavaScript file here http://www.problemio.com/js/problemio.js and I am trying to place some jQuery code into it that looks like this:
$(document).ready(function()
{
queue = new Object;
queue.login = false;
var $dialog = $('#loginpopup')
.dialog({
autoOpen: false,
title: 'Login Dialog'
});
var $problemId = $('#theProblemId', '#loginpopup');
$("#newprofile").click(function ()
{
$("#login_div").hide();
$("#newprofileform").show();
});
// Called right away after someone clicks on the vote up link
$('.vote_up').click(function()
{
var problem_id = $(this).attr("data-problem_id");
queue.voteUp = $(this).attr('problem_id');
voteUp(problem_id);
//Return false to prevent page navigation
return false;
});
var voteUp = function(problem_id)
{
alert ("In vote up function, problem_id: " + problem_id );
queue.voteUp = problem_id;
var dataString = 'problem_id=' + problem_id + '&vote=+';
if ( queue.login = false)
{
// Call the ajax to try to log in...or the dialog box to log in. requireLogin()
}
else
{
// The person is actually logged in so lets have him vote
$.ajax({
type: "POST",
url: "/problems/vote.php",
dataType: "json",
data: dataString,
success: function(data)
{
alert ("vote success, data: " + data);
// Try to update the vote count on the page
//$('p').each(function()
//{
//on each paragraph in the page:
// $(this).find('span').each()
// {
//find each span within the paragraph being iterated over
// }
//}
},
error : function(data)
{
alert ("vote error");
errorMessage = data.responseText;
if ( errorMessage == "not_logged_in" )
{
//set the current problem id to the one within the dialog
$problemId.val(problem_id);
// Try to create the popup that asks user to log in.
$dialog.dialog('open');
alert ("after dialog was open");
// prevent the default action, e.g., following a link
return false;
}
else
{
alert ("not");
}
} // End of error case
}
}); // Closing AJAX call.
};
$('.vote_down').click(function()
{
alert("down");
problem_id = $(this).attr("data-problem_id");
var dataString = 'problem_id='+ problem_id + '&vote=-';
//Return false to prevent page navigation
return false;
});
$('#loginButton', '#loginpopup').click(function()
{
alert("in login button fnction");
$.ajax({
url:'url to do the login',
success:function() {
//now call cote up
voteUp($problemId.val());
}
});
});
});
</script>
There are two reasons why I am trying to do that:
1) I am guessing this is just good practice (hopefully it will be easier to keep track of my global variables, etc.
2) More importantly, I am trying to call the voteUp(someId) function in the original code from the problemio.js file, and I am getting an error that it is an undefined function, so I figured I'd have better luck calling that function if it was in a global scope. Am I correct in my approach?
So can I just copy/paste the code I placed into this question into the problemio.js file, or do I have to remove certain parts of it like the opening/closing tags? What about the document.ready() function? Should I just have one of those in the global file? Or should I have multiple of them and that won't hurt?
Thanks!!
1) I am guessing this is just good practice (hopefully it will be
easier to keep track of my global variables, etc.
Yes and no, you now have your 'global' variables in one spot but the chances that you're going to collide with 'Global' variables (ie those defined by the browser) have increased 100% :)
For example say you decided to have a variable called location, as soon as you give that variable a value the browser decides to fly off to another URL because location is a reserved word for redirecting.
The solution to this is to use namespacing, as described here
2) More importantly, I am trying to call the voteUp(someId) function
in the original code from the problemio.js file, and I am getting an
error that it is an undefined function, so I figured I'd have better
luck calling that function if it was in a global scope. Am I correct
in my approach?
Here's an example using namespacing that will call the voteUp function:
(function($) {
var myApp = {};
$('.vote_up').click(function(e) {
e.preventDefault();
myApp.voteUp();
});
myApp.voteUp = function() {
console.log("vote!");
}
})(jQuery);
What about the document.ready() function? Should I just have one of
those in the global file? Or should I have multiple of them and that
won't hurt?
You can have as many document.ready listeners as you need, you are not overriding document.ready you are listening for that event to fire and then defining what will happen. You could even have them in separate javascript files.
Be sure your page is finding the jquery file BEFORE this file is included in the page. If jquery is not there first you will get function not defined. Otherwise, you might have other things conflicting with your jquery, I would look into jquery noConflict.
var j = jQuery.noConflict();
as seen here:
http://api.jquery.com/jQuery.noConflict/
Happy haxin
_wryteowl
Extending what KreeK has already provided: there's no need to define your "myApp" within the document ready function. Without testing, I don't know off the top of my head if doing so is a potential source for scope issues. However, I CAN say that the pattern below will not have scope problems. If this doesn't work, the undefined is possibly a script-loading issue (loading in the right order, for example) rather than scope.
var myApp = myApp || {}; // just adds extra insurance, making sure "myApp" isn't taken
myApp.voteUp = function() {
console.log("vote!");
}
$(function() { // or whatever syntax you prefer for document ready
$('.vote_up').click(function(e) {
e.preventDefault();
myApp.voteUp();
});
});

Categories