I have a rails app which displays steps and substeps in rows. I'm looking to create an action where clicking on a step row will change it's class from 'step_container' to 'step_container active', and then show the corresponding substep rows for that step. I have had a difficult time figuring out how to use AJAX (or understanding if that is the best tool) to accomplish this.
<% #steps.each do |step| %>
<div class="step_container"> <!-- add 'active' if clicked-->
<div class="medium-8 columns"><!-- add 'active_container' if clicked-->
<div class="medium-5 columns step_info">
<div class="step_number">
<span><%= step.order %></span>
</div>
<div class="custom_step">
<span class="step_title"><%= step.title %> (custom step)</span>
<span class="step_desc"><%= step.description %></span>
</div>
</div>
</div>
<!-- Only show this div if top div is clicked -->
<div class="medium-4 columns sub_steps_container">
<% #substeps.where(step_id: step.id).each do |substep| %>
<div class="sub_steps">
<div class="step_number">
<span><%= substep.order %></span>
</div>
<div class="">
<span class="step_title"><%= substep.action %></span>
<span class="step_desc"><%= substep.description %></span>
</div>
</div>
<% end %>
</div>
</div>
<% end %>
Thanks in advance for assistance. This has taken me most of the day with limited results.
There is no need for AJAX here, just little bit of javascript and css.
JavaScript:
$('.step_container').click(function() {
$(this).addClass('active');
}
CSS (sass):
.step_container {
.sub_steps_container {
display: none;
}
&.active {
.sub_steps_container {
display: block;
}
}
}
If I understand you correctly, you won't actually need Ajax for this. This could be pretty simple:
Hide the sub_step_container div initially via css.
.sub_steps_container {
display: none;
}
Add this to your HTML code (or better yet, don't use script tags and use in separate JS file).
<script>
$('.step_container').on('click', function(){
$(this).addClass('active');
$('.sub_steps_container').show()
});
</script>
Related
SO i am trying to change the value of an html tag in an ejs file to a variable i declared in a JavaScript file
let checkbox = document.querySelector('input[name="plan"]');
checkbox.addEventListener('change', function () {
if (this.checked) {
document.querySelector('.plan-title').innerHTML = investment.name;
document.querySelector('.plan-description').innerHTML = investment.description;
}
else {
document.querySelector('.plan-title').innerHTML = '';
document.querySelector('.plan-description').innerHTML = '';
}
});
So when I pass it directly it shows but I want it to be dynamic and Although it gets pass through when i click the checkbox it doesn't seem to have any value.
<%- include('../partials/sidebar'); %>
<% if(currentUser && currentUser.isAdmin){ %>
Add New Plan
<% } %>
<div class="container">
<h1>Investments</h1>
<% investments.forEach((investment)=>{ %>
<div class="col-md-4">
<div class="card">
<strong>
<%= investment.name %>
</strong>
<h4>
<%= investment.min %> - <%=investment.max %>
</h4>
<p>
<%= investment.caption %>
</p>
<p><input type="checkbox" name="plan" id="">Choose investment</p>
</div>
<% if(currentUser && currentUser.isAdmin){ %>
Edit
Delete
<% } %>
</div>
<% }) %>
<% investments.forEach((investment)=>{ %>
<div class="">
<div><strong>Package: </strong>
<p class="plan-title">
</p>
</div>
<p class="plan-description">
</p>
<input type="number" name="" id="" min="<%= investment.min %>"
max="<%= investment.max %>">
</div>
<% }) %>
</div>
<%- include('../partials/footer'); %>
I cant seem to get through this, need help thanks!
If I got it right, you are trying to insert the value of the EJS variable in the HTML tag from JavaScript when the user clicks the checkbox.
The value of the HTML tag doesn't change because in your JS code:
document.querySelector('.plan-title').innerHTML = investment.name;
document.querySelector('.plan-description').innerHTML = investment.description;
investment.name and investment.description are undefined. Check the console on your page.
This is because you tried accessing EJS variables after the page finished rendering.
EJS is mainly used to pass server-side variables to the page before it is rendered. So once it's rendered you cannot access those variables.
So to have the values of those variables in your JavaScript after the page finishes rendering, try doing:
document.querySelector('.plan-title').innerHTML = '<%- investment.name %>';
document.querySelector('.plan-description').innerHTML = '<%- investment.description %>';
instead. This is how you pass the EJS variable to JavaScript. JavaScript now sees it as a string and there's no problem, unlike in your code where it was looking for investment object and returned undefined since that variable is not defined on the client-side.
Also, since you have a for-each loop in the HTML part, I'm assuming you are trying to change the values of specific plan-title and plan-description divs. If that's the case, '<%= investment.name %>' and '<%= investment.description %>' in JavaScript part should be in a for-each loop as well, but that would be a lot of mess.
I suggest you instead to right under the for-each loop in the HTML part, add class to the div tag according to the index of the for-each loop, add on change event to the checkbox, and pass the checkbox and the index of the for-each loop to the JavaScript function which would handle the on change event, include the EJS variables in the plan-title and plan-description divs, and in the JavaScript function that handles on change event change the CSS display property from display: none to display: block to these divs.
See an example:
HTML:
<% investments.forEach((investment, index)=>{ %>
<div class="col-md-4">
<div class="card">
<strong>
<%= investment.name %>
</strong>
<h4>
<%= investment.min %> - <%=investment.max %>
</h4>
<p>
<%= investment.caption %>
</p>
<p><input onchange="displayPlan(this, '<%= index %>')" type="checkbox" name="plan" id="">Choose investment</p>
</div>
<% if(currentUser && currentUser.isAdmin){ %>
Edit
Delete
<% } %>
</div>
<% }) %>
<% investments.forEach((investment, index)=>{ %>
<div class="plan <%= index %>" style="display: none;">
<div><strong>Package: </strong>
<p class="plan-title">
<%- investment.name %>
</p>
</div>
<p class="plan-description">
<%- investment.description %>
</p>
<input type="number" name="" id="" min="<%= investment.min %>"
max="<%= investment.max %>">
</div>
<% }) %>
JavaScript:
function displayPlan(checkbox, id){
if (checkbox.checked) {
document.querySelector(`.plan.${id}`).style.display = 'block';
}
else {
document.querySelector(`.plan.${id}`).style.display = 'none';
}
}
Cheers!
EDIT: Grammar and syntax issues
It's not clear to me what variable you're referring to, but any variable you set in a client-side script will not be available to you in an EJS file that you're rendering on the server. Server-side Node.js code and client-side JavaScript code have no knowledge of each other.
I have two forms on a page which have mostly the same inputs. I have tabs on the screen that switch between each form. However when i submit one of the forms, i recieve a 'cant be blank' on the same input fields on the other form. I understand why this is happening. I tried to stop this by using a if statement to only render either form depending on which tab is clicked. This did not work as you cant target html id's in an if statement. Then i tried to use javascript which used a 'show' and 'hide' methods depending on which tab was clicked which also didnt work as i believe that that even though the form is still hidden, it is still actually there. Now im not sure what to do. My only idea is to render the forms within javascript?
<input id="tab1" type="radio" name="tabs" checked>
<label class="label-header" for="tab1"> UK Address</label>
<input id="tab2" type="radio" name="tabs">
<label class="label-header"for="tab2"> International Address </label>
<!-- <section id="content1"> -->
<%# if %>
<%= f.simple_fields_for :address do |fields| %>
<%# raise %>
<section id="content1">
<%= render "address/fields", fields: fields, addressable: addressable %>
</section>
<% end %>
<%# else %>
<%= f.simple_fields_for :address do |fields| %>
<section id="content2">
<%= render "address/international_fields", fields: fields, addressable: addressable %>
</section>
<% end %>
$(document).ready(function() {
var uk_address = $('#content1');
var international_address = $('#content2');
$('#tab1').on('click', function() {
uk_address.show();
international_address.hide();
});
$('#tab2').on('click', function() {
uk_address.hide();
international_address.show();
});
});
You should be able to enable/disable the items inside the javascript you have with this modification:
$(document).ready(function() {
var uk_address = $('#content1');
var international_address = $('#content2');
$('#tab1').on('click', function() {
uk_address.removeAttr("disabled").show();
international_address.attr("disabled", "disabled").hide();
});
$('#tab2').on('click', function() {
uk_address.attr("disabled", "disabled").hide();
international_address.removeAttr("disabled").show();
});
});
I have the Jquery code below:
$(document).ready(function() {
$('tr[href]').click(function(event) {
$('tr[href]').removeClass('selected')
$(this).addClass('selected');
event.preventDefault();
$('#profile').load('home/users/1');
event.stopPropagation();
});
});
Every time I click the target, I found the .load function load the window double times the last click. For example, in the rails log it shows several Started GET "/home/users/1in the same time thus my app becomes slow and slow. Below is the view file where the window is loaded:
<div class="col-md-5" >
<div class="table table-responsive" >
<div id='list' >
<% if params[:q] == 'a' %>
<%= render 'users' %>
<% elsif params[:q] == 'b' %>
<%= render 'jobs_index' %>
<% else %>
<%= render 'lineitems' %>
<% end %>
</div>
</div>
</div>
<div class="col-md-5">
<div id="profile">//load the window
</div>
Could any body tell me why this occurs? Very thanks!
I solved it.
I modified the code $('#profile').load('home/users/1'); in application.js as below:
var url="home/users/"+$(this).attr("href")
$('#profile-outline').load(url+" #special");
And add a in the outermost of the html file.Then the problem is solved.
In summary, just use load("url #container") to replace load("url").
Well, i have a div hide in my content and make a buttom to show this but the problem is i have many elements whit this names so i make this function to solve:
$("a.all_com").click(function(){
$(this).nextAll("div:first").slideToggle();
});
This function dont works, i try use meet this:
$("a.all_com").click(function(){
$(this).next("div").slideToggle();
});
and
$("a.all_com").click(function(){
$(this).nextAll("div").slideToggle();
});
Nobody works whit me please someone solution, the this is to apply some in the element actually.
My code to show/hide is this:
<div id="task_footer">
Comentar
Comentários
</div>
<div id="comment_list" style="display:none;" >
<% tasks.comments.each do |c| %>
<% if c.user %>
<p class="one_comment">
<strong><%= c.user.email %></strong>
<%= c.comment %>
</p>
<% end %>
<% end %>
</div>
I am using rails3 and on my page i am iterating a loop which have some records and i want when
user click on some row its color will be green and when he again click some row its color will
be green and the color of previous highlighted row should be none.
Thanks in advance
My code is like this
<div class="top-heading-detail-admin">
<div class="table-headings">
<div class="email-admin"><p>Email</p></div>
<div class="date-admin"><p>Date Added</p></div>
<div class="added-by-admin"><p>Added by</p></div>
</div>
<div id="checkbox_list">
<% #users.each do |user| %>
<div class="email-admin-detail"><%= user.email %></div>
<div class="date-admin-detail"><%= user.created_at.strftime("%m/%d/%Y") unless user.created_at.blank? %></div>
<div class="added-by-admin-detail"><%= user.added_by %></div>
</div>
<% end %>
</div>
</div>
http://jsfiddle.net/r8mY4/9/
I wrapped your user details row in a div then applied a click event, please check if that's what you want :)
$('.user-details').click(function() {
$('.user-details').css('background', 'transparent');
$(this).css('background', 'green');
});
I think you should use table why you are using div tags for table.If you want to highlight
row using this.Try out this code i think its work..But you need to make an extra div inside it
<div id="checkbox_list">
<% #users.each do |user| %>
<div id="<%= user.id %>" onclick="admin_select('<%=user.id%>')" class="admin-select">
<div class="email-admin-detail"><%= user.email %></div>
<div class="date-admin-detail"><%= user.created_at.strftime("%m/%d/%Y")%></div>
<div class="added-by-admin-detail"><%= user.added_by %></div>
</div>
<% end %>
i am making extra div and give this user id and also call onclick javascript event on it.
Here is jquery code for it
function admin_select(id) {
$(".admin-select").children().each(function () {
$(this).removeClass("color_class");
});
$("#" + id).children().each(function () {
$(this).addClass("color_class");
});
}
Check it....