How does angularjs binding work when copying objects? - javascript

I have several html checkbox that is either on/off based on the properties of an object inside of an array say: objectArray.get(i).isCheckBoxActive. Since the user can change the object properties I'm trying to implement a button that reset all changes. My idea was creating a copy of objectArray (say objectArrayOriginal) and when the button is clicked it calls a function that copies back objectArrayOriginal into objectArray. I would expect that if a checkBox is off in objectArrayOriginal then, after pressing the button, it should be off also in the html page. To copy the object I did:
var objectArrayOriginal = JSON.stringify(objectArray)
.....
function clickReset(){
vm.objectArray = JSON.stringify(objectArrayOriginal)
}
I checked and although the field objectArray.get(i).isCheckBoxActive gets reset to its original value; the checkboxes remain checked/unchecked. The solution I found to be working is iterating over objectArray and comparing the values one by one with objectArrayOriginal. I would like to understand why the previous method fails and if there's a better one. Thanks in advance for any help!

Related

Refresh input to change value ReactJS

I have a form that is dynamic and display inputs (select, multiple or text) when an answer is provided on previous question.
When a text input is created, it is because of the answer of the previous question, which means that many way can be created by answering differently.
The problem :
When I answer a select question, for example, a text input can be displayed next. If I answer this input, another input can be displayed. But, if I update my answer for the first select input, this means that a new way is created, but the next one is still a text input, so ReactJS don't create a new one, just update the existing one. The fact is that the value is still in the input, and that's not what I want, I need the value to be updated, either by a defined value, or by an empty one, but this need to be updated.
I have created a stackblitz example with a little reproduction.
In this reproduction, you can choose a value in the select input, but then if you choose the other one, the value will not be updated on the input. The only way to update it, is to clear it and recreate it by choosing a new value.
I know that in this example, using the value from the state and updating the state directly in the change method will work, but in my project I don't have a defined number of text inputs.
The only thing I see to do it with state, is to create an array and dynamically adding or removing values when inputs are added or removed from the form. But I would prefer a "refresh" input method.
You can add your selected values inside Array state then loop map the
//states
this.state = {
values: []
};
//joinin new values with previous array
handleSelect(event) {
var joined = this.state.values.concat(event.target.value);
this.setState({ values: joined });
}
//then mapping on render
<div>
{
this.state.values.map(x=>(
<Input value={x} placeholder="type here" />
))
}
</div>
Here is working example in your code:https://stackblitz.com/edit/react-n1jbk6

Local Storage set to dropdown in Javascript

I'm been using this link. The issue is when I'm done submitting and filling those dropdown it reloads, When I come back again the previous value will gone. I just want to remain those value in dropdown but I think there is a conflict when using that link above. It also didn't display the other value of dropdown. All I know I should use localStorage. Is there any expert can give me directions and ideas for this?
Setting the value of dropdown when I click search/submit button
var values = document.getElementById('province').value;
localStorage.setItem("prov", values);
getting the value of province dropdown
document.getElementById("province").innerHTML = localStorage.getItem("prov");
It is possible to apply this through that link I provided?
Firstly, make an object that you can read from with mental ease.. something like
var obj={province:provinceElement.value, municipality:Municipality.value, ...etc}
then when you save all your values to the object, save it with a key("whatever it is once it's a key only your code uses")
localStorage.setItem("uniqueKeyOnlyMyCodeUses",JSON.stringify(obj))
Then you can get all your data like
var localObj=JSON.parse(localStorage.getItem("uniqueKeyOnlyMyCodeUses"))
localObj would have all the data you saved in just one key and objects are a very easy way to play around with the data you gave

AngularJS - Editing an object and applying / reverting changes

