I have a URL route that has a parameter whose value is not known ahead of time when the page is loaded. For example:
/read/book/page/:page
But when the user is selection screen they get to type in which page number they want to start on then click submit. Is it possible to catch this form submission and place it in the URL? Normally there is a question mark (?) right because its a GET request. But Backbone how can backbone catch that?
Demo:
http://jsfiddle.net/vpetrychuk/PT2tU/
JS:
var Model = Backbone.Model.extend({
url : function () {
return 'http://fiddle.jshell.net/echo/json?page=' + this.get('page');
},
// remove it
parse : function (response) {
response || (response = {});
response.justToTriggerChangeEvent = Math.random();
return response;
},
getPageContent : function () {
return 'Here should be page a content for page #' + this.get('page');
}
});
var View = Backbone.View.extend({
el : '[data-page]',
events : {
'submit' : 'submit'
},
initialize : function () {
this.listenTo(this.model, 'change', this.showPage);
},
showPage : function () {
this.$('[data-page-content]').html(this.model.getPageContent());
},
submit : function (e) {
e.preventDefault();
var page = this.$('[data-page-num]').val();
if (page) {
app.navigate('read/book/page/' + page, true);
}
}
});
var Router = Backbone.Router.extend({
routes : {
'read/book/page/:page' : 'page'
},
initialize : function (options) {
this.bookModel = options.bookModel;
},
page : function (page) {
this.bookModel.set('page', page);
this.bookModel.fetch();
}
});
var model = new Model();
var view = new View({model:model});
var app = new Router({bookModel:model});
Backbone.history.start();
HTML:
<div data-page>
<form>
<label><input type="text" data-page-num /></label>
<button type="submit">Submit</button>
</form>
<div data-page-content></div>
</div>
Related
I have a problem, I used a get and post function to retrieve and save some url in my database, but now I d like to update a variable count, that should rapresent the votes that every video get, and after that I shoul be able to disable the button that a user click to vote. So I'm having some troubles to make the update function, or I should use another post? But if so I probably create another element inside my DB or not?
so here there is my video and for now I set the video's id invisible using css, to test it and try to find the video with that specific id and make the update
<p class="invisible" id="idVideo"> {{item._id}} </p>
<iframe class="partecipant" v-bind:src="item.video.url"> </iframe>
<p id="voti" > {{item.voti.count}} </p>
<input type="button" id="buttonVoti" v-on:click="addVoto">
so here, when the user click the button with id= buttonVoti the v-on click call addVoto function
methods: {
...
//ALL THE OTHERS METHODS
...
...
...
//AND THEN THE ADDVOTO FUNCTION
addVoto : function () {
var self = this;
//self.videos[1].voti.count++
//console.log(self.videos._id);
var i = document.getElementById("idVideo");
var idVid =i.innerHTML;
console.log(idVid);
so here I can change the variable count, using self....count++ but I have to store and then retrieve again the same video with the new count updated.
here there is my model so the logic to access to the count should be this one
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var videoSchema = new Schema({
video : {
id : String,
url : String,
idchallenge : String
},
voti : {
count : {}
}
});
module.exports = mongoose.model('Video', videoSchema);
yes so I have a method called load video, that is activated when the user click a button called loadVideo
loadVideo : function (){
var linkYoutube = this.text;
console.log(linkYoutube);
//POST
axios.post('/video',{
method: 'post',
video: {
id: '1',
url: linkYoutube
},
voti: {
count: 0
}
});
and this is my get function,
getVideo: function () {
var self = this;
// Make a request for a user with a given ID
axios.get('/video')
.then(function (response) {
self.videos = response.data;
console.log(self.videos);
When you do you GET request to your video route, in your route logic, you should be able to use Mongoose count. Here is what that route might look like:
var Router = require('express').Router();
var mongoose = require('mongoose');
var Video = mongoose.model('Video');
Router.get('/videos', function(req, res) {
var response = {};
Video.find({}, function(queryErr, videos) {
if (!queryErr) {
response.videos = videos;
Video.count({}, function(countErr, count) {
if (!countErr) {
response.count = count;
res.status(200).send(response);
} else {
res.status(500).send(countErr);
}
});
} else {
res.status(500).send(queryErr);
}
});
});
module.exports = Router;
Here is a question about Mongoose count on Stack Overflow.
i need some help. I am trying to build a fancytree with url as source
var currentTree = $('#files_tree');
var urlBase = currentTree.attr("data-url");
currentTree.fancytree({
extensions: ["glyph", "dnd"],
glyph: {map: glyphIconClasses()},
// selectMode: 1,
source: {url: urlBase ,
data: {mode: "all"},
cache: false
},
activate: function (event, data) {
//data.node.render();
//show_edit_node_fnc(data.node.key);
//currentNodeToEdit = data.node;
id = data.node.data.id;
filesof = data.node.data.filesof;
list_files( filesof , id ) ; // Call to another JS function
},
and i make the content using php array, and send the request as json response
$arrFileTree['title'] = $project->name;
$arrFileTree['folder'] = true;
$arrFileTree['expanded'] = true;
$arrFileTree['activated'] = true;
$arrFileTree['data'] = array("filesof" => "project" , "id" => $project->id);
$arrSource = $project->sources ;
if($arrSource){
$arrChildren = array();
foreach($arrSource as $source){
$arNode['key'] = $source->id;
$arNode['title'] = $source->title;
$arNode['folder'] = true;
$arNode['data'] = array("filesof" => "source", "id" => $source->id);
$arrChildren[] = $arNode;
}
$arrFileTree['children'] = $arrChildren;
}
return array($arrFileTree);
what I need is, when i load the page for the first time, that an element be activated and the default "activate" function to be called on some value i assigned in php like ($arrFileTree['activated'] = true;)
So when i page loaded the "activate" function for a node will be called, and it will call my second function "list_files"
could anyone help me with this ?
Thanks
Wael
You could define the active state in the source data
...
$arrFileTree['active'] = true;
and trigger the activate event when the data was loaded:
$("#tree").fancytree({
source: {
...
},
init: function(event, data) {
data.tree.reactivate();
},
I have a button in and it is used for calling a dialog. Dialog's content is a pdf got from jasper report.
Here is the backbone view of dialog :
var framSrc = getRSUR; //getting pdf from jasper reporting server
var ReportView = Backbone.View.extend({
tagName : "div",
id : "report",
initialize: function() {
},
events : {
'click #print' : 'printDialog'
},
'printDialog' : function(){
printReport();
},
render: function(){
this.$el.html('<div><a id="print"><img src="printer.png" width="30px"><span style="position:relative;bottom:10px; left:10px;">Print Report</span></a></div><iframe id="agingFrame" src="'+framSrc+'"></iframe>');
return this;
}
});
printReport() :
function printReport(){
try{
var oIframe = document.getElementById('agingFrame');
var oContent = document.getElementById('agingFrame').innerHTML;
var oDoc = (oIframe.contentWindow || oIframe.contentDocument);
if (oDoc.document) oDoc = oDoc.document;
oDoc.write("<html><head><title>title</title>");
oDoc.write("</head><body onload='this.focus(); this.print();'>");
oDoc.write(oContent + "</body></html>");
oDoc.close();
}
catch(e){
self.print();
}
}
But what I've got from printing is the full page of the web page, not the pdf content in iframe.
I am trying to explicitly get the system properties from my table but it is not working. I can see that the URL is returning all the data including these fields if I use https://myservice.azure-mobile.net/tables/todoitem?__systemProperties=* but on the code I cannot get it as item.__version or item.version. I have tried adding todoitemtable = WindowsAzure.MobileServiceTable.SystemProperties.All; but no success! I have also looked at http://azure.microsoft.com/en-us/documentation/articles/mobile-services-html-validate-modify-data-server-scripts/ but this is adding a new column instead of using the existing system columns.
$(function() {
var client = new WindowsAzure.MobileServiceClient('https://ib-svc-01.azure-mobile.net/', 'key');
var todoItemTable = client.getTable('todoitem');
// = WindowsAzure.MobileServiceTable.SystemProperties.All;
// Read current data and rebuild UI.
// If you plan to generate complex UIs like this, consider using a JavaScript templating library.
function refreshTodoItems() {
var query = todoItemTable.where({ complete: false });
query.read().then(function(todoItems) {
var listItems = $.map(todoItems, function(item) {
return $('<li>')
.attr('data-todoitem-id', item.id)
.append($('<button class="item-delete">Delete</button>'))
.append($('<input type="checkbox" class="item-complete">').prop('checked', item.complete))
.append($('<div>').append($('<input class="item-text">').val(item.id))
.append($('<span class="timestamp">'
+ (item.createdAt && item.createdAt.toDateString() + ' '
+ item.createdAt.toLocaleTimeString() || '')
+ '</span>')));
});
$('#todo-items').empty().append(listItems).toggle(listItems.length > 0);
$('#summary').html('<strong>' + todoItems.length + '</strong> item(s)');
}, handleError);
}
function handleError(error) {
var text = error + (error.request ? ' - ' + error.request.status : '');
$('#errorlog').append($('<li>').text(text));
}
function getTodoItemId(formElement) {
return $(formElement).closest('li').attr('data-todoitem-id');
}
// Handle insert
$('#add-item').submit(function(evt) {
var textbox = $('#new-item-text'),
itemText = textbox.val();
if (itemText !== '') {
todoItemTable.insert({ text: itemText, complete: false }).then(refreshTodoItems, handleError);
}
textbox.val('').focus();
evt.preventDefault();
});
// Handle update
$(document.body).on('change', '.item-text', function() {
var newText = $(this).val();
todoItemTable.update({ id: getTodoItemId(this), text: newText }).then(null, handleError);
});
$(document.body).on('change', '.item-complete', function() {
var isComplete = $(this).prop('checked');
todoItemTable.update({ id: getTodoItemId(this), complete: isComplete }).then(refreshTodoItems, handleError);
});
// Handle delete
$(document.body).on('click', '.item-delete', function () {
todoItemTable.del({ id: getTodoItemId(this) }).then(refreshTodoItems, handleError);
});
// On initial load, start by fetching the current data
refreshTodoItems();
});
I was trying to access the system properties from within the API scripts and found this and thought it was useful and relevant: http://www.brandonmartinez.com/2014/10/22/retrieve-system-properties-in-azure-mobile-services-javascript-backend/
Basically you can do this (example from the post):
myTable.read({
systemProperties: ['__createdAt', '__updatedAt'],
success: function(tableEntries) {
// So on and so forth
}
}
I'm using Kendo UI Mobile via Icenium Extension for Visual Studio. I'm very new at this, but I'm stumbling along. I've written a method (called popDataSource) in a view that gets some data (reads the names of files in a folder) and returns those file names. The method works perfectly if I wire it up to a button click event, but what I really want is for the method to be called when the page first loads. I've tried setting data-show=popDataSource and even data-after-show=popDataSource, but when I do that I get the error Object [object Object] has no method 'set' when I try to return the data. I'm also not that well versed in javascript, which I'm sure isn't helping me any.
Here's my code:
Snippet from index.html:
<div id="tabstrip-listSonicImages" data-role="view" data-title="Sonic Images List" data-model="app.listSonicImagesService.viewModel"
data-after-show="app.listSonicImagesService.viewModel.popDataSource">
<div data-role="content" class="view-content">
<div data-role="scroller">
<div class="buttonArea">
<a id="btnShowList" data-role="button" data-bind="click: popDataSource"
class="login-button">Display List</a>
</div>
<ul class="forecast-list" data-role="listview" data-bind="source: sonicImagesDataSource" data-template="sonic-image-list-template">
</ul>
</div>
</div>
</div>
<script type="text/x-kendo-tmpl" id="sonic-image-list-template">
<a data-role="listview-link" href="\#tabstrip-playSonicImage?fileName=${fileName}">${fileName}</a>
</script>
listiconimages.js
(function(global) {
var SonicImageListViewModel,
app = global.app = global.app || {};
SonicImageListViewModel = kendo.data.ObservableObject.extend({
popDataSource: function () {
var that = this;
var listSI = new Array();
try{
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,
function (fileSys) {
fileSys.root.getDirectory("SIData", { create: true, exclusive: false},
function (dataDirEntry) {
var directoryReader = dataDirEntry.createReader ();
directoryReader.readEntries(
function (entries) {
var rows = entries.length;
for (i = 0; i < rows; i++) {
var fName = entries[i].name;
listSI[i] = { "fileName": fName, "image": "xxx" };
}
},
function (error) {
alert("error: " + error.code);
}
);
},
null);
},
null
);
var dataSource = new kendo.data.DataSource(
{
data: listSI,
filter: { field: "fileName", operator: "endswith", value: ".simg" }
}
);
that.set("sonicImagesDataSource", dataSource);
} catch (ex) {
alert(ex.message);
}
}
});
app.listSonicImagesService = {
viewModel: new SonicImageListViewModel()
};
}
)(window);
app.js
(function (global) {
var mobileSkin = "",
app = global.app = global.app || {};
document.addEventListener("deviceready", function () {
app.application = new kendo.mobile.Application(document.body, { layout: "tabstrip-layout" });
}, false);
app.changeSkin = function (e) {
if (e.sender.element.text() === "Flat") {
e.sender.element.text("Native");
mobileSkin = "flat";
}
else {
e.sender.element.text("Flat");
mobileSkin = "";
}
app.application.skin(mobileSkin);
};
})(window)
As I said, I'm new to Icenium and Kendo, and my javascript knowledge is limited, so I'm not quite sure where the answer lies. Any help would be greatly appreciated.
Thanks