head js + jquery.validate.unobtrusive + custom validators - javascript

I'm using head.js (http://headjs.com) to do async loading of my javascripts.
I have problem with jquery.validate.unobtrusive and custom validators
All custom validations should be loaded after jquery.validate and jquery.validate.unobtrusive, and I do it like following:
<head>
<script src="#Url.Script("jquery")"></script>
<script src="#Url.Script("head.load")"></script>
</head>
<body>
<!-- entire markup -->
<script>
head.js("#Url.Script("jquery.validate")", function () {
head.js("#Url.Script("jquery.validate.unobtrusive")", function () {
head.js("#Url.Script("custom-validations")");
});
});
</script>
</body>
The problem is that custom-validations script should be loaded after jquery.validate.unobtrusive but before document.onready event, because jquery.validate.unobtrusive uses document.onready to do it's black magic. But, when I'm using head.js document.onready event fired before scripts starts to load, and my custom validation does not work.
Is there any common solutions/workarounds to solve this kind of problems with async script loading?
Another problem that my customer does not want to see jquery.validate/jquery.validate.onubtrusive in <head> tag.
#Url.Script - helper method for locating js files.

I've found solution by myself. Need to use jQuery.holdReady() to hold 'document.ready' while all scripts depend on jquery.validate.unobtrusive will not load.
<head>
<script src="#Url.Script("jquery")"></script>
<script src="#Url.Script("head.load")"></script>
</head>
<body>
<!-- entire markup -->
<script>
head.js("#Url.Script("jquery.validate")", function () {
$.holdReady(true); // set semaphore for dom ready.
head.js("#Url.Script("jquery.validate.unobtrusive")", function () {
head.js("#Url.Script("custom-validations")", function () { //fires when all provided scripts are loaded
$.holdReady(false); // release semaphore and fire event
});
});
});
</script>
</body>

Try $.validator.unobtrusive.parse('#the_form_in_question') after the load.

This should work:
head.ready("#Url.Script("jquery.validate")", function () {
head.ready("#Url.Script("jquery.validate.unobtrusive")", function () {
head.ready("#Url.Script("custom-validations")",function(){
// your code here
});
});
});
If you use jquery, you could add the scripts via getScript method which fires a callback when the script is loaded, so that can help :
$(document).ready(function(){
$.getScript("#Url.Script("jquery.validate")",function(){
$.getScript("#Url.Script("jquery.validate.unobtrusive")",function(){
$.getScript("#Url.Script("custom-validations")",function(){
// do your stuff here
});
});
});
});

Related

run internal script after external script has been loaded via defer

It is well known to everyone that using defer is an efficient way to minimize the loading time of a website.
In my project, I am using Vue (included in the header using defer) and in a circumstance, I want to use a component that is created by another person. When I try to do Vue.Component(...) in the body of the HTML, it says Vue is undefined. It seems that my script in the body is running before the external script has been loaded. Is there any way to fix this issue?
I tried to do document.onload, but the function itself is not working.
PS: Just to be clear, the external script is referring to my js file where Vue is defined and I am not talking about the third party library at all.
Instead of document.onload you need to use window.onload or document.body.onload.
But an even better way is to wait for the load event on <script> tag:
<html>
<head>
<script id="vue-script" src="vue.js" charset="utf-8" defer></script>
</head>
<body>
<script type="text/javascript">
function onVueLoaded() {
Vue.render();
}
if ('Vue' in window) {
onVueLoaded();
} else {
var script = document.getElementById('vue-script');
script.addEventListener('load', onVueLoaded);
script.addEventListener('error', () => console.warn('failed to load Vue.js'));
}
</script>
</body>
</html>
Here I also added a handler for the error event if you wanted to explicitly handle loading errors.

How do I load jquery snippets after full load of html?