I have a table of items with an edit button next to it. When the edit button is clicked, the fields in that row turn into input fields where they can be edited, and a cancel button shows up. If they click cancel, the fields turn back into regular display fields. It's kind of like inline editing. I have two sets of <td> elements: one for display and one for editing.
What I'm looking for is a good way for me to keep the item's original values, so that when they click cancel, the data goes back to what it was originally. But if they click save, I'd like that data to stay on the object and that's what should be displayed.
I originally tried this (logic and processing is in the controller): On the edit button click, I'd create a "snapshot" of the object as an attribute on itself. Something like...
vm.edit = function(item) {
item.modified = angular.copy(item);
}
So what I'm actually doing is, when the row is not being edited, I'm displaying item.someProperty. When the edit button is clicked, it performs that copy in the controller, and the fields I show are actually item.modified.someProperty. Those are the different bindings in those two sets of <td> elements I mentioned, aside from the fact that the second set are input fields.
It works well as far as reverting goes (when they click cancel), but I'm stuck at the part where I want to update the object's original values if they click save. Basically, I need a way to get item.modified properties onto item itself. I've tried doing something like:
vm.save = function(item) {
item = angular.copy(item.modified);
}
And it doesn't seem to be working. I don't think I expected it to work in the first place, because it's kind of like overwriting itself with itself. Not sure if that would work.
What is a good way to accomplish this? Or maybe there's a better way to do what I'm trying to do?
Use a combination of copy() and extend(). Only edit the copy and store a reference to original that you can extend when you save
var storedItem;
// copy to variable before editing and store reference to original
vm.edit = function(item) {
storedItem = item;
vm.editItem = angular.copy(item);
}
vm.save = function() {
angular.extend(storedItem, editItem);
vm.editItem = null;
storedItem = null;
}
Set various ng-model to vm.editItem properties. If user cancels edit the original object has been unchanged so there is nothing to revert

AngularJS edit and save values inside ng-repeat

I'm working on my first angular app and i dont know the best way to handle this problem.
I have a long hierarchical json becouse the tables of the database are like a pyramid, looks similar to this:
I have the view represented pretty well using ng-repeat, I want to be able to edit the last rows of the last table which correspond with last level of JSON.
To do this I have implemented a edit modal that works fine, it saves and updates the database perfectly, the problem is that to see the updated value i have to refresh the page losing scroll position and collapsing accordions which is very bad.
Images of accordions:
When i click edit icon a promise stores in $scope.objEdit = {}; the object and launches the modal, which is linked to this object by ng-model.
So I think that the next step is that when modal is closed, i have to override the old object placed in the $scope variable that contains the entire json for the edited one, but im not sure how to do it.
I would appreciate your help to learn the standard way to do this, thx mates.
I Just solved it, I used a similar procedure to the oen that #AnikIslamAbhi sugested, in the fiddle that #Harshad shared in the comments is solved, but i have a much more dificult json to handle, i had to go with things like those to get the index of all levels of the json:
$scope.positionEvaluacion = $scope.dataEvaluacion.indexOf(args.levelOne);
$scope.positionAsignaturaevaluacion = $scope.dataEvaluacion[$scope.positionEvaluacion].asignaturaevaluacion.indexOf(args.levelTwo);
$scope.positionTarea = $scope.dataEvaluacion[$scope.positionEvaluacion].asignaturaevaluacion[$scope.positionAsignaturaevaluacion].tarea.indexOf(args.levelThree);
And after this override this object with the edited one:
$scope.dataEvaluacion[$scope.positionEvaluacion].asignaturaevaluacion[$scope.positionAsignaturaevaluacion].tarea[$scope.positionTarea] = $scope.objEdit;
You can try this procedure
Pass the selected object on edit click from UI to Controller.
Clone it and pass that object to modal.
OnModal close pass the modal object back to the UI.
Copy the values of modal object to the previous selected object
Like this
for(var i in modalObj){
selectedObj[i]=modalObj[i];
}

Cannot pass Array elements to restore a form

I am beginner in JavaScript. For exercise, I try to restore a form (at page closed / page reloaded) using cookies. I take the following steps:
Create an array with form selections
Convert to string
Create cookie
Retrieve cookie
Extract string
Convert to array
... Until here everything goes perfect. But the next step doesn't work anymore...
Pass array values to restore the form elements
Regardless the form selections (present correctly in the retrieved array) after reloading page I get every time only last the radio button checked (even if I increase or reduce the number of buttons) and all checkboxes checked.
I tried anything I know to find the error but no success. I also converted the string "true"/"false" values to Boolean, but no change.
The real situation:
frm[0]=true
frm[1]=false // for two radio buttons
frm[2]=false
frm[3]=false // for two checkboxes
document.getElementById("myradio1").checked=frm[0]
document.getElementById("myradio2").checked=frm[1]
document.getElementById("mycheckbox1").checked=frm[2]
document.getElementById("mycheckbox2").checked=frm[3] // pass the array values to the form elements
But, as I said, any values I pass I always get selected the last radio buttons and all checkboxes.
Probably this code doesn't follow the "best practices" of JavaScript, but before I change it I want to understand why it behaves like this. I thank you in advance for your comments, because I want very much to clarify this issue.
It happens because for a radio button, only one radio button can be clicked in a group of radio buttons.
And for the checkboxes, you are using the same ID twice, so the change isn't actually reflecting on the other checkboxes.

Categories