I have a problem here with bootstrap modals, so in back-end of my app I pull out data from SQL, and I call a JS function like this:
ScriptManager.RegisterStartupScript(this, this.GetType(), "ShowPopup",
"MailLanguageChange('" + Description + "','" + TextResult + "');", true);
And JS looks like this :
function MailLanguageChange(Name, Text) {
$('#MainContent_NewMailTemplate').modal('show');
document.getElementById("Upper_txtDesc").value = Name;
document.getElementById("TextEditorTextArea").innerHTML = Text;
}
So firebug hits break point at this function, so I am sure call of function does work, but here comes the problem, JS is trying to apply this data onto the modal, before all elements of modal are loaded.
But as I use this modal for multiple purpuses ... is there anyway to write it down, "Don't do anything until modal is shown"?
$('#MainContent_NewMailTemplate').modal('show');
As docs says, it returns to the caller before the modal has actually been shown ... how can i by pass that?
EDIT :
This is how I have also tried it
function MailLanguageChange(Name, Text) {
$('#MainContent_NewMailTemplate').modal('show');
$("#MainContent_NewMailTemplate").on('shown.bs.modal', function () {
document.getElementById("Upper_txtDesc").value = Name;
document.getElementById("TextEditorTextArea").innerHTML = Text;
});
}
CONCLUSION :
With use of logic of global variables provided by #Guruprasad Rao
I ended up just simply using
$(document).ready(function () {
document.getElementById("Upper_txtDesc").value = name;
document.getElementById("TextEditorTextArea").innerHTML = text;
});
Thank you
Use twitter-bootstrap's shown.bs.modal method as below:
$("#yourmodalid").on('shown.bs.modal',function(){
//Do whatever you want here
});
There are several other events to look into regarding modal
Update
see you are showing the modal first and then you are registering that event.. So I would suggest you below steps.
Declare 2 global variables at the top in js page.
Ex
var name,text;
Assign them values inside your function MailLanguageChange.
Ex
function MailLanguageChange(Name, Text) {
name=Name;
text=Text;
$('#MainContent_NewMailTemplate').modal('show');
}
Keep shown.bs.modal event somewhere outside the above function
Ex
$("#MainContent_NewMailTemplate").on('shown.bs.modal', function () {
document.getElementById("Upper_txtDesc").value = name;
document.getElementById("TextEditorTextArea").innerHTML = text;
});
Related
I have two functions, where the first creates a div in the dom and the second gets the ID via getElementById(). Unfortunately, my second function is just returning null.
I looked in using $.Deffered() in either of my functions, but alas nothing I do seems to work
function one() {
var dynamicDiv = $("<div>").attr("id", 'test');
dynamicDiv.iziModal({
//modal content here
})
}
function two() {
var container = document.getElementById('test');
console.log(container.innerHTML); //not returning any data
}
enter code here
I had hoped to use this with a library that replaces images with a canvas object, but it requires that the "parent element to be a valid DOM Element". I have been searching for a while now, but I can not seem to find anything on the subject that is applicable.
** Edit**
Thank you for pointing out the error in my id (I had tried something else before I pasted). The iziModal function (http://izimodal.marcelodolza.com/) is currently pulling the content in via ajax (which I assume is the problem here):
The iziModal Function:
dynamicDiv.iziModal({
title: '',
autoOpen: 1,
width: 500,
onOpening: function (offer) {
offer.startLoading();
$.get(demoUrl, function (data) {
$('#' + id + " .iziModal-content").html(data);
offer.stopLoading();
});
}
});
Content of the other file:
<div id="test">
<img src="./bundle/images/coupon.jpg" />
</div>
function one() {
var dynamicDiv = $("<div>").attr("id", 'test');
dynamicDiv.iziModal({
//modal content here
});
$("body").append(dynamicDiv);
}
I'm having some problems with users clicking buttons multiple times and I want to suppress/ignore clicks while the first Ajax request does its thing. For example if a user wants add items to their shopping cart, they click the add button. If they click the add button multiple times, it throws a PK violation because its trying to insert duplicate items into a cart.
So there are some possible solutions mentioned here: Prevent a double click on a button with knockout.js
and here: How to prevent a double-click using jQuery?
However, I'm wondering if the approach below is another possible solution. Currently I use a transparent "Saving" div that covers the entire screen to try to prevent click throughs, but still some people manage to get a double click in. I'm assuming because they can click faster than the div can render. To combat this, I'm trying to put a lock on the Ajax call using a global variable.
The Button
<span style="SomeStyles">Add</span>
Knockout executes this script on button click
vmProductsIndex.AddItemToCart = function (item) {
if (!app.ajaxService.inCriticalSection()) {
app.ajaxService.criticalSection(true);
app.ajaxService.ajaxPostJson("#Url.Action("AddItemToCart", "Products")",
ko.mapping.toJSON(item),
function (result) {
ko.mapping.fromJS(result, vmProductsIndex.CartSummary);
item.InCart(true);
item.QuantityOriginal(item.Quantity());
},
function (result) {
$("#error-modal").modal();
},
vmProductsIndex.ModalErrors);
app.ajaxService.criticalSection(false);
}
}
That calls this script
(function (app) {
"use strict";
var criticalSectionInd = false;
app.ajaxService = (function () {
var ajaxPostJson = function (method, jsonIn, callback, errorCallback, errorArray) {
//Add the item to the cart
}
};
var inCriticalSection = function () {
if (criticalSectionInd)
return true;
else
return false;
};
var criticalSection = function (flag) {
criticalSectionInd = flag;
};
// returns the app.ajaxService object with these functions defined
return {
ajaxPostJson: ajaxPostJson,
ajaxGetJson: ajaxGetJson,
setAntiForgeryTokenData: setAntiForgeryTokenData,
inCriticalSection: inCriticalSection,
criticalSection: criticalSection
};
})();
}(app));
The problem is still I can spam click the button and get the primary key violation. I don't know if this approach is just flawed and Knockout isn't quick enough to update the button's visible binding before the first Ajax call finishes or if every time they click the button a new instance of the criticalSectionInd is created and not truely acting as a global variable.
If I'm going about it wrong I'll use the approaches mentioned in the other posts, its just this approach seems simpler to implement without having to refactor all of my buttons to use the jQuery One() feature.
You should set app.ajaxService.criticalSection(false); in the callback methods.
right now you are executing this line of code at the end of your if clause and not inside of the success or error callback, so it gets executed before your ajax call is finished.
vmProductsIndex.AddItemToCart = function (item) {
if (!app.ajaxService.inCriticalSection()) {
app.ajaxService.criticalSection(true);
app.ajaxService.ajaxPostJson("#Url.Action("AddItemToCart", "Products")",
ko.mapping.toJSON(item),
function (result) {
ko.mapping.fromJS(result, vmProductsIndex.CartSummary);
item.InCart(true);
item.QuantityOriginal(item.Quantity());
app.ajaxService.criticalSection(false);
},
function (result) {
$("#error-modal").modal();
app.ajaxService.criticalSection(false);
},
vmProductsIndex.ModalErrors);
}
}
you could use the "disable" binding from knockout to prevent the click binding of the anchor tag to be fired.
here is a little snippet for that. just set a flag to true when your action starts and set it to false again when execution is finished. in the meantime, the disable binding prevents the user from executing the click function.
function viewModel(){
var self = this;
self.disableAnchor = ko.observable(false);
self.randomList = ko.observableArray();
self.loading = ko.observable(false);
self.doWork = function(){
if(self.loading()) return;
self.loading(true);
setTimeout(function(){
self.randomList.push("Item " + (self.randomList().length + 1));
self.loading(false);
}, 1000);
}
}
ko.applyBindings(new viewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.0.0/knockout-min.js"></script>
Click me
<br />
<div data-bind="visible: loading">...Loading...</div>
<br />
<div data-bind="foreach: randomList">
<div data-bind="text: $data"></div>
</div>
I am having some trouble trying to store the url parameters of some dynamic links that I created with an ajax post response. The ajax post is working correctly and the name and subgenre vars are being properly filled from the ajax response. Now what I would like to happen is that a user clicks on one of the generated urls, the parameters inside of the urls, i.e. subgenre="blah", are going to be sent to a database and stored. The problem I am having is that a standard event click function will not work inside or outside of the document ready function.
$(document).ready(function() {
$.each(data, function() {
$('#artist-suggestions').append('<li>' + this.name + this.new + '</li>');
});
});
I then created an onclick function, as below, but I can not use the "this" query because it is outside of the document scope. I had to put the onclick function outside of the document ready function or else it would not work.
function artistGen(){
alert('dfdsf');
};
What am I missing here or what am I doing wrong?
You can pass these in the onclick function when you make each element.
$(document).ready(function() {
$.each(data, function() {
artist = this.name;
$('#artist-suggestions').append('<li>' + this.name + this.new + '</li>');
});
})
;
function artistGen(Blah1, Blah2){
saveData(Blah1, Blah2);
alert('dfdsf');
};
In jQuery for dynamic elements you can use the click event in this way
$('#artist-suggestions li').on('click', 'a', function() {
// do something
});
or you can continue with the way you did, by using a function but just add a parameter to that function
like
function artistGen(Artist){
// do something
};
You need to remove the artistGen() function from the scope of the .load()
$(window).load(function(){
$('#artist-suggestions').append('<li>jim new</li>');
});
function artistGen(){
alert('dfdsf');
}
JSFIDDLE DEMO
That's just how it is a function called in those event attributes have to be defined globally(or defined right there) not in any wrapper function. A better solution would be to attach event handlers.
$(document).ready(function() {
function artistGen(){
alert(this.href);
};
$.each(data, function() {
var $li = $('<li>' + this.name + this.new + '</li>');
$li.find('a').on('click', artistGen);
$('#artist-suggestions').append($li)
});
});
Is there anyway to call a function when for example pressing a close button on a modal window that will take different action depending on the function that opened the modal window?
So say for example we had a landing page with items to click on that showed a image of that item in a modal window and a certain function was called when the image was opened from this context and we had a search side nav-bar that displayed items and when these were clicked the function that opened the modal windows was different from the first. Now when closing the modal window, and depending on the function that was called to open the modal, I would like to write a condition that would allow me to either go back to landing page or return to side nav-bar.
I don't have any code to show, but I was wondering if such a thing is possible; writing a condition based on the function that was previously called? What would be the command for that condition?
So
function 1 () {
doSomething;
}
function 2 () {
doAnotherThing;
}
$("closeButton").on('click', function () {
if (function 1 was called) {
// do something else
} else if (function2 was called) {
// do another thing
}
}
Could something like that be possible?
var fnClicked = null
function fn1() {
fnClicked = fn1;
doSomething();
}
function fn2() {
fnClicked = fn2;
doAnotherThing();
}
$('closeButton').on('click', function(){
if (fnClicked === fn1) {
//do something else
} else if (fnClicked === fn2) {
//do another thing
}
});
Alternatively you could hav fn1 and fn2 unbind the closebutton click event and rebind it to the appropriate followup.
In an MVC framework, you can bind a property to the related view. If not, you can always keep bind state to the window object.
If you also don't want to do that, you can keep the state in the DOM (the close button) as an attribute. For example, a data-attribute.
$("closeButton").on('click', function (e) {
var state = $(e.currentTarget).data("state");
}
You can use data attributes on the modal element to store info that indicates what area the modal was opened from. Then when closing the modal, look in that attribute and decide what to do based on the value stored there when the modal was opened.
Variables can store references to functions in Javascript. So I would have function1 set some internal variable that would be checked when you close the modal:
var calledBy;
function1 () {
calledBy = function1;
//open modal
}
function2 () {
calledBy = function2;
//open modal
}
$("closeButton").on("click", function () {
if(calledBy === function1) {
//...
} else if(calledBy === function2) {
//...
}
});
But as hyperstack pointed out, it's better organization to have one function for opening the modal and pass in an argument. I would have an object for the modal:
var modal = {
//...
calledBy: null,
open: functio (calledBy) {
this.calledBy = calledBy;
}
};
You can use the 'this' special keyword to refer to the object on which a method is being invoked.
EG.
<div class="cval">
test
</div>
<script>
$(".cval").click(function (e) {
e.preventDefault();
alert($(this).attr('class'));
if($(this).attr('class') == 'cval')
//dosomething
else
//dosomething
});
</script>
Interrogating any of the elements attribute(s) for value and then using a conditional to control flow.
I know my question have answer in the past but I don't have the vocabulary to find this.
I call a JavaScript function like this:
Voir +
This function change the state of the element .stats-table but I want to know which button have been clicked to call this function?
Better : can I have a jQuery object of this button?
Try to pass the this reference to know which button was clicked,
HTML:
Voir +
JS:
function showTable(selec,elem){
var currentElem = $(elem); //Clicked element
}
If you don't want to change the signature of the function and the way you invoke it (as others have suggested), you can use the global window.event to identify the clicked element:
function showTable(selector)
{
var clickedElement = window.event.target;
//...
}
See MDN.
When you use jQuery, you might consider refactor your code like this:
$(document).ready(function(){
$('.show-table-link').on('click', function(){
var $usedButton = $(this)
showTable('.stats-table')
}
})
Voir +
It's good practice to attach the on click handler instead of writing it inline. Further reading document.ready and jQuery event basics.
You can pass any value or id and your can identify the function
<script type="text/javascript">
function showTable(clss_name,fun_id)
{
if(fun_id=='A1')
{
alert("First function Executed");
}
if(fun_id=='A2')
{
alert("Second Function is executed");
}
}
</script>
......
......
......
Voir +
Voir2 +
If your function is like this:
function showTable(selec) {
// some code
}
You can get the clicked element like this, using this:
function showTable(selec) {
// some code
var clickedElem = this;
}