i got an asp.net mvc project, but actually most of functions i achieved via javascript, below screenshot is the part which makes me frustrating, here you can see i use a date picker to define time slot then filter content for next dropdown button with related contents.
$('.input-daterange').datepicker({
format: "yyyymm",
minViewMode: 1,
language: "zh-CN",
beforeShowMonth: function (date) {
switch (date.getMonth()) {
case 0:
return false;
case 1:
return false;
case 2:
return false;
case 3:
return false;
case 4:
return false;
}
}
}).on('changeDate', function (e) {
var from = $('#from-date').val();
var to = $('#to-date').val();
if (from !== to) {
$.ajax({
type: "GET",
url: "DataChanged?fromDate=" + $('#from-date').val() + "&toDate=" + $('#to-date').val(),
dataType: "json"
})
.done(function (data) {
//var legth = data.chart.length;
$('#brandtable').empty();
var contents = $.parseJSON(data);
$.each(contents, function (key, values) {
$.each(values, function (k, v) {
$('#brandtable').append("<td><button class='btn btn-default' id=" + v.ID + ">" + v.BrandName + "</button></td>");
if (k % 9 === 0) {
if (k !==0) {
$('#brandtable').append("<tr></tr>");
}
}
});
});
});
};
});
});
Ok now, everything is fine, content was added successfully with button tag, but now i want click on button to get data from server just like above action, it is very strange that click event doesn't work, i don't know why? i did it in this way,
#foreach (var item in Model)
{
<text>
$("##item.ID").click(function () {
$.getJSON("#Url.Action("ReturnContentForSrpead", new { #ID = item.ID })", function (msg) {
var tags = BID.getParams.C32().tags;
var data = (msg.data || {}).wordgraph || [{ key: tags[0] }, { key: tags[1] }, { key: tags[2] }, { key: tags[3] }, { key: tags[4] }];
iDemand.drawBg().setData(data[lastTab]).drawCircle(BID.getColor(lastTab)).wordgraph = data;
});
});
</text>
}
i passed all instances from controller when i render page at very beginning, so that means all content already got, but only use jquery ajax to achieve kind of asynchronous. if you confuse with why i used Razor to render scripts, ok, i tried javascript as well, but got same result.
but one thing makes me shake was, when i run below code from console, it works fine.
$("##item.ID").click(function () {
console.log('clicked');
});
Do not render inline scripts like that. Include one script and add a class name to the dynamically added elements and store the items ID as a data- attribute, then use event delegation to handle the click event
In the datepickers .on function
var table = $('#brandtable'); // cache it
$.each(values, function (k, v) {
// Give each cell a class name and add the items ID as a data attribute
table .append("<td><button class='btn btn-default brand' data-id="v.ID>" + v.BrandName + "</button></td>");
Then use event delegation to handle the click event.
var url = '#Url.Action("ReturnContentForSrpead")';
table.on('click', '.brand', function() {
// Get the ID
var id = $(this).data('id');
$.getJSON(url, { ID: id }, function (msg) {
....
});
});
Side note: Its not clear what your nested .each() loops are trying to do and you are creating invalid html by adding <td> elements direct to the table. Best guess is that you want to add a new rows with 9 cells (and then start a new row) in which case it needs to be something like
$.each(values, function (k, v) {
if (k % 9 === 0) {
var row = $('</tr>');
table.append(row);
}
var button = $('</button>').addClass('btn btn-default brand').data('id', v.ID).text(v.BrandName);
var cell = $('</td>').append(button);
row.append(cell);
})
Recommend also that you change
url: "DataChanged?fromDate=" + $('#from-date').val() + "&toDate=" + $('#to-date').val(),
to
url: '#Url.Action("DataChanged")',
data: { fromDate: from, toDate: to }, // you already have the values - no need to traverse the DOM again
You are binding click event on every item ID but the way you are getting id is not right. This $("##item.ID") will not find any element because this will bind click to an element whose id is #item.ID and there is no such element will this id. You need to change it like below. Concatenate "#" with each item id.
$("#"+#item.ID).click(function () {
//your code
})
Related
In one page I have three connected dropboxes with parent child relation in this order
Company->Analysis->Scenario
I also have the pair or Node dropboxes in a html table which should be repeated in each row. These dropboxes values should be changed as the parent Scenario dropbox combo value changes.
I also want them to show the relevant value as selected for each row.
This maybe straightforward for a frontend developer but I am struggling a lot.
The top dropboxes are nearly ok. For the dropboxes from the table I managed to change the first row at one point but now lost that version :(
Can you please help me to solve this. I tried nearly everything?
Kind Regards,
Sofia
enter image description here
This is the related code part
`<script charset="utf-8" type="text/javascript">
function _updateNodes() {
var source_elms = document.querySelectorAll("[id='source1']");
for(var i = 0; i < source_elms.length; i++){
source_elms[i].setAttribute('disabled', 'disabled');
if (source_elms[i].hasChildNodes()) {
source_elms[i].empty();
}
for (node in allowed_nodes){
if node[0]==edge.source_id and node[2]== scenario_id
source_elms[i].append($('<OPTION value = node[0] selected>node[1]</option>');
endif
if node[0]!=edge.source_id and node[2]== scenario_id
source_elms[i].append($('<OPTION value = node[0]>node[1]</option>');
endif;
}
}
}
// jQuery selection for the 2 select boxes
var dropdown = {
company: $('#company'),
analysis: $('#analysis'),
scenario: $('#scenario'),
source: $('#source1'),
target: $('#target1')
};
// function to call XHR and update analysis dropdown
function updateAnalysiss() {
var send = {
company_id: dropdown.company.val()
};
dropdown.analysis.attr('disabled', 'disabled');
dropdown.scenario.attr('disabled', 'disabled');
dropdown.analysis.empty();
dropdown.scenario.empty();
$.getJSON("{{ url_for('_get_analysiss') }}", send, function(data) {
data.forEach(function(item) {
dropdown.analysis.append(
$('<option>', {
value: item[0],
text: item[1]
})
);
});
dropdown.analysis.removeAttr('disabled');
dropdown.scenario.removeAttr('disabled');
updateScenarios();
_updateNodes();
});
}
function updateScenarios() {
var send = {
analysis_id: dropdown.analysis.val()
};
dropdown.scenario.attr('disabled', 'disabled');
dropdown.scenario.empty();
$.getJSON("{{ url_for('_get_scenarios') }}", send, function(data) {
data.forEach(function(item) {
dropdown.scenario.append(
$('<option>', {
value: item[0],
text: item[1]
})
);
});
dropdown.scenario.removeAttr('disabled');
});
}
var scenario_id = Null;
function updateNodes() {
scenario_id: dropdown.scenario.val()
}
// event listener to company dropdown change
dropdown.company.on('change', function() {
updateAnalysiss();
});
// event listener to analysis dropdown change
dropdown.analysis.on('change', function() {
updateScenarios();
});
// event listener to scenario dropdown change
dropdown.scenario.on('change', function() {
alert("aa");
_updateNodes();
alert("bb");
});
$('#company').change(function() {
updateAnalysiss();
});
$('#analysis').change(function() {
updateScenarios();
});
$('#scenario').change(function() {
alert("aa1");
_updateNodes();
alert("bb1");
});
// call to update on load
updateAnalysiss();
</script>
`
I just implemented a DataTable in my app, but it seems like javascript doesn't work within the DataTable.
I've attached all code below for better readability.
As you can see, the ccbtn_action="delete" bit is present, but Chrome/IE/FF doesn't seem to want to do anything when the glyphicon is clicked.
This code works perfectly when called from outside the DataTable.
What gives? Is it something to do about JavaScript not being applied to dynamically generated elements?
Thank you!
Here is the Javascript code that doesn't work:
$(document).ready(function(){
// Delete Records
$('[ccbtn_action="delete"]').on('click', function() {
var type = $(this).attr('ccbtn_value_type');
var value = $(this).attr('ccbtn_value_id');
console.log('type=' + type + '&id=' + value);
if (confirm('Are you sure you want to PERMANENTLY delete this record? There is NO TURNING BACK!')) {
$.ajax({
type: 'POST',
url: 'includes/crmcore_action.php?action=cc_delete',
data: 'type=' + type + '&id=' + value,
success:
function() {
$('#cc_pagetop_status').html("<div class='alert alert-success'><strong>Success!</strong> The record was successfully deleted.</div>");
if (type == "company")
{
window.location = "companies_list.php";
}
else
{
location.reload();
}
}
});
} else {
// Do nothing!
}
});
});
Here is the code for the DataTable:
$(document).ready(function() {
var t = $('#DataTable').DataTable({
"order": [[ 1, 'asc' ]],
ajax: {
url: 'includes/dt_ss.php?getwhat=company',
dataSrc: ''
},
columns: [
{data: null},
{"data": null,
"render": function (data, type, row)
{
return ''+data.name+'';
}
},
//{data: 'name'},
{data: 'tel'},
{
"data": "id",
"render": function ( data, type, full, meta )
{
return '<span class="glyphicon glyphicon-remove" ccbtn_action="delete" ccbtn_value_type="company" ccbtn_value_id="'+data+'" data-toggle="tooltip" data-placement="bottom" title="Click me to delete"></span>';
}
}
],
});
t.on( 'order.dt search.dt', function () {
t.column(0, {search:'applied', order:'applied'}).nodes().each( function (cell, i) {
cell.innerHTML = i+1;
} );
} ).draw();
});
Since the js looks ok, this is most probably a timing issue. You part of script that binds the events is executed before the actual elements are created.
To fix that, you can:
Make sure the script runs binding after elements creation
Use dynamic binding (like .delegate() http://api.jquery.com/delegate/)
Try delegating your event like this:
$('#DataTable').on('click', '[ccbtn_action="delete"]', function() { ...
My guess is the click event is attached before your ajax request loads the DataTable rows. You can read more here about jQuery event delegation with on(). Specifically:
Event handlers are bound only to the currently selected elements; they must exist at the time your code makes the call to .on()
Try like this, but jquery version must be 1.9+
$(document).on('click', '[ccbtn_action="delete"]', function() { // your remaining code
I use query to build a mobile app. First of all I use $.getJSON to retrieve data from json file:
$.getJSON('js/sura.json', function(data){
$.each(data, function(key, value){
//alert(key+' '+value['id']);
buildList(value['id'], value['name'], value['number']);
});
});
There are more than 100 rows from json file.
After that, I need to put every lists to an elements name <ul id="list></ul>. Should I make new Javascript function then write the code:
function buildList(id, name, number){
var name_elm = '<h3>'+name+'</h3>';
var noq_elm = '<span>'+number+'</span>';
var $list_elm = '<li>'+name_elm+''+noq_elm+'</li>';
$('#list').append($list_elm);
}
After I use .append(...). I would like to add click listener to every lists (each list has unique id).
How should I write query to add listener to each <li></li>?
You can use event delegation:
var $list_elm = '<li class="noqele">'+name_elm+''+noq_elm+'</li>';
$('#list').append($list_elm);
}
And Code for click event:
$(document).on('click','.noqele',function(){
//click event code...
});
This can be done more efficiently like this
$.getJSON('js/sura.json', function (data) {
var container = $();
$.each(data, function (key, value) {
var h3 = $('<h3 />', {text : value.name}),
span = $('<span />', {text : value.number}),
li = $('<li />', {
id: value.id,
on: {
click: click_function
}
});
container = container.add(li.append(h3, span));
});
$('#list').append(container);
});
function click_function() {
// do stuff on click
}
I have an HTML table which uses jQuery DataTables (https://datatables.net/). The rows are rendered with html links to delete a row. I have used the following code to handle the click event of link, delete the row on the server and then animate deletion of the row on the front end.
$(document).on("click", ".delete-operation", function (e) {
e.preventDefault();
var oTable = $('#alloperations').dataTable();
var operationId = $(this).data('id');
// Get the parent table row and mark it as having been selected
// due to the fact rowindex does not work in order in datatables
var tableRow = $(e.toElement).parents('tr').addClass('row_selected');
bootbox.confirm("Are you sure?", function (answer) {
if (answer) {
// send request to delete operation with given id.
$.ajax({
type: 'delete',
url: "/operations/" + operationId,
success: function () {
var anSelected = fnGetSelected(oTable);
//Get all the row cells and animate a deletion
tableRow.children().animate({ backgroundColor: "red", color: "black" }, 300, function() {
tableRow.fadeOut(2000, function() {
oTable.fnDeleteRow(anSelected[0]);
});
});
},
error: function(result) {
$("#messageContainer").html(result.responseJSON.ResponseView);
}
});
return true;
}
else {
// User clicked cancel
return true;
}
});
});
QUESTION: This works perfectly in Chrome but does not work at all in Firefox, does anyone know how I would get it to work in Firefox as well?
You should use the cross browser property 'target' of event object:
var tableRow = $(e.target).parents('tr').addClass('row_selected');
I'm currently writing a JQuery plugin that loads colors from a JSON web service into a drop down list.
The drop down list background-color changes according to the selected value. For the most part it is working. on any regular change it works as expected, the problem I am having is on the initial page load I am using triggerHandler("change"); and it triggers but I seem to be getting an undefined error on the selected value from the drop down list on page load so it doesn't trigger the color change on the drop down list
My code is:
$.fn.bindColorsList = function (options) {
var defColor = options.defaultColor;
var svcUrl = options.svcurl;
//var f_target = options.filterTarget;
var $this = this;
$.ajax({
url: options.svcurl,
dataType: 'json',
/*data: { filter: src_filt },*/
success: function (fonts) { fillcolors(fonts, $this) },
error: function () { appendError(f_target, "colors failed to load from server") }
});
this.on("change", function (event) {
log($(event.target).attr("id") + " change detected");
//change ddl dropdown color to reflect selected item ;
var hcolor = $this.find('option:selected').attr("name");
$this.attr("style", "background-color:" + hcolor);
});
function fillcolors(colors, target) {
$(target).empty();
$.each(colors, function (i, color) {
$(target).append("<option name='"+color.HexValue+"' value='" + color.Name + "' style='background-color:"+color.HexValue+"'>"+color.Name+"</option>");
});
};
//in a seperate file
$(document).ready(function () {
$("#dd-font-color").bindColorsList({ svcurl: "/home/colors"});
$("#dd-back-color").bindColorsList({ svcurl: "/home/colors" });
});
You are doing an AJAX request to populate your dropdown which, by the way, is an asynchronous one. In this case you need to trigger the event in the success callback of the AJAX request.
var $this = this;
// Bind the onchange event
$this.on("change", function (event) {
..
});
// Populate using AJAX
$.ajax({
...
success: function (fonts) {
// Populate the values
fillcolors(fonts, $this);
// Trigger the event
$this.trigger("change");
},
...
});
That's it.