detect changes in a JS Object using Angular js - javascript

I have a javascript object suppose user is the name of my object and in angular js it looks like this
$scope.user = {
name:'Arpit',
class:'Computer Science',
year:'2017',
gender:'male'
}
This object I am fetching from the database and opening in the edit screen, now if in the HTML form if any field got changed by the user in edit mode I want to highlight the particular field using my CSS class applyborder. My logic is working for the first time when I am changing any field value but when I reset the value as original the class should be removed, but it is not removing the class. My angular js code is:
//Value Change Detection
Object.keys($scope.user).filter(function (key) {
$scope.$watch('user.' + key, function (newVal, oldVal) {
if (newVal != oldVal) {
var ele = $('[ng-model="user' + '.' + key + '"]');
ele.addClass("applyborder");
}
else if(oldVal == newVal){
var ele = $('[ng-model="user' + '.' + key + '"]');
ele.removeClass("applyborder");
}
});
});
It is treating last entered value as oldVal but it should treat to the value which comes from the database. Thanks.

This is the expected behavior of $watch.
You can keep a copy of the object you received from database using angular.copy:
var originalUser = angular.copy($scope.user).
then check:
//Value Change Detection
Object.keys($scope.user).filter(function (key) {
$scope.$watch('user.' + key, function (newVal, oldVal) {
if (newVal != originalUser[key]) {
var ele = $('[ng-model="user' + '.' + key + '"]');
ele.addClass("applyborder");
}
else if(originalUser[key] == newVal){
var ele = $('[ng-model="user' + '.' + key + '"]');
ele.removeClass("applyborder");
}
});
});

Just apply it under ng-dirty class will do. You might have to isolate your css scope so it doesn't get applied everywhere.
<form class='myForm'>
<input ng-model='xx' />
</form>
.myForm .ng-dirty {
background-color: yellow;
}
If you need to reset the state, you'll need to give the form a name.
<form class='myForm' name='myForm'>
$scope.myForm.$setPristine();

Related

javascript function to prevent user from changing the value of a specific column

Hope you're doing well
I'm new to JavaScript and I need your help to complete the code below.
I've written a JS code as you can see below :
$("#input_KindCode").change(function () {
if ($(this).val() == 1) {
RunSql("Select DateKey From ProjectExecution.Contractinfo WHERE PlanCode = " + $("#input_PlanCode").val() + " AND ProjectCode = '" + $("#input_ProjectCode").val() + "' AND ContractCode = '" + $("#input_ContractCode").val() + "' AND KindCode = 1 ", function (data) {
if (data.length > 0) {
$("#input_DateKey").val(data[0].DateKey);
/////// THIS PART///////
} else {
$("#input_DateKey").val('');
EnableCol("DateKey");
}
});
}
else {
$("#input_DateKey")[0].value = '';
EnableCol("DateKey");
};});
In the 'RunSql' part of the code , I'm checking whether the 'datekey' column has value if true the value will show up in the field otherwise the user must enter the value for the column.
The problem is I want to add something to the code . I want to show the value if it exists AND I want to disable the column so that the user can not change the value . I can not use the function 'disable column' cause it does not work in my case are there any other functions ??
so I want a function to prevent user from changing the value of the column if it is being shown on the field. the function must be written in the 'This part' part of the code
Thanks in advance
You can disable this input field using jquery. To perform this you need to add one line.
Code:
if (data.length > 0) {
$("#input_DateKey").val(data[0].DateKey);
$("#input_DateKey").prop('disabled',true);
} else {
$("#input_DateKey").val('');
$("#input_DateKey").prop('disabled',false);
EnableCol("DateKey");
}

How do i rearrange the number in java script loop?

