onsenui cannot change content - javascript

I’m using onsen ui version 1, followed https://onsen.io/v1/guide.html to make changes to DOM
This section to be exact
// Add another Onsen UI element
var content = document.getElementById("my-content");
content.innerHTML="<ons-button>Another Button</ons-button>";
ons.compile(content);
The problem is nothing changed on the page.
If i dump “content” variable or dump the HTML element it shows the newly edited version on browser console. but on page still the old one.
ons object is instantiated, compile method is callable, tried different HTML elements.

Either you are doing something incorrectly or it's an angular refresh issue.
For the first scenario it's easier if you provide a codepen, so that we can see the problem. Currently the code you are mentioning is working fine for me here.
For the second scenario actually the third line ons.compile(content); should remove this problem imo, it might be a version issue, or there is some context which I am missing.
If you're doing something angular related then you should also show where you are calling these 3 lines from. In order to work it should be called from something like an ng- event (for example ng-click).
JS:
app.controller('yourControllerName', function($scope) {
$scope.addButton = function () {
var content = document.getElementById("my-content");
content.innerHTML="<ons-button>Another Button</ons-button>";
ons.compile(content);
}
});
HTML:
<ons-button ng-click="addButton()">Add another button</ons-button>
Finally if you are unable to make it work you can do something like
app.controller('yourControllerName', function($scope) {
$scope.addButton = function () {
var content = document.getElementById("my-content");
content.innerHTML="<ons-button>Another Button</ons-button>";
ons.compile(content);
$scope.apply(); // should fix the issue, but not recommended
}
});
PS: You can also try out onsen 2 - there you can:
experiment with the interactive tutorial
try out the vanilla version (without any external framework) - which will not have issues like this one

Related

Materialize css initializing tabs for each result

I am doing a school project that is a Movie lookup app connected to guidebox API. I am using Materialize CSS and trying to organize the information into their tabs system. They are added dynamically so the documentation says to initialize in javascript. It says to use:
$(document).ready(function(){
$('ul.tabs').tabs();
});
However that doesn't work for me I guess since the tabs are not present at Doc Ready thaey are not pushed into the DOM until a submit request. I put just the
$('ul.tabs').tabs();
into a few places in my code and the best result was it working on the first movie returned on each search but for each subsequent return item the tabs break.
I could use some guidance on whether I can plug that in somewhere to make my existing code work.
https://github.com/jasonboru/group_project1_guidebox.git
There are some missing ending tags in your dynamically created dom elements.
Apart this, in this file assets/js/logic.js the following there are the following two lines:
$('.guidebox-search-results').append(movieResult);
$('ul.tabs').tabs();
That menas, whenever you add new tabs element you initialize them.
The mistake I see is: in this way you initialize every tabs not only the new one. And, because you have already initilized the old one I can suggest you to rewrite the previous two lines in this format:
$('.guidebox-search-results').append(movieResult);
$('.guidebox-search-results').find('ul.tabs').tabs();
You can bind on every event, when node inserted in dom and after that, do with it what you want.
$(document).bind('DOMNodeInserted', function(e) {
var element = e.target;
});

After using $sce.trustAsHtml, ng-click not working

I am trying to print to the screen custom html using angular. I am using $sce.trustAsHtml in combination with ng-bind-html to accomplish this. The goal is not only to be able to print this custom html, but that it will retain directives such as ng-click and they will be usuable. Examples I have seen in articles such as follows are promising:
AngularJS render HTML within double curly brace notation
However in my implementation I find that although the html renders correctly including references to ng-click, the directive doesn't seem to work anymore when trying to click on the link I am using it on; here is some sample code:
$scope.htmlExpression = $sce.trustAsHtml("<a ng-click='test();'>Click Me</a>");
$scope.test = function() {
console.log('Hello World!');
}
<div>
<p ng-bind-html="htmlExpression"></p>
</div>
As everything renders fine and nothing appears lost in translation when analyzing the source; I am left feeling as if I have left something out. Any help is appreciated.
Use https://docs.angularjs.org/api/ngSanitize and bind the html. If this does not work, $digest to reboot the digest cycle.

jQuery clone and append function isn't working as expected in AngularJS directive

