Having trouble updating DOM based on boolean value in my scripts - javascript

I'm trying to create and 'edit' mode for my application on the Manage Users page. I have every users values (such as name, email, etc) inside of an <input> tag with the readonly attribute. I have a button at the top of the page called "Edit Mode". When that edit mode is clicked, I would like the admin to be able to then click on the input field and change it. I am able to successfully toggle the readonly attribute on click BUT I only want that feature to happen when editing == true but for some season it seems that the DOM is never sensing when the editing boolean has been changed. Here is the code
$(document).ready(function(){
var editing = false;
$(".edit-mode-toggle").click(function(){
editing = true;
});
if(editing){
$("user-block input").click(function(){
$(this).removeAttr("readonly");
});
}
$(".user-block input").blur(function(){
$(this).attr("readonly", true);
})
});
Again I would only like to removeAttr when the ".edit-mode-toggle" button is clicked and changes the editing variable to true. My current output is that when I click that button to toggle the boolean, I'm not able to execute my editing because the DOM hasn't seen the boolean has changed. Anyone know what might be going on. Im sure ill derp once I find a solution. I'm just drawing blanks here. Strictly jQuery by the way, I know this can be easily done with Angular or some other 3 way data binding framework but I want to avoid using those. Thank you!

Dom only runs that if(editing) condition at load time, you want to move that part into your click function.
$("user-block input").click(function(){
if(editing){
$(this).removeAttr("readonly");
}
});
Also, you need to define the var editing outside of the $(document).ready() function.
var editing = false;
$(document).ready(function(){
//other stuff
})

You should update your code because you are attaching the click events in the page load, and the second condition in the IF statement will always get attached because 'editing' variable is always set to false in the page load.
to fix it you have to make the variable 'editing' a global variable
var editing = false;
$(document).ready(function(){
$(".edit-mode-toggle").click(function(){
editing = true;
});
$("user-block input").click(function(){
if(editing){
$(this).removeAttr("readonly");
}else {
$(this).attr("readonly", true);
}
});
}
});

Related

Warn user about unsaved changes to a form, when a form is being replaced during an AJAX call?

I'm new to Javascript and JQuery, and I'm implementing a warning to users that displays when they have made unsaved changes to a form's input/select/textarea elements if they navigate away from a page. I currently have the following which works fine when they leave a static form page:
/*
* Warn users when leaving a page with unsaved content, watches elements: (input, textarea, select) unless
* they are tagged with the "noWarning" class
*/
$(document).ready(function() {
$(document).on('change', 'input:not(.noWarning),textarea:not(.noWarning),select:not(.noWarning)', function () {
window.onbeforeunload = function(e) {
return 'You have unsaved changes';
};
});
});
The only page where it does not work, is in our main editing page. This page, unlike the others, has multiple tabs for editing different aspects of an item, which when clicked, trigger an AJAX call which replaces the content div with the appropriate form for editing the different aspect.
No warning dialog is displayed when a user clicks on a tab though, so any unsaved changes to the input are lost.
My intuition is that because the url is not changing, onBeforeUnload() is not executing. So I would have to check for any changes directly in the function which handles the AJAX call for replacing the form when a tab is clicked:
function clickedTabbedMenu() {
// This function replaces the content div with a new div and form
}
So my question is, how do I go about checking if any changes have been made to the elements in the current form before I replace the content div with another??? Can I directly call the "change" event listener for a true/false??? Or perhaps a different approach to handle this page's warning messages?
Any help is appreciated
Attach a change event handler to all the elements of the form. Have a variable outside the handler's scope dirty (or even a data on the form element) be set to false when a form is loaded, and true on every change event. Then, before replacing the form, check if dirty.
This would also be a good strategy for your non-AJAX pages as well - instead of setting the whole onBeforeUnload each time an element changes, just set onBeforeUnload once, and check if dirty inside it. This makes handling your AJAX and non-AJAX pages very similar.
EDIT: Untested because it's late and I need bed, but basically:
$(document).ready(function() {
var dirty = false;
$(document).on('change', 'input:not(.noWarning),textarea:not(.noWarning),select:not(.noWarning)', function () {
dirty = true;
});
function checkDirty() {
if (dirty) {
alert('You have unsaved changes');
return false;
}
return true;
}
// for non-AJAX pages
window.onbeforeunload = function(e) {
return checkDirty();
};
// for AJAX pages
$('.ajax_navigation_tab').on('click', function() {
if (!checkDirty()) {
// do the ajax thing
dirty = false;
}
});
});
I would try checking for and calling window.onbeforeunload() in your ajax script.
If it exists and returns a string, use it as an error message and halt the operation :)

