jQuery .on change event binding but not firing - javascript

var myTimelineVis = {
loadData: function(visItems, visContainer, visOptions, visTimelines) {
$.getJSON('myURL/' + $(this).val(), function(data) {
visItems.clear();
$.each(data, function(i, imp_sched_events) {
$.each(imp_sched_events.items.timeline_dataset, function(i, item) {
visItems.add(item);
if ($(visContainer).is(':empty')) {
visTimeline = new vis.Timeline(visContainer, visItems, visOptions);
} else {
visItems.update(item);
}
visTimeline.fit();
$('.vis-item-content').foundation();
});
});
});
},
setData: function(selectClass) {
var visItems = new vis.DataSet(),
visContainer = document.getElementById('visualization'),
visOptions = {},
visTimeline = '';
$(selectClass).on('change', function(visItems, visContainer, visOptions, visTimelines) {
this.loadData(visItems, visContainer, visOptions, visTimelines);
});
}
}
$(document).ready(function() {
myTimelineVis.setData('select.implementation_schedule');
});
I am trying to trying to create a vis timeline on page load and then load data onto it when my select changes (I have two selects). On page load, I can see the change event binding to both selects within Chrome console, but nothing happens, not even an error, on the actual select change. It just acts like they don't exist.
Is this is a scope issue?

For jQuery, the listener would not be added in an Ajax call, but in the $(document).ready(). It works differently than vanilla JavaScript.
If the select is dynamically changed you would need to use the following syntax with a hard-coded selector. The selector can be broad like "#myForm select". There's no need to use a variable.
$(document).on('change', '.selectClass', function(visItems, visContainer, visOptions, visTimelines) {
this.loadData(visItems, visContainer, visOptions, visTimelines);
});
});

Related

The button that I have in the datatable does not work on the second page

Below are my codes I'm using currently. Can someone help as this is important.
$("#btn" + arr[i].numberID).on("click", { id: arr[i].numberID }, function (event) {
var data = event.data;
getdet(data.id);
});
function getdet(numberID) {
window.location = "order.html?numberID=" + numberID;
}
I am not sure about this, but I think your issue is that the click event listener is not binding to the buttons in the other pages(the reason being that the buttons are dynamically generated when you change pages). This article explains the problem: Event binding on dynamically created elements?.
Try if this works:
$(document).on("click", "#btn" + arr[i].numberID, { id: arr[i].numberID }, function (event) {
var data = event.data;
getdet(data.id);
});
function getdet(numberID) {
window.location = "order.html?numberID=" + numberID;
}
Hope this helps.

$ is not defined, but only on $(function())

In my MVC partial view, the below does not fire:
$(function() {
alert('test');
});
The console reports that '$ is not defined.', which seems like jQuery is not referenced in the page.
However, in the same script block, I have other jQuery functions that work perfectly, so this problem seems isolated to just the $(function()) or $( document ).ready() on-load functions.
Here's the complete script block in the partial view:
<script type="text/javascript">
$(function () {
debugger;
alert('hi');
});
function updatePaymentTypes() {
$("#paymentTypes").empty();
$('#paymentTypes').append($('<option></option>').val("").html("- Please Select -"));
var getVoucherPaymentTypesUrl = "#Url.Action("getVoucherPaymentTypes", "Supplier", new { id = Model.Supplier.Id, area = "Configurations" })";
$.post(getVoucherPaymentTypesUrl, { "voucherPaymentMethodId": $("#paymentMethods").val() },
function (data) {
for (i = 0; i < data.length; i++) {
var paymentType = data[i];
$('#paymentTypes').append($('<option></option>').val(paymentType.Id).html(paymentType.Name));
}
// Force event
paymentTypeSelected();
});
}
function paymentTypeSelected() {
var getCardDetailsViewUrl = "#Url.Action("getVoucherCardDetailsView", "Supplier", new { id = Model.Supplier.Id, area = "Configurations" })";
$.post(getCardDetailsViewUrl, { "voucherPaymentTypeId": $("#paymentTypes").val() },
function (data) {
$("#cardDetailsView").html(data);
}).fail(function (error) {
debugger;
});
}
</script>
The partial view is being rendered within a jQuery Accordion div, and all jQuery functions in the parent view, including the $(function()) events all fire normally.
What could be wrong?
As most people pointed out in the comments, the problem is that the partial view is loaded before the script reference to jQuery.js has been rendered.
Make sure the script reference to jQuery is added on the top of the main view.

