Long story made very short, I'm working on a frontend where the main controls involve a great many individual <form> tags.
What I want is to intercept all submit() events, check the submitting form for a custom attribute, and if it's there, execute certain code.
I've got this:
$('form').submit(function(event) {
var myForm=$(this);
alert('SUBMIT!');
if(myForm.hasOwnProperty('confirm')){
alert ('Call confirmation');
event.preventDefault();
}
if(myForm.hasOwnProperty('verify')) {
alert ('Call verification');
event.preventDefault();
}
});
but it doesn't seem to be working. The alert never triggers and neither does a breakpoint I set in the console.
I'm fairly new to JQuery and I'm not sure what I'm doing wrong. Any pointers?
myForm is a jQuery object. You need to access the underlying DOM element to use hasOwnProperty:
$('form').submit(function(event) {
var myForm = this; // Do not convert to a jQuery object here
alert('SUBMIT!');
if(myForm.hasOwnProperty('confirm')){
alert ('Call confirmation');
event.preventDefault();
}
if(myForm.hasOwnProperty('verify')) {
alert ('Call verification');
event.preventDefault();
}
});
FYI, jQuery has it's own method for checking for the existence of properties called .prop, however personally I think hasOwnProperty is much nicer as it highlights what you are actually trying to achieve. Plus, you already have the DOM object by default and all browsers support the hasOwnProperty method so this has slightly less overhead than converting to a jQuery object.
Related
Reading a website's source code that uses MVC, I struggled trying to understand some of it.
Code snippet of the view:
function submitForm (action) {
var forms = document.getElementById('form')
forms.action = action
if (forms.checkValidity()) {
forms.submit()
} else {
alert('There is still an empty field')
}
}
I want to execute some code if the form is missing certain inputs.
checkValidity() is a HTML5 method and
When the checkValidity() method is invoked, if the element is a candidate for constraint validation and does not satisfy its constraints, the user agent must fire a simple event named invalid that is cancelable (but in this case has no default action) at the element and return false. Otherwise, it must only return true without doing anything else.
Please learn more about how to use form validation constraints here.
There are number of useful methods you can use, customize and even build custom validation methods.
You also can find basic explanation and examples in w3schools.
Hope this helps.
For Me this works in jQuery
$('#formSection')[0].checkValidity();
just use a required
Example
<input type"text" id="id" required>
if you press the submit button there an alert text saying PLEASE FILL OUT THIS FIELD
Mid development I decided to switch to server-side rendering for a better control amongst other benefits. My web application is completely AJAX based, no url redirecting, so the idea here is a website that builds itself up
I just couldn't figure out the proper way to send javascript events/functions along with the html string, or should all the necessary javascript always be preloaded in the static files?
Let's say client clicks a pre-rendered button 'open table'
The server will make a query, build the html table and send it back, but this table also needs javascript triggers and functions to work properly, how are these sent, received and executed?
There are a couple of articles that mention to not use eval() in Javascript, is there any way around this? I don't want to have to preload unnecessary events for elements that don't yet exist
The server is Python and the Client is Javascript/JQuery
Theoretical example :
Client Base Javascript :
$("body").on("click", "#open_table", function() {
$.getJSON('/get_table', function(response){
$("#table_div").append(response.html);
eval(response.javascript()); //??
}
});
Python Server(views.py) :
def get_table(request):
data = {}
#String containing rendered html
data['html'] = get_render_table()
#String containing Javascript code?
data['javascript'] = TABLE_EVENTS_JAVASCRIPT
return HttpResponse(json.dumps(data),content_type='json')
Worth noting my question comes from an experimental/learning perspective
Update:
You can use jQuery.getScript() to lazy load JS. I think this solution is as close as you can get to run JS without using eval().
See this example:
jQuery.getScript("/path/to/script.js", function(data, textStatus, jqxhr) {
/* Code has been loaded and executed. */
console.log( data ); // Data returned
console.log( textStatus ); // Success
console.log( jqxhr.status ); // 200
console.log( "Load was performed." );
});
and "/path/to/script.js" could be a string returned from $.getJOSN response.
Also, the documentation for getScrippt() has examples on how to handle errors and cache files.
Old Answer:
Using .on() attaches events to current and future DOM elements.
You can either attache events prior to DOM insertion or attache event after DOM insertion.
So in your example you can do something like:
$("body").on("click", "#open_table", function() {
$.getJSON('/get_table', function(response){
var code = $(response.html);
code.find(".elementToFind").on("click", function (){
// Code to be executed on click event
});
$("#table_div").append(code);
}
});
I did not test the code but I think it should work.
Assuming you can't just set up an event-binding function and then call it from the main script (the JavaScript you need can't be guessed ahead of time, for example) then one really easy way is just to append the JavaScript to the bottom of the returned HTML content within script tags. When it's appended along with the HTML, the script should simply execute, with no eval() required.
I can't swear that this would work in old browsers, but it's a trick I've used a couple of times, and I've had no problems with it in Firefox, Chrome, or any of the later IE versions.
I think I see what you're asking here, from my understanding you want to send the new "page" asynchorously, and render the new javascript and html. It looks like you already got your request/response down, so i'm not gonna go and talk about sending JSON objects, and the whole "how-to" of sending html and javascript because it looks like you got that part. To do what you want and to dynamically add your javascript in, this stackoverflow question looks like it has what you need
Is there a way to create a function from a string with javascript?
So pertaining to your example, here is how it would look when you recieve the JSON string from your python script:
$("body").on("click", "#open_table", function() {
$.getJSON('/get_table', function(response){
$("#table_div").append(response.html);
/* Create function from string */
var newFunction = Function(response.javascript['param_1'], response.javascript['param_2'], response.javascript['function']);
/* Execute our new function to test it */
newFunction();
}
});
*Your actual function contents would be the string: response.javascript['function']
*Your parameter names if any would be in separate strings ex: response.javascript['param_1']
That is almost a direct copy of the "String to function" code that you can see in the linked question, just replaced it with your relevant code. This code is also assuming that your object is sent with the response.javascript object containing an array with your actual function content and parameter names. I'm sure you could change the actual name of the var too, or maybe put it in an associative array or something that you can keep track of and rename. All just suggestions, but hopefully this works for you, and helps you with your problem.
I am also doing similar work in my project where I had to load partial html using ajax calls and then this partial HTML has elements which requires events to be attached. So my solution is to create a common method to make ajax calls and keep a js method name to be executed post ajax call in html response itself. For example my server returns below html
<input type="hidden" data-act="onPartialLoad" value="createTableEvents" />
<div>.........rest of html response.....<div>
Now in common method, look for input[type='hidden'][data-act='onPartialLoad'] and for each run the method name provided in value attribute (value="createTableEvents")
Dont Use Eval() method as it is not recommended due to security
issues. Check here.
you can run js method using window["method name"]...so here is a part of code that I use.
$.ajax(options).done(function (data) {
var $target = $("#table_div");
$target.fadeOut(function () {
$target.html(data);
$target.fadeIn(function () {
try {
$('input[data-act="onPartialLoad"]', $target).each(function () {
try {
//you can pass parameters in json format from server to be passed into your js method
var params = $(this).attr('params');
if (params == undefined) {
window[$(this).val()]();
}
else {
window[$(this).val()]($.parseJSON(htmlutil.htmlDecode(params)));
}
} catch (e) {
if (console && console.log) {
console.log(e.stack);
console.log($(this).val());
}
}
});
}
catch (e) {
console.log(e.stack);
}
});
});
});
use jQuery.getScript() (as suggested by Kalimah Apps) to load the required js files first.
I want to attach a jQuery plugin function to an element on my site that exists only on one page. Currently, I'm using this conditional to prevent triggering the limiter function and throwing an error when there is no #advertiser_co_desc in view.
jQuery(document).ready(function($) {
var elem = $('#charNum');
if ($('#advertiser_co_desc').length) {
$('#advertiser_co_desc').limiter(180, elem);
}
});
On my website #advertiser_co_desc is present only on one page.
My solution does the job, but my qualm stems from the fact that the jQuery plugin code as well as the plugin function call presented above (they are both in the same file) get fetched by the browser and the condition is continuously evaluated regardless of whether a user ever gets to a page where #advertiser_co_desc exists.
Is the method I'm using optimal, or is there a better way to attach this particular JS only to the page where '#advertiser_co_desc` exists? Naturally, I wan to avoid adding my scripts in the same file with the PHP code.
Or you can wrap the plugin method as,
var _limiter = $.fn.limiter;
$.fn.limiter = function(limit, element) { // provide complete argmuments
if(this.length) {
_limiter.call(limit, element);
}
};
Make sure that plugin is loaded before this statements.
The best and optimal way to check existence of an element by jquery, is $('#advertiser_co_desc').length that you have used already. So no need to change your code.
Setup
I've attached an event to the 'window' object, and I would like to check that it's there via code.
window.addEventListener('beforeunload', function(e){ /*...*/ }, false)
Attempts
I've tried the simple, and jQuery, without luck. I have more attempts up on jsFiddle.
window.beforeunload //is undefined as is window.onbeforeunload
$(window).data('events') //not working either
Is this possible?
There are similar questions (here and here) about the DOM, and other elements, but none of the approaches in those that I have tried have worked.
You can use the in operator...
'onbeforeunload' in window; // true (if supported)
If supported, the property will exist, though the value will be null.
I can set the onclick handler using jQuery by calling
$('#id').click(function(){
console.log('click!');
});
Also using jQuery, how can I get a reference to the function which is currently handling the click() event?
The reason is that I have another object and want to set its click handler to the same one as #id.
Update
Thank you for all the suggestions. The problem is that I do not know which function is currently handling the clicks. Keeping track of it would add state to an already complicated template-editing system.
jQuery's .click(function) method adds the function to a queue that is executed on the click event~
So actually pulling out a reference to the given function would probably be hairy-er than you expect.
As noted by others, it would be better to pass in a reference to the function; and then you already have the reference you need.
var clicky = function () { /* do stuff */ };
$('#id').click(clicky);
// Do other stuff with clicky
Update
If you really really need to get it out, try this:
jQuery._data(document.getElementById('id')).events.click[0].handler
Depending on your version of jQuery that may or may not work~ Try playing around with
jQuery._data(document.getElementById('id'))
and see what you get.
Got the idea from this section of the source:
https://github.com/jquery/jquery/blob/master/src/event.js#LC36
if you dont know the name of the function you can use
args.callee
https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope/arguments/callee
function clickHandle(e){
if($(e.target) == $('#id')) {
$(newTarget).bind('click', clickHandle);
}
}
$('#id').bind('click',clickHandle);
I think this would be the most symantic way of going about it