Setting scroller on template element - backbone.js

I am using mobiscroll with underscore. I have an underscore template. I need to do the .scroller on an element added from the template.
Here is the template:
<form>
<input type="text" id="startdate" name="startdate"/>
</form>
Here is the render function in the view:
var MyView = Backbone.View.extend({
template: render('auctioncreate'),
render: function() {
this.$el.empty().append(this.template);
$('#startdate').scroller(); // this does not work
}
});
render is a function that loads the html and makes it into a template. For completeness, here is the code for the render function:
function render(tn, td) {
if(!render.tc) {
render.tc = {};
}
if(! render.tc[tn]) {
var td = 'assets/js/templates';
var tu = td + "/" + tn + ".html";
var ts;
$.ajax({
url: tu,
method: 'GET',
async: false,
dataType: 'html',
success: function(d) {
ts = d;
},
error: function(e) {
}
});
render.tc[tn] = ts;
}
return _.template(render.tc[tn]);
}
I have tried adding a ondomready javascript in the template itself. It does not work straight away, but it does work after a refresh?!
$(function() {
$('#startdate').scroller(); // this work if I refresh once.
});
Basically I need to apply the datetime picker on the element after it gets appended to the dom.

The error was in the render function of the View.
Instead of:
$('#startdate')...
It should have been:
this.$('#startdate')...

Related

Masonry + Custom Infinite Scroll + Responsive Grid Width = Overlap with other page content on page resize?

I am working with Masonry on a shopify demo store, where we are also using an adaptation of infinite scroll to load products instead of having to paginate them. This all works fine until I try to resize the page and masonry re-calculates the height of the masonry div. It does this but only includes the height of the elements loaded on first page load, rather than all the elements that have loaded on scroll.
Here is my code:
$(document).ready(function () {
var $container = $('#container');
var msnry = new Masonry( container, {
itemSelector: '.item'
});
// initialize
$('#container').imagesLoaded( function(){
$container.masonry({
itemSelector: '.item'
});
});
// infinite Scroll
var pInfScrLoading = false;
var pInfScrDelay = 200;
function pInfScrExecute() {
if($(window).scrollTop() >= (($("#product-list-foot").offset().top)-800)){
var loadingImage;
pInfScrNode = $('.more').last();
pInfScrURL = $('.more a').last().attr("href");
if(!pInfScrLoading && pInfScrNode.length > 0 && pInfScrNode.css('display') != 'none') {
$.ajax({
type: 'GET',
url: pInfScrURL,
beforeSend: function() {
pInfScrLoading = true;
loadingImage = pInfScrNode.clone().empty().append('<img src=\"http://cdn.shopify.com/s/files/1/0068/2162/assets/loading.gif?105791\" />');
loadingImage.insertAfter(pInfScrNode);
pInfScrNode.hide();
},
success: function(data) {
// remove loading feedback
pInfScrNode.next().remove();
var filteredData = $(data).find(".item");
$('#container').imagesLoaded( function(){
filteredData.appendTo( $("#container") );
msnry.appended(filteredData);
});
var newLink = $(data).find(".more");
newLink.appendTo( $("#container") );
loadingImage.remove();
pInfScrLoading = false;
},
dataType: "html"
});
}
}
}
$(document).ready(function () {
$(window).scroll(function(){
console.log(($("#product-list-foot").offset().top)-200);
$.doTimeout( 'scroll', pInfScrDelay, pInfScrExecute);
if($(window).scrollTop() >= (($("#product-list-foot").offset().top)-800)){
pInfScrDelay = 200;
}
});
});
});
And here is a link to the demo page: http://sweetpea-bicycles.myshopify.com/collections/accessories
Again, the problem only happens when you make the screen smaller or larger to make the grid width change.
You need re-call Masonry function again for next pages. You input that code after "pInfScrLoading = false;"
Example:
function pInfScrExecute() {
if($(window).scrollTop() >= (($("#product-list-foot").offset().top)-800)){
var loadingImage;
pInfScrNode = $('.more').last();
pInfScrURL = $('.more a').last().attr("href");
if(!pInfScrLoading && pInfScrNode.length > 0 && pInfScrNode.css('display') != 'none') {
$.ajax({
type: 'GET',
url: pInfScrURL,
beforeSend: function() {
pInfScrLoading = true;
loadingImage = pInfScrNode.clone().empty().append('<img src=\"http://cdn.shopify.com/s/files/1/0068/2162/assets/loading.gif?105791\" />');
loadingImage.insertAfter(pInfScrNode);
pInfScrNode.hide();
},
success: function(data) {
// remove loading feedback
pInfScrNode.next().remove();
var filteredData = $(data).find(".item");
$('#container').imagesLoaded( function(){
filteredData.appendTo( $("#container") );
msnry.appended(filteredData);
});
var newLink = $(data).find(".more");
newLink.appendTo( $("#container") );
loadingImage.remove();
pInfScrLoading = false;
<!--INPUT IN HERE-->
},
dataType: "html"
});
}
}
}
Good luck for you!

