Creating and Defining base view for backbone.js - javascript

I am attempting to extend backbone views to add a basic implementation of a layout "skeleton". This will be used to piece together a page using the different components. The problem as listed below is the scope changes for all the nested object layout pieces. Could I create closures for all of these that point to the same scope or am I limited to a single object tier? Maybe I am thinking about it wrong?
define(['backbone', 'underscore'
], function (backbone, _) {
var base = backbone.View.extend({});
_.extend(base.prototype, {
sections: {
head: {},
body: {
nav: {},
main: {
header: {
title: "",
description: "",
inner_html: function () {
return this.render().el
},
menu_items: [],
changed: false,
scripts: function () { }
},
content: {
title: "",
description: "",
inner_html: function () {
return this.render().el
},
scripts: function () { }
},
buttons: {
items: [], // { id: "save", value: "Save" }, { id: "edit", value: "Edit" }
changed: false,
scripts: function () { }
}
},
footer: {}
}
}
});
return base;
});

This looks a lot like Marionette's Layout views and regions. You may not need to write this yourself. I often use the Layout,Regions, and specialized views from Marionette without the App and Module portions.

Related

Inner widgets disappear after page reload

I am having an issue with my nested widgets. There's two widget container (full-width and TwoColumn), which share pretty much same code for configurations but different html code; as well as, 4 different types of widgets that are nested inside any of the previous containers.
So, I can create any type of container and it sill remain on the page. However, only nested widgets in full-width container get saved. Meaning that if I reload the page, the content of TwoColumn containers, is missing.
Please find below code for both containers:
Full-width
module.exports = {
extend: 'apostrophe-widgets',
label: 'Row Block',
contextualOnly: true,
addFields: [
{
type: 'area',
name: 'row',
label: 'row',
contextual: true
}
],
construct: function(self, options) {
var superPushAssets = self.pushAssets;
self.pushAssets = function() {
superPushAssets();
self.pushAsset('stylesheet', 'always', { when: 'always' });
};
}
};
TwoColumn
module.exports = {
extend: 'apostrophe-widgets',
label: 'Two column row Block',
contextualOnly: true,
addFields: [
{
type: 'area',
name: 'twoColumnRow',
label: 'twoColumnRow',
contextual: true
}
],
construct: function(self, options) {
var superPushAssets = self.pushAssets;
self.pushAssets = function() {
superPushAssets();
self.pushAsset('stylesheet', 'always', { when: 'always' });
};
}
};

does autocomplete works on multiple files

I am using EasyAautocomplete on my project. I was wondering if its possible to use autocomplete from 2 different file in one single searchbox. I have tried beyond the code but it reads only one of them:
<script>
var options = {
url: "file1.json",
getValue: "name",
list: {
match: {
enabled: true
}
},
theme: "square"
};
$("#KUNDE").easyAutocomplete(options);$('div.easy-autocomplete').removeAttr('style');
var options2 = {
url: "file2.json",
getValue: "name",
list: {
match: {
enabled: true
}
},
theme: "square"
};
$("#KUNDE").easyAutocomplete(options2);$('div.easy-autocomplete').removeAttr('style');
</script>
I recommend to you that:
Get json files at first
Merge them
Use them for autocomplete
The code is like:
$.getJSON("file1.json", function (data1) {
$.getJSON("file2.json", function (data2) {
var mergedData = $.extend({}, data1, data2);
var options = {
data: mergedData,
getValue: "name",
list: {
match: {
enabled: true
}
},
theme: "square"
};
$("#KUNDE").easyAutocomplete(options); $('div.easy-autocomplete').removeAttr('style');
});
});

enyo framework to integrate which raphael

