.on('click') with ajax content from another ajax content - ajax

Trying to get an event triggered with ajax content whose parent elements were also ajax loaded.
<div id="content"><!-- NOT ajax-loaded -->
<div id="location"> <!-- #location IS ajax-loaded -->
<div id="add_location> <!-- #add_location IS ajax-loaded from a #location event -->
<input type="text" id="add_location_city_example" />
<input type="text" id="add_location_state_example" />
<input type="submit" id="add_location_confirm" />
</div>
</div>
</div>
$(function(){
$('#content').on('click', '#add_location_confirm', function(){
console.log('debug 1');
add_location();
// will not be called
});
$('#location').on('click', '#add_location_confirm', function() {
console.log('debug 2');
// will not be called either
add_location();
});
});
If I have onclick="add_location()" and function add_location() { console.log('debug 3); } in my .js then it will obviously be called BUT I then cannot get $('#add_location_city_example').val() because none of it will be in the dom.
NOTE: using 1.9.1

I've been using this for a while, makes it much easier to handle situations like you are describing + there is only one even assignment for pretty much all clicks on the page, including elements that will appear on the page in the future:
$(document).bind('click', function (e) {
var target = $(e.target);
if (target.is('#content')) {
e.preventDefault();
// do whatever
} else if (target.is('#location')) {
e.preventDefault();
// do whatever else
}
});
or in your case it would probably be more like this:
$(document).bind('click', function (e) {
var target = $(e.target);
if (target.is('#add_location_confirm')) {
e.preventDefault();
if (target.closest('#location').length == 0) { // not yet have location injected via ajax
// do something
} else {
// location has been injected, do something else
}
});

Related

Ajax submit and replace submit button with checkmark after success

First, I'm not having luck with ajax submitting at all in cakephp 1.3 environment. Once I successfully submit, I'm hoping user stays on page and submit button hidden or replaced with a checkmark. I've tried a few things... controller without $action and then .click function instead of on submit. I'm also not versed in debugging js to see where it might be wrong so any suggestions are welcome.
Maybe "update_a" is the $action within my dashboard controller
"function applications($action) {" instead?
dashboard controller
function update_a($action) {
...
switch ($action) {
case 'save':
if (!empty($this->data)) {
// update fields in database table matching model
$this->data['Model']['submitted'] = $_POST['submitted'];
$this->data['Model']['locked'] = $_POST['locked'];
if ($this->Model->save($this->data)) {
// save form fields to other models
$this->OtherModel->saveField('form_status_id',$_POST['form_status_id']);
$this->OtherModel->saveField('form_status',$_POST['form_status']);
}
}
}
break;
default:
//$this->redirect("admin/index");
$this->render("dashboard/applications");
break;
} //case
} // end function
html
<body>
<form id='update_a' action='save'>
<div class='form-group'>
<input type='hidden' class='hidden' name='locked' id='locked' value='1'>
<input type='hidden' class='hidden' name='form_status' id='form_status' value='Locked'>
<input type='hidden' class='hidden' name='form_status_id' id='form_status_id' value='3'>
<input type='hidden' class='hidden' name='submitted' id='submitted' value='<?php echo date("Y-m-d G:i:s") ?>'>
</div>
<div class='text-center'>
<input name='submit' type='button' class='btn btn-default' value='Submit Form A'>
</div>
</form>
</body>
<script>
$(document).ready(function () {
$('#update_a').on('submit', function (e) {
//$('#update_a').click(function (e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: '/dashboard/update_a',
data: $('#update_a').serialize(),
success: function () {
alert('Form A has been submitted and locked for editing');
$('#update_a').hide();
},
error : function() {
alert("Error");
}
});
return false;
});
});
</script>

reCAPTCHA : Grey out Submit button until backend interaction is finished

I've integrated reCAPTCHA and it is working fine, except for when the users are too quick to click the Submit button right after checking the "I'm not a robot" checkbox. It takes quite some time for reCAPTCHA to register the user action via Ajax, and if they click on Submit too quickly, the g-recaptcha-response is missing, and the validation fails.
Hence my question: how to I grey out the Submit button until g-recaptcha-response value is available?
<form id="capform" action="/captchaverify" method="POST">
<div class="g-recaptcha" data-sitekey="..."></div>
<p>
<input id="capsubmit" type="submit" value="Submit">
</form>
I ended up using the data-callback attribute as described in the documentation:
<form action="/captchaverify" method="POST">
<div class="g-recaptcha" data-sitekey="..." data-callback="capenable" data-expired-callback="capdisable"></div>
<p>
<input id="capsubmit" type="submit" value="Submit">
</form>
JavaScript (mootools-based, but the general idea should be clear):
function capenable() {
$('capsubmit').set('disabled', false);
}
function capdisable() {
$('capsubmit').set('disabled', true);
}
window.addEvent('domready', function(){
capdisable();
});
Here's an example that begins with the submit button disabled, and enables it once the callback is received from reCaptcha. It also uses jquery validate to ensure the form is valid before submitting.
var UserSubmitted = {
$form: null,
recaptcha: null,
init: function () {
this.$form = $("#form").submit(this.onSubmit);
},
onSubmit: function (e) {
if ($(this).valid()) {
var response = grecaptcha.getResponse();
if (!response) {
e.preventDefault();
alert("Please verify that you're a human!");
}
}
},
setupRecaptcha: function (key) {
UserSubmitted.recaptcha = grecaptcha.render('recaptcha', {
'sitekey': key,
'callback': UserSubmitted.verifyCallback
//'theme': 'light'//,
//'type': 'image'
});
},
verifyCallback: function (response) {
if (response) {
$(".visible-unverified").addClass("hidden");
$(".hidden-unverified").removeClass("hidden");
}
}
};
I call setupRecaptcha from the page with a named function that's part of the js include.
<script>
var recaptchaLoader = function () {
UserSubmitted.setupRecaptcha("yourkey");
};
</script>
<script src="https://www.google.com/recaptcha/api.js?onload=recaptchaLoader&render=explicit" async defer></script>
You could simplify this. I use it in a multi-tenant application with different keys, and UserSubmitted is actually part of a larger library. You can't usenamespaces (UserSubmitted.somefunction) as the onload param either (to my knowledge).

