Spaces being turned into in angular - ruby-on-rails

I'm using ng_repeat to display text from an object. On the rails backend I call strip_tags(text) to remove html. When looking at the output it looks fine. Even when looking at the object in 'view source' it looks fine.
It only looks weird when you look at the text that is actually rendered from the ng_repeat - after a certain point (200 words in the example below) every space is replaced by an
This is causing the text to overflow the div. Any suggestions for dealing with this?
Edit: Some of the code (simplified)
JS:
$scope.init = function(id){
$scope.episodes = gon.episodes
Haml:
.episode-edit{ng_repeat:"episode in episodes"}
%p {{episode.sanitized_summary}}

You should try ng-bind-html. Your snippet would look like
<p ng-bind-html="YourObject"></p>
You can use it in ng-repeat as well.
If you want to secure the data first then include $sce service in your controller. Your snippet would be like
var ExampleCtrl = function($scope, $sce) {
$scope.YourObject = $sce.trustAsHtml($scope.YourObject); // that's it
}

Sorry, turns out it had nothing to do with angular, more to do with Ruby.
Ruby's whitespace regex doesn't capture unicode non-breaking space.
Instead of str.gsub(/\s/m, ' ') you have to use str.gsub(/[[:space:]]/m, ' ')

Related

Replace grails datepicker with jquery-ui datepicker

I am using Grails 4. My book domain has a date field called publishDate. I use <f:all bean="book"/> in my edit view to display the input fields. The Fields plugin displays 3 dropdown boxes with the day, month, and year in the html for the date field in the book.
Would you teach me how to replace the Grails Datepicker with the jQuery UI datepicker please?
Thanks!
If the old community plugins were still up, you could search through their code for your solution. Since Grails no longer supports its community, you can try looking through github for an older plugin. This would be your quickest solution.
In case this is helpful to you or anyone else who comes across this issue: what we have done is create our own tag to accomplish this. You'll have to adjust it a bit to make it work for you, and include the necessary assets from jquery ui, but the tag is something like:
/*
* Render an input field that includes a calendar popup.
*/
def dateField = { attrs ->
if (!attrs.id) {
out << "'id' is a required attribute."
return
}
def additionalKeys = attrs.keySet() - ['id','name','value','className']
def passthroughAttrs =""
additionalKeys.each{key->
passthroughAttrs += "${key}='${attrs[key]}' "
}
out << "<input type='text' class='calendarField ${attrs.className ?: ''}' id='${attrs.id}' name='${attrs.name ?: attrs.id}' value='${attrs.value ?: ''}' autocomplete='off' "
out << "onfocus=\"jQuery(this).datepicker().datepicker('show');\" "
out << "$passthroughAttrs/>"
out << "<img id='cal_${attrs.id}' class='calendarIcon' alt='Show Calendar' title='Show Calendar' src='${assetPath(src: 'calendar.png')}' "
out << "onclick=\"jQuery('#${attrs.id}').focus();\"/>"
}
Usage is something like:
<ns:dateField id="someUniqueID" name="fieldName" />
As stated by Daniel you can write you own tag and that is something that I have done as well. I would also like to note that the html input tag has a date type.
<input type="date" id="some-id">
That has worked for me instead of doing all the work of creating a new tag.
The downside (in my opinion) to the html input is that some of the functions do not have complete browser support (min, max). At least they were not working for me. Also if you use the jQuery ui in some spots and the html in others, the data is submitted differently on the post request.
The input tag would give you something like yyyy-mm-dd
while the jQuery gives you something like mm-dd-yyyy.

Html.Raw splits string unintentionally

I am working on a page, where customers can write own descriptions for articles they sell. They can use html tags for this.
The code in the view looks like this:
#Html.Raw("<p class='description short'>" + shopItem.ShortDescription + "</p>")
The problem is, that this is splitted into two p-tags:
<p class="description short"></p>
and below that the content of shopItem.ShortDescription:
<p><em><strong>Title</strong></em></p>
I also tried
<p class="description short">#Html.Raw(shopItem.ShortDescription)</p>
but that leads to the same behavior.
I´m sure I´m missing or not seeing something. So, what is wrong with that code snippet?
I believe the issue here is that you cannot nest p elements. If you try it with just html it still will not work, but for example this works fine
#{
var shopItem = "<em><strong>Title</strong></em>";
}
#Html.Raw("<p class='description short'>" + shopItem + "</p>")

How to prevent the <p> tag from wrapping around my input with tinymce in Rails?

