I am developing a spring boot web application. In the view for products list, when I want to delete one of the rows after clicking on "Yes" when the pop up appears, the row delete is always the first in the table, not the chosen row. I think I have an issue with my loop. I am using Bootstrap with thymeleaf
index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymleaf/layout">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<title>Product Management</title>
</head>
<body>
<header>
<div class="navbar navbar-inverse">
<div class="container-fluid">
<ul class="nav navbar-nav">
<li><a th:href="#{/}">Products list</a></li>
<li><a th:href="#{/new}">Add a product</a></li>
</ul>
</div>
</div>
</header>
<div align="center">
<br /> <br />
<h2>
<b><p class="bg-danger">PRODUCTS LIST</p></b>
</h2>
<br /> <br />
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Manufacturer</th>
<th>Country</th>
<th>Price</th>
<th>Designation</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr th:each="product : ${listProducts}">
<td th:text="${product.id}">Product ID</td>
<td th:text="${product.name}">Model name</td>
<td th:text="${product.brand}">Manufacturer</td>
<td th:text="${product.madein}">Country</td>
<td th:text="${product.price}">Price</td>
<td th:text="${product.price}">Designation</td>
<td><a class="btn btn-primary" role="button"
th:href="#{'/edit/' + ${product.id}}">Edit</a>
<a class="btn btn-danger" role="button"
data-toggle="modal" data-target="#myModal">Delete</a> <!-- Modal -->
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-body">
<p>Are you sure to delete this products ?</p>
</div>
<div class="modal-footer">
<a class="btn btn-primary" role="button"
th:href="#{'/delete/' + ${product.id}}">Yes</a>
<button type="button" class="btn btn-default"
data-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div></td>
</tr>
</tbody>
</table>
</div>
<br /> <br /> <a class="btn btn-success" href="new" role="button">Create
a new product</a> <br /> <br /> <br /> <br />
<!-- Footer -->
<footer class="page-footer font-small blue fixed-bottom">
<!-- Copyright -->
<div class="footer-copyright text-center py-3">
© 2020 Copyright: www.sample.com
</div>
<!-- Copyright -->
</footer>
<!-- Footer -->
</body>
</html>
ProductController :
package com.gestion.products.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.gestion.products.entity.Product;
import com.gestion.products.service.ProductService;
#Controller
#RequestMapping(name = "/all")
public class ProductController {
#Autowired
private ProductService service;
#RequestMapping("/")
public String viewHomePage(Model model) {
List<Product> listProducts = service.listAll();
model.addAttribute("listProducts", listProducts);
return "index";
}
#RequestMapping("/new")
public String showNewProductForm(Model model) {
Product product = new Product();
model.addAttribute("product",product);
return "new_product";
}
#RequestMapping(value = "/save", method = RequestMethod.POST)
public String saveProduct(#ModelAttribute("product") Product product) {
service.save(product);
return "redirect:/";
}
#RequestMapping("/edit/{id}")
public ModelAndView showEditProductForm(#PathVariable(name = "id") Long id) {
ModelAndView mav = new ModelAndView("edit_product");
Product product = service.get(id);
mav.addObject("product", product);
return mav;
}
#RequestMapping("/delete/{id}")
public String deleteProduct(#PathVariable(name = "id") Long id) {
service.delete(id);
return "redirect:/";
}
}
I faced the same issue yesterday and I found another way to solve it.
So I was using modal too and the problem comes from it.
I recommend you to use bootstrap confirmation plugin instead of modal then it will be easier for the controller to get the id of the chosen row.
Using a modal makes the controller choose a random id instead of the chosen one.
Related
I get this ExpressionChangedAfterItHasBeenCheckedError when i am using random numbers progress bar in my html grid table.It says "ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: some value. Current value: some value.". Someone please help me with the issue.
<nav class="navbar navbar-expand-sm bg-primary navbar-dark">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" routerLinkActive="active">
<button class="btn btn-primary" (click)="goToAddUser()">Add User</button>
</a>
</li>
</ul>
</nav>
<div class="panel panel-primary">
<div class="panel-heading">
<h2>User List</h2>
</div>
<div class="panel-body">
<table class="table table-striped">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
<th>Actions</th>
<th>Progress</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let user of users | async">
<td>{{user.firstname}}</td>
<td>{{user.lastname}}</td>
<td>{{user.email}}</td>
<td>
<button (click)="goToEditUser(user.id)" class="btn btn-info">Update</button>
<button (click)="deleteUser(user.id)" class="btn btn-danger" style="margin-left: 10px">Delete</button>
<button (click)="goToViewUser(user.id)" class="btn btn-info" style="margin-left: 10px">Details</button>
</td>
<td>
<mat-progress-bar [value]="number" style="margin-right: 300px"></mat-progress-bar>
{{ number }}%
</td>
</tr>
</tbody>
</table>
</div>
</div>
The getRandomNumber() return value changes after angular change detection already checked its value. To understand the error better, read this article:
https://hackernoon.com/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error-e3fd9ce7dbb4
Here's one solution, make a class field called randomNumber and assign it to the value of getRandomNubmer().
class YourComponentClass { randomNumber : number = this.getRandomNumber(); ... }
In Html
<td> <mat-progress-bar [value]="randomNumber" style="margin-right: 300px">
</mat-progress-bar> {{ randomNumber }} </td>
if you want to change your randomNumber just create a click event handler to reassign randomNumber to getRandomNumber() method
You need to manually check for changes.
// Import
import { Component, OnInit, ChangeDetectorRef } from '#angular/core';
// Inject
constructor(private cd: ChangeDetectorRef)
// Call after making changes in component
someMethod() {
this.cd.detectChanges();
}
The problem is when i run application and go to localhost:8080 i dont see the header which i made in but when application is not running and i want to see how the web is lookign i see it so the problem might be in link for my main.css.
this is for newest bootstrap 4.3.1 java 12 spring boot 2.1.5
home.html
<!DOCTYPE html>
<html lang="en">
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Home page</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css">
<link href="../static/css/main.css" th:href="#{/css/main.css}" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="jumbotron home-jumbo">
<div class="container text-center text-white jumbo-container">
<h1 class="display-3">Foodie</h1>
<p>Welcome in our restaurant. You can order what You want and how much You want and we will do it for
You.</p>
</div>
</div>
<div th:remove="all-but-first">
<div class="media col-6 offset-3" th:each="item: ${items}">
<i class="fas fa-utensils fa-4x"></i>
<div class="media-body">
<h5 th:text="|${item.name}(${item.price}zł)|">Pizza Margherita (25zł)</h5>
<p th:text="${item.shortDescription}">Short description pizza margherita, delicious classic on thin
crust and melt cheese.</p>
</div>
</div>
<div class="media col-6 offset-3">
<i class="fas fa-utensils fa-4x"></i>
<div class="media-body">
<h5>Pizza Capriciosa (26zł)</h5>
<p>Short description pizza margherita, delicious classic on thin crust and melt cheese.</p>
</div>
</div>
<div class="media col-6 offset-3">
<i class="fas fa-utensils fa-4x"></i>
<div class="media-body">
<h5>Pizza Mafioso (27zł)</h5>
<p>Short description pizza margherita, delicious classic on thin crust and melt cheese.</p>
</div>
</div>
</div>
</div>
</body>
</html>
main.css
.home-jumbo {
background: url("../img/fork.png") center;
}
.media-body {
margin-left: 10px;
}
HomeCotroller
package pl.karol.foodieapp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import pl.karol.foodieapp.item.Item;
import pl.karol.foodieapp.item.ItemRepository;
import java.util.List;
#Controller
public class HomeController {
private ItemRepository itemRepository;
#Autowired
public HomeController(ItemRepository itemRepository) {
this.itemRepository = itemRepository;
}
#GetMapping("/")
public String home(Model model) {
List<Item> items = itemRepository.findAll();
model.addAttribute("items", items);
return "home";
}
}
I expect the same website but including the header i put in jumbotron.
Solved. In main.css instead of typing image url address in "address" use 'address'
.home-jumbo {
background: url('../img/fork.png') center;
}
.media-body {
margin-left: 10px;
}
I can not seem to style my website... for example the <pre> tags.
Nothing I do works. I am trying to style the whois results, I've tried wrapping it in a div and styling that, styling the pre tags only, styling everything. I just can't seem to get it working. I am hoping I am missing something stupid. You can see from the CSS I have tried numerous combinations (tried deleting them all just having pre ect)
Nav bar:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="stylesheet.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script type="text/javascript" src="javascript.js"></script>
<meta http-equiv="content-type" content="text/html; charset=windows-1250">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="generator" content="PSPad editor, www.pspad.com">
<title>CWCS Domain Checker Tool</title>
</head>
<body>
<!--- This Keeps the navbar from staying right near top -->
<div class="header">
</div>
<!---- Nav bar, Using bootstrap ----->
<nav class="navbar navbar">
<div class="container-fluid">
<div class="navbar-header">
<div class="nav-bar-logo">
<img src="images/cwcs-logo.png">
</div>
</div>
<div class="nav-list-container">
<ul class="nav navbar-nav">
<li>Domain Diagnostics</li>
<li><a id="sd" href="#">Server Diagnostics</a></li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Second Line Tools
<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a id="dc" href="#">Daily Checklist</a></li>
<li><a id="bt" href="#">Backup Tracker</a></li>
<li><a id="tl" href="#">Task List</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<!------- End of nav bar ---->
Main page -
<?php
## Includes nav bar
include('navbar.php');
include('phpfiles/domainclass.php');
if (isset($_GET['userInput']))
{
$domainName = $_GET['userInput'];
}
?>
<!---- The input form ---->
<form class="form">
<div class="domainquery">
<div class="input-group">
<input id="domainName" name="userInput" class="form-control input-md" type="text" placeholder="example.com" value="<?php if (isset($domainName)) echo $domainName ?>" autocomplete="off" autofocus>
<div class="input-group-btn">
<button type="submit" class="btn btn-primary btn-md">Query Domain</button>
</div>
</div>
</div>
</form>
<!---- End of input form --->
<!---- start of content --->
<div class ="container-fluid">
<!----- Check of the variable has been set before showing --->
<?php
##checks if the variable name $domainName is set, before loading everything below
if (isset($domainName)):
?>
<div class="container-fluid">
<div class="row">
<div class="col-lg-6 col-md-5 col-sm-12 col-xs-12">
<h3>DNS Records </h3>
<div class="dnscontain">
<script>
// Loads the return vaue of the call into the "dnscontain" div.
$(".dnscontain").load("ajaxhandler.php",
{ // ajax call to pass variable to ajax handler, which then decides what to do with it
d: "<?php echo $domainName ?>",
q: 'dns'
});
</script>
</div>
<h3>SSL Result</h3>
<h3>NMAP Result</h3>
<div class="nmapcontain">
<script>
// Loads the return vaue of the call into the "dnscontain" div.
$(".nmapcontain").load("ajaxhandler.php",
{ // ajax call to pass variable to ajax handler, which then decides what to do with it
d: "<?php echo $domainName ?>",
q: 'nmap'
});
</script>
</div>
<h3>PING Result</h3>
<div class="pingcontain">
<script>
// Loads the return vaue of the call into the "dnscontain" div.
$(".pingcontain").load("ajaxhandler.php",
{ // ajax call to pass variable to ajax handler, which then decides what to do with it
d: "<?php echo $domainName ?>",
q: 'ping'
});
</script>
</div>
<!--- Closing div tag for left column -->
</div>
<!--- starting right column -->
<div class="col-lg-6 col-md-5 col-sm-12 col-xs-12">
<h3>WHOIS Result</h3>
<div class="whoiscontain">
<script>
// Loads the return vaue of the call into the "whoiscontain" div.
$(".whoiscontain").load("ajaxhandler.php",
{ // ajax call to pass variable to ajax handler, which then decides what to do with it
d: "<?php echo $domainName ?>",
q: 'whois'
});
</script>
<!--Whoiscontain div end -->
</div>
<!--- right column div end -->
</div>
<!--- closing div tag for 1st row --->
</div>
</div>
<!---- ends the check on if the variable is set -->
<?php
###End the "IF" check
endif
?>
<!---- Closing div tag for container-fluid --->
</div>
</body>
</html>
Ajax return page --
<?php
include 'domainclass.php';
$result = domain::getWhois($domainName);
?>
<pre class="whois"> <?php echo $result ?> </pre>;
Style sheet
.header
{
margin:1%;
}
.domainquery
{
margin-bottom:3%;
padding:40px 50px;
}
.nav-bar-logo
{
margin-right:20px;
padding-right:20px;
}
.table
{
font-size:5px;
}
pre .whois
{
white-space:pre-wrap;
background-color:black;
color:white;
word-wrap: break-word;
}
.whoiscontain
{
white-space:pre-wrap;
background-color:black;
width:100%;
color:white;
word-wrap: break-word;
}
pre
{
white-space:pre-wrap;
background-color:black;
color:white;
word-wrap: break-word;
}
HTML output of page as requested (ignore style sheeting being above the bootstrap stylesheet, was trying something.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<link rel="stylesheet" type="text/css" href="stylesheet.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script type="text/javascript" src="javascript.js"></script>
<meta http-equiv="content-type" content="text/html; charset=windows-1250">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="generator" content="PSPad editor, www.pspad.com">
<title>CWCS Domain Checker Tool</title>
</head>
<body>
<!--- This Keeps the navbar from staying right near top -->
<div class="header">
</div>
<!---- Nav bar, Using bootstrap ----->
<nav class="navbar navbar">
<div class="container-fluid">
<div class="navbar-header">
<div class="nav-bar-logo">
<img src="images/cwcs-logo.png">
</div>
</div>
<div class="nav-list-container">
<ul class="nav navbar-nav">
<li>Domain Diagnostics</li>
<li><a id="sd" href="#">Server Diagnostics</a></li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Second Line Tools
<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a id="dc" href="#">Daily Checklist</a></li>
<li><a id="bt" href="#">Backup Tracker</a></li>
<li><a id="tl" href="#">Task List</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<!------- End of nav bar ---->
<!---- The input form ---->
<form class="form">
<div class="domainquery">
<div class="input-group">
<input id="domainName" name="userInput" class="form-control input-md" type="text" placeholder="example.com" value="lomcn.org" autocomplete="off" autofocus>
<div class="input-group-btn">
<button type="submit" class="btn btn-primary btn-md">Query Domain</button>
</div>
</div>
</div>
</form>
<!---- End of input form --->
<!---- start of content --->
<div class ="container-fluid">
<!----- Check of the variable has been set before showing --->
<div class="container-fluid">
<div class="row">
<div class="col-lg-6 col-md-5 col-sm-12 col-xs-12">
<h3>DNS Records </h3>
<div class="dnscontain">
<script>
// Loads the return vaue of the call into the "dnscontain" div.
$(".dnscontain").load("ajaxhandler.php",
{ // ajax call to pass variable to ajax handler, which then decides what to do with it
d: "lomcn.org",
q: 'dns'
});
</script>
</div>
<h3>SSL Result</h3>
<h3>NMAP Result</h3>
<div class="nmapcontain">
<script>
// Loads the return vaue of the call into the "dnscontain" div.
$(".nmapcontain").load("ajaxhandler.php",
{ // ajax call to pass variable to ajax handler, which then decides what to do with it
d: "lomcn.org",
q: 'nmap'
});
</script>
</div>
<h3>PING Result</h3>
<div class="pingcontain">
<script>
// Loads the return vaue of the call into the "dnscontain" div.
$(".pingcontain").load("ajaxhandler.php",
{ // ajax call to pass variable to ajax handler, which then decides what to do with it
d: "lomcn.org",
q: 'ping'
});
</script>
</div>
<h3>Tracert Result</h3>
<div class="tracecontain">
<script>
// Loads the return vaue of the call into the "dnscontain" div.
$(".tracecontain").load("ajaxhandler.php",
{ // ajax call to pass variable to ajax handler, which then decides what to do with it
d: "lomcn.org",
q: 'trace'
});
</script>
</div>
<!--- Closing div tag for left column -->
</div>
<!--- starting right column -->
<div class="col-lg-6 col-md-5 col-sm-12 col-xs-12">
<h3>WHOIS Result</h3>
<div class="whoiscontain">
<script>
// Loads the return vaue of the call into the "whoiscontain" div.
$(".whoiscontain").load("ajaxhandler.php",
{ // ajax call to pass variable to ajax handler, which then decides what to do with it
d: "lomcn.org",
q: 'whois'
});
</script>
<!--Whoiscontain div end -->
</div>
<!--- right column div end -->
</div>
<!--- closing div tag for 1st row --->
</div>
</div>
<!---- ends the check on if the variable is set -->
<!---- Closing div tag for container-fluid --->
</div>
</body>
</html>
to style bootstrap you can over ride bootstrap styles or make your own new styles.
They recommend not editing the bootstrap .CSS directly so updates to bootstrap will not change your design.
You are correct to place your own style sheet call below the bootstrap call, so yours will override.
Even though your styles will over ride you might not be able to over ride a bootstrap rule that has the !important tag. You can either use the bootstrap classes and ID's in your stylesheet and make new rules, using your own !Important to force them through if necessary, or add additional classes for your styles:
a bit of code
was `<div class="col-md-12">`
make `<div class="col-md-12 myCol">`
and then make rules on your stylesheet for
.myCol{
these styles should persist
}
I have a mobile web app that uses Bootstrap. Everything looks fine on a desktop; however, when I pull up certain pages on an iPhone 4S, the nav bar is much narrower than it should be. Both of the pages that have this behavior have tables, so that may have something to do with it.
Screenshot:
My shared _Layout Razor view looks like this:
#using FCTech.Quotes.Helpers
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>#ViewBag.Title</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<meta name="viewport" content="width=device-width" />
#Styles.Render("~/Content/css")
#Styles.Render("~/Content/themes/base/css")
#Styles.Render("~/Content/bootstrap")
#Scripts.Render("~/bundles/modernizr")
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/jqueryui")
#RenderSection("Styles", false)
</head>
<body>
<header>
<div class="content-wrapper">
<div>
<nav class="navbar navbar-default col-xs-12">
<div class="container-fluid">
<div class="navbar-header float-left">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navLinks" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
#Html.ActionLink("Home", "Index", new { controller = "Home" }, new { #class = "logo navbar-brand" })
</div>
<div class="collapse navbar-collapse" id="navLinks">
<ul class="nav navbar-nav">
<li>#Html.ActionLink("Home", "Index", "Home")</li>
#if (HttpContext.Current.User.Identity.IsAuthenticated)
{
<li>#Html.ActionLink("Quotes", "Index", new {controller = "Quotes", salesPerson = AccountHelper.GetCurrentUserFullName()})</li>
<li>#Html.ActionLink("Orders", "Index", new {controller = "Orders", salesPerson = AccountHelper.GetCurrentUserFullName()})</li>
}
#if (HttpContext.Current.User.Identity.IsAuthenticated && AccountHelper.AuthorizeAdmin())
{
<li>#Html.ActionLink("Shipments", "ShipmentSummary", new { controller = "Admin", salesPerson = AccountHelper.GetCurrentUserFullName() })</li>
<li>#Html.ActionLink("Bookings", "BookingSummary", new { controller = "Admin", salesPerson = AccountHelper.GetCurrentUserFullName() })</li>
}
<li>
#if (Request.IsAuthenticated)
{
#Html.ActionLink("Log Off", "LogOff", "Account")
}
else
{
#Html.ActionLink("Log in", "Login", "Account")
}
</li>
</ul>
</div>
</div>
</nav>
</div>
</div>
</header>
<div id="body" class="content">
#RenderSection("featured", required: false)
<section class="content-wrapper main-content clear-fix">
#RenderBody()
</section>
</div>
<footer>
<div class="content-wrapper">
<div class="float-right">
<p>v #typeof(FCTech.Quotes.MvcApplication).Assembly.GetName().Version</p>
</div>
</div>
</footer>
#Scripts.Render("~/bundles/bootstrap")
#RenderSection("Scripts", required: false)
</body>
</html>
And the body of one of the views that is displaying incorrectly looks like this:
#using System.Linq
#model IEnumerable<FCTech.Quotes.Models.OpenQuoteModel>
#{
ViewBag.Title = "Open Quotes";
}
<head>
<title>
Open Quotes
</title>
</head>
<fieldset>
<legend>
Open Quotes
</legend>
#if (Model != null && Model.Any())
{
<table id="OpenQuotesTable" class="table table-responsive table-bordered table-condensed table-striped tablesorter">
<thead>
<tr class="header">
<th>
#Html.DisplayNameFor(model => model.QuoteNumber)
</th>
<th>
#Html.DisplayNameFor(model => model.QuoteDate)
</th>
<th>
#Html.DisplayNameFor(model => model.Customer)
</th>
<th>
#Html.DisplayNameFor(model => model.City)
</th>
<th>
#Html.DisplayNameFor(model => model.State)
</th>
<th>
#Html.DisplayNameFor(model => model.EndUser)
</th>
<th>
#Html.DisplayNameFor(model => model.Product)
</th>
<th>
#Html.DisplayNameFor(model => model.TotalValue)
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr class="#(item.QuoteDate < DateTime.Today.AddDays(-30) ? "red" : string.Empty ) ">
<td>
#Html.ActionLink(item.QuoteNumber.ToString(), "Detail", new { quoteNumber = item.QuoteNumber, productLine = item.Product, salesRep = item.SalesRep })
</td>
<td style="text-align: right;">
#Html.DisplayFor(model => item.QuoteDate)
</td>
<td>
#Html.DisplayFor(model => item.Customer)
</td>
<td>
#Html.DisplayFor(model => item.City)
</td>
<td>
#Html.DisplayFor(model => item.State)
</td>
<td>
#Html.DisplayFor(model => item.EndUser)
</td>
<td>
#Html.DisplayFor(model => item.Product)
</td>
<td style="text-align: right;">
#Html.DisplayFor(model => item.TotalValue)
</td>
</tr>
}
</tbody>
</table>
}
</fieldset>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
What am I doing wrong here?
In Bootstrap 3 you should wrap your table tag into a .table-responsive div.
<div class="table-responsive">
<table class="table">
</table>
</div>
http://getbootstrap.com/css/#tables-responsive
To expand on Samuel's answer,
This looks to be simply happening because Bootstrap's media query at that mobile level has a max-width on it with no hidden overflow while the table content exceeds this width.
Mobile tables are always a pain for front-end devs.
Other than the solution Samuel provided, you can always make your own custom media query to display the data in a cleaner way.
Personally, I suggest using jQuery DataTables for your display formatting. DataTables provides handling for smaller devices.
DataTables Responsive example
After having adding DataTables plugin and datatables responsive to your project, initialize it with this property turned on like this:
$(document).ready(function() {
$('#OpenQuotesTable').DataTable( {
responsive: true
} );
} );
I am trying to align some button and a input box with a table. Previous day and next day may or may not be present on the page depending on if a day exists. Below is by start code, current output and desired output.
<!DOCTYPE html>
<html lang="en">
<head>
<link href="bootstrap/css/bootstrap.css" rel="stylesheet">
</head>
<body>
<div class="container">
<form class = "form-inline" >
<h1>some data</h1>
<br>
<button class="btn" name = "prevDayBtn"><i class="icon-backward"></i> Previous Day</button>
<input type='text' READONLY name = 'pageDate' value = '2013-05-18' />
<button class="btn" name = "nextDayBtn" >Next Day <i class="icon-forward"></i></button>
<br>
<br>
<table class = "table table-striped">
<th>col1</th><th>col2</th><th>col3</th><th>col4</th><th>col5</th><th>col6</th><th>col7</th><th>col8</th>
</table>
</form>
</div> <!-- /container -->
</body>
</html>
Current Output
Desired Output
Edit:
I tried Accipheran answer and got the result below. Also added code to jsFiddle http://jsfiddle.net/Y9SLs/1/
I would give the next-day button a class of pull-right (a bootstrap class) and the date field a class of center (custom class) where center is defined as
.center {
float: none;
display: table;
margin: 0 auto;
}
Think that should work
In addition to Accipheran's answer I used Twitters grid system to get the desired result. Code Below:
HTML
</head>
<body>
<div class="container">
<form class = "form-inline" >
<h1>some data</h1>
<div class = "row">
<div class = "span4">
<button class="btn" name = "prevDayBtn pull-left"><i class="icon-backward"></i> Previous Day</button>
</div>
<div class = "span4">
<input class = "center " type='text' READONLY name = 'pageDate' value = '2013-05-18' >
</div>
<div class = "span4">
<button class="btn pull-right" name = "nextDayBtn" >Next Day <i class="icon-forward"></i></button>
</div>
</div>
<br>
<div class = "row">
<div class = "span12">
<table class = "table table-striped">
<th>col11</th><th>col2</th><th>col3</th><th>col4</th><th>col5</th><th>col6</th><th>col7</th><th>col8</th>
</table>
</div>
</div>
</form>
</div> <!-- /container -->
</body>
</html>
Additional CSS
input.center {
float: none;
display: table;
margin: 0 auto;
}