Displaying HTML from ArrayController - model-view-controller

I am attempting to display some information from my controller into my view, but the information is not being displayed.
I have a fiddle to demonstrate my code so far:
Fiddle
If I check in the console for MovieTracker.movieController.content, the 2 objects do show up. However, the HTML is not showing up correctly. What could be the problem?
Here is my View:
<script type="text/x-handlebars">
{{#each MovieTracker.movieController}}
<h2>{{title}}</h2>
<h3>{{rating}}</h3>
{{/each}}
​
And my Ember Application + Controller:
// Create our Application
MovieTracker = Ember.Application.create();
// Inherit outlet Support
MovieTracker.ApplicationController = Ember.Controller.extend();
// ArrayController to create some new Movies
MovieTracker.movieController = Ember.ArrayController.create({
content: [],
init: function(){
var kidsMovie = MovieTracker.Movie.create({
title: 'Toy Story',
rating: 4
});
this.pushObject(kidsMovie);
var avengers = MovieTracker.Movie.create({
title: 'The Avengers',
rating: 5
});
this.pushObject(avengers);
}
});
// Start our Ember Application
MovieTracker.initialize();​

I've updated your fiddle (see here: http://jsfiddle.net/schawaska/hKPQy/24/) to have a "movies" view binding to your controller instance, and also added a content property binding to the controller content. Also added the references to latest version of ember and handlebars.
Now you have a couple of templates:
<script type="text/x-handlebars" data-template-name="application">
<h1>Movie Tracker</h1>
{{view MovieTracker.MovieTrackerView }}
</script>
<script type="text/x-handlebars" data-template-name="movie-tracker">
Movies:<br />
{{#each movie in content}}
<h2>{{movie.title}}</h2>
<h3>{{movie.rating}}</h3>
{{/each}}
</script>
Now your each helper will iterate through a collection assigning each value to movie, which is your model (that was missing too, so I've created one) and its properties.
Your controller and view look like this:
MovieTracker.moviesController = Ember.ArrayController.create({
content: [],
init: function(){
// you missed the call to _super()
this._super();
var list = [
MovieTracker.MovieModel.create({
title: 'Toy Story',
rating: 4
}),
MovieTracker.MovieModel.create({
title: 'The Avengers',
rating: 5
})];
// also, it's a good idea to use .set whenever you can
this.set('content', list);
}
});
MovieTracker.MovieTrackerView = Em.View.extend({
templateName: 'movie-tracker',
controllerBinding: 'MovieTracker.moviesController',
contentBinding: 'controller.content'
});

Related

Call view in Laravel Controller with anchor tag

I need to call a view in a Laravel Controller, with parameters and with Anchor Tag.
I have this code in my controller:
return view('plans/editPlanView',
['plan' => $plan,
'patient' => $patient,
'aliments'=>$aliments, 'menu'=>$menu, 'tabName'=>$tabName]);
But i need to add an Anchor tag to land in a specific section of the page.
I can't use
return Redirect::to(URL::previous() . "#whatever");
proposed in other posts because i need to pass some parameters.
I think there are some base problem, trying with console this:
$('html, body').animate({
scrollTop: $('#whatever').offset().top
}, 1000);
scrolling to the desired section does not work.
it seems the page makes a small snap but always returns to the top.
Update
I have found the cause of the problem. At the bottom of the blade page I have the following code, without it the anchor tag works fine. Adding it the page makes a small scroll to return to the head. I need to use the datepicker, how can I fix the problem and get the anchor tag to work?
#push('scripts')
<script type="text/javascript">
$(document).ready(function () {
$('.date').datepicker({
firstDayOfWeek: 1,
weekDayFormat: 'narrow',
inputFormat: 'd/M/y',
outputFormat: 'd/M/y',
markup: 'bootstrap4',
theme: 'bootstrap',
modal: false
});
});
</script>
#endpush
You can create the method showPage() in your contoller for example TestController
public function showPage(Request $request)
{
$plan = $request->plan;
...
return view('plans/editPlanView', [
'plan' => $plan,
'patient' => $patient,
'aliments'=>$aliments, 'menu'=>$menu, 'tabName'=>$tabName
]);
}
Then create a route for rendering that view
Route::get('/someurl', 'TestController#showPage')->name('show-page');
And then in your methods you can use something like that:
$url = URL::route('show-page', ['#whatever']);
return Redirect::to($url)
I found a workaround, I added the disable attribute to the date input, in doing so, when the datepicker is initialized, the page does not scroll up. Then, as a last javascript statement I re-enabled the fields:
$('.date').prop("disabled", false);

Add element to this.$el before rendering

I have the following template:
<a data-rel="back" data-role="button" data-icon="delete" data-iconpos="notext" class="ui btn-right" data-theme="e"></a> <p id="msg"></p>
which is loaded from the following view:
define(['backbone', 'marionette', 'jquery', 'jquerymobile', 'hbs!templates/Popup'],
function (Backbone, Marionette, $, jqm, template) {
return Backbone.Marionette.ItemView.extend({
attributes: function() {
return {
// For dialogs to work correctly, url will need to be unique
'id' : 'popupMsg',
'data-role': 'popup',
'class': 'ui-content'
};
},
template: template,
initialize: function() {
_.bindAll(this);
},
onBeforeRender: function(){
this.$el.find("#msg").text("{{$ message}}");
}
});
});
I try to add some text in the #msg element of the template by adding the code above in OnBeforeRender event. The reason is that I want to pass a string to be localized from handlebars before the view is rendered.
Is that possible?
Thanks
Unfortunately, the #msg element won't exist until the view is rendered, so trying to set its text in onBeforeRender won't work.
Why can't you make the handlebars expression just a part of the template?

Ember event in one view update another?

I have a small extract from my Ember app here. My page contains a number of views each containing different data each with their own controllers.
I want a search field (in index view) to go in one view which should "talk" to the stationList controller to update the content of the stationList view. This doesn't work. I get an error: TypeError: this.get(...).search is not a function
The logging outputs the name of the contoller I've asked it to use: App.StationListController
I added a second search form inside on the StationList View. This one works just fine. The logging this time outputs a dump of the StationListController object. So I am guessing that the other search form, despite my code (in SearchFormView): controllerBinding : 'App.StationListController', is not correctly setting the controller.
So I guess my question is why not?
How can I route the change on the form field in the one view to call a funciton on another view's controller?
Here's my code:
<script type="text/x-handlebars" data-template-name="application">
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
<div id="searchForm">search form view search:
{{#view App.SearchFormView}}
{{view App.StationSearchField}}
{{/view}}
</div>
<div id="stationList">{{render stationList}}</div>
</script>
<script type="text/x-handlebars" data-template-name="stationList">
station list view search: {{view App.StationSearchField}}
<ul>
<li>List</li>
<li>will</li>
<li>go</li>
<li>here</li>
</ul>
{{searchTerm}}
</script>
And
App = Ember.Application.create({})
App.SearchFormView = Ember.View.extend({
init : function()
{
console.log("SearchFormView init", this.get('controller'))
}
})
App.StationSearchField = Ember.TextField.extend({
keyUp: function(event) {
var searchTerm = this.value
console.log("value",searchTerm,this.get('controller'))
this.get('controller').search(searchTerm)
}
})
App.StationListController = Ember.ArrayController.extend({
content : [],
searchTerm : null,
search : function(term)
{
this.set("searchTerm",term)
console.log("searching",term)
}
});
Fiddle: http://jsfiddle.net/ianbale/8QbrK/14/
I think the controllerBinding stuff is from the older version, I don't think that works anymore.
You can use controllerFor on get('controller') in the StationSearchField.
this.get('controller').controllerFor('station_list').search(searchTerm)
But controllerFor is deprecated and may be removed. Depending on your application structure you use needs on the controller.
Another way which I am using, is to send a custom event from the View, which the Route then sends to the corresponding controller.
App.IndexRoute = Ember.Route.extend({
events: {
search: function(term) {
controller = this.controllerFor('station_list')
controller.search(term);
}
}
});
and dispatch a search event from view like so.
this.get('controller').send('search', searchTerm);
The advantage of this method is you dispatch the same event from multiple places and it would get handled in the same way.
Here's the updated jsfiddle.

Ember.js - child nested views' controller

I'm building a simple calendar app with Ember. My views are nested this way :
<script type="text/x-handlebars" data-template-name="calendar">
{{content.monthAsString}}
{{#each day in content.days}}
{{view App.DayView contentBinding="day"}}
{{/each}}
</script>
<script type="text/x-handlebars" data-template-name'="calendarDay">
{{content.date}}
</script>
My JS code :
App.CalendarController = Ember.ObjectController.extend({
content:App.Calendar.create(...);
oneDayHover:function(day){
}
});
App.CalendarView = Ember.View.extend({
templateName:"calendar"
});
App.CalendarDayController = Ember.ObjectController.extend({
dayHOver:function(){
//???? HOW TO ACCESS CalendarController?????
}
});
App.CalendarDayView = Ember.View.extend({
templateName:"calendarDay",
init:function(){
this._super();
this.set('controller', App.CalendarDayController.create());
},
mouseEnter:function(){
this.get('controller').dayHover();
}
});
Problem 1:
Isn't there a nicer solution than to override the init method of the view to set it's controller?
Problem 2:
How can I access the oneDayHover of CalendarController from the CalendarDayController?
Thanks in advance for the help
Update 1:
I should remark that those controllers exists in the same state. The point of the mouseenter is to display a popup on top of the CalendarDayView containing extra information.
1 - Do not assign Controllers to Views manually. Let Ember do the heavy Lifting! Have a look at Embers Router API / how to define routes. Routes will connect controllers and views and render them (Doc).
2 - If you follow point 1, your other problem will get easy with Embers way of dependency injection:
App.CalendarDayController = Ember.ObjectController.extend({
needs : ["calendar"],
dayHOver:function(){
//Access the single instance of CalendarController
var calendarController = this.get("controllers.calendar");
}
});
Update in response to Comment:
The CalendarRoute is created implicitly. Therefore all you would need to do, is modifying your template, i guess:
<script type="text/x-handlebars" data-template-name="calendar">
{{content.monthAsString}}
{{#each day in content.days}}
{{control "calendarDay" day}}
{{/each}}
</script>
As you see, i am suggesting the use of the {{control}} helper. What the code above basically says is :
"Dear Ember, please use the name 'calendarDay' to lookup
App.CalendarView and App.CalendarDayController and use them to render
the object day"
Additionally you have to tell ember, that it should not use the controller as singleton (which is the defaul behaviour):
App.register('controller:calendarDay', App.CalendarDayController, {singleton: false });
Note: I have not yet used the control helper myself, but this should be the way it works.

How to load more than one DIVs using AJAX-JSON combination in zend?

I am learning AJAX in zend framework step by step. I use this question as first step and accepted answer in this question is working for me. Now I want to load more than one DIVs using JSON. Here is my plan.
IndexController.php:
class IndexController extends Zend_Controller_Action {
public function indexAction() { }
public function carAction() { }
public function bikeAction() { }
}
index.phtml:
<script type="text/javascript" src="js/jquery-1.4.2.js"></script>
<script type="text/javascript" src="js/ajax.js"></script>
<a href='http://practice.dev/index/car' class='ajax'>Car Image</a>
<a href='http://practice.dev/index/bike' class='ajax'>Bike Image</a>
<div id="title">Title comes here</div>
<div id="image">Image comes here</div>
car.phtml:
<?php
$jsonArray['title'] = "Car";
$jsonArray['image'] = "<img src='images/car.jpeg'>";
echo Zend_Json::encode($jsonArray);
?>
bike.phtml:
<?php
$jsonArray['title'] = "Bike";
$jsonArray['image'] = "<img src='images/bike.jpeg'>";
echo Zend_Json::encode($jsonArray);
?>
ajax.js:
jQuery(document).ready(function(){
jQuery('.ajax').click(function(event){
event.preventDefault();
// I just need a js code here that:
// load "Car" in title div and car2.jped in image div when "Car Image" link clicked
// load "Bike" in title div and bike2.jped in image div when "Bike Image" link clicked
});
});
I think you have got this. When any link with class='ajax' is clicked then it means its AJAX call. index of array(title, image) in phtml files(car.phtml, bike.phtml) show that in which DIV this content should be loaded.
My Question:
Now how to implement ajax.js to do this job if it gets data in json form?
Thanks
Encode JSON using the Zend Framework as
echo Zend_Json::encode($jsonArray);
If you are already using JSON for serialization, then don't send the images in HTML tags. The disadvantage of doing that is basically the JavaScript code cannot do much with the images other than sticking it into the page somewhere. Instead, just send the path to the images in your JSON.
$jsonArray = array();
$jsonArray['title'] = "Hello";
$jsonArray['image'] = "<img src='images/bike.jpg' />";
On the client side, the received JSON will look like:
{
"title": "Hello",
"image": "<img src='images/bike.jpg' />"
}
So the jQuery code needs to loop through key each, and inject a new image into the div with matching key - "image1" or "image2".
jQuery('.ajax').click(function(event) {
event.preventDefault();
// load the href attribute of the link that was clicked
jQuery.getJSON(this.href, function(snippets) {
for(var id in snippets) {
// updated to deal with any type of HTML
jQuery('#' + id).html(snippets[id]);
}
});
});
YOu could encode your json to have two values for example {value1:"data",value2:"data2"}
Then when your ajax returns you can...
jQuery(document).ready(function(){
jQuery('.ajax').click(function(event){
event.preventDefault();
$.ajax({
url: '<Link to script returning json data>',
data:json, //says we are receiving json encoded data
success: function(json) {
$('#div1).html('<img src="'+json.value1+'"/>');
$('#div2).html('<img src="'+json.value2+'"/>');
}
});
});
});

Resources