Can't pass js value "pageUid" in f:link.page viewhelper - javascript

I get some values from js and formatting page. I used fluid viewhelper for create link. My js look like
function buildEstablishments(title, page) {
...
$('#myid').append(
'<div class="col-md-6 col-sm-6 col-xs-6">' +
'<f:link.page pageUid="' + page + '" title="' + title + '" >More</f:link.page>' +
'</div>'
);
}
Everything works good, but I can't pass value "pageUid" in f:link.page viewhelper. Parametr ' + page + ' is exists and has a value. How can even pass values? Thanks.

You can not, in simple words all Fluid syntax works on server side and JS works on client side, that means that server side job is done long, long before it goes to the client (if you're using caching it may be months or years before client side will load it), you can use it rather like this:
In your Fluid view:
<div onclick="buildEstablishments('{someTitle}', '{f:uri.page(pageUid: somePageUid)}')">Foo Bar Baz</div>
Where of course {someTitle} and {somePageUid} are resolvable Fluid variables
so you can use it in your JS script like:
function buildEstablishments(title, href) {
// ...
$('#myid').append(
'<div class="col-md-6 col-sm-6 col-xs-6">' +
'<a href="' + href + '" title="' + title + '" >More</a>' +
'</div>'
);
}

Related

Bootstrap Data-Toggle attribute is not working with Cards generated from JS loop

I'm working on a website that makes a call to a database. It takes the JSON from the database and loops through a specific node -- appending HTML code to a div tag, which creates a Card for each database entry. I want to be able to have a Bootstrap Popover (or Tooltip) that appears when a Card is clicked (or hovered over if Tooltip). The Cards that are generated within the function fail to produce a Popover or Tooltip at all. If I append the same HTML code outside the function using JQuery, it works just fine. I'm unsure what is happening here.
Here's the function that loops through the database JSON and creates a card for each child.
function getWeekEvents(day, id) {
return firebase.database().ref(day).once('value').then(function(snapshot) {
var data = snapshot.val();
for (item in data) {
var event = data[item]["event"];
var loc = data[item]["loc"];
var time = data[item]["time"];
$("#" + id).append("<div class='card border border-primary week-cards-ann event-style' data-toggle='popover' data-content='Content' data-placement='right'>" +
"<div class='card-body my-lg-n3'>" +
"<div class='card-text my-lg-n1 float-left ml-lg-n3'>" +
"<p>" + event.substring(0,10) + "...</p>" +
"</div>" +
"</div>" +
"</div>");
}
});
}
The code below is outside any function and works just fine. It creates a card in the same way, but the Popover works.
$("#tuesday").append("<div class='card border border-primary week-cards-ann event-style' data-toggle='popover' data-placement='top' title='Hello'>" +
"<div class='card-body my-lg-n3'>" +
"<div class='card-text my-lg-n1 float-left ml-lg-n3'>" +
"<p>" + "...</p>" +
"</div>" +
"</div>" +
"</div>");
And I also have this part that is required for Popovers to work.
$(function () {
$('[data-toggle="popover"]').popover()
});
I also tried creating a Tooltip in the same way, instead of a Popover, but it resulted in the same problem. This lead me to believe that there may be something happening with the data-toggle attribute? I could be wrong. Does anyone have any thoughts?

When I .load a HTML template, JSON elements don't populate but they work fine as static HTML.

I don't think this is a broken code question as much as it is a question about understanding JS.
I have HTML templates that I load when an element is clicked. To be clear, there is already an HTML template loaded on document.ready that has all functionality working just fine. The HTML that loads is the exact HTML that is in place when you intitially load the page, aside from some small differences(images, etc...). This all loads no problem, but for some reason my JSON elements don't load. Is this because the actual javascript I wrote that is responsible for loading the JSON is within the document.ready wrap?
To be clear, the HTML is EXACTLY the same, aside from text and img src's. I have provided the JS though since that may be the issue.
Just looking for some guidance on why this may be occurring since I also have a few other JS/jquery strings of code that also don't work on template load(like hiding elements with .hide that work on document.ready no problem, but once the template loads, the elements aren't hiding).
This all sits in $(document).ready
var trinketJSON;
$.getJSON("js/trinket.json", function (data) {
trinketJSON = data;
// TRINKET SELECTION TABLE
$.each(trinketJSON, function (i, item) {
$("<div>")
.html(
'<div class="trinket-tile"><div class="trinket-img" style=\'background-image: url("' +
trinketJSON[i].RarityBG +
'");\'><img src="' +
trinketJSON[i].TrinketIMG +
'" class="trinket-tile-img"></div><div class="trinket-effects"><ul><li class="trinket-effect">' +
trinketJSON[i].EffectOne +
'</li><li class="trinket-effect">' +
trinketJSON[i].EffectTwo +
'</li><li class="trinket-effect">' +
trinketJSON[i].EffectThree +
'</li><li class="trinket-effect">' +
trinketJSON[i].EffectFour +
'</li><li class="trinket-effect">' +
trinketJSON[i].EffectFive +
'</li><li class="trinket-effect">' +
trinketJSON[i].EffectSix +
'</li></ul></div><div class="trinket-info"><ul><li class="trinket-name">' +
trinketJSON[i].TrinketName +
'</li><li class="trinket-rarity">' +
trinketJSON[i].Rarity +
'</li><li class="trinket-class">' +
trinketJSON[i].Class +
'</li><li class="trinket-set"></ul></div></div>'
)
.appendTo(".trinket-select");
});

angular ng-click event not firing

I have a function that adds certain html to my page when called :
function htmlAppend(i)
{
dynamicHtml = dynamicHtml + '<div id="list_item_wrapper">' +
'<div class="list_item_template" id="list_image_wrapper">' +
'<img class="list_image_style" ' +
'src=" ' + jsonData.cars[i].ImgURL + ' "/>' +
'</div>' +
'<div class="list_item_template white_font car_details_wrapper">' +
jsonData.cars[i].CarName+ '<br>' +
jsonData.cars[i].Brand + '<br>' +
jsonData.cars[i].Model + '<br>' +
jsonData.cars[i].FuelType + '<br>' +
'<span style="font-size:40px;">' +
'₹ ' + jsonData.cars[i].Price +
'</span> <br> ' +
jsonData.cars[i].Experience +
'<input type="button" id="buy_now_btn" class="button1" ng-click="alert("hi")">Buy</button>' +
'</div>' +
'</div>'
}
Problem : Now this html is displayed correctly in my page but for some reason when button is clicked ng-click event doesn't fire , when i replaced it with onClick then onClick fires . i am unable to understand why ng-click is not firing , can somebody help ?
Additional Info : htmlAppend is a private function of a service that is called from the controller upon some user input.
No, you can't just write alert on your ng-click. When you write alert("hi") on your ng-click directive, it automatically goes and look for a method in your controller that is named $scope.alert(). That is why onClick works, because it is just plain old JavaScript, where as ng-click involves scope binding.
In your controller, write this:
$scope.alert=function(string){
alert(string);
};
and you are good to go. Here is the working plnkr.
Edit: did not read carefully that you are dynamically binding it. Updated plnkr.
For this case you will need to compile it:
var $el = $('<button ng-click=' + 'alert("hello")' + '>I am a button</button>');
$compile($el)($scope).appendTo('#testing');
where #testing can be any DOM selector you want.
Still the point is to tell you you can't just write alert in ng-click directive.
Added bonus: do not write DOM manipulating logic inside the controller. You may want to use a directive instead.

Put a Modal inside Javascript

I'm making a Carnival calendar for my city.
I'm using this as a basic calendar engine: https://github.com/jlord/sheetsee-calendar
For a basic Modal i'm using this: https://github.com/FinelySliced/leanModal.js
I want to be able to click on the event and put it to show some information about it: name, time and place.
var eventElement = $('<div class="event"><a class="' +
event.location + '" href="#informa" rel="leanModal" >' +
event.name + "#" + event.tickets +
'</a></div> <div id="informa"> <p>' +
event.name + '</p></div>')
I made a test modal in the index.html and it worked, but it is not working when i try to do this.
You have created an element, but haven't added it to the DOM of the page.
try something like
$('body').append(eventElement);
as the next line.

Breaking a string into multiple lines inside a javascript code

I am trying to format (beautify, tidy, clear up.. you name it) a snippet of HTML inside my javascript code or, in other words, spread it out on multiple lines rather than having it written on one line so it can be read easily.
Basically, it's a piece of html code that I am trying to append to the page by calling the jQuery's .append(); method.
And here's what I am trying to do:
$('.videos').append('<li>
<span>' + count + '</span> -
<a href="' + vList[i].player + '">
<span class="title">' + videoTitle + '</span>
</a>
</li>');
Appearantly, it won't work that way. I am getting Uncaught SyntaxError: Unexpected token >
When It is written as follows, everything works fine.
$('.videos').append('<li><span>' + count + '</span> - <span class="title">' + videoTitle + '</span></li>');
It's kind of weird that when I tried to do the exact thing here,
var albumURL = API + '/video.get?=owner_id=' + userID +
'&album_id=' + aList[i].album_id +
'&access_token=' + accessToken;
I had no problem at all.
I know this issue is not that big of a deal but I am trying to get around with it just for the sake of simplicity.
Any suggestions?
If you have a multiline string, you need to use the multiline string syntax.
However, it's better to store your HTML in templates and not code :) That makes them more readable, more reusable and more maintainable.
What about something like - in your HTML:
<script type="text/template" id="videoTemplate">
<li>
<span>{{count}}</span>
<a href="{{videoURL}}">
<span class="title">{{videoTitle}}</span>
</a>
</li>
</script>
Then in JavaScript
var template = $("#videoTemplate").html();
$(".videos").append(template.replace("{{count}}",count).
replace("{{videoURL}}",vList[i].player).
replace("{{videoTitle}}",videoTitle));
That way, you get a clearer separation of the template you're using and your code. You can change the HTML independently and reuse it in other parts of code more easily.
The code does not have to even be aware of template changes and a designer can change the design without knowing JavaScript.
Of course, if you find yourself doing this often you can use a templating engine and not having a .replace chain.
ES2015 also introduces template strings which are also kind of nice and serve the same purpose in principle:
const videoTemplate = `<li>
<span>${count}</span>
<a href="${vList[i].player}">
<span class="title">${videoTitle}</span>
</a>
</li>`;
If you want to write a multiline string you should use the "\":
example:
$('.videos').append('<li> \
<span>' + count + '</span> - \
<a href="' + vList[i].player + '"> \
<span class="title">' + videoTitle + '</span> \
</a> \
</li>');
New answer:
With ES6 you can actually use string concatenation that is line-break insensible:
var html = `
<li>
${count}
</li>
`;
and the line breaks will not be a problem. Prior to ES6 I used mostly arrays and concat them. Its faster:
var html = [
'<li>',
count
'</li>'
].join('');
Old answer:
In javascript you cannot break lines without concatenating them with a + or using \. Try this:
$('.videos').append('<li>' +
'<span>' + count + '</span> - ' +
'<a href="' + vList[i].player + '">' +
'<span class="title">' + videoTitle + '</span>' +
'</a>' +
'</li>');
If you simply want to split rendered output onto new lines then append \n where you want the newline to appear, like this...
$('.videos').append('<li>\n<span>' + count + '</span> -\n\n<span class="title">' + videoTitle + '</span>\n\n</li>\n');
And if you want your JS to look nice you could try this, which will also ensure that your rendered HTML is indented.
var item = '';
item += '<li>\n';
item += ' <span>' + count + '</span> -\n';
item += ' <a href="' + vList[i].player + '">\n';
item += ' <span class="title">' + videoTitle + '</span>\n';
item += ' </a>\n';
item += '</li>\n';
$('.videos').append(item);
you can try like this
$('.videos').append( ['<li>',
'<span>' + count + '</span> - ' ,
'<a href="' + vList[i].player + '">' ,
'<span class="title">' + videoTitle + '</span>' ,
'</a>' ,
'</li>'].join('') );
From New Perspectives on HTML5, CSS, and JavaScript 6th Edition, Chapter 9 Getting Started with JavaScript:
"If you want to break a text string into several lines, you can indicate that the text string continues on the next line by using the following backslash \ character.
Example of proper line break:
      window.alert("Welcome \
      to Tulsa");
If you are rendering HTML using backticks and want to pass a variable inside it's very easy just add the backticks around the variable and concatenate it. let's take an eye on the below example
var x = 1;
$(wrapper).append(`
<div class="card">
<div class="card-body">
<h5 class="card-title">Plot `+ x +` </h5>
</div>
</div>
`);

Categories

Resources