By default, the tinymce input gets passed to the DOM as a paragraph tag:
I would like to remove that element wrapper so that tinymce passes exactly what I entered in the text editor.
How do I do that ? Please if you provide a code, can you also let me know where that code gets added ?
Regards !!!
Actually I solved my problem. All I had to do was change the styling for paragraph tag :
p {margin: 0; padding: 0;}
You need to specify the forced_root_block to false. However the documentation states that not having your root block as a <p> tag can cripple the editors behaviour. Newlines will be spaced with <br> tags instead.
tinyMCE.init({
selector: 'textarea',
forced_root_block: false
});
See the documentation here
I strip out those pesky things with gsub and regex like this:
<%= #event.desc_long.gsub(/^\<p\>/,"").gsub(/\<\/p\>$/,"") %>
First .gsub removes the <p> at the start of the TinyMCE string, and the second one removes the </p> at the end. Working great for me. This would work for any language that uses regex (gsub is for rails). JavaScript example:
var str = "{TinyMCE HTML string}";
str = str.replace(/^\<p\>/,"").replace(/\<\/p\>$/,"");
Hope this helps!
EDIT:
Re: where to put it. You leave what TinyMCE puts in your database alone. Add the above only when you display it (in the view, e-mail whatever).
In case you just want to get rid of margins:
tinymce.init({
...
setup: function(ed) {
ed.on('init', function() {
var doc = this.getDoc().getElementById("tinymce");
doc.style.margin = 0;
});
},
});

.trigger('create') cannot create a listview

Here are the codes I have to dynamically create and enhance a page. The similar pattern has been working for many other kinds, such as text field, button, grid-view, etc. But I found it cannot work with a listview.
$(document).bind("pagebeforechange", function route(e, data) {
...
$content = $page.children(":jqmData(role=content)");
var markup = '<ul id="calendarList" data-role="listview"><li>HELLO</li></ul>';
$content.html(markup);
$page.trigger('create');
$.mobile.changePage($page);
});
I would always get an error message like,
Cannot read property 'jQuery16409763167318888009' of undefined
Through debugging using Chrome, I found it always fails on the line of $page.trigger('create');
I found the solution myself. It works fine if I replaced the line,
$page.trigger('create');
with,
$page.page();
$content.find( ":jqmData(role=listview)" ).listview();
However, I still don't understand why. I thought the former was a newer, simpler syntax to replace the latter. A single call of $page.trigger('create'); can enhance the entire page at one shot. Does anyone know the difference of these two?

How to show interactive character limits?

How does Stack Overflow show interactive character limits? Like when editing comments, it shows you how many characters you have left, as well as warning if it is too few.
I'd like that exact functionality in my Ruby on Rails... But not sure how to do it?
Stackoverflow uses the jQuery JavaScript Framework and it has a lot of existing scripts and plugins for this sort of thing.
One example is this Interactive Character Limit for TextArea in jQuery demonstrated here.
I'm sure there are others as well.
I use the following JavaScript function to restrict max length in textareas
function checkLength(edit, maxlen)
{
if (edit.value.length > maxlen)
edit.value = edit.value.substring(0, maxlen);
document.getElementById('remaining').innerHTML = edit.value.length;
}
Link this to your textarea's onKeyDown and onKeyUp attributes:
onKeyDown = "checkLength(this, 100);"
by using the onkeydown event on the input. There are millions of examples out there and frankly I'd be surprised if this isn't a duplicate question.
It is: How to show interactive character limits?
I think you are looking for some javascript, basically you add a handler to the textbox onkeypress event then to get the current length:
mytextbox.value.length
and to limit it you could do something like:
if (mytextbox.value.length > maxlimit)
mytextbox.value = mytextbox.value.substring(0, maxlimit);
You can also use simple javascript event handling to show character counts
for input elements. No server side processing required.
This javascript catches the key-press event for a text area "txt"
and shows the character count in a span "count".
See it running at
http://aaron.oirt.rutgers.edu/myapp/root/charCount.html
<html>
<head>
<script>
function go() {
var txt=document.getElementById("txt");
txt.onkeydown = countTxt;
}
function countTxt() {
var txt=document.getElementById("txt");
var count=document.getElementById("count");
count.innerHTML = txt.value.length+1; // count the character not shown yet ;)
}
</script>
</head>
<body onload="go()">
<h3>type in the text area and see the count change</h3>
<textarea id="txt" rows="8" cols="30"></textarea>
<br>
count: <span id="count"> 0</span>
</body>
The count can be off my +-1 -- fixing that (if you really want to) is left to the reader.

Resources