Display Buttons in a Horizontal Row and Highlight the Active Button

I am presenting four buttons that trigger POST requests, therefore they are enclosed in a form:

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

<form action="books/all" method="POST>
  <input class="btn btn-md btn-success" type="submit" value="All Books"></input>
</form>
<form action="books/fiction" method="POST">
  <input class="btn btn-md" type="submit" value="Fiction"></input>
</form>
<form action="books/biographys" method="POST">
  <input class="btn btn-md" type="submit" value="Biography"></input>
</form>
<form action="books/new" method="POST">
  <input class="btn btn-md" type="submit" value="New"></input>
</form>

I would like to know how I can

  1. arrange the four buttons horizontally and evenly spaced across the page (rather than all together)
  2. employ JS/JQuery or plain CSS to highlight the clicked button with the btn-success class while removing it from the others.

Even though these are POST requests, users will be redirected back to the same page, so ideally the last clicked button should appear as active.

Answer №1

Set the buttons to display inline-block:

form[action^="books/"] {
  display: inline-block;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

<form action="books/all" method="POST">
  <input class="btn btn-md btn-success" type="submit" value="All Books"></input>
</form>
<form action="books/fiction" method="POST">
  <input class="btn btn-md" type="submit" value="Fiction"></input>
</form>
<form action="books/biographys" method="POST">
  <input class="btn btn-md" type="submit" value="Biography"></input>
</form>
<form action="books/new" method="POST">
  <input class="btn btn-md" type="submit" value="New"></input>
</form>

Use jQuery to handle classes:

$('form[action^="books/"] > input').on("click", function (event) {
  if (event.target !== this) return; //Event was bubbled to the form
  
  event.preventDefault(); //Prevent the submission, can be removed as it is purely for example
  
  $('form[action^="books/"] > input').removeClass("btn-success");
  
  $(this).addClass("btn-success");
});
form[action^="books/"] {
  display: inline-block;
  margin: 5px; /*Fix position*/
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

<form action="books/all" method="POST">
  <input class="btn btn-md btn-success" type="submit" value="All Books"></input>
</form>
<form action="books/fiction" method="POST">
  <input class="btn btn-md" type="submit" value="Fiction"></input>
</form>
<form action="books/biographys" method="POST">
  <input class="btn btn-md" type="submit" value="Biography"></input>
</form>
<form action="books/new" method="POST">
  <input class="btn btn-md" type="submit" value="New"></input>
</form>

I hope you find this useful!

Answer №2

Dealing with Content Alignment

When it comes to aligning content, there are various methods at your disposal. Options like flexbox, grid, or utilizing classes for centering items through translations can be explored. In this scenario, employing flexbox seems like a suitable choice due to its user-friendly nature.

For more insights, refer to: https://css-tricks.com/snippets/css/a-guide-to-flexbox/

Regarding Page Reloading

I strongly advise against reloading the page using POST-Requests.

If absolute necessity demands it, one could establish the "active" class logic based on the URL. This simple if-else logic would ideally reside within the page controller or relevant component in use.

In scenarios where page reload is not mandatory, toggling classes via JavaScript remains a viable option. However, do note that such changes will not persist post-reload. For single-page applications, this might suffice. While storing selection states in cookies or sessions is plausible theoretically, it may not be the ideal approach.

Another approach involves incorporating links with route symbols like # within the href. This enables state retention within the URL sans page reloading, facilitating direct scrolling or jumping to referenced elements.

The example demonstrated below illustrates how selection status is lost after a reload:

const menuItems = document.querySelectorAll('.menu a.btn');

const selectItem = (i, menuItems) => {
  for (let j = 0; j < menuItems.length; j++) {
    menuItems[j].classList.remove('btn-success');
  }
  menuItems[i].classList.add('btn-success');
}

for (let i = 0; i < menuItems.length; i++) {
  menuItems[i].addEventListener('click', (e) => {
    e.preventDefault();
    selectItem(i, menuItems);
    return false;
  });
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

<nav class="menu" role="navigation">
  <a href="books/all" class="btn btn-md btn-success" role="button">All books</a>
  <a href="books/fiction" class="btn btn-md" role="button">Fiction</a>
  <a href="books/biography" class="btn btn-md" role="button">Biography</a>
  <a href="books/new" class="btn btn-md" role="button">New</a>
</nav>

An alternative method you could implement is as follows:

const menuItems = document.querySelectorAll('.menu a.btn');

const selectItem = (i, menuItems) => {
  for (let j = 0; j < menuItems.length; j++) {
    menuItems[j].classList.remove('btn-success');
  }
  menuItems[i].classList.add('btn-success');
}

for (let i = 0; i < menuItems.length; i++) {
  menuItems[i].addEventListener('click', (e) => {
    selectItem(i, menuItems);
  });
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

<nav class="menu" role="navigation">
  <a id="#books/all" href="#books/all" class="btn btn-md btn-success" role="button">All books</a>
  <a id="#books/fiction" href="#books/fiction" class="btn btn-md" role="button">Fiction</a>
  <a id="#books/biography" href="#books/biography" class="btn btn-md" role="button">Biography</a>
  <a id="#books/new" href="#books/new" class="btn btn-md" role="button">New</a>
</nav>

The # symbol can also be utilized in CSS by means of the :target selector.

Answer №3

For those wondering about CSS, I recommend looking into Flexbox. Check out this guide to Flexbox here.

In response to the second question, I've attempted a solution, but I'm not entirely sure if it aligns with what you're seeking. When a form is submitted, the browser typically refreshes the page, undoing any changes made by JavaScript or jQuery.

I'm new to stack overflow, so please feel free to provide feedback on my answer if there are any inaccuracies.

$(() => {
  $('.btn').click(function(event) {
    currentButton = event.currentTarget;
    $(currentButton).toggleClass( "btn-success" );
  });
});
.container {
  display: flex;
  flex-flow: row nowrap;
  justify-content: space-between;
  width: 100%;
  padding: 16px
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">


<div class="container">
  <button class="btn btn-md">Example button to test the jQuery</button>
  <form action="#" method="POST">
    <input class="btn btn-md btn-success" type="submit" value="All Books"></input>
  </form>
  <form action="books/fiction" method="POST">
    <input class="btn btn-md" type="submit" value="Fiction"></input>
  </form>
  <form action="books/biographys" method="POST">
    <input class="btn btn-md" type="submit" value="Biography"></input>
  </form>
  <form action="books/new" method="POST">
    <input class="btn btn-md" type="submit" value="New"></input>
  </form>
</div>

<script src="https://code.jquery.com/jquery-3.6.0.slim.min.js" integrity="sha256-u7e5khyithlIdTpu22PHhENmPcRdFiHRjhAuHcs05RI=" crossorigin="anonymous"></script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

If I needed to include extra information within an element for easy retrieval using JavaScript

Using PHP, I have generated a list of products in a <select> element. Each product has a weight that I want to store within each <option> so I can access it later using Javascript. Is there a way to include the weight data directly in the HTML ...

Showing a vertical arrangement of lists containing updated information

I am struggling to create lists that seamlessly flow together to showcase data. I am using the following website as a reference: I have examined the style sheet thoroughly but I cannot figure out how they are achieving this effect. I am hoping someone can ...

Creating a dynamic 2x2 grid with centered responsiveness in Angular Ionic framework

I'm having trouble achieving a 2 x 2 grid that is centered on my screen. The code snippet below shows what I have so far in the HTML file. Just to provide some context, this project is meant for a native mobile application. <ion-header> <i ...

React Native - Issue with Chart not updating correctly when new data is added

I'm struggling to create a dynamic chart using the Victory-Native library (click here for documentation). The goal is to modify the chart after pressing the "Get Data" button, but I've encountered a problem that has me stumped after hours of att ...

Checking for CSS-truncated text with JavaScript

I am currently working on a JavaScript project to determine if text is truncated. While I found a useful solution mentioned here, there is one edge case that needs to be addressed. Despite the visual truncation of the text, the first block on mouse hover i ...

When resizing an anchor tag with a percentage in CSS, the child image width may not scale accordingly

In short, I have multiple draggable images on a map enclosed in anchor tags (<a><img></a>) to enable keyboard dragging. The original image sizes vary, but they are all too large, so I reduced them to 20% of their original sizes using the ...

I am having trouble with my scripts not working on a rendered partial view after using ajax to render it. Specifically, my datetimepicker is not functioning properly

I have implemented the following action on my controller: public ActionResult Absent() { Response.Cache.SetCacheability(HttpCacheability.NoCache); Response.Cache.SetExpires(DateTime.UtcNow.AddHours(-1)); Response.Cache.SetNoSto ...

What are the steps for positioning the footer at the bottom of the page?

Need help positioning a footer at the bottom of the page? Using the class fixed-bottom causes the footer to overlap the content when scrolling. <div class="sticky-top"> <qipr-header></qipr-header> <qipr-sidenav>&l ...

jQuery tabs become non-functional following submission of form

I have a form contained within a jQuery tab div that is loaded using AJAX: <div id="tabs-2"> <form id="frmLogin" name="frmLogin" class="cmxform" method="post" action="actions/login.php"> <p> <label>Username& ...

The JSON data appears to be correct, yet it is not functioning properly when transmitted to X

I have a JSON object that has been validated using https://jsonlint.com/. However, I am encountering an error when trying to use this JSON with the Xero API as shown below. { "Type": "ACCREC", "Status": "AUTHORISED", "DueDate": "2021-12-11T14:24:0 ...

Is it possible to modify a dependency import based on the specific request?

How can I switch between test mode and live mode using Stripe's SDK based on a query parameter in my internal form service for collecting payments? For example, consider this route: router.post("/:formId", function(req, res, next) { let isTest ...

Utilize data attributes for streamlined markup efficiency

I'm facing a challenge with two almost identical animations, the only difference being the positioning of "left vs right". I want to find a way to reuse the same block of code for both .forward and .backward. I have considered using HTML 5 data-attrib ...

using vuejs, learn how to retrieve properties within the .then function

This is the code I am working on: methods: { async pay() { this.$notify(`working`); if (!this.$v.$invalid) { try { var data = { to: this.to, subject: this.subject, }; let resp ...

Attempting to display numerous react components on various divs instead of just one ID

Currently, I am facing a challenge in creating multiple react comment boxes. The package I am using is based on #id instead of class, which resulted in only rendering one box instead of all. To resolve this issue, I attempted to switch from GetelemntbyID t ...

The premature reveal of the back side in the Kendo UI flip effect on Internet Explorer

Currently, I am in the process of creating a BI dashboard for a business application using JavaScript Kendo UI version v2014.1.416. Unfortunately, I have encountered an issue with certain visuals while testing on IE11. I must mention that due to practical ...

Tips for integrating leaflet maps according to the number of elements in your dataset

I'm looking to incorporate leaflet maps onto my page, under the following conditions: If there is only one map, it should span the entire width using bootstrap grid columns. If there are two maps, they should be placed side by side with equal column ...

Having trouble displaying json data in an HTML file with d3.js

I am having trouble loading data from a json file into an HTML file and using D3 to visualize it. Even though the file loads correctly and is verified with a 200 status, the contents are interpreted as null. Below are the contents of the json file: [{"to ...

Incorporating Bootstrap 4 into your Grails project

Currently utilizing Grails for a web project as part of my CSE course in college. Interestingly, most other groups working on this project have opted for Bootstrap 4 for web design (my group is the only one using Grails). After exploring Bootstrap 4, I am ...

What is the best way to design a grid consisting of 14 divs that span the entire width of the browser screen, incorporating dividers to separate different groups, utilizing a combination of html,

I am interested in creating a layout with two rows of divs that span the entire width of the screen, with a total of 14 divs in each row. These divs are fixed in size and grouped by color, with dividers separating each color group. I am hoping to achieve ...

When the text input is selected, automatically scroll to the bottom

I found a codepen example by Chris Coyer and decided to fork it. My goal is to make the label move to the top instead of staying at the bottom, as in his original design. However, I am facing an issue with getting the cursor to move to the bottom when typ ...