I'm trying to set the height, width and background image of a <ul> element.
Here's what I've got for my Backbone.View:
var RackView = Backbone.View.extend({
tagName: 'ul',
className: 'rack unselectable',
template: _.template($('#RackTemplate').html()),
render: function () {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
attributes: function () {
var isFront = this.model.get('isFront');
var imageUrlIndex = isFront ? 0 : 1;
return {
'background-image': 'url(' + this.model.get('imageUrls')[imageUrlIndex] + ')',
'height': this.model.get('rows') + 'px',
'width': this.model.get('width') + 'px'
};
}
}
This doesn't work because the attributes are not written into a 'style' property of the element. Instead, they're treated like attributes... which makes sense because of the function name, but it has left me wondering -- how do I achieve something like this properly?
The image, height and width are immutable after being set, if that helps simplify...
Do I just wrap my return in a style? That seems overly convoluted...
Here's the generated HTML:
<ul background-image="url(data:image/png;base64,...)" height="840px" width="240px" class="rack unselectable">
</ul>
EDIT: This works, but I'm not stoked:
attributes: function () {
var isFront = this.model.get('isFront');
var imageUrlIndex = isFront ? 0 : 1;
var backgroundImageStyleProperty = "background-image: url(" + this.model.get('imageUrls')[imageUrlIndex] + ");";
var heightStyleProperty = "height: " + this.model.get('rows') + 'px;';
var widthStyleProperty = "width: " + this.model.get('width') + 'px;';
return {
'style': backgroundImageStyleProperty + ' ' + heightStyleProperty + ' ' + widthStyleProperty
};
},
You could just use the jquery css function in your render function:
render: function () {
this.$el.html(this.template(this.model.toJSON()));
var backgroundImageStyleProperty = "background-image: url(" + this.model.get('imageUrls')[imageUrlIndex] + ");";
var heightStyleProperty = "height: " + this.model.get('rows') + 'px;';
var widthStyleProperty = "width: " + this.model.get('width') + 'px;';
this.$el.css({
'height' : heightStyleProperty,
'width' : widthStyleProperty,
'background-image': backgroundImageStyleProperty
});
return this;
},
In Marionette, right in your view you can call:
onRender: function () {
this.$('yourElement').css('whatever', 'css');
},
The only way to do this is to pass in the attributes using a style attribute as described in the question. In backbone, the attribute map is passed directly into jQuery by this line of code:
var $el = Backbone.$('<' + _.result(this, 'tagName') + '>').attr(attrs);
So, there is no way to pass in styles as a Javascript object.
Related
I want to create modal in materialize dynamically.
this is my javascript code:
$(document).ready(function(){
var modalContainer = $('<div id="modal_id" class="modal"></div>');
var modalContent = $('<div class="modal-content"><p>my content</p></div>');
modalContainer.append(modalContent);
modalContainer.modal(); // or modalContainer.modal('open');
});
and this is my trigger button:
<a class="waves-effect waves-light btn modal-trigger" href="#modal_id">Show Modal</a>
but, this is not working. when i click to Show Modal anchor, show me the wrapper of modal and do not show modal box.
please help me. thanks.
You can do it with this simple approach. Create and an empty div with .modal class and whatever the id you want to assign.
Then in jQuery, create a variable and save a div with class modal-content. In that div specify your message or content, you want to add dynamically. After that, append that variable to modal using $(.modal).append() and open your modal using .modal()
Take a look at Example
I've created a jsfiddle take a look at it.
Demo - jsFiddle
Example
HTML
<a class="waves-effect waves-light btn modal-trigger" href="#modal1">Modal</a>
<div id="modal1" class="modal"></div>
jQuery
$(document).ready(function(){
// Here specify your content or message, enclose between <p>
var content = '<div class="modal-content"><p>my content</p></div>';
$('.modal').append(content);
$('.modal').modal();
});
You can open the modal on 1.0.0 using pure javascript like this
const elem = document.getElementById('modalId here');
const instance = M.Modal.init(elem, {dismissible: false});
instance.open();
I wrote a small class to create modals dynamically. Note that setting the height and width is a bit buggy, I don't really know why. I only need fixed-footer modals in my application, but that class could easily be set dynamically to fit your needs. Anyways, I hope it helps:
class Modal {
constructor(opt) {
this.name = opt.name;
this.width = opt.width || '';
this.height = opt.height || '';
this.topMargin = opt.height ? Math.floor((100 - this.height) / 2) : '';
this.style = (opt.width && opt.height) ? 'width: ' + this.width + '%; height: ' + this.height + 'vh; top: ' + this.topMargin + 'vh;' : opt.width ? 'width: ' + this.width + '%;' : opt.height ? 'height: ' + this.height + 'vh; top: ' + this.topMargin + 'vh' : '';
this.footerButtons = opt.footerButtons || '';
this.openButton = opt.openButton || null;
this.title = opt.title || '';
this.onOpen = opt.onOpen;
this.fixedContent = opt.fixedContent || '';
this.template = '<div id="' + this.name + '" class="modal modal-fixed-footer" style="' + this.style + '"><div class="modal-content" style="padding-top: 17px;"><h4>' + this.title + '</h4><div class="divider"></div><br>' + this.fixedContent + '<div class="modal-content-dynamic"></div></div><div class="modal-footer">' + this.footerButtons + '</div></div>';
$('.container').append(this.template);
var self = this;
if (this.openButton) {
$(document).on('click', this.openButton, function () {
self.open();
});
}
}
open() {
$('#' + this.name).openModal({
dismissable: false,
preventScrolling: false
});
if (this.onOpen) this.onOpen(this);
}
close() {
$('#' + this.name).closeModal();
}
setContent(content) {
$('#' + this.name).find('.modal-content-dynamic').html(content);
}
addContent(content) {
$('#' + this.name).find('.modal-content-dynamic').append(content);
}
setTitle(title) {
$('#' + this.name).find('.modal-content h4').html(title);
}
setFooterButtons(buttons) {
$('#' + this.name).find('.modal-footer').html(buttons);
}
}
And then use it like this:
var testModal = new Modal({
name: 'testModal',
openButton: '#open_testModal',
title: '<b>TestModal</b>',
fixedContent: '<p>Some static content</p>',
onOpen: function (modal) {
// do something every time the modal is opened
}
});
I'm trying to make a background slideshow using jQuery. I'm trying to have a hidden div (nextDiv) on the right of activeDiv slide nextDiv over activeDiv so that activeDiv will be overlapped by nextDiv. Once that is done, the background of nextDiv will then be changed to prepare for the new background image. Below is the code I have written.
// Scroll background
var bgClicked = false;
var bgList = [];
$(".bg-img").each(function(idx, el) {
bgList.push($(el).css('background-image').substr(4, 50));
bgList[idx] = bgList[idx].substr(0, bgList[idx].length -1);
});
var bgNum = bgList.length;
var bgNextDiv = $("#bg-next");
var bgActiveDiv = $("#bg-active");
var bgActive = 0;
var bgNext = 1;
// Scroll until clicked
console.log(bgList);
if(bgClicked == false) {
setInterval(function() {
$(bgList[bgNext]).animate({left:0}, 1000, 'linear', function() {
bgActiveDiv.css('background-image', 'url(' + bgList[bgNext] + ')');
bgActive = bgNext;
bgNext = bgNext < bgNum - 1 ? bgNext + 1 : 0;
bgNextDiv.css('background-image', 'url(' + bgList[bgNext] + ')');
});
}, 5000);
}
However, I'm getting
Uncaught Error: Syntax error, unrecognized expression: http://localhost:3000/img/bg2_2560x1440px.jpg`
when setting
bgActiveDiv.css('background-image', 'url(' + bgList[bgNext] + ')');
I think I missed something, but I don't know where.
Please help?
Cheers,
Agi
EDIT 1
Content of bgList = ["http://localhost:3000/img/bg1_2560x1440px.jpg", "http://localhost:3000/img/bg2_2560x1440px.jpg"]
You are using bgList[bgNext] as jQuery selector that is why you are getting error.
So, use this instead:
$(".bg-img:eq(" + bgNext + ")").animate({left:0}, 1000, 'linear', function() {
bgActiveDiv.css('background-image', 'url(' + bgList[bgNext] + ')');
bgActive = bgNext;
bgNext = bgNext < bgNum - 1 ? bgNext + 1 : 0;
bgNextDiv.css('background-image', 'url(' + bgList[bgNext] + ')');
});
I'm in a situation where i want to populate Model url from Model attributes dynamically
here is my code
var MailboxModel = Backbone.Model.extend({
defaults: {
key: 'inbox',
filter: 'date',
orderby: 'desc',
mailPageSize: 10,
pageOffSet: 0
},
url: window.sessionStorage.getItem('mail_link') + "/" + this.key + "?order_by=" + this.filter + "&order=" + this.orderby + "&offset=" + parseInt(this.pageOffSet) + "&count=" + this.mailPageSize
// the output will be http://website.com/rest/users/123456/mail/inbox?order_by=date&order=desc&offset=0&count=10
// instead output is "http://website.com/rest/users/1926856/mail/inbox?order_by=undefined&order=undefined&offset=NaN&count=undefined"
});
or this way? both not working
var mailboxmodel =new MailboxModel({});
mailboxmodel.set('key', sessionStorage.getItem('message_key'));
mailboxmodel.set('filter', 'subject');
mailboxmodel.set('orderby', 'desc');
mailboxmodel.set('mailPageSize', 10);
mailboxmodel.set('pageOffSet', 0);
var mailboxlist = new MailboxList({
model: new MailboxModel,
render: function(){
// render function is working fine
}
});
mailboxlist.render();
Backbone.history.start();
});
The reason why it isn't working is because at the point where you are setting the url property the default values haven't been set yet. To work around this you can use a function that returns the url instead.
For example
var MailboxModel = Backbone.Model.extend({
defaults: {
key: 'inbox',
filter: 'date',
orderby: 'desc',
mailPageSize: 10,
pageOffSet: 0
},
url: function () {
return window.sessionStorage.getItem('mail_link') + "/" + this.key + "?order_by=" + this.filter + "&order=" + this.orderby + "&offset=" + parseInt(this.pageOffSet) + "&count=" + this.mailPageSize;
}
});
You can also just set it in the initialize method
var MailboxModel = Backbone.Model.extend({
//...
initlaize: function (options) {
this.url = ....
}
});
I solve this problem in my solution passing all the values when I instantiate the model.
Like this.
url : /somePath/' + #key + '/' + #filter
initialize:(options)->
#key = options.key
#filter = options.filtes
// ....
getSomeThing:->
#fetch()
Hope it helps.
I have the following JS code that changes the width depending on value of the data-percentage HTML attribute:
var addRule = (function (sheet) {
if(!sheet) return;
return function (selector, styles) {
if (sheet.insertRule) return sheet.insertRule(selector + " {" + styles + "}", sheet.cssRules.length);
if (sheet.addRule) return sheet.addRule(selector, styles);
}
}(document.styleSheets[document.styleSheets.length - 1]));
var i = 101;
while (i--) {
addRule("[data-percentage='" + i + "%']", "width:" + i + "%");
}
See the demo: http://jsfiddle.net/YYF35/
Instead of width, for some elements I want to change their height.
How can I change the code so that depending on class of the div I change the height or width of element (depending on the data-percentage attribute number of course)?
I don’t want to create a different HTML attribute for it, like so:
while (i--) {
addRule("[data-percentage-width='" + i + "%']", "width:" + i + "%");
addRule("[data-percentage-height='" + i + "%']", "height:" + i + "%");
}
jQuery can be used as well. Any ideas?
Your code is adding rules. If you really want to be doing that, just add more rules:
var i = 101;
while (i--) {
addRule("[data-percentage='" + i + "%'].change-width", "width:" + i + "%");
addRule("[data-percentage='" + i + "%'].change-height", "height:" + i + "%");
}
Now, elements with the change-width class will have their width modified, and elements with the change-height class will have their height modified (and you can use both if you like).
Try this:
$("div[data-percentage]").each(function(){
$(this).css({
width: $(this).attr('data-percentage')
//height: $(this).attr('data-percentage')
});
});
http://jsfiddle.net/YYF35/1/
im trying to create this function in javascript but its not working, im a bit new to js, so i don't what im really doing wrong here.
the code:
<div id="test">TESTING</div>
JS:
function animateDiv(div){
var text = $('#' + div + '"').text();
var doAnimate = function() {
$('span').each(function() {
var that = $(this);
setTimeout(function() {
that.animate({ fontSize: "90px" }, 1500 )
.animate({ fontSize: "50px" }, 1500 );
},that.index()*100);
});
}
$('#' + div + "'").html('');
for(i=0; i<text.length; i++) {
$('#' + div + "'").append('<span>'+text[i]+'</span>');
if(i==text.length-1) doAnimate();
}
}
// using the function here to run animation on div test from html
animateDiv(test);
the jsfiddle is here: http://jsfiddle.net/aA8Un/3/
This works now
function animateDiv(div){
var text = $('#' + div.id).text();
var doAnimate = function() {
$('span').each(function() {
var that = $(this);
setTimeout(function() {
that.animate({ fontSize: "90px" }, 1500 )
.animate({ fontSize: "50px" }, 1500 );
},that.index()*100);
});
}
$('#' + div.id).html('');
for(i=0; i<text.length; i++) {
$('#' + div.id).append('<span>'+text[i]+'</span>');
if(i==text.length-1) doAnimate();
}
}
animateDiv(test);
Actually you were trying to concatenate a string and an object by this $("#"+div), which is wrong, you should do this $("#"+div.id) which is legal.
You have to call the function using single/double quotes like
animateDiv("test");
instead of
animateDiv(test);
And remove '"' from your code everywhere
So Make it $('#' + div + '"') to $('#' + div)
Working Demo
var text = $('#' + div + '"').text();
replace with
var text = $('#' + div).text();
animateDiv('test')
subsitute $('#' + div + '"') with $('#' + div)