My code looks something like this
HTML
<div><input type="checkbox" name="showInactiveBox" value="showInactiveBox" id="showInactiveBox">Show inactive project numbers</div>
Javascript
$("#showInactiveBox").live("click", function () {
if ($(this).is(":checked")) { //checkbox is checked
$.ajax({
type: "POST",
url: "#Url.Action("UpdateInactiveBox", "Project")",
data: {
showInactive: true
}
})
.done(function (data) {
Debug.writeln("Check box is checked?: " + $("#showInactiveBox").is(":checked"));
$("#project-numbers-grid").data("kendoGrid").dataSource.read();
});
I have an else that looks similar to above, just sets the checkbox to false basically. My debug line above in the .done of the Ajax function returns the correct value whether it be checked or not. However I then call the .read() on my grid which relates to more javascript below:
read: {
url: "#Html.Raw(Url.Action("GetActiveProjectNumbers", "Project"))",
type: "POST",
cache: false,
dataType: "json",
data: {
q: function () {
var model = {
projectid: "#Model.Id",
};
return JSON.stringify(model);
},
showinactive: $("#showInactiveBox").is(":checked")
}
},
When I put another Debug.writeline in the server, it is receiving the correct value for "q" but "showinactive" is always read in as false. Is there something with javascript that I don't quite understand where going from function to function will read a different value for ($"checkboxid").is(":checked")?
Thanks
Are you sure .is() works with the jQuery version you are running? You could also try .prop('checked'). I would try running this in the Chrome developer tools on the page:
$("#showInactiveBox").is(":checked")
and
$("#showInactiveBox").prop("checked")
If those return the value you are looking for, then there is something else going on. Try running those in console.log at the point at which you are calling those functions to see what the active output is:
console.log('This is my checkbox value', $("#showInactiveBox").is(":checked"));
In addition to Lawrence Johnson's (.prop) answer I'd take a look at some of the other code you are using.
For instance, when dealing with checkboxes it's always better to use the .change() method rather than click.
Also, the .live method is deprecated now and should be using .on().
When dealing with checkboxes you can easily use "vanilla javascript" to test if the box is checked or not. jQuery is not always the "less code/best solution".
See the below code for all the amendments mentioned above:
<input type="checkbox" name="showInactiveBox" value="showInactiveBox" id="showInactiveBox">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
$('#showInactiveBox').on('change',function(){ //using .on and change rather than click
if ( this.checked ) {//test if checked or not
console.log('checked');
}
})
});
</script>
Change
showinactive: $("#showInactiveBox").is(":checked")
to
showinactive: function() {
return $("#showInactiveBox").is(":checked");
}
and call it with
showinactive()
Currently, you are setting showinactive to the value of the property, which I'm assuming starts as false. Values in javascript don't update with the DOM like that--you need to explicitly check each time.
Related
I have an MVC page that contains multiple text entries. The controls on the page are all data driven. What I've done, is tag each of the autocomplete inputs with class="ACBox". They all have their own Ids. I have also added a custom attribute called fname, where fname is the field identifer. fname could be "size", "color", "connectionpoints", etc. (could be lots of these)
What I would like to do, is use one autocomplete function to make an ajax call to my controller with the fname of the control passed back to my function to return the appropriate list of possibles.
However, I do not find a way to get a reference to the calling object for autocomplete to read in the fname attribute. My current solution below, the pfield is Nothing when I examine in GetOptionsFromField.
Is there a way to set pfield? Optionally, I could use this.id to set as pfield.
$(".ACBox").autocomplete({
source: function (request, response) {
$.ajax({
url: "#Url.Action("GetOptionsFromField", "ControllerX")",
dataType: "json",
data: {
pfield: $(this).attr("fname")
},
success: function (data) {
response(data);
}
});
},
minlength: 5,
open: function () {
$(this).removeClass("ui-corner-all").addClass("ui-corner-top");
},
close: function () {
$(this).removeClass("ui-corner-top").addClass("ui-corner-all");
}
});
Okay, It looks like I needed to search better. This was answered back in 2014, with this question.
I use
$(this.element).data("colname")
and it works like a charm.
A very interesting problem I am facing these days is regarding one of my JavaScript function. My JavaScript function with some specific name is not working but if I change its name to anything else then it is working. Have a look -
// function to retain the jquery ui css for toolbar
function retain_css() {
alert('hi');
$( "#new_sort_options" ).buttonset();
}
// new sort
$(document).on("click", ".new_sort_button", function() {
var order = $(this).val();
var make_id = $('#new_make_id').val();
$.ajax({
beforeSend : start_loader(),
type : 'POST',
url : '/ajax/new-sort.php',
data : 'order='+order+'&make_id='+make_id,
dataType : 'json',
success : function(data) {
$("#new_results_toolbar").html(data.toolbar);
$("#new_results").html(data.models);
retain_css();
end_loader();
}
});
});
But retain_css() is not working at all. Even alert() is not firing. But if i change its name to anything such as my_fun() then the code works. I don't understand why it is happening so? Any idea? Don't worry about end_loader() function as it has nothing to deal with my problem. I also changed the order of code when retain_css() was being used but didn't work.
Try not to create global functions because it may collide with other frameworks or libraries.
//define private namespace
window.user3779493Functions = {};
//define method
user3779493Functions.retain_css = function() { ... }
//call method
user3779493Functions.retain_css();
Some functions are already programmed like 'alert('hi');', that is a function called alert:
function alert() {
/* do something */
}
That function also doesn't work.
My question is what is better to use onfocus="ajaxUpdateCompanyList2();" in my input OR $("#CompanyNameFilter").focus(function(), I'm new to jquery, so I have quite some issues with code aswell.
JS code option 1:
$(document).ready(function() {
$("#CompanyNameFilter").autocomplete("ajaxFuncs.php",{cacheLength:1,mustMatch:1,extraParams:{getClientList:1}});
});
$("#CompanyNameFilter").focus(function() {
var CN99 = $("#CompanyNameFilter").val();
url: "clientsFiltering.php?companyname=" + CN99,
method: "GET",
success : function( data ) {
var content = $(data).find("#companyList").html();
}
});
JS code option 2:
$(document).ready(function() {
$("#CompanyNameFilter").autocomplete("ajaxFuncs.php",{cacheLength:1,mustMatch:1,extraParams:{getClientList:1}});
});
$.fn.ajaxUpdateCompanyList2=function() {
var CN99 = $("#CompanyNameFilter").val();
url: "clientsFiltering.php?companyname=" + CN99,
method: "GET",
success : function( data ) {
var content = $(data).find("#companyList").html();
}
};
html code option 1:
It doesn't work at all :S
<input id="CompanyNameFilter" style="width: 205px;"/>
html code option 2:
I get error like, ajaxUpdateCompanyList2 is undefined function :S
<input id="CompanyNameFilter" onfocus="ajaxUpdateCompanyList2();" style="width: 205px;"/>
If using jQuery 1.7+ something like this is the way to go:
$("#CompanyNameFilter").on('focus', function() {
//code here
});
Inline JS is almost never the way to go!
Then again, you should probably start by reading the jQuery documentation, and figure out exactly what it is your trying to do, as the first code looks like it's missing an Ajax function, and the second code looks like some sort of attempt to create a plugin, also missing something essential?
I'm using bsmSelect jQuery plugin. Basically, what it does is changing the way a select-multiple is rendered to make easier to pick up the options. It hides the select element and shows a list instead.
So, first of all I'm applying the plugin function to my select-multiple element:
$(document).ready(function() {
...
$('#my_select_multiple').bsmSelect({
plugins: [$.bsmSelect.plugins.sortable()],
title: 'Add',
removeLabel: 'Remove'
});
...
});
On the other way, I have another select element (this one is simple) which has an ajax request bind to its change event. This ajax request get new #my_select_multiple options depending on the select simple value. Ajax response is the new HTML for #my_select_multiple options. So I have:
function getNewOptions(val) {
var r = $.ajax({
type: 'GET',
url: /*My URL*/
}).responseText;
return r;
}
...
$(document).ready(function() {
...
$('#my_select_simple').change() {
$('#my_select_multiple').html(getNewOptions($(this).val()));
}
...
});
AJAX is working as expected. New options are got correctly and they are inserted into #my_select_multiple (which is hidden by bsmSelect plugin, but I can check it with Firebug). But bsmSelect didn't realize new changes and doesn't get updated.
So, I think what I want is to reapply $('#my_select_multiple').bsmSelect(); with its new options.
I've been looking around a little bit and here is what I have tried.
1. I've tried to call again the funcion with the success and complete (one at time) of the AJAX request. Didn't work:
function getNewOptions(val) {
var r = $.ajax({
type: 'GET',
url: /*My URL*/,
success: function() { $('#my_select_multiple').bsmSelect(); }
}).responseText;
return r;
}
2. I've tried to bind the function with the on jQuery function. Didn't work:
$('#my_select_simple').on('change', function() {
$('#my_select_multiple').bsmSelect();
});
3. I've tried 1 and 2 removing previosly the HTML generated by bsmSelect. Didn't work.
Thank you very much.
UPDATE: The exact code
First I have a global.js file which apply bsmSelect plugin to some select multiples (.quizzes):
$('.quizzes').bsmSelect({
plugins: [$.bsmSelect.plugins.sortable()],
title: 'Add',
removeLabel: 'Remove'
});
And then, in the php file I define the updateQuizzes function and bind it to the select simple (project_id) change event:
<script type="text/javascript">
function updateQuizzes(project_id) {
var r = $.ajax({
type: 'GET',
url: '<?php echo url_for('event/updateQuizzes')?>'+'<?php echo ($form->getObject()->isNew()?'':'?id='.$form->getObject()->getId()).($form->getObject()->isNew()?'?project_id=':'&project_id=')?>'+project_id,
success: function() { $('.quizzes').bsmSelect({
plugins: [$.bsmSelect.plugins.sortable()],
title: 'Add',
removeLabel: 'Remove'
}); }
}).responseText;
return r;
}
$('#project_id').change(function(){
$('.quizzes').html(updateQuizzes($(this).val()));
});
</script>
As I told, the AJAX request works without problems, but not the calling bsmSelect the second time...
Not sure if this is what the problem is, but you could try
$('#my_select_simple').change() {
$('#my_select_multiple').html(getNewOptions($(this).val())).trigger('change');
}
This triggers a change event on select_multiple, and might fire bsmSelect. I'm not sure what the problem here is exactly, but that's the best I can come up with.
I think you want to set your HTML in the success of the Ajax call, something like:
function loadNewOptions(val) {
$.ajax({
type: 'GET',
url: /*My URL*/,
success: function(data) {
$('#my_select_multiple').html(data).bsmSelect();
}
});
}
And then calling like:
$('#my_select_simple').change() {
loadNewOptions($(this).val());
}
$(document).ready(function() {
$('#my_select_simple').change() {
$('#my_select_multiple').load("your Url", function(){
$('#my_select_multiple').bsmSelect();
});
}
});
something like this should work.
.load will put whatever your url returns into #my_select_multiple
the first parameter is the url to load, and the 2nd is a function to call when it is done. which is where you need to set up your fancy selector.
Ok, I opened a ticket and bsmSelect developer has answered me in minutes. Great!
To let bsmSelect know about its select changes, you have to trigger a change event on the select. There is no need to call bsmSelect again.
So it can be that way:
function loadNewOptions(val) {
var r = $.ajax({
type: 'GET',
url: /*My URL*/,
success: function(data) {
$('#my_select_multiple').html(data).trigger('change');
}
}).responseText;
return r;
}
$('#my_select_simple').change(function() {
loadNewOptions($(this).val());
});
The code:
$('input.media-checkbox').live('click', function(e){
e.preventDefault();
var that = $(this);
if (that.attr('checked') == 'checked'){
var m = that.attr('media');
var mid = 'verify_' + m;
that.parents('div.state-container').find('ul.' + mid).remove();
that.attr('checked', false);
} else {
var url = AJAX_URL;
$.ajax({
type: 'GET',
url: url,
dataType: 'html',
success: function(data){
that.parents('li').siblings('li.verification').children('div.media-verification').append(data).fadeIn(500);
that.attr('checked', 'checked');
}
});
}
return false;
});
I am ajaxing in a form, then firing the click event on relevant checkboxes to ajax in another partial if necessary. The form is inserted nicely, and the click events are fired, checking the boxes that need to be checked and firing the second ajax, since the checked attribute of the checkbox was initially false.
What's curdling my cheese is if I UNCHECK one of those boxes. Despite e.preventDefault(), the checked attribute is set to false BEFORE the test, so the if statement always executes the else statement. I've also tried this with $.is(':checked'), so I'm completely baffled.
It appears that unchecked -> checked state reads the original state, but checked -> unchecked doesn't. Any help?
B.E., I know it has been a year but I think I found the solution,
The issue here is that the click event actually get's called and runs BEFORE the "checked" property is added to the checkbox input. So the function runs, looks to see if the input has the "checked" attribute, and runs the else condition. THEN the element is given the "checked" property.
I just ran into this as well, and my solution was to bind the function to the change function rather than the click function, as change only fires AFTER the checked property has been updated on the input.
Hopefully this help you, and if not, anyone else who happens to stumble upon this post while experiencing a similar issue.
Well, right. You have set the live event, so I think your script might also be responding to setting it as checked, but I can't totally tell what you're trying for here without seeing markup, but here's my rewrite.
$('input.media-checkbox').live('click', function(e){
if ($(this).is(':checked')) {
var m = $(this).attr('media');
var mid = 'verify_' + m;
$(this).parents('div.state-container')
.find('ul.' + mid)
.remove();
$(this).attr('checked', false);
} else {
var url = AJAX_URL;
var that = this;
$.ajax({
type: 'GET',
url: url,
dataType: 'html',
success: function(data) {
$(that).parents('li')
.siblings('li.verification')
.children('div.media-verification')
.append(data)
.fadeIn(500);
$(that).attr('checked', true);
}
});
}
return false;
});
Try using e.stopPropagation() instead of e.preventDefault() and also remove return false. Returning false in jQuery is equivalent to e.stopPropagation() + e.preventDefault(). e.preventDefault() prevents the checkbox from being checked.
It seems to be a due to asynchronous requests. The execution goes past $.ajax, before it's success callback fires. When you click the checkbox again, it's state has not yet been updated by the previous request's callback. What you can try is to disable the checkbox control prior to firing the ajax call, and enable it again within the success callback:
that.attr("disabled", "disabled");
var url = AJAX_URL;
$.ajax({
type: 'GET',
url: url,
dataType: 'html',
success: function(data){
that.parents('li').siblings('li.verification').children('div.media-verification').append(data).fadeIn(500);
that.attr('checked', 'checked');
that.removeAttr('disabled');
}
});
That will ensure that two successive clicks will not lead to unpredictable behaviour. The other way would be to use a synchronous request, i.e. async: false but that will block the entire browser for it's duration.
I think it's due to a weird bug in IE. Check/set attribute defaultChecked along with checked. Try this in your if condition,
if (that.attr('checked')=='checked' || that.attr("defaultChecked")=='checked'){
var m = that.attr('media');
var mid = 'verify_' + m;
that.parents('div.state-container').find('ul.' + mid).remove();
that.attr('checked', false);
that.attr('defaultChecked', false);
} else {
This is probably only a partial answer, but in your test, $(this).attr('checked') should return true if checked and false if not. So just change your conditional to if (that.attr('checked'))