Angular directive not rendering dynamically

I'm using angular directive with jquery datatables, in the mRender function I used the following code to render row actions:
datatables mRender function:
var renderRowActions = function (data, type, row) {
//var markup = $('#rowActions').html().replace(/{rowId}/g, row[0]);
var markup = '<div row-actions action="delete(" + row[0] + ")" ></div>';
return markup;
};
directive code:
app.directive('rowActions', function () {
return {
restrict: 'A',
replace: true,
template: '<button data-ng-click="action()"></button>',
scope: {
action: "&"
}
};
});
This question is old as dirt, but here goes.... For my directive called "spinner":
{
className: 'spinner-control',
orderable: false,
data: null,
render: function (data, type, row, meta) {
return '<spinner ng-model="accounts['+meta.row+'].alloc" ng-format="percentage" width="75px" step="0.5"></spinner>';
}
}
You can then update the jQuery after the fact and replace the innerHTML with the compiled element. Code is written "long form" to make it obvious what it's doing.
$('.spinner-control').each(function(){
var innerHTML = $(this);
console.log("InnerHTML", innerHTML);
var html = $compile(innerHTML)($scope);
console.log("HTML", html);
$(this).innerHTML = '';
$(this).append(html);
});

Re-binding a tree (Wijmo tree) with AngularJS

I am fairly new to AngularJS, and really struggling to re-bind a Wijmo tree (or even a tree implemented using UL and LI elements wth ng-repeat) with new data on changing of value of a Wijmo combobox (or, even a regular dropdown of HTML select elem).
Below is the code I have written, which is working fine in initial page load. But on changing the dropwdown, the tree is not being reloaded with new data fetched by loadDomainTree method; it is still showing old data. Can somebody help me figure out what's wrong with this code?
HTML:
<div ng-controller="DomainCtrl">
<select id="domain" ng-model="currentDomain" ng-options="item.Name for item in domainList"></select>
<div>
<ul id="wijtree">
<li ng-repeat="item in domainEntityList" id={{item.Id}}>
<a>{{item.Name}}</a>
</li>
</ul>
</div>
</div>
JS:
$(document).ready(function ()
{
$("#domain").wijcombobox({
isEditable: false
});
$("#wijtree").wijtree();
});
function DomainDropdownModel(data) {
this.Id = data.Id.toString();
this.Name = data.Name;
};
function DomainTreeModel(data) {
this.Id = data.Id;
this.Name = data.Name;
};
function DomainCtrl($scope, $locale) {
$scope.domainList = [];
$.ajax({
url: dropDownUrl,
async: false,
success: function (data) {
$(data).each(function (i, val) {
var domain = data[i];
var domainId = domain.Id.toString();
var domainName = domain.Name;
$scope.domainList.push(new DomainDropdownModel({ Id: domainId, Name: domainName }));
});
}
});
$scope.currentDomain = $scope.domainList[0];
$scope.loadDomainTree = function (domainId) {
domainEntitiesUrl = DOMAIN_API_URL + DOMAIN_ID_PARAM + domainId;
//alert(domainEntitiesUrl);
$scope.domainEntityList = [];
$.ajax({
url: domainEntitiesUrl,
async: false,
success: function (data) {
$(data).each(function (i, entity) {
var domainEntity = data[i];
var domainEntityId = domainEntity.Id.toString();
var domainEntityName = domainEntity.Name;
$scope.domainEntityList.push(new DomainTreeModel({ Id: domainEntityId, Name: domainEntityName }));
});
}
});
};
//Will be called on setting combobox dfault selection and on changing the combobox
$scope.$watch('currentDomain', function () {
$scope.loadDomainTree($scope.currentDomain.Id);
});
}
You may $watch for the selectedItem of WijCombobox and then, re-load the wijtree accordingly. Here is the code:
$scope.$watch('selectedItem', function (args) {
if (args === 'Tree 1') {
$("#wijtree").wijtree("option", "nodes", $scope.nodes1);
}
else {
$("#wijtree").wijtree("option", "nodes", $scope.nodes2);
}
});
HTML Code
<wij-combobox data-source="treeList" selected-value="selectedItem">
<data>
<label bind="name"></label>
<value bind="code"></value>
</data>
</wij-combobox>