Is there any way to load these snippets after full load of html?
I'd be very happy if loading the snippets after the js file (set to ASYNC load) or even set a timer.
<script>$(document).ready(function(){var modals = ['#bookings', '#studios', '#mygallery', '#social', '#reviews', '#articles', '#contactme', '#credits', '#pagemap', '#tsandcs', '#events'];if (window.location.hash && ~modals.indexOf(window.location.hash)) {$(window.location.hash).modal();}})</script>
<script>$(document).ready(function(){$("#myModal11").modal('show');});</script>
<script>$(".modal:not(.noclose) a").click(function(){$(this).closest(".modal").modal("hide");});</script>
You can try this Behaviour
Hope this helps !
<html>
<head>
</head>
<body>
// My Html Here
<script>
$(document).ready(function(){
var modals = ['#bookings', '#studios', '#mygallery', '#social', '#reviews', '#articles', '#contactme', '#credits', '#pagemap', '#tsandcs', '#events'];
if (window.location.hash && ~modals.indexOf(window.location.hash)) {
$(window.location.hash).modal();
}
$("#myModal11").modal('show');
$(".modal:not(.noclose) a").click(function(){
$(this).closest(".modal").modal("hide");
});
});
</script>
</body>
// And Remove this click function and use .on instead of it for single handler
$(".modal:not(.noclose)").on("click","a",function(){
$(this).closest(".modal").modal("hide");
});
});
You are putting them in a document on ready function,
$(document).ready(function(){$("#myModal11").modal('show');});
Just put the last one in that same on ready function and you're good to go
Although you could just put in them in one of those functions too:
$(document).ready(function(){
// put all code here...
});

How to call js document.ready function in html?

I am writing a webgame using jquery document.ready. When I call js function in html, it does not work:
js:
$(document).ready(function(){
function init(){blablabla...}
})
html:
<script src="function.js"></script>
<script>
function bla(){
if (blablabla)
init();
}
</script>
I learned html and js for only a few weeks. I have no idea why it does not work.
Please Follow Bottom Step:
There are two versions of jQuery available for downloading:
minified and compressed
The jQuery library is a single JavaScript file, and you reference it with the HTML <script> tag (notice that the <script> tag should be inside the <head> section):
Like:
<head>
<script src="jquery-1.12.0.min.js"></script>
</head>
You might have noticed that all jQuery methods in our examples, are inside a document ready event:
<script>
$(document).ready(function(){
// jQuery methods go here...
});
</script>
One approach to achieve expected result is to set init as property of document
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<script>
$(document).ready([
function() {
function init() {
// do stuff
alert("blablabla...")
}
// set `init` as property of `document`
this.init = init;
},
function bla() {
if ($.isReady /* blablabla */)
document.init();
}
])
</script>
<body></body>

How to integrate jquery code without any code in the html file

