How to create Custom ng-repeat without using angular.js? - javascript

I am trying get data from server with json and manupulate it to html.This will be really hard to write and really unclear to understand when I scan my code again if I write it on javascript because I will get data and use jquery append to append data to html element and I should add a lot of html inline.For example:
$.getJSON( "json.php", function( json ) {
$.each( json, function( key, data ) {
$('#content').append('<li class="h" id="id5" >+data.type4+</li><a href="www.example.com" ><li class="fg" id="id6" >+data.typ5e+</li></a><a href="www.example.com" ><li class="gfh" id="id7" >+data.type6+</li></a><a href="www.example.com" ><li class="example213" id="id8" >+data.typ7e+</li></a>');
enter code here
Imagine It will be more more big than this and I should write a lot of inline html in javascript and It will be incredible unreadable.Solution is Angular.js ng-repeat beacause I can write noormal html which is easy to read for all developers andd easy to write but I dont want to use angular.js beacuse It is slow,It contain a lot of bytes and I only want to use two of its method (ng-repeat with databinds).How can I achive this?

I found pretty simple way and without any template library.Just write \ tag end of each line ,native,very simple and readable.In my case I have a lot of if else statement,a lot of adding new variables, that why I cant use angular or that kind of thing and I will simply use \ tag just break line.

Related

making links clickable while pushing the data into templates

I am taking inputs from user, then adding links for mentioned users and then passing the same in the template
Input: hello #ds
String after adding links -
"#<a class="tweet-url username" href="/user/ds" data-screen-name="ds" rel="nofollow">ds</a>"
Passing the above string in .Msg (using golang template) :
<div class="panel-body" >
<p > {{.Msg}} </p>
</div>
Expected outcome is: Hello #ds (with clickable link on #ds)
However getting everything in text format (same as input).
#<a class="tweet-url username" href="/user/ds" data-screen-name="ds" rel="nofollow">ds</a>
What am I missing?
Got a better solution. First of all I am doing htmlEscape on the input then store it in db, then while presenting adding links followed by using document.write(string) function. With this I dont have to change the template and I dont have to worry about XSS attach. Also I am also avoiding XSS scripts in my database. –
Try wrapping your string (Msg) in template.HTML to disable the escaping that html/template does.
Example from the docs:
The template
Hello, {{.}}!
can be invoked with
tmpl.Execute(out, template.HTML(`<b>World</b>`))
to produce
Hello, <b>World</b>!
instead of the
Hello, <b>World<b>!
that would have been produced if {{.}}
was a regular string.
Note that you should do this with great care... make sure that you trust the string you're wrapping in template.HTML. This is an easy way to open yourself up to XSS attacks.

Keeping DOM Object in Memory Vs String HTML in Memory for repeated use

I'm creating a plug and play chat module which loads (via ajax) a chatbox html as string. This html string has some elements which are hidden(display:none) and are to be used repetitively. eg:
<div class="chatboxmain">
<div class="incomingmsg" style="display:none;">
<div>
<span class="msgtext"></span>
<span class="msgtime"></span>
</div>
</div>
<div class="outgoingmsg" style="display:none;">
<div>
<span class="msgtext"></span>
<span class="msgtime"></span>
</div>
</div></div>
<!-- .....So on 5 types of messages contact,video,image -->
<div class="incomingcontactmsg"></div>
<div class="outgoingcontactmsg"></div>
</div>
Since I can have multiple chatboxes, I load the template only once and save it in a javascript string object.
template.chatbox=chatboxstring;
I have to extract the message templates from within the chatbox template and save them in memory so that I don't query my dom again and again.
template.incomingmsg="";
template.outgoingmsg="";
To achieve the above I do the following:
var a=createElement("div");
a.innerHTML=template.chatbox;
template.incomingmsg=a.querySelector('.incomingmsg').innerHTML;
template.outgoingmsg=a.querySelector('.outgoingmsg').innerHTML;
Question 1: Is the above the only way to go about it?
Question 2: I'm saving strings for incoming and outgoing message and wrapping them in a div everytime a message comes.
Which is better?
a.Keeping a DOM Node saved in a javascript object for it's life time, or
b.keeping a string(for innerhtml) and parsing it again and again everytime a message is received and sent. I raise the question because NODE object in memory eats more memory than a string object vs on appending string as InnerHtml I'll be repeatedly parsing the same string again.
1)
For handling XML(HTML) in js maybe i wouldn't use pure html dom access and would use some framework for example jQuery (there is more frameworks with diferent performance):
https://api.jquery.com/jQuery.parseXML/
It is more readeble then using html DOM and innerHTML. And remember that readibility is rly important. if you look at your own code after few months you wont know what is going on.
2) It is good to realize that on client side (browser) you are handling only one client. So Even when there are 20 000 users using your application it is not such a big problem if you are using one or antoher way on CLIENT side. Your performance focus should be on server side.
I would use sollution where i use a little bit more memory and dont have to parse everytime(a).

Append AngularJS after clicking an AJAX call

I am searching SoundCloud's API and want to be able to add a song to the page once it is clicked from the search results. I am using Plangular and need to also append the tags for that. However, jQuery doesn't seem to like including Angular tags in the append function.
Here is the Search.js
$.ajax({
type: 'POST',
url: '/api/v1/add_song',
data: songParams,
success: function (newSong) {
$('#latest-posts').append(
"<div class='sc-track' plangular='"
+ newSong.url
+ "'><div class='pull-left'<img ng-src='{{track.artwork_url}}'></div> <h3>{{track.user.username}} - {{track.title}}</h3> <button ng-click='playPause()'>Play/Pause</button><progress ng-click='seek($event)' ng-value='currentTime / duration' > {{ currentTime / duration }} </progress> <br> <a ng-href='"
+ newSong.url
+ "'> View on SoundCloud </a>"
+ "</div>"
)
}
})
I am new to Angular, so I'm sure there is a better way to do this. Any help is greatly appreciated!
If you are using Angular, you shouldn't be using jQuery for the ajax calls. I'd suggest you first learn more about the declarative way Angular works, instead of the imperative way jQuery works. Basically you don't modify elements from the controller directly. What you could do is make an array of posts in a controller: $scope.posts. Then you make an ajax call with $http, and in the callback you add the retrieved post to the $scope.posts e.g. $scope.posts.push(response). In your HTML you do something like this:
<body ng-controller="YourController">
<div class="latest-posts">
<div plangular="post.url" class="post" ng-repeat="post in posts">
...
</div>
</div>
</body>
The post in posts will bind to $scope.posts, and by using the ng-repeat the tags (like plangular) get compiled automatically.
In fact, I barely use jQuery in my apps and I can't even remember giving a div an id. I'd suggest you to follow a good tutorial first and check out this: "Thinking in AngularJS" if I have a jQuery background?
This is not the correct way to append Angular's model values.
You can directly access model values like this. Give it try!
$scope[model_name]

Display raw HTML markup from CKEditor in Angular template

I use CKEditor in my AngularJS Application. When I try to display the text that I saved from the TextEditor, it doesn't take the style. For Example if I want to display a sentence it appears as:
<p>How old are you</p>
instead of :
How old are you
I tried using ng-bind:
<div ng-bind="Item.Header"></div>
and the regular binding method:
<h3>{{Item.Header}}</h3>
But both methods didn't work. Is there a solution for this issue?
You should use "ngBindHtmlUnsafe". Since this command doesn't sanitize the expression, but you should only use it if you trust the source.
So the html will be written as follows:
<div ng-bind-html-unsafe="Item.Header"></div>

How to effectively change local changes made to an html document via javascript back to the server?

So let's say you display a list of divs that each represent a list item with certain properties (for an example a todo list):
<div class="list">
<div class="items" id="item1">
<div class="itemtitle">Some title</div>
<div class="icon"><img src="1.jpg"></div>
<div class="footer1" />
</div>
.
.
.
<div class="items" id="itemN">
<div class="itemtitle">Some other title</div>
<div class="icon"><img src="2.jpg"></div>
<div class="footer4" />
</div>
</div>
Now each item has three properties (title, a specific icon, and a custom footer). All these properties can be changed via javascript (say clicking on one cycles through the options).
Now everytime something is changed i want to save these changes to the server (and no, i don't want to store the whole html code block (that way i can't sort by the properties later, also it's ugly ;) ). What would be the most elegant and effective way to do this ? (I'm using jQuery if that helps...)
Thanks a bunch !
As long as you have a unique id for each block, you could push each change on blur of that element.
A user changes .itemTitle in #item4, you know the id is 4. So you can use an ajax post, send the item id, the item type (title), and the updated value. Then, on the server side (php, for example), you can do a simple mysql (i'm assuming) update.
Does that make sense? I can show actual code if need be.
If you want to transmit all the changes back to the server in one go, then naturally you need to put them into some kind of <input> element. <input type="hidden"> is the most obvious choice. If you go that route, you can either use an onsubmit handler on your form to update your hidden inputs from the text in the document, or you can update the hidden inputs in realtime as you update the document itself.
As far as how to structure the inputs, that's a harder question because there are several ways to do it and the best way to decide between them, it seems to me, is what's easiest to parse in your server-side framework.
You could create a whole bunch of hidden inputs with name="itemtitle" and a bunch with name="icon" etc, as long as your server-side framework knows how to interpret the resulting form post data as a list-of-values for itemtitle and for icon.
You could create hidden inputs with name="itemtitle1" etc.
Or you could just use one fixed hidden input and populate it with the entire list encoded in some form, such as JSON, if your server-side framework has an easy method for parsing JSON. Then you'd use javascript either in onsubmit or on every change to update the hidden input to consist of [{itemtitle="whatever", icon="whatever, ...}, {itemtitle="..."}] and parse that out as a JSON list on the server side.
Another choice would be to not use hidden inputs at all, but actual textboxes in the document itself. With styling, it's possible to make a textbox look un-editable. If you did that, then your list structure would post back all by itself when it's part of a form post.
One thing you can try is to collect the information into a JavaScript object literal, which essentially like a hashtable/dictionary structure, but you can nest structures inside. It's not a fixed structure, and doesn't require you to have hidden elements in your DOM -- you can have this completely separated from your DOM.
You can then take advantage of JSON notation for transferring this information to your server via a POST. Using Douglas Crockford's JSON2.js library allows you to serialize and de-serialize this structure to/from the object literal notation. And, there's lots of support for JSON on the server side.
So for your example, you could do something like this in jQuery (I extended your markup a little just to have a valid working example):
<div class="list">
<div class="items" id="item1">
<div class="itemtitle">Some title</div>
<div class="icon"><img src="1.jpg"></div>
<div class="footer1">blah</div>
</div>
<div class="items" id="item2">Stuff</div>
<div class="items" id="item3">Stuff2</div>
<div class="items" id="item4">
<div class="itemtitle">Some other title</div>
<div class="icon"><img src="2.jpg"></div>
<div class="footer4">boo</div>
</div>
</div>
(I'm assuming that your DIV ids are sequentially numbered -- item1, item2, item3, etc.)
and the JavaScript...
var theData = {};
$(document).ready(function() {
$(".items").click(function() {
theData["title"] = $(this).find(".itemtitle").text();
theData["icon"] = $(this).find(".icon img").attr("src");
theData["footer"] = $(this).find(".footer" + ($(this).index()+1)).text();
alert(JSON.stringify(theData));
});
});
(I'm assuming the footer data can be selected based on the sequentially numbered DIV id.)
Now that your changed data is in the theData object literal variable, you can send it to your server/service via a jQuery $.ajax call:
$.ajax({
url: "/ajax_json_echo/",
data: theData, //just pass the literal to your server...most can handle it
type: "POST",
dataType: "json",
success: function(data) { alert(JSON.stringify(data)); }, //output it readable form
error: function(x, t, m) { alert("Error: " + t + " :: " + m); }
});
You can check out a fiddle I put together that demos this.
I hope this helps!

Categories

Resources