javascript - jQuery mobile: links have improper format on first load? -
i'm learning jqm , backbone.js
, have few problems. im making recipe app following todo list example trying blend them both.
anyway can't refresh page besides first one, i'm getting undefined variables. believe has dom , many views have. secondly upon entering recipe search query api, displays results first plain links!
if got forward page or page , return results page display links should jqm style. because couldn't figure how or append in js, did in html.
i know long shot can give me guidance hell i'm doing wrong, general advice, anything?
var todo = backbone.model.extend({ defaults: function() { return { id: 0, title: 'defaultname', imgurl: 'defaultimageurl', order: searchtemp.nextorder(), rating: 0, timetomake: '', salty: 0, sour: 0, sweet: 0, bitter: 0, isperm: false, taggedforlist: false }; }, initialize: function(){ if( !this.get('ingrs') ){ this.set({ingrs: new array()}); } }, savemodel: function() { this.set({isperm: true}); this.save(); } }); var todolist = backbone.collection.extend({ model: todo, localstorage: new backbone.localstorage("searchtemp"), initialize: function() { }, nextorder: function() { if (!this.length) return 1; return this.last().get('order') + 1; }, comparator: 'order', taggedforlist: function() { return this.where({taggedforlist: true}); }, remaining: function() { return this.without.apply(this, this.taggedforlist); }, findrecipes: function(thequery) { console.log("findrecipes called"); searchtemp.each(function (model) { if (!model.isperm) { model.destroy(); } }); $.ajax({ url: 'http://api.yummly.com/v1/api/recipes?_app_id=d8087d51&_app_key=005af5a16f1a8abf63660c2c784ab65f&maxresult=5&q='+thequery, datatype: 'jsonp', success: function(apistuff){ var result = new array(); result = apistuff; //saves api's response new array result = result.matches; //trims information json object, has information on various recipes $.each(result, function(i, item) { var anotherrecipe= new todo(); // makes new model each result anotherrecipe.set({ id: result[i].id, //then sets attributes title: result[i].recipename, ingrs: result[i].ingredients, imgurl: result[i].smallimageurls, rating: result[i].rating, timetomake: result[i].totaltimeinseconds, }); //not recipes support flavor ratings, error catching must used avoid setting null values try { anotherrecipe.set({ salty : result[i].flavors.salty }); } catch(e) {anotherrecipe.set({salty : "?"});} //maybe replace error condition setting flavor '?' try { anotherrecipe.set({ sour: result[i].flavors.sour }); } catch(e) {anotherrecipe.set({sour : "?"});} try { anotherrecipe.set({ sweet: result[i].flavors.sweet }); } catch(e) {anotherrecipe.set({sweet : "?"});} try { anotherrecipe.set({ bitter: result[i].flavors.bitter }); } catch(e) {anotherrecipe.set({bitter : "?"});} searchtemp.add(anotherrecipe); //adds model temporary }); } //eventually, should add checks empty search result, appending warning if happens }); // console.log("search done"); } }); var shopitem = backbone.model.extend({ defaults: function() { return { ingr : 'ingredient', done : false } }, toggle: function() { this.save({taggedforlist: !this.get("taggedforlist")}); } }); var shoplist = backbone.collection.extend({ localstorage: new backbone.localstorage("grocery-list"), generate: function() { console.log("shop list! asssssemmmmblllllle!"); searchtemp.fetch(); var ingrlist = searchtemp.pluck('ingrs'); //this returns array of arrays console.log(ingrlist); ingrlist = _.union(ingrlist); //this needs series of arrays ( _.union(array1, array 2); ) console.log(ingrlist); }, getlist: function() { var list = new array(); list = this.tojson(); return list; } }); var todos = new todolist; //i afraid move this, 95% sure obsolete, though /* var savedrecipesview = backbone.view.extend({ tagname: "li", initialize: function() { this.render(); this.listento(this.model, 'change', this.render); this.listento(this.model, 'destroy', this.remove); }, render: function() { var template = _.template( $("#list_item").html(), {} ); this.$el.html( template ); //this.$el.html(this.template(this.model.tojson())); //this.$el.toggleclass('done', this.model.get('done')); //this.input = this.$('.edit'); //return this; }, events: { "click input[type=button]": "sendtogroceries" }, sendtogroceries: function() { var temp = new array(); temp = this.tojson(); $.each(temp, function(i, item) { var shopitem = new shopitem(); shopitem.set({ name: temp[i].title }); shoppinglist.add(shopitem); //use pluck [ingrs] shopitem.save(); }); } }); */ window.homeview = backbone.view.extend({ template:_.template($('#home').html()), render:function (eventname) { $(this.el).html(this.template()); return this; } }); window.newsearchview = backbone.view.extend({ template:_.template($('#newsearch').html()), //this vaguely works, causes visual chaos first run through, //still relies on appending initialize: function() { console.log(searchtemp); //searchtemp.bind('searchdone', this.render, this); searchtemp.bind('add', this.render, this); }, render:function (eventname) { var temp = new array(); // think line isnt doing anyting results = searchtemp.tojson(); // console.log(results); var variables = { recipes: results }; $(this.el).html(this.template()); return this; }, events: { "keypress #recipe-search": "searchonenter", //add listener newsearch change what's displaye don list }, searchonenter: function(e) { //the search bar's functionality if (e.keycode != 13) return; var searchin = $("input[id='recipe-search']").val(); console.log("searched - "+ searchin); //this function in todolist, api call , //adds new model each result (there 5 results) searchtemp.findrecipes(searchin); } }); window.newlistview = backbone.view.extend({ template : _.template($('#newlist').html()), initialize: function() { }, render:function (eventname) { recipe = this.model.tojson(); ///incomplete, modify newlist accept straight json var variables = { recipe_name : this.model.get("title"), img_url : this.model.get("imgurl"), timetomake: this.model.get("timetomake"), ingrs : this.model.get("ingrs"), rating : this.model.get("rating"), salty : this.model.get("salty"), sour : this.model.get("sour"), sweet : this.model.get("sweet"), bitter : this.model.get("bitter") }; $(this.el).html(this.template(variables)); return this; }, events: { "click #save-this": "savemodel" }, savemodel: function() { console.log("savemodel() called"); //console.log(permstorage.taggedforlist()); //shift model on permstorage //searchtemp.remove(this.model); //console.log(this.model); this.model.savemodel(); //console.log(this.model) //now save permstorage local storage searchtemp.each(function (model) { if(model.isperm) { model.save(); } }); } }); window.savedrecipesview = backbone.view.extend({ template:_.template($('#savedrecipes').html()), initialize: function() { console.log("about fetch local storage..."); searchtemp.fetch(); console.log("...fetched!"); }, render:function (data) { results = searchtemp.tojson(); //results = results.models; //console.log(results); var variables = { results: results }; _.each(data, function(task) { console.log("meow"); this.addone(task); }, this); $(this.el).html(this.template(variables)); return this; }, addone: function(task) { var view = new listitemview({ model:task }); $(this.el).append( view.render().el ); } }); window.listitemview = backbone.view.extend({ tagname: 'li', template:_.template($('#list-item').html()), initialize: function() { _.bindall(this, 'render'); this.model.bind('change', this.render); this.model.view = this; }, events: { "click input[type=button]" : "onclick" }, render: function() { $(this.el).html(this.template(this.model.tojson())); this.setcontent(); return this; }, onclick: function(){ searchtemp.add(this.model); console.log("model added searchtemp, current state of searchtemp:"); console.log(searchtemp); } }); window.oldlistview = backbone.view.extend({ template:_.template($('#oldlist').html()), render: function (eventname) { $(this.el).html(this.template()); return this; } }); window.deleteoldview = backbone.view.extend({ template:_.template($('#deleteold').html()), render: function (eventname) { $(this.el).html(this.template()); return this; } }); window.shoppinglistview = backbone.view.extend({ template:_.template($('#shoppinglist').html()), initialize: function() { shoplist.generate(); }, render: function (eventname) { var variables = { }; $(this.el).html(this.template(variables)); return this; } }); var approuter = backbone.router.extend({ routes:{ "":"home", "newsearch":"newsearch", "newlist/:id":"newlist", "savedrecipes":"savedrecipes", "oldlist":"oldlist", "deleteold":"deleteold", "shoppinglist":"shoppinglist" }, initialize:function () { // handle button throughout application $('.back').live('click', function(event) { window.history.back(); return false; }); this.firstpage = true; }, home:function () { this.changepage(new homeview()); }, newsearch:function () { this.changepage(new newsearchview()); }, newlist:function (theid) { var tempmodel = searchtemp.get(theid); this.changepage(new newlistview({ model: tempmodel, id: theid })); //console.log(permstorage.taggedforlist()); }, savedrecipes:function () { this.changepage(new savedrecipesview()); }, oldlist:function () { this.changepage(new oldlistview()); }, deleteold:function () { this.changepage(new deleteoldview()); }, shoppinglist:function () { this.changepage(new shoppinglistview()); }, changepage:function (page) { $(page.el).attr('data-role', 'page'); page.render(); $('body').append($(page.el)); var transition = $.mobile.defaultpagetransition; // don't want slide first page if (this.firstpage) { transition = 'none'; this.firstpage = false; } $.mobile.changepage($(page.el), {changehash:false, transition: transition}); } }); $(document).ready(function () { console.log('document ready'); app = new approuter(); backbone.history.start(); searchtemp = new todolist(); //this stores searched recipes, rename myrecipes shoplist = new shoplist(); }); <!doctype html> <html class="ui-mobile-rendering"> <head> <title>recilist</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="css/jquery.mobile-1.0.1.min.css"/> <!-- templates --> <script type="text/template" id="home"> <div data-role="header" > <h1 style="color:black">recilist home</h1> </div> <img src="store.jpg" id="vege"> <div data-role="content" style="color:red"> <!-- <h3>recilist home page</h3> <p>welcome recilist!</p> <p>this home page. </p> --> <h1>save recipes & <br/> create shopping <br/> lists anywhere</h1> <p class="blurb">create , manage grocery shopping list, find , <br/>save favorite recipes across web,<br/> great savings , share entire family - freeee!!!!</p> <ul data-role="listview" id="choices" data-inset="true"> <li><a style="color:red" href="#newsearch">search new recipes</a></li> <li><a style="color:red" href="#savedrecipes">view saved recipes</a></li> </ul> </div> <div data-role="footer" class="ui-bar" id ="footer"> <h5 style="color:black"> powered <img src="http://static.yummly.com/api-logo.png"> </h5> </div> </script> <script type="text/template" id="newsearch"> <div data-role="header"> <h1 style="color:black">search new recipe</h1> </div> <div data-role="content"> <input name= "recipe-search" id="recipe-search" data-icon="search" type="text" placeholder="what want cook?"> <ul id="search-list" data-role="listview" data-inset="true"> <% for(var in results) { %> <li> <img src="<%= results[i].imgurl %>"> <a href="#newlist/<%= results[i].id%>"><%= results[i].title %> </a> </li> <% } %> </ul> </div> <img src="list.png" id="list"> <div data-role="footer" class="ui-bar"> <a href="#" data-icon="back" class="back ui-btn-left">back</a> <a href="#" data-icon="home">home</a> </div> </script> <script type="text/template" id="newlist"> <div data-role="header"> <h1 style="color:black"> <%=recipe_name%> </h1> </div> <div> <div data-role="content"> <img src= <%=img_url%> > <h4>recipe rating: <%= rating %> </h4> <h4>total time prepare: <%= timetomake %> </h4> <h4>flavor ratings</h4> <div class="ui-block-a"> <div class="ui-bar ui-bar-e"> <h4>saltiness</h4> <%= salty %> </div> </div> <div class="ui-block-b"> <div class="ui-bar ui-bar-e"> <h4>sourness</h4> <%= sour %> </div> </div> <div class="ui-block-c"> <div class="ui-bar ui-bar-e"> <h4>sweetness</h4> <%= sweet %> </div> </div> <div class="ui-block-d"> <div class="ui-bar ui-bar-e"> <h4>bitterness</h4> <%= bitter %> </div> </div> </div> <div data-role="collapsible" data-collapsed="true"> <h3>ingredients</h3> <ul id="ingr-list" data-role="listview" data-inset="true"> <% for(var in ingrs) { %> <li><%= ingrs[i] %></li> <% } %> </ul> </div> <div data-role="content"> <input type="button" id="save-this" data-icon="check" value="save recipies"> <div> <img src="store3.jpg" id="aisle"> </div> <div data-role="footer" class="ui-bar"> <a href="#" data-icon="back" class="back ui-btn-left">back</a> <a href="#" data-icon="home">home</a> </div> </script> <script type="text/template" id="savedrecipes"> <div data-role="header"> <h1>my recipes</h1> </div> <div data-role="content"> <p>list of saved recipes, retrieved local storage</p> <p>saved recipes:</p> <ul id="search-list" data-role="listview" data-inset="true"> <% for(var in results) { %> <li> <img src="<%= results[i].imgurl %>"> <a href="#newlist/<%= results[i].id%>"><%= results[i].title %> </a> </li> <% } %> </ul> <a href="#deleteold" data-role="button">manage saved recipes</a> <a href="#shoppinglist" data-role="button">generate shopping list</a> </div> <div data-role="footer" class="ui-bar"> <a href="#" data-icon="back" class="back ui-btn-left">back</a> <a href="#" data-icon="home">home</a> </div> </script> <script type="text/template" id="deleteold"> <div data-role="header"> <h1>delete recipes</h1> </div> <div data-role="content"> <p>select recipes wish delete local storage</p> <p>recipes:</p> <p>(currently lacks functionality populate list)</p> <ul data-role="listview" data-inset="true" id="recipe-list"> </ul> <input type="button" data-icon="delete" value="delete selected" /> </div> <div data-role="footer" class="ui-bar"> <a href="#" data-icon="back" class="back ui-btn-left">back</a> <a href="#" data-icon="home">home</a> </div> </script> <script type="text/template" id="oldlist"> <div data-role="header"> <h1>---name of recipe----</h1> </div> <div data-role="content"> <p>this list of ingredients in recipe</p> <p>ingredients:</p> <ul data-role="listview" data-inset="true"> <li>ingredient 1</li> <li>ingredient 2</li> <li>ingredient 3</li> <li>ingredient 4</li> </ul> <p> (button view recipe) </p> </div> <div data-role="footer" class="ui-bar"> <a href="#" data-icon="back" class="back ui-btn-left">back</a> <a href="#" data-icon="home">home</a> </div> </script> <script type="text/template" id="shoppinglist"> <div data-role="header"> <h1>shopping list</h1> </div> <div data-role="content"> <ul id="search-list" data-role="listview" data-inset="true"> <% for(var in results) { %> <li> <input type="checkbox" name=i id=i class="custom" /></li> <!-- these checkboxes hideously deformed--> <label for=i> <%= results[i].title %> </label> <% } %> </ul> </div> <div data-role="footer" class="ui-bar"> <a href="#" data-icon="back" class="back ui-btn-left">back</a> <a href="#" data-icon="home">home</a> </div> </script> <script type="text/template" id="list-item"> <li>cheese</li> </script> <!-- <li> <img src= <%=img_url%> > <a href="#newlist/"+ <%=model_id%> +"' class='ui-link-inherit'>" + <%=model_title%> + "</a> </li> --> <!-- scripts --> <script src="lib/jquery-1.7.1.min.js"></script> <script src="js/jqm-config.js"></script> <script src="lib/jquery.mobile-1.0.1.min.js"></script> <script src="js/underscore.js"></script> <script src="lib/backbone-min.js"></script> <script src="js/backbone.localstorage.js"</script> <script src="js/json2.js"></script> <script src="js/main.js"></script> </head> <body></body> </html>
to enhance dynamically created list view, need refresh markup using below.
$('[data-role=listview]').listview('refresh');
Comments
Post a Comment