Two way Databinding with Angular-UI Select2 with Ajax functionality

Two way Databinding with AngularJS + Angular-UI Select2 with Ajax functionality.
I created a directive to implement Select2 dropdown Ajax behavior in Generic way:- (It requires few attributes to get formatResult, formatSelection methods to call, and url).
My problem is how to load value in "Edit Mode", selected value from dropdown is received in formatselection method, but while loading the screen, I want to load the dropdown from the same value to which it is binded.
Example:-
<input type="hidden" for="part" class="bigdrop" style="width: 250px" formatresult="partFormatResult" formatselection="partFormatSelection" aurl="/api/Part" search-drop-down ui-select2="configPartSelect2" ng-model="product.SalesPart" data-placeholder="Select Part" ng-change="onPartSelect();" />
Directive Code
One23SRCApp.directive('searchDropDown', ['$http', function (http) {
return function (scope, elm, attrs) {
var raw = elm[0];
var fetchFuncName = "fetch" + attrs["uiSelect2"];
console.log("Directive load pat " + scope[attrs["ngModel"]]);
scope[fetchFuncName] = function (queryParams) {
var result = http.get(queryParams.url, queryParams.data).success(queryParams.success);
result.abort = function () {
return null;
};
return result;
};
scope[attrs["uiSelect2"]] = {
minimumInputLength: 3,
initSelection: scope[attrs["initselection"]],
ajax: {
url: attrs["aurl"],
data: function (term, page) {
return { params: { isStockable: true, query: term, pageNo: page, pageSize: 20 } };
},
dataType: 'json',
quietMillis: 100,
transport: scope[fetchFuncName],
results: function (data, page) {
var more = (page * 20) <= data.length; // whether or not there are more results available
return { results: data, more: more };
}
},
formatResult: scope[attrs["formatresult"]],
formatSelection: scope[attrs["formatselection"]],
dropdownCssClass: "bigdrop" // apply css that makes the dropdown taller
};
return { bind: attrs["ngModel"] };
};
}]);
//inside controller-
after loading of data
$("#partDD").select2("val", product.SalesPart);
//$scope.partInitSelection definition.
$scope.partInitSelection = function (element, callback) {
if (! $scope.PartList) {
$scope.PartList = [$scope.product.SalesPart];
} else {
$scope.PartList.push($scope.product.SalesPart);
}
callback($scope.product.SalesPart);
};
}
Fixed it finally:-
As i kept configuration object in scope[attrs["uiSelect2"]],
I called the .ajax.data method of above configuration object each time I load data.
scope[attrs["uiSelect2"]].ajax.results(product.SalesPart.text, 1);

Backbone.js routes don't fire correctly

My code is as follow:
var AppRouter = Backbone.Router.extend({
_data: null,
_length: 0,
_index: null,
_todos: null,
routes: {
"*action": "index",
"category/:name": "hashcategory"
},
initialize: function(options){
this._data = options.data;
this._todos = new TodosCollection(options.data);
this._length = this._todos.length;
this._index = new CategoriesView({collection: this._todos});
},
index: function(){
this._index.render();
},
hashcategory: function(name){
console.log('started');
}
});
initializeRouter = function (router) {
Backbone.history.start({ pushState: true });
$(document).on('click', 'a:not([data-bypass])', function (evt) {
var href = $(this).attr('href');
var protocol = this.protocol + '//';
if (href.slice(protocol.length) !== protocol) {
evt.preventDefault();
router.navigate(href, true);
}
});
return router;
};
var start = function(){
p = $.ajax({
url: 'data/todolist.json',
dataType: 'json',
data: {},
success: function(data) {
var approuter = initializeRouter(new AppRouter({data: data}));
}
});
};
I have a <a> link in my html which has a href = "category/num1" attibute. But every time I click the link, it always shows a security error in firebug. Actually I just have one index.html page, what I want to do is append a string to it to make a fake html page like folder/index.html/category/num1 and all of the things will still be rendered in current page. But the url shown to me when the link is hovered is folder/category/num1. Because this path actually doesn't exist in my folder, I think that's why it shows a security error.
So how should I fix it? Should I create another html page and the corresponding folder? Or can I make all of the routing in one index.html page?
Try putting a # in the href, like
href = "#category/num1"

Resources