Load javascript file after button click - javascript

I am trying to use a set of textboxes to define some data within my JavaScript file. So in a textbox I enter a Team name "Team name", and the javascript file uses this textbox to store the name of a team in order to print a set of tournament brackets.
The javascript file is included in my <head> so it loads before I have actually entered the data in the text boxes. I have this code for a button in the html like so:
script(type='text/javascript')
$('#buttontest').click(function() {
$('div.bracket').show();
$('div.teamList').hide();
});
So when the button is pressed, the textboxes are all hidden, and the brackets with the user-defined team names should appear....here is the code at the end of my javascript file:
$(function() {
$('#singleElim8').bracket({
init: singleElim8Data
})
$('.bracket').hide();
});
So within div.bracket I have the class #singleElim8 which the javascript uses. But how would I change it so that this javascript to initialize the brackets only runs once the button has been clicked? That way the brackets render AFTER the textboxes have been filled in. Any help appreciated.

Just use the getScript method of jQuery
It's very easy to use
$( '#buttontest' ).on( 'click', function() {
$.getScript( 'url to your js file', function( data, textStatus, jqxhr ) {
// do some stuff after script is loaded
} );
} );

When you pass a function as the parameter to jQuery it will execute that function during document.ready(). It allows your page to load all of the scripts before executing them.
$(function() {
$('#buttontest').click(function() {
$('div.bracket').show();
$('div.teamList').hide();
});
$('#singleElim8').bracket({
init: singleElim8Data
})
$('.bracket').hide();
});

Related

Call a Custom Class Method from jQuery/JavaScript