Enable button on checkbox selection in MVC 4

Lot of research and tries but didn't work.My Problem is I want to enable my button on check of at least one checkbox from the available list.
Following is the screen:
Initially this button is enabled but my requirement is it should be disabled initially and if at least one of the checkbox is checked then it should be enabled.
Here,I have one view as Create inside which one more partial view is there which displays all the list view with the help of one controller method i.e within my Create view one more view is being rendered which displays all the available list.
If it would have been in one view then I would have easily done this as lot of fiddles are there with jquery by getting the id of the checkbox and passing to one jquery function. I know that I need to check the count for the checkbox in order to make my button enable/disable but again we dont have any change event as that in ASP.
Also on click of add , method for controller is begin triggered as:
[HttpPost]
public ActionResult Create(int id, List<MyModel> myModelList)
{
// code...
}
Here once I click on Add button this controller method is triggered where in my parameters(myModelList) I am able to check which checkbox is checked.So, this thing I need to implement on checking any of the checkbox such that the add button will be enabled on click of which I will be able to add my teams.
So how to implement this or what I need to do for this?
Thanks in advance.
UPDATE: Oops. Added the :checked pseudo class
This is how you might do it in jQuery
$('#add_button_id').prop('disabled', true); // To disable initially
$(document).on('click', '.checkbox_class', function(){
if( $('.checkbox_class:checked').length > 0 ){
$('#add_button_id').prop('disabled', false);
}
else{
$('#add_button_id').prop('disabled', true);
}
});
You'll have to add the id for the button and classes for checkbox as you have in your html code
you can do it this way:
$(document).on('click', '.checkbox_class', function(){
if(".checkbox_class:checked").length > 0)
$('#add_button_id').prop('disabled', false);
else
$('#add_button_id').prop('disabled', true);
}).change();
you can also trigger change on page load:
$(function(){
$(".checkbox_class").tirgger('change');
})

.on change function works first time not second?

I have a shopping cart that calculates cost and shipping based on quantity and weight. Because of this there are two possible shipping options and I have a function to auto-select the correct shipping on page load. However, if a person changes the quantity the function to select the shipping must run again.
To do this I tried this code:
$('.cartInputText').on('change', function() {
$('#ShippingOptions option').each(function(){
if (this.value == '163182') {
$('#ShippingOptions option[value="163182"]').prop('selected', true)
return false;
}
if (this.value == '163183') {
$('#ShippingOptions option[value="163183"]').prop('selected', true)
return false;
}
});
});
This works the first time I change the quantity. If I change the quantity a second time it doesn't work. How do I fix this so no matter how many times I change the quantity it works?
Update
The onchange event fires the first time but does not fire the second time. Why?
Please use live instead of on, or if the version of jQUery is higher than 1.9, please make you code like this: $(document).on('change','.cartInputText',function(){});
For your sample code, you only bind the function to .cartInputText, if the page re-renders or whatever the reason cause .cartInputText re-generate, it loses the function.
For my code, I bind the function to document and I think you know the event of html element can bubble, you click on .cartInputText and it bubbles up to document and let the function be triggered. More, please check Live and Bind difference in jQuery.
User KeyUp function instead of change for detecting input text.
Like:
$('.cartInputText').keyup(function () {
alert('test');
});
Here's the official jQuery documentation for .keyup().
DEMO
the above code works for the html code which is added before executing the previous statements,
if some other content with the same class (cartInputText) is added dynamically
you need to assign above functionality by calling it again after adding the content.