Javascript loop not creating jquery controls correctly

I would like to replace:
var linuxControls = ["CreateLinuxUser", "EditLinuxUser", "DeleteLinuxUser", "Export"];
$("#dlgCreateLinuxUser").dialog({autoOpen: false});
$("#btnCreateLinuxUser").click(function () {
$("#dlgCreateLinuxUser").dialog("open");
});
$("#dlgEditLinuxUser").dialog({
autoOpen: false
});
$("#btnEditLinuxUser").click(function () {
$("#dlgEditLinuxUser").dialog("open");
});
$("#dlgDeleteLinuxUser").dialog({autoOpen: false});
$("#btnDeleteLinuxUser").click(function () {
$("#dlgDeleteLinuxUser").dialog("open");
});
$("#dlgExport").dialog({autoOpen: false});
$("#btnExport").click(function () {
$("#dlgExport").dialog("open");
});
with:
for (i = 0; i < linuxControls.length; i++) {
var strDlg = "#dlg" + linuxControls[i];
var strBtn = "#btn" + linuxControls[i];
$(strDlg).dialog({autoOpen: false});
$(strBtn).click(function () {
$(strDlg).dialog("open");
});
}
However it is only creating the last control "Export." As looping constructs and string building goes, it all looks fine. Is there something weird with jquery that is preventing this?
Use a closure loop so that i won't be changed at runtime, can do that with jQuery each.
$.each(linuxControls, function(i) {
var strDlg = "#dlg" + linuxControls[i];
var strBtn = "#btn" + linuxControls[i];
$(strDlg).dialog({autoOpen: false});
$(strBtn).click(function () {
$(strDlg).dialog("open");
});
});
Since you're jQuery already why not try something similar to this:
$('.linux-control').click(function() {
$('#' + $(this).data('dialog')).dialog("open");
});
<button type="button" id="btnCreateLinuxUser" class="linux-control" data-dialog="dlgCreateLinuxUser">Create User</button>
Edit
The above snipped binds .click() to all .linux-control classes. It then looks for the data-dialog attribute and creates a jQuery selector to open your dialog. In the instance above the button contains dlgCreateLinuxUser in the data-dialog attribute of the element. No loops needed since the .click() function is bound only to element that fires it but listens for all elements with the class .linux-control.

Get Component Reference in AuraJS

I'm using jQuery dataTables to display a table. I need to be able to pass a row selection event on to my Aura component that handles the selection and performs some operations on the data from that row.
In the initialize() function:
initialize: function()
{
$("#mytable tbody").click(function(event)
{
$(mytable.fnSettings().aoData).each(function ()
{
$(this.nTr).removeClass('row_selected');
});
$(event.target.parentNode).addClass('row_selected');
});
mytable = $('#mytable').dataTable();
},
I set up the click handler for the row selection, but how do I get a reference to the enclosing component so I can sandbox.emit() function to issue messages? I can put a reference to the component into the Closure, but that essentially makes this component a singleton and I could never have two instances of the component on the page at the same time.
Is there a standard way, using jQuery selectors or some other method, that I can retrieve a reference to the enclosing component from inside the click() handler?
Edit: I should never try to write code until I have had 32oz of caffine. You can pass a reference to the current component via the click() method itself. Like so:
$("#mytable tbody").click(this, function(event)
{
$(mytable.fnSettings().aoData).each(function ()
{
$(this.nTr).removeClass('row_selected');
});
$(event.target.parentNode).addClass('row_selected');
event.data.sandbox.emit('mychannel', {data: 'stuff'});
});
If I understand your question correctly, you could try something like this
initialize: function () {
var that = this;
$("#mytable tbody").click(function(event) {
//have acces to component as 'that'
});
}
what I used for events is view inside component configuration:
View: {
events: {
'click a[data-question-edit-id]': function (e) {
var button = $(e.currentTarget),
id = button.attr('data-question-edit-id'),
examId = this.component.examModel.get('id');
this.sandbox.router.navigate('/exams/' + examId + '/questions/' + id + '/edit', {trigger: true});
},
'click a[data-question-delete-id]': function (e) {
var button = $(e.currentTarget),
id = button.attr('data-question-delete-id');
this.component.showDeleteConfirmation(id);
}
}
}
If you'll find be helpful, here is my repo of aura project I'm working on:
https://github.com/lyubomyr-rudko/aura-test-project