I have done the dynamic generates textbox based on the number that user type. For example, user types 10 in the input box clicked add will generate 10 input box. I have a label to catch the number.
here is my question
how do I start from 1?
how do I rearrange the number when user remove one of the input boxes
here is my javascript
$(document).ready(function () {
$("#payment_term").change(function () {
var count = $("#holder input").size();
var requested = parseInt($("#payment_term").val(), 10);
if (requested > count) {
for (i = count; i < requested; i++) {
$("#payment_term_area").append('<div class="col-lg-12 product_wrapper">' +
'<div class="col-lg-12 form-group">' +
'<label>' + i + 'Payment</label>' +
'<input type="text" class="payment_term form-control" name="PaymentTerm[]"/>' +
'</div>' +
'cancel' +
'</div>');
}
$("#payment_term_area").on("click", ".remove_field", function(e) { //user click on remove text
e.preventDefault();
$(this).parent('.product_wrapper').remove();
calculateTotal();
x--;
})
}
});
});
here is my view
<input type="text" id="payment_term" />
<button onclick="function()">Add</button>
<div id="payment_term_area"></div>
You were nearly there, however, by hardcoding the label's you were making updating them difficult for yourself. I have created a jsfiddle of my solution to your problems. I personally prefer to cache the values of my jQuery objects so that they arent hitting the DOM each time they are referenced, for the performance boost (hence why they are listed at the top). I also, find it nicer to bind the click event in JS rather than using the html attribute onclick, but this is just a preference.
JSFIDDLE
Javascript
// create cache of jQuery objects
var add_payment_terms_button = $('#add_payment_terms');
var payment_term_input = $('#payment_term');
var payment_term_area = $('#payment_term_area');
var default_payment_values = ['first value', 'second value', 'third value', 'forth value', 'fifth value'];
var default_other_value = 'default value';
// bind to generate button
add_payment_terms_button.on('click', generatePaymentTerms);
function generatePaymentTerms(){
var requested = parseInt(payment_term_input.val(), 10);
// start i at 1 so that our label text starts at 1
for (i = 1; i <= requested; i++) {
// use data-text to hold the appended text to the label index
payment_term_area.append(
'<div class="col-lg-12 product_wrapper">' +
'<div class="col-lg-12 form-group">' +
'<label data-text=" Payment"></label>' +
'<input type="text" class="payment_term form-control" name="PaymentTerm[]"/>' +
'</div>' +
'cancel' +
'</div>');
}
// call the function to set the labels
updateProductIndexes();
}
function updateProductIndexes(){
// get all labels inside the payment_term_area
var paymentLabels = payment_term_area.find('.product_wrapper label');
for(var x = 0, len = paymentLabels.length; x < len; x++){
// create jQuery object of labels
var label = $(paymentLabels[x]);
// set label text based upon found index + 1 and label data text
label.text( getOrdinal(x + 1) + label.data('text'));
// either set the next input's value to its corresponding default value (will override set values by the user)
label.next('input.payment_term').val(default_payment_values[x] || default_other_value)
// or optionally, if value is not equal to blank or a default value, do not override (will persist user values)
/* var nextInput = label.next('input.payment_term');
var nextInputValue = nextInput.val();
if(nextInputValue === '' || default_payment_values.indexOf(nextInputValue) >= 0 || nextInputValue === default_other_value){
nextInput.val(default_payment_values[x] || default_other_value)
} */
}
}
// courtesy of https://gist.github.com/jlbruno/1535691
var getOrdinal = function(number) {
var ordinals = ["th","st","nd","rd"],
value = number % 100;
return number + ( ordinals[(value-20) % 10] || ordinals[value] || ordinals[0] );
}
payment_term_area.on("click", ".remove_field", function(e) { //user click on remove text
e.preventDefault();
$(this).parent('.product_wrapper').remove();
// after we remove an item, update the labels
updateProductIndexes();
})
HTML
<input type="text" id="payment_term" />
<button id="add_payment_terms">Add</button>
<div id="payment_term_area"></div>
First you have to give id for each label tag ex:<label id='i'>
Then you can re-arrange the number by using document.getElementById('i')
Refer the Change label text using Javascript
hope this will be much helpful

Replace prototype objects property