I want to clear my code a little bit and I want to run my jquery code without any function call in the html file. My actual code is :
HTML:
<head>
<script src="js/colorpick.js"></script>
<script>
$(document).ready(function() {
colorpick_start();
});
</script>
</head>
JS:
function colorpick_start() {
...
}
But if I write for example an alert in the first row of the js without any function call, that works.
alert('test');
function colorpick_start() {
...
}
But this is not working for jquery selectors or something. Is there any solution to get my jquery working without code in the html file?
I want my html file to look like this, if this is possible:
<head>
<script src="js/colorpick.js"></script>
</head>
The
$(document).ready(function() {
Waits until the DOM is ready for selectors etc.
If you add the
$(document).ready(function() {
to your colorpick.js file it will wait for the DOM to be ready and then execute colorpick_start().
And believe me this catches out most people when they start using JQuery.
In order to achieve this:
<head>
<script src="js/colorpick.js"></script>
</head>
Move the document ready call to the js file you are referencing in your HTML file and make sure that the method called is present.
$(document).ready(function() {
colorpick_start();
});
This should so it.
Put your script
<script src="js/colorpick.js"></script>
before </body> tag. This will ensure that your page is loaded fully before script starts.
$(document).ready(function() {
colorpick_start();
});
this code is working because you are calling your function after document is loaded. document load is event. you can put your function on any event you want, but it wont start if you just define your function. You have to somehow call your function. example would be on click (or on document load)
<div id="example"></div>
$("#example").on('click', function () {
your function here
});
Use that code:
$(function(){
$('.colorpicker').val("colorpicker"); //or whatever you like
});
Plnkr example code

How to make JQuery DatePicker work after dynamically loaded in a partial view?

I have lost jquery datepicker functionality in this scenario...
1- Originally I had a normal view, which worked fine, having this code for date input...
<input type="text" name="date_start" id="date_start"
value="#(Model.TimeStart)" />
<script language="javascript" type="text/javascript">
$("#date_start").datepicker();
</script>
2- Then, I converted that view in a partial view which is dynamically loaded with...
$('#TargetEmptyDiv').load("/MyController/MyAction");
3- The partial view loads ok, the data can be (manually) entered and all its fine. The only problem is that the jquery datepicker is no longer working. I tryed to assign it after the loading, using this...
$('#TargetEmptyDiv').load("/MyController/MyAction",
function () { $("#date_start").datepicker(); });
That did not work.
4- Later I've learned that jquery provides the live() and delegate() functions which are capable of attach javascript code to elements loaded "now and in the future". So, I tryed this in the document initialization...
<script type="text/javascript">
$(document).ready(function () {
$("#date_start").live("click", function () { $(this).datepicker(); });
});
</script>
and later also...
<script type="text/javascript">
$(document).ready(function () {
$("#date_start").delegate("click", function () { $(this).datepicker(); });
});
</script>
none of which worked, maybe because they directly reference to the "click" event, but the datepicker is "attached" (if that is the proper term) to the whole element.
So, question is:
How to make the jquery datepicker work on elements loaded after dynamic load???
Thanks for your time!
SOLVED:
The problem was that at the bottom of _Layout.cshtml there is this line...
#Scripts.Render("~/bundles/jquery")
..which loads the minified version of jquery libraries (already referenced by myself).
So, the libraries were loaded twice and got invalid, producing the error "datepicker() is not a function".
Just commenting or deleting that line, makes all work fine!
Put the following jQuery in the base view, not the partial view
<script>
$(document).ready(function () {
$(document).on('focus', '.datefield', function () {
$(this).datepicker();
});
});
</script>
This will work when a partial view is dynamically loaded and on page load.
Your approach in #3 looks to me like it should have worked, so it seems like you need to do some debugging. Try this:
Get the Firebug extension, if you use Firefox (Chrome has dev tools built in)
Add a debugger line to your code (see below for example)
Load your page up with Chrome or Firebug/Firefox (or any other browser's dev tools)
What should happen is that your browser will pause at that point. However, if things aren't working as you expect, it might not be hitting that code at all, and then you'd get no pause.
If you do get a pause, use the console to inspect the value of $("#date_start"); it's possible that jQuery selector isn't grabbing what you think it is.
Here's a debugger example with your code:
$('#TargetEmptyDiv').load("/MyController/MyAction", function () {
debugger;
$("#date_start").datepicker();
});
On your partial page say "/MyController/MyAction",
Partial Page Code:
<div>
<form>
<!--Other Elements-->
<input type="text" id="adate" name="adate" title="date" />
</form>
<script type="text/javascript">
$(document).ready(function(){
$( "#adate" ).datepicker();
});
</script>
</div>
Full Page(Page From Where You are Calling Ajax Request) Code:
<div id="TargetEmptyDiv"></div>
<script type="text/javascript">
function abc(){
$.ajax({
type: "POST",
url: "/MyController/MyAction",
success: function(response)
{
$("#TargetEmptyDiv").html(response);
}
});
}
</script>
call function abc and you are done.assuming you already have all jquery files loaded.
In my case, the Id of the date field that I tried to hook up the datepicker to was not what I thought it was. I am using ViewModels and the id got prefixed with the ViewModel name of my partial view.
machineghost's answer put me on to it.
So I now use Charly's answer but instead of #BirthDate I have #IdentityModel_BirthDate:
<script>
$(document).ready(function () {
$(document).on('focus', '#IdentityModel_BirthDate', function () {
$(this).datepicker({
format: 'MM/dd/yyyy',
changeMonth: true,
changeYear: true,
yearRange: "-90:+0"
});
});
});
</script>
All you need to make the datepicker work is steps 1-3.
Here's a sample:
http://jsfiddle.net/delrosario/Xd8py/
You got datepicker to work without loading the markup dynamically and your pseudo code for the dynamic version is sound from steps 1-3. The thing you need to check now is to make sure that your dependencies are being loaded before your main program (in this case make sure that jquery and jquery ui are available before running the request + datepicker setup).
1) load jquery
2) load jquery ui
3) wait till the dom is ready or the element that will contain your payload is ready
4) execute your main app that does steps 1-3 from your description.
So it would be something like this.
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="path-jquery-ui-css" />
<script src="path-to-jquery"></script>
<script src="path-to-jquery-ui"></script>
<script id="main_app">
(function () {
// wait till dom is ready before executing our code,
// in this case steps 1-3.
});
</script>
</head>
<body>
<div id="datepicker_target">datepicker target</div>
</body>
</html>
After invoking ajax, hookup your jquery to the 'ajaxStop' event. (SEE: '#section Scripts' )
$(document).ajaxStop handles the post ajax jquery call and now datapicker works after ajax call(s). yea...
Note: $(document).ready... handles the initial page load datapicker decoration, but after an ajax form reload, datepicker jquery was not executed...
#model Q_Admin.Models.AllQAViewModel
<div id="mainContent">
#using (Ajax.BeginForm("EAAll","Answer",new AjaxOptions {
UpdateTargetId = "mainContent",
HttpMethod = "POST",
InsertionMode = InsertionMode.Replace
}))
for (int i = 0; i < Model.VMs.Count; i++)
{
#switch (Model.QAVMs[i].qN.Node1.TypeAnswer.AnswerType.Trim().ToUpper())
{
case "DATETIME":
#Html.TextBoxFor(m => m.VMs[i].CurrentNodeText,
new { #class = "datepicker", #id = "datepicker" });
break;
case "DROPDOWNLIST":
#Html.DropDownListFor(m => m.QAVMs[i].AnswerRecord.AnswerID,
new SelectList(Model.QAVMs[i].answerNodes, "ID", "NodeText.Text", Model.QAVMs[i].SelectedNodeID),
"-- Select an Answer --",
new { #onchange = "$(this).parents('form:first').find(':submit')[0].click();" }) }
break;
default:
break;
}
}
</div>
#section Scripts{
<script type="text/javascript">
$(document).ready(function () {
// debugger;
$("#datepicker").datepicker(
{
dateFormat: "mm/dd/yy",
constrainInput: true
});
});
$(document).ajaxStop(function () {
// debugger;
$("#datepicker").datepicker(
{
dateFormat: "mm/dd/yy",
constrainInput: true
});
});
</script>}
I've had this problem before. In my situation I had <script src='jQueryUI.js'></script> referenced at the bottom of the page. Moving the reference to the top of page fixed it for me.
Seems like #3 should works. But maybe you can try a hacky way like this:
<script type="text/javascript">
$(document).ready(function () {
$(this).on("mousedown", "#date_start", function (e) {
$(this).datepicker(); e.preventDefault();$(this).click();
});
});
</script>
I have this working
Action Method:
public ActionResult GetControl()
{
return View("_partial");
}
Main View:
<div id="TargetEmptyDiv"></div>
<script type="text/javascript">
$(function () {
$('#TargetEmptyDiv').load("/Home/GetControl");
});
</script>
Partial View:
#{
Layout = "";
}
<input type="text" name="date_start" id="date_start" />
<script type="text/javascript">
$(function () {
$("#date_start").datepicker();
});
</script>
Of course you have to remember to include jquery-ui.js in your Layout
<script src="#Url.Content("~/Scripts/jquery-ui-1.8.20.min.js")" type="text/javascript"></script>
My suspicion is that your JS is executing, but you have improperly referenced jquery-ui. I recommend adding all jquery libraries at a higher level than a partial view. Try putting the <script src="jquery-ui.js"> tag in either the page or the layout, not the partial view. If this doesn't fix it, try putting alert("test"); in your javascript code to make sure that it is executing.
I had the exact same problem. If using ajax, then bind the below jquery function to the document. Each time ajax is executed, this will fire. Check out the api doc here - http://api.jquery.com/category/ajax/global-ajax-event-handlers/
$(document).ajaxComplete(function (){//your code here})
I had the same problem, solved using a previous version of JQuery-UI. In my case goes to use the version 1.9.2 and 1.10.3 to JQuery version 1.10.1. Know the reason, but I think the latest versions bring some problems compactness, so I chose to use always backward to the past.
I hope it will be useful
<script type="text/javascript">$(function () {$("#datefield").datepicker();});</script>
just load this line with the content you have to load by ajax
hi: you put below code in load document event script tag in your partial view :
$(function(){
$("#date_start").datepicker();
})

Categories

Resources