Have a news story display, similar to HackerNews, that uses an <ol> tag for numbering and vote ranking. When trying to paginate using the Kaminari gem the <li> numbers of each article get reset to 1-20 on every page.
I've tried using CSS counter-reset and counter-increment, but I cannot get it to work yet. I also tried manually adding counter-reset for each page, but if the site somehow sees more than 5 pages, I'll have to manually encode the increments, which isn't possible.
I'm wondering if there's a js solution.
Here's the index method of my stories_controller:
def index
if params[:sort] && params[:sort].to_sym == :newest
#stories = Story.order("created_at DESC").page(params[:page]).per(20)
else
#stories = Story.order('karma DESC').page(params[:page]).per(20)
end
end
Here's my Story index.html.haml:
%ol
- #stories.each do |story|
= render partial: 'story', locals: { story: story, tag_type: :li }
= paginate #stories
And the _story.html.haml partial off the above:
= content_tag defined?(tag_type) ? tag_type : :div, class: 'story' do
= link_to "⇧", upvote_story_url(story), class: 'upvote', method: :post
%div
.title
= link_to story.title.titlecase, story.url
%span.link-domain (#{story.url_domain})
.metadata
= statusline story
|
= link_to 'comments', story, class: 'comments-link'
= "(#{story.comments.all.count})"
And finally my relevant CSS:
ul, ol {
margin: 0 1.5em 1.5em 0;
padding-left: 2.0em;
counter-reset: section;
li {
margin: 10px;
}
}
li {
float: top;
counter-increment: section;
}
Thanks in advance for any help or new ideas!
EDIT:
Fixed this by taking out the Ordered List tag and switching to a Unordered List with list-style-type set to none to remove the bullet.
Here's the code I used in the haml view:
- if params[:page].nil? || params[:page] == "0" || params[:page] == "1"
- x = 0
- else
- page = params[:page].to_i - 1
- x = page * 15
- #stories.each_with_index do |story, index|
= content_tag defined?(tag_type) ? tag_type : :div, class: 'story' do
%li
.title
.story_number
= index + x + 1
= etc...
Fixed the issue in the edit above..
Related
i m working on a piece of cq component, what i need is to retrieve an image filereference path and render the image on the page.
e.g this is my page structure as shows on picture.
say i m current on index page, i know how to retrieve index page's children page and get their value map of jcr:content, and get all the properties out from jcr:content...
but i dont know how to retrieve it's jcr:content/image node-> the image, and how to retrieve it's filereference property...
here is my code, it crashes...
<%
boolean includeTitle = properties.get("includeTitle", false);
boolean includeImage = properties.get("includeImage", false);
boolean includeSubTitle = properties.get("includeSubTitle", false);
boolean includeDescription = properties.get("includeDescription", false);
String type = currentStyle.get("type", "plain");
%>
<%
Iterator<Page> currentPageChildren = currentPage.listChildren();
while(currentPageChildren.hasNext()){
Page childPage = currentPageChildren.next();
ValueMap childPageProperties = childPage.getProperties();
//trying to retrieve the image node
Node imageNode = childPage.getContentResource("image").adaptTo(Node.class);
String childPageTitle = childPageProperties.get("jcr:title", String.class);
String childPageSubTitle = childPageProperties.get("subtitle", String.class);
String childPageDescription = childPageProperties.get("jcr:description", String.class);
%>
<div>
<% if (includeTitle) { %>
<p><%= childPageTitle%></p>
<% }
if (includeSubTitle) { %>
<p><%= childPageSubTitle%></p>
<% }
if (includeDescription) { %>
<p><%= childPageDescription%></p>
<% } %>
//test to print image's filereference path in string on page
<p><%=imageNode.getProperty("fileReference") %></p>
</div>
<%
}
%>
please help me with some code example, thx
I suggest using the Image class, which takes care of null checks. I think in your code you stumble over a page where imageNode is null or has no property fileReference.
Code snippet:
String fileReference = "";
Resource imgRes = childPage.getContentResource("image");
if (imgRes != null) {
Image image = new Image(imgRes);
fileReference = image.getFileReference();
}
I'd like to include a rails object in my keywords as well as straight text but the code is clearly not the right way to do it...how can I do this?
set_meta_tags :keywords => %w[keyword1 keyword2 #{params[:hospital]}]
You might want to have a look at two plug-ins for including rails object in meta tags:
Meta Magic: https://github.com/lassebunk/metamagic
Head Liner: https://github.com/mokolabs/headliner
Edit: For Meta tag gem
What I usually do is write a meta helper that I simply stick in my ApplicationHelper, that looks like this:
def meta(field = nil, list = [])
field = field.to_s
#meta ||= {
'robots' => ['all'],
'copyright' => ['My Copyright'],
'content-language' => ['en'],
'title' => [],
'keywords' => []
}
if field.present?
#meta[field] ||= []
case list.class
when Array then
#meta[field] += list
when String then
#meta[field] += [list]
else
#meta[field] += [list]
end
case field
when 'description' then
content = truncate(strip_tags(h(#meta[field].join(', '))), :length => 255)
else
content = #meta[field].join(', ')
end
return raw(%(<meta #{att}="#{h(field)}" content="#{h(content)}"/>))
else
tags = ''
#meta.each do |field, list|
tags += meta(field)+"\n"
end
return tags.rstrip
end
end
You can simply set meta tags in your views, by adding a call to meta() in it. So in an articles/show.html.erb you might add this to the top of your view:
<% meta(:title, #article.title) %>
And in your layouts, you add it without any parameters, so it'll spit out the meta tags.
<%= meta %>
Or have it output an individual tag:
<%= meta(:title) %>
I bet you there's more elegant solutions, though.
But if you were looking for something already implemented in Rails you're out of luck.
Thanks.
Try this in your view as it worked for me (using meta-tags gem):
<% keywords [[#modelname.keyword1], [#modelname.keyword2]] %>
and you cad additional keywords in text format by adding them within the ruby in the following format ['keyword3']
I have been struggling with this for a while. As well as some specific help I would be grateful for some pointers how I may fill some of the gaps in my knowledge. BTW I am new to Rails and web development.
I have used DataTables to display a table records and have some code which shows me the id of the row selected by the user. From within my index view I want to use that row id to load the edit view for that data row. My .js code is as follows:
$(document).ready(function() {
/* Init the table */
TableTools.DEFAULTS.aButtons = [];
oTable = $("#highways").dataTable({
sPaginationType: "full_numbers",
bJQueryUI: true,
"bProcessing": true,
"bServerSide": true,
iDisplayLength: 25,
sAjaxSource: $('#highways').data('source'),
"aoColumns": [
null,
null,
null,
null,
null
],
"sDom": 'T<"clear">lfrtip',
"oTableTools": {
"sRowSelect": "single",
"fnRowSelected": function ( node ) {
var oTT = TableTools.fnGetInstance('highways');
var aData = oTT.fnGetSelectedData();
var n = '/highways/' + aData[0][4] + '/edit'
alert(n);
var jqxhr = $.get(n, function() {
alert("success");
})
}
},
});
} );
The development log shows:
Started GET "/highways/8/edit" for 127.0.0.1 at 2012-08-21 07:57:14 +1000
Processing by HighwaysController#edit as /
Parameters: {"id"=>"8"}
[1m[35mHighway Load (0.3ms)[0m SELECT highways.* FROM highways WHERE highways.id >= 8 LIMIT 1
Highway BARKLY HIGHWAY
Rendered highways/_form.html.erb (67.1ms)
Rendered highways/edit.html.erb within layouts/highways (258.5ms)
Completed 200 OK in 276ms (Views: 274.6ms | ActiveRecord: 0.3ms)
I have tried various things in the controller code, and in some cases the log says the edit view has been renedered but it does not show in the browser. Current controller code:
class HighwaysController < ApplicationController
respond_to :html, :json
def index
# #highways = Highway.all
# logger.debug "Highway Count: #{#highways.size}"
respond_to do |format|
format.html
format.json { render json: HighwaysDatatable.new(view_context) }
end
end
def edit
# logger.debug "Edit (render :layout => false) Highway ID #{params[:id]}"
#highway = Highway.find(params[:id])
logger.debug "Highway #{#highway.name}"
# render
respond_to do |format|
format.html
format.json { render json: HighwaysDatatable.edit(view_context) }
end
Is the $.get returning JSON ?
I have also tried a different approach. I have a link_to in the index view:
<div id ="highway_edit" >
<% #n = 11.to_s %>
<%= link_to "Edit 2", edit_highway_path(#n), :remote => true %>
</div>
This hard coded version works but I could not find a way to modify that link from within the javascript code so that it reflected the selected row id, or to call a function which would return the row id into the variable #n.
I realize that there must be some fundamentals I am missing so some suggested starting points for my education would be appreciated. I have read many other related questions but do not have enough knowledge to extract what I need.
PS I see that DataTables has an Editor feature which does pretty much what I want to achieve in the long run, but it is not 'Rails ready'.
Thanks!
EDIT:
In preparing this question I did not properly restore my code to the stage I wanted to discuss. So I have changed the controller code and the subsequent development log. So instead of a template error the problem is that the view is not rendered.
EDIT
I have proceeded with this problem and now have a result. I added a new div (class of 'result') to the top of my index view and changed my js code as follows:
var n = '/highways/' + aData[0][4] + '/edit'
$.get(n, function(data) {
$('.result').html(data);
and the edit view is rendered in that div. The result is ugly as it pushes the table down and doubles up the DataTable headers and footer. But at least it renders. I don't understand why this works when both ways go via the Edit method in the controller. I can now work on the cosmetics, or better still have the edit view appear as a modal overlay.
I would prefer to be able to click (or preferably double-click) a row and the edit view for that row be loaded. I will continue to look to do it that way. In the meantime I have added a link to the view:
<div id="EditLink">
<%= link_to "Edit Highway", :controller => :highways, :action => :edit, :id => 1 %>
</div>
and have the following code in the call back function:
"oTableTools": {
"sRowSelect": "single",
"fnRowSelected": function(node) {
var oTT = TableTools.fnGetInstance('highways');
var aData = oTT.fnGetSelectedData();
$("div#EditLink a").attr('href','/highways/' + aData[0][4] + '/edit')
}
},
which modifies the link based on the id of the selected row. Using this method the user has to know to first select a row and then click the link. If they do not first select a row they will go to the default (id = 1). You have to make sure that such an id exists in the table.
I have this in my form, it's really simple:
<script>
$(function() {
var availableProducts = [
<% #products.each do |p| %>"<%= p.id %> <%= p.title %> (<%= p.product_type.name %>)",<% end %>
""
];
$( "#tags" ).autocomplete({
source: availableProducts
});
});
</script>
That gives me lists of things like 1 Title (Trade Paperback). All rails needs of course, is the id attribute. I'd planned on updating a hidden field with the attribute, using the select: event, but I'm not quite sure how to extract just the id from the data source to update the hidden field with. Should I change the data source to something that can have keys? Like JSON? I still wouldn't know how to extract from that.
Here's what the above code looks like in straight html:
<script>
$(function() {
var availableProducts = [
"1 Test Title (eBook)",
"2 Another Test Title (eBook)",
""
];
$( "#products" ).autocomplete({
source: availableProducts
});
});
</script>
Your source should be an array of {value: , label: } pairs. The labels are what will be displayed and autocompleted on, but then you can store the value in a hidden input.
Here's an example:
http://jsfiddle.net/vZeHr/4/
and check out this sample on the jquery-ui docs page
http://jqueryui.com/demos/autocomplete/#custom-data
To generate the array from rails, you can do something like
var availableProducts = <%= #products.collect { :label => p.title, :value => p.id }.to_json ->;
When I run the following code in the view:
- if #object.winner.present? && #object.winner.prizes.any?
%ul
= #object.winner.prizes.each do |p|
%li= p.description.html_safe
It's returning this:
li prize1
li prize2
li prize3
...
[#<Prize object...> ... ]
Does anyone know why it is listing the #object.winner.prizes collection in the view directly after the last #object.winner.prizes object is displayed?
Extremely baffled! I'm using Rails v3.0.6
This is because you're using = when you should be using - to iterate over the objects:
- #object.winner.prizes.each do |p|