how to expand and collapase list - javascript

The following is working fine. But its only working for the first instance of the revenue other instance are just showing the list without collapse or expand. As the user clicks on the revene.Amount it should expand and show revenue.Q1, revenue.Q2, revenue.Q3 and revenue.Q4. And by default everything should be collapsed.
<% #estate.revenues.each do |revenue| %>
<tr>
<td><%= revenue.Year %></td>
<div id="listContainer">
<ul id="expList">
<li>
<%= revenue.Amount %>
<ul>
<li><%= revenue.Q1 %></li>
<li><%= revenue.Q2 %></li>
<li><%= revenue.Q3 %></li>
<li><%= revenue.Q4 %></li>
</ul>
</li>
</ul>
</div>
<%= link_to 'Destroy', estate_revenue_path(#estate,revenue), method: :delete, data: { confirm: 'Are you sure?' } %>
<%= link_to 'Edit', edit_estate_revenue_path(#estate,revenue) %>
<%= link_to 'View', estate_revenue_path(#estate,revenue) %>
<br/>
</tr>
<% end %>
<br />
<%= link_to 'New Revenue', new_estate_revenue_path(#estate.id) %>
<script>
function prepareList() {
$('#expList').find('li:has(ul)')
.click( function(event) {
if (this == event.target) {
$(this).toggleClass('expanded');
$(this).children('ul').toggle('medium');
}
return false;
})
.addClass('collapsed')
.children('ul').hide();
};
$(document).ready( function() {
prepareList()
});
</script>

Your selector is likely the issue here. Furthermore, I feel you are trying to do too much with your chaining. Please try the refactored version of your code below:
$(function() {
var $list = $('#expList'),
$listItem = $list.find('ul li'),
$listItemChildren = $listItem.children('ul');
function prepareList() {
$listItemChildren.hide();
$listItem.addClass('collapsed');
$listItem.on('click', onListItemClick);
};
function onListItemClick(event) {
$this = $(this);
if (this == event.target) {
$this.toggleClass('expanded');
$this.children('ul').toggle('medium');
}
return false;
};
prepareList();
});
It is good practice to cache selectors like I have done in the first few lines of the closure. If you are still having problems, log $listItem and make sure that it contains an array containing the 4 list items you expect. If the selection is correct, add a log inside of the onListItemClick callback and log out what this is etc. etc.

Related

Setting a variable when user selects from a dropdown

In my rails view, I have a dropdown menu of patients. When a user selects a patient, I want to set #patient to be Patient.find(id) where id a data attribute on the item the user selected.
How can I achieve this?
Action:
def options
#assessment = current_user.assessments.new
#patients = current_user.patients.sort_by{|e| e.first_name.downcase}
#patient = current_user.patients.new
#templates = Template.all
end
View:
<%= form_for #assessment, :method=>"get", :url => url_for(:action => 'new') do |f| %>
<%= f.select :patient_id, content_tag(:option,'select patient...',:value=>"")+content_tag(:option,'New Patient',:value=>"")+options_from_collection_for_select(#patients, 'id', 'full_name'), :class=>"form-control" %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<div class="row" id="assessment-type" style="display:none;">
// WANT TO SET #patient HERE TO WHATEVER THE USER SELECTED IN ABOVE SELECT TAG //
<% if #patient.has_past_assessments? %>
<%= link_to "New Injury", templates_path, :id=>"new-injury", :remote=> true %> or <%= link_to "Followup Assessment", "#" %>
<% end %>
<%= f.hidden_field :template_id %>
<% end %>
</div>
<script>
$(function(){
$('#assessment_patient_id').chosen({width: "100%"});
});
$('#assessment_patient_id').change(function(){
var e = document.getElementById("assessment_patient_id");
var patient_id = (e.options[e.selectedIndex].value)
if (patient_id == 0) {
window.location.href = "/patients/new"
} else {
$('#assessment-type').slideDown(350);
}
$('#assessment-type').find('.template').on('click', function(){
startSpinner()
var templateId = parseInt($(this).find('a').attr("id"));
$('#assessment-type').find('.template').removeClass('active');
$(this).addClass('active');
$('#assessment_template_id').val(templateId);
$('.new_assessment').submit();
});
});
</script>

Change an forEach depending on the locale

<% if (locale === 'pt') {
data[i].info.pt.forEach(function(info) { %>
<li><%= info %></li>
<% }); %>
<% } else if (locale === 'en') {
data[i].info.en.forEach(function(info) { %>
<li><%= info %></li>
<% } else if (locale === 'es') {
data[i].info.es.forEach(function(info) { %>
<li><%= info %></li>
<% } %>
I have a variable called locale, which changes the value according to the language of the site, and I'm doing this forEach on an object, depending on the value of the locale, is there any way to make this better?
I was trying like this:
<% data[i].info. + locale + .forEach(function(info) { %>
<li><% info %></li>
<% }); %>
But it seems that I can not.
Use bracket notation:
<% data[i].info[locale].forEach(function(info) { %>
<li><% info %></li>
<% }); %>

How to Change Date Format According to User Selection?

How can I change the date :order according to the User's "f.select :categories" choice?
For example when a User goes to the Quantified _form he can select between "Monthly Average" or "One-Time Instance";
If he selects "Monthly Average" I want the _results_fields.html.erb to provide the date selection as ":order => [:month, :year]" if he selects "One-Time Instance" I want the _results_fields.html.erb to provide the date selection as ":order => [:month, :day, :year]
Ideally this would be done dynamically via javascript, but I would be happy to accept an answer that does it via the view.
_results_fields.html.erb
<div class="nested-fields">
<div class="form-group">
<%= f.text_field :result_value, class: 'form-control', placeholder: 'Enter Result' %>
<br/>
<%= f.date_select :date_value, :order => [:month, :year], class: 'date-select' %>
<%= link_to_remove_association "Remove Result", f %>
</div>
</div>
_form.html.erb
<%= form_for #quantified do |f| %>
<div class="america">
<%= f.select :categories, Quantified::CATEGORIES %>
<br/>
<br/>
<div class="form-group">
<%= f.text_field :name, class: 'form-control', placeholder: 'Enter Name' %>
</div>
<div class="form-group">
<%= f.text_field :metric, class: 'form-control', placeholder: 'Enter Metric' %>
</div>
<div id="results">
<%= f.fields_for :results do |result| %>
<%= render 'result_fields', :f => result %>
<% end %>
</div>
<div class="links">
<%= link_to_add_association 'add result', f, :results %>
</div>
<%= f.submit %>
</div>
<% end %>
quantified.rb
class Quantified < ActiveRecord::Base
belongs_to :user
scope :averaged, -> { where(categories: 'Monthly Average') }
scope :instance, -> { where(categories: 'One-Time Instance') }
has_many :results
accepts_nested_attributes_for :results, :reject_if => :all_blank, :allow_destroy => true
CATEGORIES = ['Monthly Average', 'One-Time Instance']
end
Github: https://github.com/RallyWithGalli/ruletoday
Thank you for your time.
The answer here was to use some jquery provided by the gem that was being used to add the date selects, as well as some jquery of our own
First things first, we rig up the checkboxes with a click() event, that hides anything with the class 'day' if instance is checked, and shows it if not.
$('.date-toggle').click(function(){
if( $(this).attr('id') == 'instance') {
$('.day').show();
} else {
$('.day').hide();
}
});
The trick here is to use the rails date select option :with_css_classes on the date select, so that it looks like this:
<%= f.date_select :date_value, :order => [:month, :day, :year], :with_css_classes => true, class: 'date-select' %>
This causes each included field to get a class corresponding to its name, hence our reference to '.day' up there.
The next important part, however, because he is using a gem called cocoon to add new elements that included date fields, we had to use some of their jquery event bindings to make sure that the new ones got the right action applied to them.
$('#container').on('cocoon:after-insert', function(e, insertedItem) {
if($('#instance').is(':checked')) {
$('.day').show();
} else {
$('.day').hide();
}
});
Technically, the $('.day').show() is not necessary, because it defaults to being shown, but this, to me, gets across the intent a little clearer.
I think my solution is a little bit messy, but hopefully it gives you an indication of my train of thought and give you something to build upon.
I have changed your categories to work with a radio button group because the select field is a bit weird for 2 elements (subjective I know), to change it back to a select form,simply keep your code as is, but you will need to check the value of the select dropdown using jQuery .change() or some other vanilla Javascript way...
You haven't provided any controller names, so I didn't know how to name my JS file, but hopefully you know how to integrate.
IMO, I'm not sure why this needs AJAX, so maybe you can explain to me where that comes in.
_form.html.erb
<%= Quantified::CATEGORIES.each do |c| %>
<%= f.radio_button(:category, c) %>
<%= label(c, c) %>
<% end %>
_results_fields.html.erb
<%= f.date_select :date_value, :order => [:month, :year], class: 'date-select-my' %>
<%= f.date_select :date_value, :order => [:month, :year], class: 'date-select-mdy' %>
vanilla.js
$(document).ready(function(){
$('.date-select-mdy').hide();
$('.date-select-mdy').attr("disabled", true);
$('input[name$=\category\']').click(function() {
var target_value;
target_value = $(this).val;
if (target_value === 'Monthly Average') {
$('.date-select-my').show();
$('.date-select-mdy').hide();
$('.date-select-my').attr("disabled", false);
return $('.date-select-mdy').attr("disabled", true);
} else {
$('.date-select-my').hide();
$('.date-select-mdy').show();
$('.date-select-my').attr("disabled", true);
return $('.date-select-mdy').attr("disabled", false);
}
});
});
a_little_bit_of_coffee_because_i_dislike_js.coffee
$->
$('.date-select-mdy').hide()
$('.date-select-mdy').attr("disabled",true)
$('input[name$=\category\']').click ->
target_value = $(this).val
if target_value == 'Monthly Average'
$('.date-select-my').show()
$('.date-select-mdy').hide()
$('.date-select-my').attr("disabled",false)
$('.date-select-mdy').attr("disabled",true)
else
$('.date-select-my').hide()
$('.date-select-mdy').show()
$('.date-select-my').attr("disabled",true)
$('.date-select-mdy').attr("disabled",false)
return

adding value again and again in javascript

In my JavaScript I have three Links. The second link is open depends upon the first link id selected. Everything works fine. But After selecting the second link, if i want to change the first link, the second link is still opens for the old id.If I want to change the first link, all the fields should change and opens as per the first link.
var generic_lookup_Enr_Rds_Section2009_selected = function(id, to_s) {
var question_link = $('#question_picker').attr('href');
question_link = question_link.replace(/\?+$/, '');
question_link = question_link + '?columns[enr_rds_section_id]=' + id;
$('#question_picker').attr('href', question_link);
$("#modal_popup").dialog("destroy");
};
var generic_lookup_Enr_Rds_Question2009_selected = function(id, to_s) {
var answer_link = $('#answer_picker').attr('href');
answer_link = answer_link.replace(/\?+$/, '');
answer_link = answer_link + '?columns[enr_rds_question_id]=' + id;
$('#answer_picker').attr('href', answer_link);
$("#modal_popup").dialog("destroy");
};
html
<div class="question">
<%= f.label :Section %>
<%= link_to pro_generic_lookup_data_path("Enr::Rds::Section2009", format: :js), data: {remote: true} do %>
<%= image_tag("Search-icon.gif", border: 0, :alt => "Look up Sections", title: 'Lookup Sections') %>
<% end %>
</div>
<div class="question">
<%= f.label :Question %>
<%= link_to pro_generic_lookup_data_path("Enr::Rds::Question2009", format: :js), data: {remote: true}, id: "question_picker" do %>
<%= image_tag("Search-icon.gif", border: 0, :alt => "Look up Questions", title: 'Lookup Questions', :class => "image_section_search") %>
<% end %>
</div>
Solved it by Javascript using cascading dropdown function by example. Thanks guys.

Refresh a div when a user signs in via ajax?

I currently have a <ul> in my navigation area which holds a <%= render :partial => "sessions/manager" %> which basically calls another partial which depending on the users login status renders either a login form or a welcome statement.
My login section is powered by ajx and so refreshes automaticlly. Here's the code im using.
login.js
$(document).ready(function() {
$('form#sign_in').bind('ajax:success', function(e, data, status, xhr) {
console.log(data);
if(data.success) {
$('.user_nav').html(data.content);
} else {
$('.user_nav').prepend(data.errors.join('<br />'));
}
});
});
Now I want another div on my page containing various links to either hide or show depending on the users logged in status.
Currently my code is this.
<% if(signed_in?) %>
<li><%= link_to "Clients", "/clients" %></li>
<li><%= link_to "Jobs", "/jobs" %></li>
<% else %>
<% end %>
However, this doesn't work how id like. The links don't show at first which is cool BUT the links don't show again when im signed in... unless I do a full page refresh.
How can I ajax-ify this section?
The easiest thing is to put the divs on the page and then set toggle their visibility with javascript.
Put this in your code:
<li class="login-show" <%= signed_in? ? "" : "style='display:none'" %> >
<%= link_to "Clients", "/clients" %>
</li>
<li class="login-show" <%= signed_in? ? "" : "style='display:none'" %> >
<%= link_to "Jobs", "/jobs" %>
</li>
And then this is your js:
$('form#sign_in').bind('ajax:success', function(e, data, status, xhr) {
console.log(data);
if(data.success) {
$('.user_nav').html(data.content);
// show the li items hidden from non-logged in users
$('.login-show').show();
} else {
$('.user_nav').prepend(data.errors.join('<br />'));
}
});
});
That should work. but to keep things really tidy, I would move this junk:
<%= logged_in? "" : "style='display:none'" %>
into a helper method

Categories

Resources