kicking off ajax query to php mysql DB by use of onblur - javascript

I'm trying (and failing) to make an ajax process work when people leave a form input field. I need it to happen for each input field, of any type, on the form.
I'm trying to modify the following (which does work):
$("document").ready(function() {
$("#getcontent").click(getContent);
});
function getContent() {
$("#example").load("sampletextcontent.txt");
}
(there would be a button with id="getcontent" in the html, and a div with id="example" also in the html. When button clicked, contents of external file sampletextcontent.txt is displayed within said div)
jquery IS being used, version 2.0.3 jquery.min.js
So I am trying (and this is where I am failing) is to convert the above to become:
$("document").ready(function() {
$("#input_1_1").onblur(doSend);
$("#input_1_2").onblur(doSend);
$("#input_1_3").onblur(doSend);
$("#input_1_4").onblur(doSend);
$("#input_1_5").onblur(doSend); // etc for as many fields there are
})
function doSend() {
// Do some ajax stuff to send the entire value of all form fields in here
}
But it does not seem to like the concept of using the replacement of the ".click" to ".onblur" here. Why is this? Isn't onblur a valid JS function/item?
Sorry I'm not a JS guru, I have great problems understanding JS.
C
Edit - sorry I was not clear about the code I am trying to get working. There is no button in the version I want to work, it's just wanting to trigger by when a user clicks/tabs away from each input field. Sorry about not making that clear before.

For dynamic jQuery event binding, I would try switching out the .click and .blur functions with the .on function.
As an example, I would try the following:
$('body').on('click', '#getcontent', function(){
DoSomething();
});
and
$('body').on('blur', '#input_1_1', function(){
DoSomething();
});
The documentation for the on function can be found http://api.jquery.com/on/.
Here is another Stack Overflow article that also explains this: Event binding on dynamically created elements?.

Thanks to the comments and answer attempts. However the answer that I'm using, that actually does answer the specific question is the following. Simply change:
$("document").ready(function() {
$("#input_1_1").onblur(doSend);
$("#input_1_2").onblur(doSend);
$("#input_1_3").onblur(doSend);
$("#input_1_4").onblur(doSend);
$("#input_1_5").onblur(doSend); // etc for as many fields there are
})
To become:
$("document").ready(function() {
$("#input_1_1").blur(doSend);
$("#input_1_2").blur(doSend);
$("#input_1_3").blur(doSend);
$("#input_1_4").blur(doSend);
$("#input_1_5").blur(doSend); // etc for as many fields there are
})
And it works. This retains the ability to call different functions per field if I so wish, and is very straightforward for a JS novice like me to work with.
A better cleaner solution may be implemented later, but for now this will do and directly answers the original question.

Related

Run js function when a tag is created

I am writing a plugin for a website, where I create a couple of table-rows and they get injected into an already existing table on the website.
My table-rows will get created when a button is pressed, however I have no access to this button since it's already on the website, not in my plugin.
Is it possible for me to create a JS function that runs when my table-rows are created?
Transforming my comment as an answer for future viewer to see :
Maybe you can use what in this answer : https://stackoverflow.com/a/9845549/10153945 It detect a change in the DOM using jquery
in this answer courtney christensen propose to use jQuery's DOMSubtreeModified to detect changes
$('#content').bind('DOMSubtreeModified', function(e) {
if (e.target.innerHTML.length > 0) {
// Content change handler
}
});
Look at his answer and upvote him too ; )

Can you use a jQuery selector on a HTML tag that a JS string printed?