I am creating an eCommerce website for school in Visual Studio 15. I am using jQuery and a handler to display the products retrieved from my database. Doing it this way I am unsure how to call methods from my shopping cart class that I wrote within the <script> tag. Each product has this button:
<button type=\"button\" data-itemID=\"" + dt.Rows[i]["itemID"] +
"\" class=\"btnAddItem\">Add To Cart</button>
I'm trying to bind a click event to each button to call my method Add(itemID), I understand I could do it a lot easier just using C# but I already wrote my jQuery and handler.
You could do something like this:
$("button.btnAddItem").on('click', function(){
Add($(this).attr('data-itemID');
});
The jquery selector ( the thing in $() ) matches all buttons with the class "btnAddItem", and then once clicked, fires an anonymous function that calls Add() with the data-itemID attribute form the button that was clicked. This can also be achieved without an anonymous function:
function buttonClickHandler(event){
Add($(this).attr('data-itemID'));
};
$("button.newAddItem").on('click', buttonClickHandler);
Hope this answers your question.
I assume thet method Add(itemId) is written in C#, in Controller named Home.
class Home : Controller {
public ActionResult Add(string itemId) //...
}
Every item in controller is by default mapped to GET and POST http request. So what you can do is call your method from jQuery with GET like so:
$.get( "/Home/Add" , {itemId: "test"} ,function( data ) {
$( ".result" ).html( data );
alert( "Add was performed." );
});
or with POST:
var responce = $.post("/Home/Add",
{
itemId: "test",
},
function () {
console.log(responce);
...
});
And now for connecting to the button event, you can use jquery method in your script:
$("button.addItemButton").on('click', function()
{
var responce = $.post("/Home/Add", ///rest of the code...
});

Passing a value to a Javascript function from an ActionLink with MVC3

I must call this javascript function from inside a view:
$("#addCompositionItem").click(function (carrier) {
$.mobile.loading('show');
$.ajax({
url: this.href,
cache: false,
success: function (html) {
$("#Compositions"+carrier).append(html);
$("#newServicePageContent").trigger("create");
$.mobile.loading('hide');
}
});
return false;
});
As you can see, carrier is a parameter used to load html portions in different containers. How can I pass this value from an action link?
I'm trying with:
#Html.ActionLink("Text", "ActionName", "ControllerName", new { id = "addCompositionItem", carrier="XYZ",type = "submit" })
but with no success
The way I understand what's happening is that you're using the HTML Helper to generate an anchor tag and then attaching via JavaScript to handle the click event. In your handler, you want to be able to get a piece of data from the original link.
My suggestion is to use HTML data annotations to hold the data. As you have it now, your parameters are just being encoded into the href attribute via the route parameters. If you instead move it to the html attributes and use data_carrier the framework will generate your anchor tag like the following (not the underscore-to-hyphen is automatic conversion):
#Html.ActionLink("Text", "ActionName", "ControllerName", new { /*route params*/}, new { data_carrier="..." })
Should result in something like:
<a href='...' data-carrier='...'>...</a>
Then in your JavaScript, instead of trying to get the value as a parameter, simply use the jQuery data() method or any raw JavaScript you like to access the attribute.
var carrier = $(this).data('carrier');
I think this will cover your use case.
The code snippet below was given by EndangeredMassa in this SO question. It should solve your problem.
<html>
<head>
<script type="text/javascript">
// Wait for the page to load first
window.onload = function() {
//Get a reference to the link on the page
// with an id of "mylink"
var a = document.getElementById("mylink");
//Set code to run when the link is clicked
// by assigning a function to "onclick"
a.onclick = function() {
// Your code here...
//If you don't want the link to actually
// redirect the browser to another page,
// "google.com" in our example here, then
// return false at the end of this block.
// Note that this also prevents event bubbling,
// which is probably what we want here, but won't
// always be the case.
return false;
}
}
</script>
</head>
<body>
<a id="mylink" href="http://www.google.com">linky</a>
</body>
</html>

jQuery - load from another page after all elements are loaded

I want to display the rating of a product, witch is on the product page in div with id rating, on the category page, so I made a script below:
$('.product').each(function(){
var url = $(this).find('a').attr('href');
$(this).prepend('<div class="rating"></div>');
$(this).find('.rating').load(url +'#rating');
});
The problem is, that the rating on the product page is generated with another script, so the element #rating is not present on the site from the start, so after doing some search I tried adding ajaxcomplete function:
$('.product').each(function(){
var url = $(this).find('a').attr('href');
$(this).prepend('<div class="rating"></div>');
$(this).ajaxComplete(function(nxt) {
$(this).find('.rating').load(url +'#rating');
nxt();
});
});
But that also doesn't seem to work, so I'm wondering is there any solution for this to work?
Thanks
You need to load the script that does the rating using jQuery getScript. This way you can put processing dependent on the rating script in the success handler of the getScript call.
The code will look something like this:
$.getScript( "rating.js", function( data, textStatus, jqxhr ) {
console.log( "rating complete" );
$('.product').each(function(){
var url = $(this).find('a').attr('href');
$(this).find('.rating').load(url +'#rating');
}
});

How do get a parent node without having a starting reference point?

I want to provide a method for my web app that allows a user to call my function anywhere within his code (inside script tags) that will display a fade-in/fade-out message. What I don't know how to do is determine where I am at in the DOM without having a starting reference point.
Function:
function displayMessage(message) {
// Display a notification if the submission is successful.
$('<div class="save-alert">' + message + '</div>')
.insertAfter($('')) // Do not know how to know where to put the message.
.fadeIn('slow')
.animate({ opacity: 1.0 }, 2000)
.fadeOut('slow', function () {
$(this).remove();
});
}
The HTML:
<!-- Some HTML -->
<div>
<script type="text/javascript">
displayMessage("My message.");
</script>
</div>
<!-- Some more HTML. -->
There isn't any reliable way to get this information. You should do what most other libraries do -- have the user pass in the ID or reference of an element to your displayMessage function so that you can use it.
Generally there are two ways, one, as Casablanca noted you provide a div in the DOM to append the message. Second, and this is the one I think you want, is to create a div node on the DOM itself. That way you have total control. After all it is going to fade out when you're done. Might as well kill it from the dom as well. This is what fancylightbox (and I am sure many others) does with the DOM. You'd want to place it right at the beginning of the body, so there are no other containing elements, and style it as you wish - likely so it floats somewhere near the middle of the page like a lightbox/dialog box.
Unless you want to take in a css selector or an id as argument there is also an alternative to create a jQuery widget. This way you can use it like:
$("#msgArea").messageWidget("displayMessage");
or even reuse it many times
$("#msgArea").messageWidget("displayMessage", "message to display");
Sample boilerplate widget:
(function( $ ) {
$.widget("ui.messageWidget", {
// default options
options: { message: undefined},
// constructor
_create: function() {
if (this.options.message !== undefined) {
this.displayMessage(this.options.message);
}
},
// Displays the message
displayMessage: function() {
this.element.append("your div's and messages");
},
// Allows constructor/setter arguments
_setOption: function( key ) {
$.Widget.prototype._setOption.apply( this, arguments );
}
});
}(jQuery));
You probably want to use fixed positioning to put your box at a place relative to the browser's viewport, regardless of where a user has scrolled to in the document.

Activate jquery ui widgets within dynamically loaded form

What is the best practice of activating jquery ui widgets for html loaded and inserted into the document by ajax?
I am an advocate of unobtrusive javascript and strongly believe that all functionality accessed by javascript should be also accessible without it. So in the ideal case, each form which opens in a popup, should also have its separate page and links to them should be replaced with javascript-based ajax loading.
I find this pattern very useful for loading and inserting a part of another page into the current document:
$('#placeholder').load('/some/path/ #content>*');
Or to make it more generic:
$('a.load').each(function() {
$(this).load($(this).attr('href') + ' #content>*');
});
However, I would also like to activate the javascripts from the dynamically loaded page, so that different widgets function correctly.
I know, I could add those javascripts to the current document and activate all of them in the callback of .load(), or I could use $.get() to get some JSON with html and javascripts separately, but I guess, there might be a more elegant generic solution to this.
What would you recommend?
BTW, I am using Django in the backend.
The question is how you're activating your javascript currently. If you're doing something like:
$(document).ready(function() {
$('a.foo').click(function() { ... });
})
You could consider changin things to:
$(document).ready(function() {
$('a.foo').live('click', function() { ... });
})
That way when new DOM objects are loaded the event handlers are attached.
What I've done is used the "load" option that is specifiable by jquery.ui widgets. Unfortunately, this isn't well documented, so you won't see the option here: http://jqueryui.com/demos/tabs/#options for example, but you will see it here: http://jqueryui.com/demos/tabs/#method-load
For the most part, each of the methods you invoke have an initial option that can be set, which is what prompted me to try using the load.
In my own application, I have 3 levels of nested tabs that are being created dynamically via AJAX. In order to have the javascript for each of the tabs applied dynamically, I have nested load functions that are first initiated when the document is loaded.
So my template file has:
<script type="text/javascript" src="{{ MEDIA_URL }}js/tabs.js"></script>
<script type="text/javascript">
$(function() {
$('.overall_tabs').tabs({
load: initializeOverallTabs
});
});
</script>
My tabs.js file has:
function initializeOverallTabs(event, ui){
...
$('.lvl_two_tabs').tabs({
load: initializeTabLevel2
});
...
}
function initializeTabLevel2(event, ui){
...
// So on and so forth
...
}
Also, I recommend when working inside the loaded areas to make your references be specific to that pane. This was extremely important when working with tabs. The best way I found to do this is below.
In your tabs.js file:
function initializeOverallTabs(event, ui){
$panel = $(ui.panel);
$panel.find('lvl_two_tabs').tabs(...);
}
I found this question strangely coincidental! I recently explained my solution to a few developers to the same situation with the same Jquery/Django Environment. I hope that helped!
One way I decided myself for handling widgets from external pages is parsing the HTML of the other page, searching for scripts and executing them in the current page.
For example, there is a form with autocomplete widget on another page which is loaded and inserted to this page. The autocomplete widget should be activated with specific properties, like available choices:
<script type="text/javascript">
//<![CDATA[
$(function() {
$("#colors").autocomplete({
source: ['red', 'green', 'blue', 'magenta', 'yellow', 'cyan']
});
});
//]]>
</script>
Then in the current page I can have the following script which loads HTML and additionally collects all javascripts within it and executes them:
var oRe = /<script\b[^>]*>([\s\S]*?)<\/script>/gm;
$('#placeholder').load(
'/some/path/ #content>*',
function(responseText, textStatus, XMLHttpRequest) { // <-- callback function
var sScripts = "";
responseText.replace(
oRe,
function($0, $1) {
sScripts += $1;
return $0;
}
);
eval(sScripts);
}
);
One drawback here is that the current document should initially be loading all the libraries which might appear in the included forms. For example, in this case, it would be the jquery-ui including the autocomplete widget. I guess I could extend the code by searching for script tags which load external scripts and loading them in the current document if they are not present.

Categories

Resources