Refresh Partial view

I used #Html.RenderAction("_DisplayImages") to render a partial view.
#model List<Univems4.Models.ImageViewModel>
#foreach (var image in Model)
{
<div class="set">
<div class="header invisible">
<label class="edit">#image.Name</label>
<button class="close btnDeleteImage" title="Delete">×</button>
</div>
<img class="img-thumbnail edit" src="data:image/bmp;base64,#image.base64string" id="#image.Id" />
</div>
}
Upon button click, I want to refresh this partial view. The approach I tried is by using jQuery ajax get method.
$.get("/VmsMessage/_DisplayImages", null, function (data) {
//success
$('#bit').html(data);
}, "html");
The partial view was refreshed. but it no longer responds to the events. Why?
$(".set").hover(function (e) {
// do something
});
$(".edit").click(function (e) {
// do something
});
As the html will be genrated dynamically so events are not binded on DOM load you need to do event delegation:
$(document).on("mouseover",".set",function (e) {
// do something
});
$(document).on("click",".edit",function (e) {
// do something
});

Knockout - load data into model with Ajax - not straight away

Here's a simplified example of my knockout model. The problem I'm having is that as soon as the page loads, the quiz is loaded. Why does it get run straight away and how can I stop it so that it only get's run when I want, say, on the click of a button?
Do I even need to use subscribe to do this?
HTML:
<h1>Test</h1>
<button class="btn btn-primary" data-bind="click: quizCount(quizCount() + 1)">
Click Me
</button>
<hr />
<div data-bind="visible: !loaded()">No Quiz</div>
<div data-bind="visible: loaded">Quiz Loaded!</div>
<hr />
<h3>Debug</h3>
<div data-bind="text: ko.toJSON(quizModel)"></div>
Javascript:
<script type="text/javascript">
var quizModel = { };
// DOM ready.
$(function () {
function QuizViewModel() {
var self = this;
self.loaded = ko.observable(false);
self.questions = ko.observable();
self.quizCount = ko.observable();
};
quizModel = new QuizViewModel();
quizModel.quizCount.subscribe(function (newCount) {
$.getJSON('#Url.Action("GetNew", "api/quiz")', function (data) {
quizModel.questions(data.Questions);
}).complete(function () {
quizModel.loaded(true);
});
});
ko.applyBindings(quizModel);
})
</script>
Subscribe is only used for listening to changes in an observable so it will run immediately as soon as the observable gets a value.
You need to add this function to your viewmodel as a method, likely to be called getQuestions:
function QuizViewModel() {
var self = this;
self.loaded = ko.observable(false);
self.questions = ko.observable();
self.quizCount = ko.observable();
self.getQuestions = function(){
$.getJSON('#Url.Action("GetNew", "api/quiz")', function (data) {
self.questions(data.Questions);
}).complete(function () {
self.loaded(true);
});
}
};
then you can easily have a button or something that binds to this method on click:
<button data-bind="click: getQuestions">Get questions</button>

How get the value from a link and send the form using mootools?

I have a such form with many links:
<form name="myform" action="" method="get" id="form">
<p>
My link
</p>
<p>
My link 2
</p>
<p>
My link 3
</p>
<input type="hidden" name="division" value="" />
</form>
I would like to send the form's value from the link that was clicked to php script and get the response (not reloading the page).
I'm trying to write a function that gets the value from a link:
<script type="text/javascript">
window.addEvent('domready', function() {
getValue = function(division)
{
var division;
division=$('form').getElements('a');
}
</script>
but I don't know how to write it in a right way. Next I would like to send the form:
$$('a.del').each(function(el) {
el.addEvent('click', function(e) {
new Event(e).stop();
$('form').submit();
});
});
How I should send it to get the response from a php file not reloading the page?
Instead of putting in javascript inline in the HTML, I would suggest using a delegated event instead. I would also send the form using an ajax call instead of a form submit.
<form id="form">
<a data-value="A">My link</a>
...
</form>
<script>
var formEl = document.id('form');
formEl.addEvent('click:relay(.del)', function() {
var value = this.getProperty('data-value');
new Request.JSON({
url: '/path/to/your/listener',
onSuccess: function(data) {
// ...
}
}).get({
value: value
});
});
</script>
This works for me:
<form id="form">
<a data-value="A">My link</a>
...
</form>
<script>
var links = document.id('form').getElements('a');
links.each(function(link) {
link.addEvent('click', function(e) {
e.stop();
var value = link.getProperty('data-value');
var req = new Request.HTML({
url: "/path/to/your/listener",
data: value,
onRequest: function(){
$('display').set('text', 'Search...');
},
onComplete: function() {
},
update : $('display')
}).get(
{data: value}
);
});
})
</script>

Resources