Sorry if the question was misleading, I couldn't find a better way to describe my problem. Anyway, here goes:
Suppose I had a button start that initially displays a string for me. Said string (let's call it stringA) is output through jQuery like this:
$(".start").click(function() {
$(".startButton").hide('slow', function() {
$("#table1").html(stringA);
});
});
Alright. Cool. That worked without a hitch. Now inside stringA I have multiple
<span class="optButton">this is a button</span> buttons. I have another onClick handler for my optButton button, and it goes like this:
$(".optButton").click(function() {
alert("Testing");
$("#table1").html(stringB);
});
Needless to say, clicking on optButton is supposed to replace the contents of #table1 with stringB. However, when I tried it, it doesn't work. I tried adding alert() to test and see if jQuery managed to select optButton, but it seems that it didn't because I get no popup from the alert() function.
My theory is that since optButton was not part of the original HTML and is within a string stringA, jQuery is unable to select optButton as a result. If this is true, is there a workaround to this issue? If it is not, what is the actual cause of the problem here?
You need to use event delegation since your span element has been dynamically added to the DOM:
$('#table1').on('click', '.optButton', function() {
alert("Testing");
$("#table1").html(stringB);
});
This technique will helps you to attach click handler to these newly created span elements.

Expanding an Accordion Pane on Invalid Validation

I have a collection of AccordionPanes containing various TextBox controls and DropDownLists, each with their own validators.
If a few server-side validations occur on form submit, is there something that can automatically expand a previously minimized pane that contains the invalid validator message? Otherwise, it will seem to the user that the form isn't submittable without reason.
Another scenario: Let's say I have multiple panes with client side validators tied to the inputs. If a pane is minimized (and therefore you can't see the validator's ErrorMessage), is there a way to expand the appropriate pane when the AJAX page validation occurs on submit?
I know there's a brute-force way to this approach, where I keep track of every validator and their associated AccordionPane, but I was hoping for a better solution that can handle my situation for a large number of inputs/validators and panes.
How about something like this (using JQuery but I'm sure it can be converted into plain javascript)...
$(document).ready(function(){
if (isPostback()){
$.each(Page_Validators, function(index, validator) {
if (!validator.isvalid) {
// do something here to locate the accordion based on the validator
// $(this) is the currently invalid validator element as a jquery object/wrapped set
// so for example...
$(this).parent().slideDown();
// This assumes that the immediate parent of of the validator is the accordion which is unlikely but if you post your emitted html I can write the appropriate selector for you.
}
});
}
});
Because you dont want it to fire on initial load you can use a technique like this How to detect/track postback in javascript? and check if you are in a postback after the document.ready - I have assumed you've used the advice in the link and your function for postback detection is called isPostback().
there is a project built for this issue try to take a look at it....you can also download the source to analysis more details or use the same code-base if you want....http://www.codeproject.com/Articles/43397/Validating-Accordion-and-RadPanelBar-using-Ajax-an
Rich beat me to it, but here's the vanilla js version (ie9+):
Page_Validators
.filter(function(v) { return !v.isvalid; })
.forEach(function (v) { console.log(v.parentNode); });
Remember to place the code beneath the </form>-tag. I've had issues with using jQuerys document.ready and window.onload, since it might execute the code before all the needed JavaScript from asp.net is loaded.
Update: A more browser compatible version
for(var i = 0; i < Page_Validators.length; i++) {
var validator = Page_Validators[i];
if (!validator.isvalid) {
console.log(validator.parentNode);
}
}

web2py: How do I add javascript to Web2py Crud form?

Working with Web2Py. I'm trying to attach some javascript either to a field (onchange) or to the form (onsubmit), but I see absolutely no way to pass such argument to crud.create or to form.custom.widget.
Anyone has an idea?
Of course there is a way. The appropriate way is to ask people on the web2py mailing list who know how to, as opposed to generic stack overflow users who will guess an incorrect answer. :-)
Anyway, assume you have:
db.define_table('image',
Field('name'),
Field('file', 'upload'))
You can do
def upload_image():
form=crud.create(db.image)
form.element(name='file')['_onchange']='... your js here ...'
form.element('form')['_onsubmit']='... your js here ...'
return dict(form=form)
Element takes the css3/jQuery syntax (but it is evaluated in python).
I do not believe there is a way to do this directly. One option is just to manipulate web2py generated HTML, it is just a string. Even cleaner, in my opinion, is just to bind the event using jQuery's $(document).ready() function.
Say you have a database table (all is stolen from web2py's docs):
db.define_table('image',
Field('name'),
Field('file', 'upload'))
With form:
def upload_image():
return dict(form=crud.create(db.image))
Embedded in a view (in the simplest manner):
{{=form}}
And you want to add an onblur handler to the name input field (added to the view):
<script type="text/javascript">
$(document).ready(function(){
$("#image_name").blur(function(){
// do something with image name loses focus...
});
});
</script>

Where to put custom JavaScript/Prototype code for an ActiveScaffold form?

I have a Select dropdown on the form of an ActiveScaffold. I am trying to hide some of the fields on the form if a particular value is selected.
A [similar question][1] was posted to the ActiveScaffold Google Group, and the supplied Prototype code looks to do what I need, however I don't know where I need to add this.
--
I tried taking a copy of -horizontal-subform-header.html.erb from Vendor/plugins/
active_scaffold/frontends/default/views, placing it in views folder of my controller, and then adding my script into it:
<script type="text/javascript">
document.observe('dom:loaded', function() { //do it once everything's loaded
//grab all the product-input classes and call 'observe' on them :
$$('.product-input').invoke('observe', 'change', function(e) {
this.up('td').next('td').down('input').hide();
});
});
</script>
... but that doesn't seem to work properly. It works if I use a URL to go direct to the form (i.e. http://localhost:3000/sales/20/edit?_method=get). But when I test it with the main list view (i.e. http://localhost:3000/sales/) and opening the form via Ajax, then it doesn't work. Looking at the HTML source the just does not appear.
The common place for adding JavaScript is application.js found in public/javascripts. I'm a jQuery guy myself, however I'm sure you can hook up to the onchange event in application.js with prototype. A quick search looks like Event.observe should do the trick.

Categories

Resources