<script>
Croppic = function (id, options) {
var that = this;
that.id = id;
that.obj = $('#' + id);
that.outputDiv = that.obj;
};
Croppic.prototype = {
form: {}
};
init: function () {
var that = this;
var cropControlUpload = '';
if (that.options.customUploadButtonId === '') {
cropControlUpload = '<i class="cropControlUpload"></i>';
}
var cropControlRemoveCroppedImage = '<i class="cropControlRemoveCroppedImage"></i>';
if ($.isEmptyObject(that.croppedImg)) {
cropControlRemoveCroppedImage = '';
}
if (!$.isEmptyObject(that.options.loadPicture)) {
cropControlUpload = '';
}
var html = '<div class="cropControls cropControlsUpload"> ' + cropControlUpload + cropControlRemoveCroppedImage + ' </div>';
that.outputDiv.append(html);
var formHtml = '<form class="' + that.id + '_imgUploadForm" style="visibility: hidden;"> <input type="file" name="img" accept="image/*" id="' + that.id + '_imgUploadField"> </form>';
that.outputDiv.append(formHtml);
that.form = that.outputDiv.find('.' + that.id + '_imgUploadForm');
},
reset:function (){
var that=this;
that.init();//This initializes using init function
}
</script>
I have a crop module which does something like above.So everytime reset is called the module is initialized by using the init function.
However, the output is not coming as expected what is happening that when a reset is called more than twice, the form object shows this kind of behavior.
That is what console shows when reset is called the first time.Look for the property 0.
When the reset is called twice the result is something like this.Instead of removing the property 0 , it appended a new property 1.
This thing go on if i make more calls to the reset.
So when this happens Inspector in Mozilla shows more than one form when reset is called more than one time(Here i have called reset twice hence two forms in Inspector).
To overcome this problem i tried deleting the property 0 and even tried deleting the whole object and tried to create a new object but nothing helps.
if(that.form.hasOwnProperty("0"))
{
delete that.form["0"];// Here i even did this delete that.form;
that.form = that.outputDiv.find('.' + that.id + '_imgUploadForm');
}else{
that.form = that.outputDiv.find('.' + that.id + '_imgUploadForm');
}
I did everything but the same thing happens.How do i make sure it doesn't add more properties if 0 exists .If 0 exists just replace 0 by the new one.
Full Code :http://codepad.org/03EiunbL

Holding Down Backspace not Triggering Keyup

I'm trying to write text from an input to a div on keyup with javascript and jquery by checking if the current value of the input is the same as the previous value of the input. This works fine except when you hold down the backspace key until all of the text is gone from the input. In this case it doesn't update the variables that I'm using for some reason. This happens in all browsers and only if all of the text is deleted, also only if the backspace key is used (instead of another key)
I'm pretty new at javascript so any tips are appreciated :)
javascript:
fsa = (function() {
var inputId = "";
var sigId = "";
function resetOnFocus() {
inputId = document.activeElement.id;
sigId = "sig-" + document.activeElement.id;
}
function getText() {
lastentry = $("#" + inputId).val();
}
function writeText() {
if ($("#" + inputId).val() != lastentry) {
document.getElementById(sigId).innerHTML = 'current entry :' + $("#" + inputId).val() + '</br>last entry: ' + lastentry;
}
}
return {
resetOnFocus: resetOnFocus,
getText: getText,
writeText: writeText
}
})();
//call the functions
//clear variables on focus
$('input').focus(function() {
fsa.resetOnFocus();
});
//get input value on key press
$('input').keydown(function() {
fsa.getText();
});
//prints input value on keyup if input value is new
$('input').keyup(function() {
fsa.writeText();
});
and html:
<input id="first-name" class="i1" />
<div id="sig-first-name" class="o1" /></div>
<input id="last-name" class="i2" />
<div id="sig-last-name" class="o2" /></div>

Make a transition text without href

I have a div containing a group of divs.
I want the divs inside to work as links that move to another page after saving this link's value.
The div consists of the id in the div attribute, & the name in the div's value as follows:
Html:
<div id="ClasssesList" ></div>
jQuery:
function GetClassesList(data) {
var classes = (typeof data) == 'string' ? eval('(' + data + ')') : data;
$('#ClasssesList').empty();
for (var i = 0; i < classes.length; i++) {
var text = '<button class="BigDiv" value="' + classes[i].Cls_ID + '" >' + classes[i].Cls_Name + '</button>';
$('#ClasssesList').append(text);
}
}
I want to save the value of the clicked id in a localStorage then move to the next page:
I tried to make it as follows, but it doesn't seem to be working:
$("#ClasssesList").bind('click', 'button.BigDiv',CallLink());
function CallLink(e) {
localStorage['ClassID'] = $('Button.BigDiv').attr('value');
window.location.replace("Teacher_Attendance.htm");
}
Do you know what should I do to let it work ?
function CallLink(e) {
localStorage.setItem('ClassID', $('Button.BigDiv').attr('value'));
window.location.replace("Teacher_Attendance.htm");
}
And to get that item try:
localStorage.getItem('classID');
Format to set data to localStorage is
localStorage.setItem(key, value);
here value is string format;
you will get more here Microsoft, Mozilla and Apple.
And one note
I think your bind function
$("#ClasssesList").bind('click', 'button.BigDiv',CallLink())
should be written as
$("#ClasssesList").on('click', 'button.BigDiv',CallLink())

Categories

Resources