Ember.js ToDoMVC - Chrome firing ObjectController action multiple times - ember.js

I have been following the getting started guide for ember.
I have come to the parts that deal with editing and removing items and have come across a problem that seems to occur in chrome but not firefox.
The custom component "edit-todo" has 2 events that are linked to the action "acceptChanges"
{{#if isEditing}}
{{edit-todo class="edit" value=title focus-out="acceptChanges" insert-newline="acceptChanges"}}
{{else}}
The "acceptChanges" action fires the "removeTodo" action if the item's title is empty
acceptChanges: function () {
this.set('isEditing', false);
if (Ember.isEmpty(this.get('model.title'))) {
this.send('removeTodo');
} else {
this.get('model').save();
}
},
removeTodo: function () {
var todo = this.get('model');
todo.deleteRecord();
todo.save();
}
If you edit an item, delete the text and press enter or switch focus, the item gets deleted. This works perfectly for me in Firefox.
In Chrome however, the acceptChanges action is firing twice if you delete the title and press enter. When the DOM updates to remove the item, the acceptChanges action is fired again, presumably because it loses focus.
This jsbin shows the problem, it is essentially just the code from the guide with some console logs. If you edit the item "BBB", delete the text and press enter, the data for "CCC" is deleted also. It remains in the DOM but you can no longer interact with the item and the items remaining count is wrong. If you open ember inspector in the developer tools you can see that the only data left is for the item "AAA".
I am wondering if this is a bug with ember, with ember-data, with chrome, or if it is expected behaviour that I should be checking for in my js?
I am using Chrome Version 26.0.1410.63

Related

How to properly set state to allow React Bootstrap Modal to work on mapped data?

Trying to build a D.R.Y. list of vocabulary terms with React Bootstrap (v.2.2.3) using Bootstrap 5.1.
I bring in my data:
import vocData from '../data/vocData'
My component:
const VocList = () => {
const [show, setShow] = useState(false)
const handleClose = () => setShow(false)
return (
<ul className="list-inline">
{Object.keys(vocData).map((item, key) => (
<React.Fragment key={key}>
<li className="list-inline-item voc-item">
<Button>
<small>{vocData[item].title}</small>
</Button>
</li>
<Modal
show={show}
onHide={handleClose}
backdrop="static"
keyboard={false}
aria-labelledby={`contained-modal-title-${vocData[item].href}`}
centered
>
<Modal.Header closeButton>
<Modal.Title id={`contained-modal-title-${vocData[item].href}`}>
{vocData[item].title}
</Modal.Title>
</Modal.Header>
<Modal.Body>{vocData[item].content}</Modal.Body>
</Modal>
</React.Fragment>
))}
</ul>
)
}
I can see my list of vocabulary terms is working but my modal is not appearing when I click the button. I've tried to research and read through:
React-Bootstrap Multiple Modal
React-bootstrap Modal component opens/closes all modals when I map through a list
How do I get my react app to display object information in my bootstrap modal when they click on a list item?
How to use React-Bootstrap modals inside a map array method to display AJAX data on button click in React?
how to show react bootstrap modal inside the function
but I'm unable to find an answer.
How can I dynamically setState and be able to render my modal for that vocabulary term in my list?
Try to use Modal only once and not render it many times. You can show only one Modal at time anyway. I have created a subcomponent for clarity.
There are many ways how to play with state. Here the initial state is null and hides the modal. When we click on button we set state with one vocData entry. This also toggles the visibility of Modal.
Finally, when we close its again, we set our state to null. In this way we use one state for two purposes - control vision and rendering of Modal and holding data for it.

Clear modal form textbox from value on closing event

I have a "Subscribe" modal form that opens when the users clicks on "Inscription"
and I wish that the data typed in it by the user disappears or the modal 'resets' the value when it's closed.
I tried multiple options but nothing worked.
Here is a link to a fiddle:
http://jsfiddle.net/0tekp47g/3/
solution:
http://jsfiddle.net/0tekp47g/29/
This should do the trick:
$('.modal').on('hidden.bs.modal', function () {
$(".modal input").val("");
$('.modal select').val("");
});
Try it on JSFiddle.

Return values from ionic2 modal to parent page

I am opening a Modal in ionic2, to search the values from a list. After search, I want to get the selected values back in my parent screen.
searchRooms(){
let modal = this.modalCtrl.create(RoomSearch);
modal.present();
}
This opens my search Modal and there I have list of available rooms. If user click on any room then I want to return back the value to parent page. I am not sure how to do this.
From documentation I feel NavConroller.pop can be used to pass back the values but I don't know how to use that.
Thanks in advance.
You can use onDidDismiss method explained in the Modal Controller.
In the page that opens your modal you can do :
let modal = this.modalCtrl.create(RoomSearch);
modal.onDidDismiss(data => {
// Do things with data coming from modal, for instance :
console.log(data);
});
modal.present();
And this in your modal controller, to close the modal :
this.viewCtrl.dismiss({"foo" : "bar"});

Ember do action on arrray push

http://jsbin.com/qoyudape/4/edit
Every time you click update, item gets inserted. I would like to blink item red for one second after insertion, like on stackoverflow when linking to answer, it blinks orange for a second https://stackoverflow.com/a/22645880/1175593
How do I do that ?
Only CSS doesn't work, because I want the effect only on newly added items, and not on initial load
I don't know CSS, but this, Using CSS for fade-in effect on page load, seems to be just fine...
http://jsbin.com/qoyudape/6/edit
note, the render stuff I did isn't necessary, you could have just as easily done it without it...
http://jsbin.com/qoyudape/8/edit
or when the item is inserted into the page, you can do time sensitive animation
App.BlinkingFooView = Em.View.extend({
didInsertElement: function(){
if(this.get('controller.b') % 2 === 0){
this.$().addClass('mod')
}
}
});
http://jsbin.com/qoyudape/11/edit

Facebook Phonegap xCode: Program Freaks Out When Returns From Authorization

Here's what I want: Dialog box that says "Hey we gotta login to facebook and authorize" and then a button that goes to the facebook login page, then for it to return to a main page (the one that launched the dialog.
Right now, the dialog pops up fine, then it properly redirects to facebook, then redirects back but instead of just popping out to the main page, it pops out, then pops back up, then pops back out again. I'm sure I've done something I'm not supposed to. Also PLEASE comment on my jquery because I'm new to it and would rather not get into bad habits.
Here's what I have.
index.html which has this dialog box in the body:
<div id="dialog1" data-role="dialog" data-theme="b">
<div data-role="header" data-position="inline">
<h1> Welcome!</h1>
</div>
<div data-role="content">
<p>
<h5> Hey! Welcome to Tag Search. We need to take a few steps to set up the app. <br><br>
First you have to login to facebook and authorize Tag Search. Don't worry, we'll never post anything to your wall unless you tell us to! <br>
</h5>
</p>
<a id="loginBtn" data-role="button">Click Here to Login!</a>
</div>
</div>
In my <script> tags I have this event listener:
$("#loginBtn").bind("click",function(x){
$('#dialog1').dialog('close');
login();
});
Also:
function login() {
FB.login(
function(response) {
console.log(response.session);
if (response.session) {
getLoginStatus();
//alert('logged in');
} else {
alert('not logged in');
}
},
{ perms: "email, friends_photos, offline_access" }
);
}
And:
function getLoginStatus() {
FB.getLoginStatus(function(response) {
if (response.status == 'connected') {
//alert('Connected');
if(!session_access_token)
session_access_token=response.session.access_token;
getMe();
$("#loginout").text('Logout');
$("#loginout").bind('click', function(){logout()});
} else {
$.mobile.changePage('#dialog1', 'pop');
}
console.log(response);
});
}
getLoginStatus is called on document.addEventListener('deviceready', function() {
just guessing, but these should be good ways to start:
A) multiple binds (easier)
It could be you are binding to your button multiple times, so when you click on it, your functions fire multiple times.
To check just add a console.log to your click handler and see how often it fires when you click on the button.
You have to keep in mind how Jquery Mobile handles pages - the first page loaded is your "anchor-page" which should stay in the DOM as long as you are not rel="external"-linking to another page (which will then become your new anchor-page). All additional pages (including dialogs) are appended to the anchor-page DOM, when you load them. Your anchor page is just hidden, but is not gone, so it's easy to bind multiple times thinking "page is gone, need to bind again". Using Phonegap I think you have a single file with all pages contained, so this should also hold there.
B) Too many hashchanges firing (tricky)
Think of JQM transitions as two parallel processes, because a hashChange fires along with every transition. On forward transitions, the hashchange is blocked (check JQM $.mobile.urlHistory.ignoreNextHashChange), on backwards transitions it can pass and takes care of the reverse transition.
You would have to find out, which processes are triggered and blocked if your page is behaving strange. Console inside JQM in the _handleHashChange and click routing (search for "click routing " just before _handleHashChange) to see what happens.
My guess would be A)
Good luck and let me know if it works or if you have any more questons on both A) and B)