I am trying to set up search box for bootgrid control, like it is shown in the example page here. Page navigation invokes the ajax call and the server method processing the ajax call receives the searchPhrase, but typing into the search box does not invoke the server method. Both the documentation and various Q&A did not have guidance, this is the closest question but did not address my issue.
I am doing this in ASP.NET MVC website, here is the relevant code fragment.
<div id="grid-command-buttons-header" class="bootgrid-header container-fluid">
<div class="row">
<div class="col-sm-12 actionBar">
<div class="search form-group">
<div class="input-group">
<span class="icon fa input-group-addon fa-search"></span>
<input type="text" class="search-field form-control" placeholder="Search">
</div>
</div>
</div>
</div>
</div>
<table class="table table-condensed table-hover table-striped" id="redisKeyResults">
<thead>
<tr>
<th data-column-id="KeyName" data-formatter="link" data-type="string" data-order="desc" data-identifier="true">Key</th>
<th data-column-id="KeyName" data-formatter="commands">Flush</th>
</tr>
</thead>
</table>
Javascript code to setup bootgrid is as below
$("#redisKeyResults").bootgrid({
ajax: true,
url: "RedisCacheKeyManagement/GetRedisKeyResultGrid",
post: function() {
return {
id: "b0df282a-0d67-40e5-8558-c9e93b7befed"
};
},
formatters: {
"commands": function(column, row) {
return "<button type=\"button\" class=\"btn btn-xs btn-danger command-delete\" data-row-id=\"" +
row.KeyName +
"\">Flush</button>";
},
"link": function(column, row) {
return "<a class=\"link-get\" data-row-id=\"" + row.KeyName + "\" href=\"" + row.link + "\">" + row.KeyName + "</a>";
}
}
})
The answer to setting up search is to enable header navigation on bootgrid. General settings can be set using API on the table tag and column settings on th tag.
Based on the documentation guidance, setting data-navigation attribute on the table tag with the value 2 or 3 shows the search box with all the functionality.
<table class="table table-condensed table-hover table-striped" id="redisKeyResults" data-navigation="3">
Hope this helps someone facing the same issue.
Related
I'm trying to get to grips with ViewComponents but having trouble trying to get the ViewComponent to reload on a button click. Whats the correct way to handle this?
Initially on the page loading it looks OK like this
In my controller I have
public IActionResult ReloadViewComponent(int characterRegionId, int materialTypeId)
{
return ViewComponent("MarketOrderComponent", new { characterRegionId, materialTypeId});
}
and in my razor view I'm passing parameters to the ReloadViewComponent method
<td><button class="btn btn-sm btn-outline-primary" value="#material.MaterialTypeID" onclick="location.href='#Url.Action("ReloadViewComponent", "BlueprintBreakdown", new { Model.CharacterRegionId, material.MaterialTypeID })'">View</button></td>
full razor view
<body>
<div class="row" style="margin-top:5px;">
<div class="col-lg-4 col-md-12">
<div class="card" style="margin-bottom:0; ">
<div class="header" style="margin-bottom:55px;">
<h2 class="text-primary">Blueprint Breakdown</h2>
</div>
<div class="body">
<div>
<h5 class="text-center">#Model.BlueprintName</h5>
</div>
<div class="row text-center">
<div class="col-6 border-right pb-4 pt-4" style="padding-top:0px !important; padding-bottom:0px !important;">
<img src="#Model.ImageUrl" alt="#Model.BlueprintName">
</div>
<div class="col-6 pb-4 pt-4" style="padding-top:0px !important; padding-bottom:0px !important;">
<img src="#Model.ProductImageUrl" alt="#Model.BlueprintName">
</div>
</div>
<div class="text-center" style="margin-top:5px;">
<text style="font-size:small;">Material Quantity Based on Manufacturing Efficiency</text>
<br />
<text style="font-size:small;">Price Based on Lowest Region Market Sell Orders</text>
<br />
<text style="font-size:small;">Current Region is <span class="text-green">#Model.CharacterRegionName</span></text>
</div>
</div>
</div>
<div class="table-responsive">
<table class="table table-hover table-custom spacing5">
<thead>
<tr>
<th></th>
<th>Material</th>
<th>Quantity</th>
<th>Price</th>
<th>Market</th>
</tr>
</thead>
<tbody>
#foreach (var material in Model.RequiredMaterials)
{
<tr class="text-cente" style="font-size:small;">
<td><img src="#(String.Format("{0}{1}{2}", "https://imageserver.eveonline.com/Type/", material.MaterialTypeID, "_32.png"))" /></td>
<td>#material.TypeName</td>
<td>#material.Quantity</td>
<td>#material.MaterialCost</td>
<td><button class="btn btn-sm btn-outline-primary" value="#material.MaterialTypeID" onclick="location.href='#Url.Action("ReloadViewComponent", "BlueprintBreakdown", new { Model.CharacterRegionId, material.MaterialTypeID })'">View</button></td>
</tr>
}
</tbody>
</table>
</div>
</div>
<div class="col-lg-8 col-md-12">
#await Component.InvokeAsync("MarketOrderComponent", new { Model.CharacterRegionId, Model.RequiredMaterials.First().MaterialTypeID })
</div>
</div>
but when clicking the view button to reload the ViewComponent it is rendered like this.
Note by using the ViewComponent() controller method, your client only gets the component part of the view. So instead of changing the browser's current location, you should send an ajax request and dynamically replace the right side content.
Add an id='MarketOrderComponent'attribute so that we can reference this element later:
<div id='MarketOrderComponent' class="col-lg-8 col-md-12">
#await Component.InvokeAsync("MarketOrderComponent", new { Model.CharacterRegionId, Model.RequiredMaterials.First().MaterialTypeID })
</div>
And change the button click event handler to send an ajax request. For example, in order to reload the market order component, you can change your code as below:
<script>
function reload(url){
return $.ajax({
method:"get",
url:url,
success:function(resp){ $('#MarketOrderComponent').html(resp);},
});
}
</script>
<div class="card" style="margin-bottom:0; ">
...
</div>
<div class="table-responsive">
...
<tbody>
#foreach (var material in Model.RequiredMaterials)
{
<tr class="text-cente" style="font-size:small;">
<td><img src="#(String.Format("{0}{1}{2}", "https://imageserver.eveonline.com/Type/", material.MaterialTypeID, "_32.png"))" /></td>
<td>#material.TypeName</td>
<td>#material.Quantity</td>
<td>#material.MaterialCost</td>
<td>
<button class="btn btn-sm btn-outline-primary"
value="#material.MaterialTypeID"
onclick="var link='#Url.Action("ReloadViewComponent", "BlueprintBreakdown", new { Model.CharacterRegionId, material.MaterialTypeID })'; event.preventDefault(); reload(link)"
>
View
</button>
</td>
</tr>
}
</tbody>
...
</div>
<div id='MarketOrderComponent' class="col-lg-8 col-md-12">
#await Component.InvokeAsync("MarketOrderComponent", new { Model.CharacterRegionId, Model.RequiredMaterials.First().MaterialTypeID })
</div>
I have a view that creates a document with a Title, Date, and name of file that I upload. Once that document is created it is returned to a View that shows the document that I just created and is stored in a database.
Here is the code that creates the document:
<form asp-action="CreateDirectorDocument" role="form" class="form-
horizontal">
<div asp-validation-summary="ModelOnly" class="alert-
danger text-danger"></div>
<div class="form-group">
<div class="col-md-10"><a asp-
action="Index">View Documents</a></div>
</div>
<div class="form-group">
<div class="col-md-10"><label asp-for="Date">
</label></div>
<div class="col-sm-2"><input asp-for="Date" />
</div>
</div>
<div class="form-group">
<div class="col-md-2"><label asp-
for="DocFile"></label></div>
<div class="col-md-4">
<input asp-for="DocFile" type="file"
multiple>
</div>
</div>
<div class="form-group">
<div class="col-sm-2"><label asp-for="Title">
</label></div>
<div class="col-sm-2"><input asp-for="Title"
/></div>
</div>
</form>
View that is return after document has been created:
<table>
<thead>
<tr>
<th class="col-md-2" style="border-bottom: solid">
</th>
<th class="col-md-2" style="border-bottom:
solid">Title</th>
<th class="col-md-2" style="border-bottom:
solid">Date</th>
<th class="col-md-2" style="border-bottom: solid">
</th>
</tr>
</thead>
<tbody>
#foreach (var dirDocs in Model.Docs)
{
<tr>
<td class="col-md-2">
<a asp-area="Admin" asp-controller="Docs"
asp-action="EditDirectorDocument" asp-route-
id="#dirDocs.Id">Edit</a>
<a asp-area="Admin" asp-controller="Docs"
asp-action="DeleteDirectorDocument" asp-route-
returnViewName="#returnViewName" asp-route-id="#dirDocs.Id"
onclick="return confirm('Are you sure you want to delete
this document?');">Delete</a>
</td>
<td class="col-md-2">#dirDocs.Title</td>
<td class="col-md-2">#dirDocs.Date</td>
<td class="col-md-2"><a asp-route-
id="#dirDocs.Url" target="_blank">Open</a></td>
</tr>
}
</tbody>
</table>
The file that is uploaded gets stored as a document file and is created as a url for the user to view. How do I do this in MVC. Is that set up in the controller? If so how is that done?
Not sure, but I think you just need:
Open
Instead of
<a asp-route-id="#dirDocs.Url" target="_blank">Open</a>
I assume you mean you get a URL back from the upload process that you want to display to the user so they can click on it and see the file they uploaded.
If you wanted to display some thing like that inline you could probably use an iframe whose src is set to #dirDocs.Url:
<iframe src="#dirDocs.Url"></iframe>
I've been trying to sort table data on click (ng-click if i use angularJS)
I'm getting data from database.I only need Sort functionality, if it happens through angularJs I would be very happy
Here it is what i did till now, I haven't done much as I'm new to AngularJS
#model WebApplication3.Models.StudentModel
#{
ViewBag.Title = "Index";
}
<h2>Students</h2>
<div><button class="create btn btn-success"><span class="glyphicon glyphicon-plus"></span> Create New</button></div>
<br/>
<table class="table" ng-app="StudentApp">
<tbody ng-controller="StudentCtrl">
<tr>
<th>Key</th>
<th ng-click="">First Name</th>
<th ng-click="">Last Name</th>
<th>Profile picture</th>
<th>Options</th>
</tr>
#foreach (var student in Model._StudentList)
{
<tr>
<td>#student.StudentID</td>
<td>#student.FirstName</td>
<td>#student.LastName</td>
<td>
<a class="example-image-link" href="~/Images/#student.PhotoURL" data-lightbox="example-set" data-title="#student.FirstName #student.LastName profile Picture"><img class="example-image" width="60" height="40" src="~/Images/#student.PhotoURL" alt="" /></a>
</td>
<td>
<span class="glyphicon glyphicon-pencil img-rotate" title="Edit"></span>
<span class="glyphicon glyphicon-exclamation-sign img-rotate" title="Infomation"></span>
<span class="glyphicon glyphicon-remove img-rotate" title="Remove"></span>
</td>
</tr>
}
</tbody>
</table>
I need to sort firstName, LastName when they click on respective th tag
Thanks
There is a sort table filter in AngularJS, which his name is OrderBy (documentation)
Currently, you cannot use that with your code, because OrderBy filter only works if AngularJS writes himself the table.
Example :
<table class="friend">
<tr>
<th>
Name
<span class="sortorder" ng-show="predicate === 'name'" ng-class="{reverse:reverse}"></span>
</th>
<th>
Phone Number
<span class="sortorder" ng-show="predicate === 'phone'" ng-class="{reverse:reverse}"></span>
</th>
<th>
Age
<span class="sortorder" ng-show="predicate === 'age'" ng-class="{reverse:reverse}"></span>
</th>
</tr>
<tr ng-repeat="friend in friends | orderBy:predicate:reverse">
<td>{{friend.name}}</td>
<td>{{friend.phone}}</td>
<td>{{friend.age}}</td>
</tr>
</table>
In your case, the table is written in the view, and I think the only way to do it now with your code, is using a jQuery plugin.
Sadly, you loose the power of AngularJS...
Solution :
A solution would be to use ng-init attribute :
<div ng-app="" ng-init="names=[
{name:'Jani',country:'Norway'},
{name:'Hege',country:'Sweden'},
{name:'Kai',country:'Denmark'}]">
<ul>
<li ng-repeat="x in names">
{{ x.name + ', ' + x.country }}
</li>
</ul>
</div>
And you can use names variable in your controller, like :
console.log($scope.names); // Display the names
oh thats so sad, can i bind my MVC Model data to AngularJs
I mean like we bind JSON data
var app = angular.module('studentApp', []);
app.controller('StudntCtrl', function($scope, $http) {
htp.get('Student.json').success(function(data){
$scope.People = data;
});
});
like wise can i bind MVC model data to $scope.People ???
Hello im back with another tedious question!
Trying to get my table to paginate. There are 12 users in the table. Here is my controller function
def listDuplicates(params) {
def result = User.getAllWithDuplicateIDs()
def totalDupCount = result.size()
/*sout for troubleshooting */
System.out.println("Duplicate:" + result.ID + " " + result.username)
params.max = Math.min(params.max ? params.int('max') : 10, 100)
return [resultList: result, totalDupCount: totalDupCount, params:params ]
}
Here is my view
<div>
<fieldset class="warningFieldSet">
<h1 style="color: red" align="center">
<g:message code="Duplicate IDs" />
</h1>
<p style="color: red; margin-left: 20px;">Duplicate IDs Found!</p>
<table>
<thead>
<tr>
<g:sortableColumn property="Username" title="Username" />
<g:sortableColumn property="ID" title="ID" />
<g:sortableColumn property="Status" title="Status" />
</tr>
</thead>
<tbody>
<g:each in="${resultList}" status="i" var="resultDuplicate">
<tr class="${(i % 2) == 0 ? 'even' : 'odd'}">
<td>
${resultDuplicate.username}
</td>
<td style="color: red; font-weight: bold">
${resultDuplicate.id}
</td>
<td>
${resultDuplicate.accountStatus }
</tr>
</g:each>
</tbody>
<tfoot>
<g:if test="${totalDupCount >10 }">
<div class="paginateButtons">
<g:paginate action= "listDuplicates" total="${totalDupCount}" />
</div>
</g:if>
</tfoot>
</table>
</fieldset>
</div>
Domain function for finding the duplicate IDs
static List<User> getAllWithDuplicateIDs() {
findAll("FROM User WHERE id IN (SELECT id FROM User group by id having count(*) > 1) AND id != '' ", [])
}
The buttons show up. And in the URL the offset and max is displayed. The table just puts all 12 displayed instead of 10 on one page and 2 on the other. 2 Page numbers show up so It knows that it is only suppose to display only 10 per page. It just isn't doing it in the table itself. Im assuming its some kind of issue with passing params and such.
Any Suggestions/Opinions/Help are/is greatly appreciated!
Grails pagination is based on two parameters: max and offset. max determines the page size, and offset determines where the current page starts. The controller receives these parameters and generally passes them to a database query. The list method added to domain objects by grails handles these parameters, and the finder methods take a queryParams. The usual pattern is to pass the params object directly to list or as the queryParams parameter to the finders. This returns a result set starting at the given offset, with one page length.
In your example, you're calling getAllWithDuplicateIDs without making use of these parameters. Update your query to take them, like this:
static List<User> getAllWithDuplicateIDs(params) {
findAll("FROM User WHERE id IN (SELECT id FROM User group by id having count(*) > 1) AND id != '' ", [], params)
}
Alternatively, page it in memory with something like
results = results.drop(params.offset).take(params.max)
Paging directly in the query is preferable, since it will perform better handle cases where the entire list doesn't fit in memory.
Provide max and offset function params this:
def result = User.getAllWithDuplicateIDs([max:params.max, offset:params.offset])
And use them in in query to database.
Or check the answer how to get results from list with max and offset in answer here
Look at this example .
Domain class ..
class Job {
static belongsTo = [company:Company]
String jobtitle
String jobdescription
String jobskills
String joblocation
String experience
String jobtype
String salary
}
Controller Code..
def uijobs () {
[res:Job.list(params),jobcount:Job.count()]
}
and view is here.
<div class="container" id="main">
<div class="row">
<g:each in="${res}">
<div class="col-sm-4">
<div class="panel panel-warning">
<div class="panel-heading">
<h4 class="panel-title"><g:link action="infopagejob" controller="Job" id="${it.id}">${it.jobtitle}</g:link></h4>
</div>
<div class="panel-body">
<table class="table">
<tr class="info" >
<td > Job Location</td>
<td >${it.joblocation}</td>
</tr>
<tr class="info">
<td>Description</td>
<td>${it.jobdescription}</td>
</tr>
</table>
</div>
</div>
</div>
</g:each>
</div>
<g:paginate next="Forward" prev="Back" maxsteps="10" controller="Job" action="uijobs" total="${jobcount}" params="${params}"/>
</div></div>
I have program in mvc which fetch data from controller and then display in view.It makes dynamic table with data in it. Inside it there is a link "SEE DETAILS", but instead of a single link i want to make whole table as a link like :
#Html.ActionLink("SEE DETAILS", "AppDetail", new { #id = item.id, appnameformp = item.AppNameForMP }, new { #style = "color:#C55000;font-size: 11px;text-decoration:none;" })
but i don't know how to do it...Any help is really appreciated and thanks in advance.
<div class="grid_9.5 alpha">
#foreach (var item in Model)
{
<div class="grid_4 alpha box_shadow" id="featured-subbillboard" style="margin-bottom:10px;" >
<table>
<tr >
<td><img height="140" width="130" src=#item.imgfile />
</td>
<td> </td>
<td class="table">
<h1 class="heading1" style="margin-top:10px; line-height: .4em;">#item.AppNameForMP </h1>
<h2 class="heading2">#item.DevName </h2>
<br />
<p class="para">
#if (item.AppDesc.Length > 50)
{#item.AppDesc.Remove(#item.AppDesc.Length -50)}
else
{ #item.AppDesc}
</p>
#Html.ActionLink("SEE DETAILS", "AppDetail", new { #id = item.id, appnameformp = item.AppNameForMP }, new { #style = "color:#C55000;font-size: 11px;text-decoration:none;" })
</td>
</tr>
</table>
</div>
}
</div>
Just use a regular anchor tag, and use #Url.Action() to get the href:
<a href="#Url.Action("AppDetail")">
<!-- table here -->
</a>
Also, note that while block-level links are now supported in HTML5, browser support and even implementation is not consistent. Some will handle linking the whole table well, while others will do all kinds of weird stuff. Just something to be aware of.