jQuery focus between .click() events

This is homework, just declaring it now.
I have to load a 'quiz' via XML (completed successfully), and generate td cells (done) to display said questions (not done, test data instead).
Here is my source code for the javascript
var selected;
var $cell;
var $cell2;
$(document).ready(function() {
$("#getTitle").click(function() {
selected = $("#quizname>option:selected").text();
$("#quiztitle").html(selected+" Quiz");
$("#quiz2").html(selected+" Quiz");
murl = "quizdata.xml";
$.ajax({type:"GET",
url:murl,
success:loaddata,
cache:false,
dataType:"xml",
data:selected,
error:ajaxerror
});
});
});
var $xml;
function loaddata(respobj,status,xhr) {
//to do:
//dynamic td creation for each xml question
$("#questions").empty();
$xml = $(respobj).find("quiz:contains("+selected+")");
for (var i=0;i<$xml.attr("qnum");i++) {
$('<tr>').attr("id","questions"+(i+1)).appendTo("#questions");
$("<td>").attr("id","question"+(i+1)).appendTo("#questions"+(i+1));
$("#question"+(i+1)).html((i+1)+". "+$xml.find("question[num='"+(i+1)+"']").text());
$("#question"+(i+1)).addClass("th.thirty");
$("<td>").attr("id","blank_question"+(i+1)).appendTo("#questions"+(i+1));
$("#blank_question"+(i+1)).addClass("question");
$("#blank_question"+(i+1)).html("Put Answer Here");
$("<td>").attr("id","answer"+(i+1)).appendTo("#questions"+(i+1));
$("#answer"+(i+1)).addClass("question");
$("#answer"+(i+1)).html((i+1)+". "+$xml.find("answer[num='"+(i+1)+"']").text());
$("#answer"+(i+1)).click(selectCell);
}
}
function selectCell() {
$cell = $(this);
$cell.css("background-color","red");
for (i=0;i<$xml.attr("qnum");i++) {
$("#blank_question"+(i+1)).click(function() {
$cell2 = $(this);
$cell.css("background-color","lightgray");
temp_text = $cell.text();
temp_id = $cell.attr("id");
$cell.attr("id",$cell2.attr("id"));
$cell.text($cell2.attr('id'));
$cell2.attr("id",temp_id);
$cell2.text(temp_id);
$("#answer"+(i+1)).unbind("click");
$("#answer"+(i+1)).bind("click", function() {
selectCell();
});
});
}
}
function swapCell() {
$cell.css("background-color","lightgray");
alert($(this).attr("id"));
}
function ajaxerror(xhr,status,error) {
$("td#desc").attr("class","");
$("td#desc").html("xhr="+xhr);
$("td#desc").append("<br /><br />status="+status)
$("td#desc").append("<br /><br />error="+error);
}
My issue is (try it here: HomeWork Link) that the first time you click the first cell, swap it with the second, it works. However, it only works every OTHER click and swap, which makes me think that there are some binding issues or focus issues because I need it to swap seamlessly. Is there an obvious error in the code or am I missing a specific focus/bind event?
Thanks!
Edit: the values being displayed AFTER swapping are the cells ID attribute
After googling "jquery recursive .click binding" I found that instead of .click() I changed it to .live() and that works perfectly.

Categories