Set character limit in ejs - javascript

I am fetching content from JS in EJS template. I have a body field that contains more than 200 characters, but I want to show only 100 Characters in my view.

Simply you can put up an if else condition like this in your EJS Template:
<%if (yourField.length > 100) { %>
// Code to show 100 characters
<%= yourField.substring(0, 99) %>
<% } %>
<% else{ %>
//COde to print full value of your field
<%= yourField %>
<% } %>

Related

Nested url queries in ruby on rails

I'm making this choose your own adventure page and I'm using form_tag to accept user input. At the start of this page a user will enter a number through this text field
<% choice_1a = "1" %>
<% choice_1b = "2" %>
<%= form_tag("/pathfinder/quest1", method: "get") do %>
<center><%= text_field_tag(:a, #input_1, maxlength: 1) %>
<%= submit_tag("Submit") %></center>
<% end %>
<% input_1 = #input_1 %>
<% if input_1 == choice_1a %>
**Run code if user entered 1 **
<%= form_tag("/pathfinder/quest1", method: "get") do %>
<center><%= text_field_tag(:b, #input_2, maxlength: 1) %>
<%= submit_tag("Submit") %></center>
<% end %>
<% elsif input_1 == choice_1b %>
**Run code if user entered 2 **
<% else %>
** Prompt user to enter a 1 or 2**
<% end %>
Which results in this output in the url of the query "a" equaling whatever input was given. In this case I entered one ("&a=1")
https://192.168.0.200:3000/pathfinder/quest1?utf8=checkmark symbol&a=1&commit=Submit
After that path is taken they are given another form_tag that shown as below
Path if 1 was chosen at form_tag "a"
<%= form_tag("/pathfinder/quest1", method: "get") do %>
<center><%= text_field_tag(:b, #input_2, maxlength: 1) %>
<%= submit_tag("Submit") %></center>
<% end %>
When they enter a number here the url would change to this. Note how "a" was replaced with "b".
https://192.168.0.200:3000/pathfinder/quest1?utf8=checkmark symbol&b=1&commit=Submit
I was hoping to somehow nest these queries so that if a=1 I can have the user set the input to "b" it would still reflect their previous input to "a"
Here's a partial of the show section of the pathfinder controller that this code is running off
Controller code
if url == ('/pathfinder/quest1')
if params[:a].present?
#input_1 = "#{params[:a]}"
elsif params[:b].present?
#input_2 = "#{params[:b]}"
end
render 'quest1/index'
What I'm trying to do is give the user the option to set a=1 and then under that branch allow b to set 1 or 2. An example of what I'm trying to accomplish
a=1 (being one path) or a=2(being the other path)
| |
V V
b=1 <---> b=2 c=1 <-----> c=2
**Different paths if the user were to set "a" to one or two**
If the user set "a" equal to one, they would have the option of setting "b" to one or two. The same concept would be for "a" equal to two where the user would only have the option of setting "c" to one or two.
I'm open to any other ideas that doesn't require changing the url if its through html, css or javascript

Access form_group div via id

I want to perform a check to provide instant validation feedback on the input of a field in my bootstrap form for my Profiles model using java/coffee-script. My current solution is working but feels rather clunky and I would like to improve it.
Here are some code examples of what I'm doing.
app/views/profiles/_form:
<%= bootstrap_form_for(#profile, layout: :horizontal, html: {id: "profile-form"} ) do |f| %>
<%= f.text_field :name %>
<%= f.text_field :number, id: "number-field" %> //Field to check
<%= form_group do %>
<%= f.primary %>
<% end %>
<% end %>
app/assets/javascript/profile_number_control.coffee:
$(document).on 'ready page:load', ->
$field = $("#number-field")
$group = document.getElementById("profile-form").childNodes[5]
numberPattern = "^(19|20)[0-9]{6}-[0-9]{4}$"
$helpBlock = $group.getElementsByClassName("help-block")[0]
$field.keyup ->
//This works fine, just wanted to show what is going on
if inputIsValid()
set $group class to " has-success"
set $helpBlock message to successful
else
set $group class to " has-error"
set $helpBlock message to corresponding error message
Here is the problem. I want this script to work for both profile#new and profile#edit, but since the array of elements given by document.getElementById("profile-form").childNodes differs in length depending of the current view I can not use the same index (5 in the example) for both #new and #update.
Does anyone know how to set an id to that specific form_group in my view? Or do I have to actually write out the whole html code to be able to place an id there properly?
This might help !
<%= bootstrap_form_for(#profile, layout: :horizontal, html: {id: "profile-form"} ) do |f| %>
<%= f.text_field :name %>
<%= f.text_field :number, :input_html => { id: "number-field" } %> //Field to check
<%= form_group do %>
<%= f.primary %>
<% end %>
<% end %>

Rails - Dynamically Login People

I have a rails app and when user clicks to login button on header a bootstrap popup modal opens with a form, asks for user email and password. When user types and presses enter, I use window.location.reload(); and the button login turns in to a button with a text says "Welcome <%= current_user.name %>"
What I want to do is, instead of using window location reload, can I update this dynamically?
Here is my sessions#create action
def create
user = User.find_by(email: params[:session][:email].downcase)
respond_to do |format|
if user && user.authenticate(params[:session][:password])
if user.activated?
log_in user
params[:session][:remember_me] == '1' ? remember(user) : forget(user)
format.html { redirect_back_or user }
flash[:notice] = t('flash.sessions.create.success.html')
format.js #here I should do smth
else
format.html { redirect_to root_url }
format.json { render json: {email:['Account not activated. Check your email for the activation link.']} , status: :unprocessable_entity}
format.js { render json: {email:['Account not activated. Check your email for the activation link.']}, status: :unprocessable_entity }
end
then the create.js.erb
// close modal
$('#login-dialog').fadeToggle();
// clear form input elements
// todo/note: handle textarea, select, etc
$('form input[type="text"]').val('');
//Clear previous errors
$('.form-group.has-error').each(function(){
$('.help-block').html('');
$('.form-group').removeClass('has-error');
});
window.location.reload(); #here I am reloading the page then I can see login button disappears and new button saying Welcome Billy appears.
So how can I do that without reloading the window.
Thank you
EDIT
The thing is, I have also signup modal which user can click to open and these modal codes are in header.html.erb, when I render the page as you suggested it gives an error for sign up form;
<% modal ||= false %>
<% remote = modal ? true : false %>
<%= form_for(#user, remote: modal, :html => {role: :form, 'data-model' => 'user'}) do |f| %>
<div class="form-group">
<%= f.label :name, t('header.nameSurname') %>
<span class="help"></span>
<%= f.text_field :name, class: 'form-control' %>
<span class="help-block"></span>
</div>
<div class="form-group">
<%= f.label :username, t('header.username') %>
<span class="help"></span>
<%= f.text_field :username, class: 'form-control' %>
<span class="help-block"></span>
</div>
....
because of #user variable, if I change it to User.new is it ok?, would it create problem?.
I also have 3 different header partials. I normally render them in application.html.erb as;
<div id="render_main">
<% if #header_main %>
<%= render 'layouts/header_main' %> <!--Header comes here-->
<% elsif #header_listing %>
<%= render 'layouts/header_listing' %> <!--Header comes here-->
<% else %>
<%= render 'layouts/header' %>
<% end %>
</div>
But then in create.js.erb;
// close modal
$('#login-dialog').fadeToggle();
// clear form input elements
// todo/note: handle textarea, select, etc
$('form input[type="text"]').val('');
//Clear previous errors
$('.form-group.has-error').each(function(){
$('.help-block').html('');
$('.form-group').removeClass('has-error');
});
//window.location.reload();
<% if #header_main %>
$('#render_main').html('<%= j render "layouts/header_main"%>')
<% elsif #header_listing %>
$('#render_main').html('<%= j render "layouts/header_listing"%>')
<% else %>
$('#render_main').html('<%= j render "layouts/header"%>')
<% end %>
as I render it can not find #header_main variable I believe, so It does not work as it should be. How can I fix this?.
Main controller;
before_action :show_main_header, only: [:home]
def show_main_header
#header_main = true
end
Considering user login, from main controller home action. But it is probably because I actually run from session#create action. how can I fix it?
EDIT
firstly, thank you Rodrigo,
I have written a function to hold last action;
def location_action_name
if !logged_in?
url = Rails.application.routes.recognize_path(request.referrer)
#last_action = url[:action]
end
end
Then I write to create.js.erb;
<% if (#last_action == "home") %>
$('#render_main').html('<%= j render "layouts/header_main"%>')
<% elsif (#last_action == "listings") %>
$('#render_main').html('<%= j render "layouts/header_listing"%>')
<% else %>
$('#render_main').html('<%= j render "layouts/header"%>')
<% end %>
and worked! in case anyone wonders..
Let's say that you have an partial view for render the header (app/views/shared/_header.html.erb), what you need to do is rerender this partial and replace the header html:
create.js.erb
// window.location.reload();
$('#header-container').html('<%= j render "shared/header"%>')
EDIT:
If the #header_main and #header_listing variables are used to render the header partial, you'll need to instantiate them in your sessions#create action.
To do this, add the show_main_header filter to SessionsController too.

Variable inaccessible to JS when in partial

I have a signup form with JS validation. It works fine when the signup form is directly in the html. However, when the signup form is accessed via a partial, it fails to read the variables from the form. In that case the form always displays the error 'Please type in your name.'
JS:
$('.js-sign-up-submit').click(function(event) {
event.preventDefault ? event.preventDefault() : event.returnValue = false;
var nameFirst = $('.js-user-name-first').val();
if (!nameFirst) {
$('.js-sign-up-error').text('Please type in your name.');
}
...
});
html layout:
<body>
<%= render :partial => "/shared/header" %>
<% if notice %>
<p class="alert alert-notice"><%= notice %></p>
<% end %>
<% if alert %>
<p class="alert alert-error"><%= alert %></p>
<% end %>
<%= yield %>
<%= render :partial => "/shared/login_form" %>
<%= render :partial => "/shared/sign_up_form" %>
<%= render :partial => "/shared/password_reset_form" %>
<%= render :partial => "/shared/footer" %>
<%= javascript_include_tag "home" %>
</body>
Turns out the partial for the signup form was called in two places: in the layout file (as shown above) AND in the shared header file. So the JS was validating the signup form linked to in the layout which was not the one filled out by the user, hence failing to register the inputted text. We simply removed the duplicate signup partial in the header and it now works fine.

AJAX micropost's comments on the user page

On the user's page there are microposts and each of them have it's own comment form and comments. Using "Endless Page" railscast i'm trying to create "show more comments" button, which will load comments by AJAX. But it's not working.
The problem is in show.js.erb file because:
1) common pagination of comments (without AJAX) is working well
2) "show more button" is working well too. I tested it on the users list page
I think "show more comments" not working because it don'understand <%= j render(comments) %> , <%= j will_paginate(comments) %> and i should have here variables like <%= j render(#comments) %> , <%= j will_paginate(#comments) %>.
But when i try to write in my users_controller.rb
def show
#micropost = Micropost.find(params[:micropost_id])
#comments = #micropost.comments
end
it's not working because on my user's page there are many microposts and i have an error "Couldn't find micropost without an id". So in my microposts/_micropost.html.erb i had to use this
<% comments = micropost.comments.paginate(:per_page => 5, :page => params[:page]) %>
<%= render comments %>
Can anyone please help? How should i change my show.js.erb?
users/show.html.erb
<%= render #microposts %>
microposts/_micropost.html.erb
...
micropost's content
...
<%= render 'comments/form', micropost: micropost %>
<% comments = micropost.comments.paginate(:per_page => 5, :page => params[:page]) %>
<div class="commentaries">
<%= render comments %>
</div>
<div id="append_and_paginate">
<%= will_paginate comments, :class =>"pagination", :page_links => false %>
</div>
javascripts/users.js.coffee
jQuery ->
if $('.pagination').length
$('#append_and_paginate').prepend('<a id="append_more_results" href="javascript:void(0);">Show more</a>');
$('#append_more_results').click ->
url = $('.pagination .next_page').attr('href')
if url
$('.pagination').text('Fetching more...')
$.getScript(url)
users/show.js.erb
$('.commentaries').append('<%= j render(comments) %>');
<% if comments.next_page %>
$('.pagination').replaceWith('<%= j will_paginate(comments) %>');
<% else %>
$('.pagination').remove();
<% end %>
<% sleep 0.3 %>
Bennington, in users/show.html.erb you have
But #microposts is not defined in your controller. What I think you want is to define #microposts as all the microposts associated with what, a User?
If so, you'd want something like `#microposts = Micropost.where(:user_id => current_user.id) or something.

Categories

Resources