in my app I'm trying I'm building a shopping cart. You can see the app in this codepen: http://codepen.io/summerfreeze/pen/VjqJYW. It's almost working, but I'm struggling with the last part. I want the "ADD ORDER LINE" button to add another order lines under the existing one. I'm trying to do this using jQuery:
myApp.directive('myDirective', function($scope) {
$scope.addline = function() {
$(".orderline").clone().appendTo('.main');
};
return addline();
});
But this doesn't seem to work. I would be grateful if someone would look at the code and tell me what mistake did I make.
Not sure why you were using a directive. I removed that from your code and it works. You still have other errors, but I'm guessing you can attend to those.
Here's the link to the modified version
new codepen version
$scope.addline = function(){
$(".orderline").clone().appendTo('.main');
};
As the others suggested, in order to follow clean code standards, please refrain from using jQuery code in AngularJS, in time it will lead to problems.
From what I can tell, you shouldn't be appending to #main, but to #main div[0]

Angular JS - Evaluation Timing

I have the following problem in angularjs. I want to use an UI libary that injects some html code itself (Metro UI CSS) and I have troubles to getting the execution order right.
A simple example: http://metroui.org.ua/hint.html
If I declare in html:
<span data-hint="My hint"></span>
The UIjs will create the html elements needed for the hint display. Nofurther script code has to be added. Well actually when you load the js the following code gets executed: $('[data-hint]').hint();
Since the angular created html doesn't exist when I load the javascript, it doesn't work at first at all.
I believe I need an angular directive to solve the problem (and in parts it does) - I created the fowlling directive:
app.directive('hints', function() {
return {
link: function() {$('[data-hint]').hint()}
};
});
The following does work, even if this is in html created by angular:
<span hints data-hint="the text for my hint">test</span>
The following doesn't work (at least it doesn't behave the way I'd like to):
<span hints data-hint="{{something}}">Test</span>
The hint text will display literally {{something}} and not whatever is behind the angular expression. I tried already to create template like, but the result is still the same:
app.directive('hints', function() {
return {
template: '<span data-hint="{{something}}">Test</span>',
link: function() {$('[data-hint]').hint()}
};
});
Any hints on how to solve that problem would be greatly appreciated.
The main problem seems to be that if you attach the hint() in the link function, jquery takes the old value before angular has evaluated it. One option would be to wrap $timeout(function(){..}) around element.hint(), but I use that hack too much already, and it doesn't solve another problem: the hint needs to update when the $scope changes (if it depends on the $scope). To solve that problem we can add a $watch function and update the hint value when needed.
So, in conclusion:
/* This directive triggers automatically on data-hint as well */
app.directive('hint', function($timeout) {
return {
link: function(scope, element, arguments) {
/* set the value of the hint, then attach the metro-hint widget */
element.data('hint' , arguments.hint).hint();
/* watch for changes in the value so the hint gets updated */
scope.$watch(function(){
return arguments.hint;
}, function() {
element.data('hint' , arguments.hint);
});
}
};
});
(Tested with jquery 1.10.2, jquery-ui 1.10.3 and angular 1.2.6)

Is it possible to create element on the fly with jQuery Mobile?

I have an app built using jQuery (and using various jQuery-UI tools).
For some reason, i have to port it to smartphones/tablet computer, and decided to use jQuery Mobile for that (in order to minimize the number of changes).
In my vanilla app, I created some elements of the page on the fly, depending of user interactions.
For example a slider could be created like that (p is an object with a bunch of params):
function createSlider(p){
return $("<div/>",{
"id":p.id,
"class":p.divClass,
}).slider({
"orientation": p.align,
"min":p.constraint.min,
"max":p.constraint.max,
"step":p.step,
"value":p.curVal,
"animate":"normal"
/*and some event handling here, but it doesn't matter*/
});
}
And it will produce a nice looking slider. Now it looks like:
function createSlider(p){
return $("<range/>",{
"id":p.id,
"class":p.divClass,
"min":p.constraint.min,
"max":p.constraint.max,
"step":p.step,
"value":p.curVal,
});
}
But as it's created on the fly, all the stuff done by jQuery Mobile on the page load isn't done on it.
Is there a way to force that initialization without writing the slider in the html?
Thanks.
EDIT: I found in the doc that it could be achieved using container.trigger("create");
However this does not work yet.
EDIT2: Ok create was the solution.
According to the documentation (see edit in the question), using trigger("create") on the containing element works.
And to make that work, you also need to remember that range is an input type and not a tag...
Working solution:
function createSlider(){
return $("<input/>",{
"type":"range",
"id":"sl",
"min":0,
"max":15,
"step":1,
"value":1,
});
}
function appendSlider(){
$("#yourdiv").append(createSlider()).trigger("create");
}
As a sidenote, the documentation for jQuery mobile lacks a search option.
Try calling .page() on the container the content is being added to. Alternatively, adding .page() to the content you're returning may also work.

Categories

Resources