I'm trying to integrate Raphael with enyo.js to create SVG component using Raphael instead of through enyo so i can use some of the Raphael functionality. I would like to replace the div that is rendered by default with it child component svg, i have created below jsfiddle. Can anyone help me fix it?
http://jsfiddle.net/stackit/uzjafamo/8/
Code
enyo.kind({
name: "Board",
kind: "enyo.Control",
paper: null,
create: function(){
this.inherited(arguments);
},
rendered: function(){
this.inherited(arguments);
if(this.hasNode()){
paper = Raphael(this.hasNode().id, 100, 100);
}
}
})
enyo.kind({
name: "pages",
kind: "enyo.Control",
create: function(){
this.inherited(arguments);
this.loadView();
},
loadView: function(){
if(!this.$.board){
var com = this.createComponent({
name: "board",
kind: "Board",
},{
owner: this
});
com.render();
}
}
});
new pages().renderInto(document.getElementById("cans"));
I looked at your fiddle and saw a little bit that could be improved. The jsFiddle container was giving me some trouble though initially, until I forked it for some reason.
Here's what I came up with: http://jsfiddle.net/Djspaceg/5qyLej05/4/
enyo.kind({
name: "Board",
kind: "enyo.Control",
paper: null,
create: function () {
this.inherited(arguments);
},
rendered: function () {
this.inherited(arguments);
if (this.hasNode() && !this.paper) {
this.generateRaphael();
}
},
generateRaphael: function () {
this.paper = Raphael(this.hasNode().id, 100, 100);
}
});
enyo.kind({
name: "pages",
kind: "enyo.Control",
create: function () {
this.inherited(arguments);
this.loadView();
},
loadView: function () {
if (!this.$.board) {
var com = this.createComponent({
name: "board",
kind: "Board",
});
com.render();
}
}
});
new pages().renderInto(document.getElementById("cans"));
It just generates an empty Raphael canvas.
Cheers!

ExtJS TaskRunner

I'm still in the learning process with EXTJS and any help would be much appreciated.
The goal for me is to load data into a grid where one cell needs to have the value incremented every minute. From my research using the TaskRunner function is the way to go but can't figure out where to put it and how to use it. My assumption is that it needs to go into the model or the controller but I'm not sure. In my simple project I'm using the MVC architecture.
Currently my gird works as expected. It reads in a file does a date conversion that produces a minute value. It's that minute value that I need to increment.
The code below is a sample TaskRunner snippit that I'm working with, right or wrong I don't know yet.
var runner = new Ext.util.TaskRunner();
var task = runner.newTask({
run: store.each(function (item)
{
var incReq = item.get('request') + 1;
item.set('request', incReq);
}),
interval: 60000 // 1-minute interval
});
task.start();
Model:
Ext.define("myApp.model.ActionItem", {
extend : "Ext.data.Model",
fields : [
{
name: 'pri',
type: 'int'
},
{
name: 'request',
type: 'int',
defaultValue: 0,
convert : function(v, model) {
return Math.round((new Date() - new Date(v)) / 60000);
}
}
]
});
Controller:
Ext.define("myApp.controller.HomeController", {
extend: "Ext.app.Controller",
id: "HomeController",
refs: [
{ ref: "ActionItemsGrid", selector: "[xtype=actionitemgrid]" },
{ ref: "DetailsPanel", selector: "[xtype=actionitemdetails]" }
],
pri: "",
models: ["ActionItem"],
stores: ["myActionStore"],
views:
[
"home.ActionItemDetailsPanel",
"home.ActionItemGrid",
"home.HomeScreen"
],
init: function () {
this.control({
"#homescreen": {
beforerender: this.loadActionItems
},
"ActionItemsGrid": {
itemclick: this.displayDetails
}
});
},
displayDetails: function (model, record) {
this.getDetailsPanel().loadRecord(record);
},
loadActionItems: function () {
var store = Ext.getStore("myActionStore");
store.load();
this.getActionItemsGrid().reconfigure(store);
}
});
View:
Ext.define("myApp.view.home.ActionItemGrid", {
extend: "Ext.grid.Panel",
xtype: "actionitemgrid",
resizable: true,
multiSelect: false,
enableDragDrop : false,
store: null,
columns:
[
{ header: "Pri", dataIndex: "pri", sortable: false, autoSizeColumn: true},
{ header: "Req", dataIndex: "request", sortable: false, autoSizeColumn: true}
],
viewConfig:
{
listeners: {
refresh: function(dataview) {
Ext.each(dataview.panel.columns, function(column) {
if (column.autoSizeColumn === true)
column.autoSize();
})
}
}
}
});
Sample JSON File:
{
"actionitems" : [
{
"pri": 1,
"request": "2014-12-30T03:52:48.516Z"
},
{
"pri": 2,
"request": "2014-12-29T05:02:48.516Z"
}
]
}
You have error in code which creates task - you should provide function to run configuration property, not result of invocation. Try this:
var runner = new Ext.util.TaskRunner();
var task = runner.newTask({
run: function() {
store.each(function (item)
{
var incReq = item.get('request') + 1;
item.set('request', incReq);
})
},
interval: 60000 // 1-minute interval
});
task.start();
You can put that code in loadActionItems method.