How to ensure link is disabled by default when the page is loaded

I have twp problems
Mark up for the link
DisplaySpreadsheetData
1)
Under document.ready i have this line of code to make sure the link is disabled by default but it does not work.
$('#displaySpreadSheetLink').bind('click', disableLink);
Code to disable the link
var disableLink = function (e) {
e.preventDefault();
return false;
}
2)
when the link is clicked i want to make sure that if checkFile() returns true the link should be disabled
$('#displaySpreadSheetLink').click(function (e) {
if (checkFile()) {
e.preventDefault();
}
});
There are two problems here. How can i correct the first problem and for the second one i think e.preventDefault() does not get executed even if checkFile() returns true.
Can anyone help please?
You might have an issue because you've actually bound two click events to your link. You should unbind the disableLink function before you bind the new functionality:
function disableLink(e) {
e.preventDefault();
// don't use return false here.
}
$(function() {
$('#displaySpreadSheetLink').click(disableLink);
});
// later on
$('#displaySpreadSheetLink').unbind('click').click(function (e) {
if (checkFile()) {
e.preventDefault();
}
});
Also, double-check your logic for checkFile(). Just based on the name I would assume, having never seen your code before, that you'd want to prevent the default behavior if checkFile() fails. Are you sure you don't want if (!checkFile()) { ... }?
Another approach might be to deal with only a single event, but take into account some extra state information as to whether the default behavior should execute or not:
(function($) {
var loaded = false;
$('#displaySpreadSheetLink').click(function(e) {
if (!loaded || checkFile()) {
e.preventDefault();
}
});
$(function() {
loaded = true;
});
})(jQuery);
Instead of disabling a link with a function after the page loads, you should change the HTML to be disabled initially by using a <span> with a CSS class that looks like a disabled link.
Instead of calling checkFile() every time the user clicks the link, have code in the sections that can alter whether checkFile() is true or false. For example, if checkFile() becomes true after a file is uploaded, put code in the file upload function to enable the link by replacing the <span> with an <a>, and link-disabling code in the appropriate places where checkFile() might become false again.
Merely using preventDefault() will make the link look clickable, which is probably bad UI design if it actually does nothing.

Detecting form changes using jQuery when the form changes themselves were triggered by JS

I have a list of radio buttons that I can toggle "yes" or "no" to using Javascript.
$(document).ready(function(){
$('#select-all').click(function(){
$('#notifications .notif-radio').each(function(){
$('input[type="radio"]', this).eq(0).attr('checked', true);
$('input[type="radio"]', this).eq(1).attr('checked', false);
});
});
$('#deselect-all').click(function(){
$('#notifications .notif-radio').each(function(){
$('input[type="radio"]', this).eq(0).attr('checked', false);
$('input[type="radio"]', this).eq(1).attr('checked', true);
});
});
});
this works just fine. Now I have a separate piece of code that detects when a user has changed something, and asks them if they want to leave the page.
var stay_on_page;
window.onbeforeunload = confirm_exit;
$('.container form input[TYPE="SUBMIT"]').click(function(){
stay_on_page = false;
});
$('#wrapper #content .container.edit-user form').change(function(){
stay_on_page = true;
});
function confirm_exit()
{
if(stay_on_page){ return "Are you sure you want to navigate away without saving changes?"; }
}
The problem is that if the user uses the first piece of functionality to toggle all radio buttons one way or another. The JS detecting form changes doesn't see that the form was changed. I have tried using .live, but to no avail. Anyone have any ideas?
I do something similar to this by adding change() (or whatever's appropriate, click() in your case I suppose) event handlers which set either a visible or hidden field value, then check that value as part of your onbeforeunload function.
So, my on before unload looks like:
window.onbeforeunload = function () {
if ($('#dirtymark').length) {
return "You have unsaved changes.";
}
};
And, or course, dirtymark is added to the page (a red asterisk near the Save button), when the page becomes dirty.

Categories