Sencha Touch Load a different View on click

This is my first attempt on Sencha Touch. So please excuse me if I am asking any silly questions.
I am trying to follow clean MVC pattern from Sencha. on Home page when user clicks I want to load AdboutView, I am not sure what is wrong in this code, but it doesn't fire "onGoToAboutMeCommand"
app.js
Ext.application({
name: "HaBoMobile",
models: ["HomeModel"],
stores: ["HomeStore"],
controllers:["HomeController"],
views: ["HomeView", "AboutView"],
launch: function () {
var homeLandingView = {
xtype: "LandingView"
};
var aboutView = {
xtype: "AboutView"
};
Ext.Viewport.add([homeLandingView, aboutView]);
}
});
HomeView.js
Ext.define("HaBoMobile.view.HomeView", {
extend: "Ext.navigation.View",
fullscreen:true,
requires: "Ext.form.FieldSet",
alias: "widget.LandingView",
config: {
//scrollable: 'vertical',
items: [
{
title: 'Harsha Bopuri',
padding: 10,
items: [
{
itemId: "aboutButton",
xtype: 'button',
text: 'About me',
handler: function () {
this.fireEvent("goToAboutMeCommand", this);
}
}
]
}
],
//Not sure when I have handler, if I still need listeners?
listeners: [
{
delegate: "#aboutButton",
event: "tap",
fn: "onAboutButtonTap"
}
]
},
onAboutButtonTap:function(){
this.fireEvent("goToAboutMeCommand", this);
},
onBackButtonTap: function () {
console.log("backToHomeCommand");
this.fireEvent("backToHomeCommand", this);
}
});
HomeController.js
Ext.define("HaBoMobile.controller.HomeController", {
extend: "Ext.app.Controller",
config: {
refs: {
homeView: "HomeView"
},
control: {
homeView: {
goToAboutMeCommand: "onGoToAboutMeCommand"
}
}
},
// Transitions
slideLeftTransition: { type: 'slide', direction: 'left' },
slideRightTransition: { type: 'slide', direction: 'right' },
// Commands.
onGoToAboutMeCommand: function () {
console.log("onBackToHomeCommand");
this.showAboutMe();
},
onBackToHomeCommand: function () {
console.log("onBackToHomeCommand");
this.shoHomePage();
},
showAboutMe: function () {
Ext.Viewport.animateActiveItem(this.getAboutView(), this.slideRightTransition);
},
shoHomePage: function () {
Ext.Viewport.animateActiveItem(this.getHomeView(), this.slideRightTransition);
},
// Base Class functions.
launch: function () {
this.callParent(arguments);
var homeStore = Ext.getStore("HomeStore");
homeStore.load();
console.log("launch");
},
init: function () {
this.callParent(arguments);
console.log("init");
}
});
I think the problem is in your refs section of your controller,refs takes key value pair.key can be any reference and while value is used in ComponentQuery.
I would suggest to add xtype in your HomeView.js file,like below.
Ext.define("HaBoMobile.view.HomeView", {
extend: "Ext.navigation.View",
xtype: 'HomeView',
//-----
Button handler that fires goToAboutMeCommand event runs in the scope of the button but in the controller you listen to homeView so the event is never caught.
This button handler should work:
handler: function (btn) {
var hv = btn.up('homeView');
hv.fireEvent("goToAboutMeCommand", hv);
}

Categories

Resources