Can not edit the form from sails.js - sails.js

Hey guys I'm really new at sails.js and I'm using version 1.0 of it. I just tried to create a CRUD application on adding article to my list and showing them. All goes right but when I want to delete or edit it says 404 error. I am going through this tutorial series and as I know this series is using sails js version 0.12.
I am using mongodb as my database as a default. Data insertion is going well but problem is when I wanted to edit or delete it. Here I think the problem is getting the id value from the url. I skipped the edit portion here and posted the delete portion here.
api/controllers/ ArticleController.js
module.exports = {
delete: function(req, res){
Articles.destroy({id:req.params.id}).exec(function(err){
if(err){
res.send(500,'Database Error');
}
res.redirect('/articles/list');
});
return false;
}
};
api/models/ Articles.js
module.exports = {
attributes: {
title:{
type:'string'
},
body:{
type:'string'
}
},
};
views/pages list.ejs
<h1 class="display-4">Articles</h1>
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>Title</th>
<th></th>
</tr>
</thead>
<tbody>
<% articles.forEach(function(article){ %>
<tr>
<td><%= article.id %></td>
<td><%= article.title %></td>
<td>
<form class="d-inline" action="/articles/delete/<%= article.id %>" method="POST">
<input type="submit" class="btn btn-danger" value="Delete">
</form>
</td>
</tr>
<% }) %>
</tbody>
</table>
config/route.js
module.exports.routes = {
'/': {
view: 'pages/homepage'
},
};

Related

Footable table timeout when row count is over 1000

I have tried to implement footable pluglin on an MVC application and it currently has 3000+ users which fail to load and the browser page times out. For the User Admin section I have created the following View:
#model IEnumerable<MyBudgetWeb.Models.ApplicationUser>
#{
ViewBag.Title = "Index";
}
<script src="~/Scripts/jquery-1.10.2.js"></script>
<script type="text/javascript">
$(function () {
$('.footable').footable();
});
</script>
<br /><br />
<h2>Bill Pay Users</h2>
<input id="filter" type="text" placeholder="Filter" />
<br /><br />
#if (Model.Count() > 0)
{
<table class="table" data-filter="#filter" data-page-size="50">
<thead>
<tr>
<th data-type="numeric">Customer Number</th>
<th data-type="numeric">Account Name</th>
<th data-type="numeric" data-hide="phone">Go Live Date</th>
<th data-type="numeric" data-hide="phone">Online Live Date</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>#item.CustomerNumber</td>
<td>#item.AccountName</td>
<td>#item.GoLiveDate</td>
<td>#item.OnlineCreationTimestamp</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
#Html.ActionLink("Details", "Details", new { id = item.Id }) |
#*#Html.ActionLink("Delete", "Delete", new { id = item.Id })*#
</td>
</tr>
}
</tbody>
<tfoot class="hide-if-no-paging">
<tr>
<td colspan="12" class="text-center">
<ul class="pagination"></ul>
</td>
</tr>
</tfoot>
</table>
}
else
{
<h2>You are still awaiting users to be added. All users will be displayed here.</h2>
}
My controller looks as follows:
public async Task<ActionResult> Index()
{
return View(await UserManager.Users.ToListAsync());
}
Is there any way workarounds to prevent this?
there are 2 option to solve:
1. PHP Side script, by setting the time limit of execution. Use this code on top your PHP script:
set_time_limit(0);
Use Footable AJAX what describe here:
http://fooplugins.github.io/FooTable/

how to format a date in embeddedjs

app.js
app.get('/user.html', function(req, res){
dbConnect.collection("users").find().toArray(function(err, docsData) {
res.render('user', {
data: docsData,
title: "EJS example",
header: "Some users"
});
});
});
user.html
<% data.forEach(function(user){ %>
<tr>
<td>
<%= user.date %>
</td>
</tr>
<% }) %>
output is
2014-12-24T09:47:07.436Z
this is the value coming from mongodb. I want to format this to Dec-24-2014. How to format it in embeddedjs.
You can use toDateString() to better format date in JavaScript :
<% data.forEach(function(user){ %>
<tr>
<td>
<%= user.date.toDateString() %>
</td>
</tr>
<% }) %>
If you want to display date in a custom format, you can use third party module like Moment.js. Using Moment.js your code would be like following:
app.js
var moment = require('moment');
app.get('/user.html', function(req, res){
dbConnect.collection("users").find().toArray(function(err, docsData) {
res.render('user', {
data: docsData,
title: "EJS example",
header: "Some users",
moment: moment
});
});
});
user.html
<% data.forEach(function(user){ %>
<tr>
<td>
<%= moment(user.date).format( 'MMM-DD-YYYY') %>
</td>
</tr>
<% }) %>
Hope this help!

How to use knockout mapping?

I have applied bindings to the following view model
var groupDeleteViewModel = {
group: { Id: ko.observable(), Name: ko.observable(), Members: ko.observableArray() },
load: function (item) {
debugger
},
remove: function (item) {
groupDeleteViewModel.group.Id(item.Id());
groupDeleteViewModel.group.Name(item.Name());
groupDeleteViewModel.group.Members(item.Members());
$("#groupDelete").show();
},
cancel: function () {
$("#groupDelete").hide();
}
}
the remove function loads the view with the data that has been passed in item to the remove function.
<div id="groupDelete" class="pop-window filter-view">
<h2>
Delete Group
</h2>
<table>
<tr>
<th>
Name
</th>
<td>
<span data-bind="text:group.Name" />
</td>
</tr>
<!--ko foreach: group.Members-->
<tr>
<th>
</th>
<td>
<div data-bind="text:Name" class="grey-border">
</div>
</td>
<td>
</td>
</tr>
<!--/ko-->
</table>
<span class="centeralign">
<input type="button" value="Delete" data-bind="click: remove" class="delete" />
<input type="button" value="Cancel" data-bind="click: cancel" />
</span>
</div>
I don't want to keep mapping each element of item to each element of groupDeleteViewmodel.group. I have done it at a lot of other places also in the code which has made the code really messy. I want to use the ko.mapping plugin to do the same thing.
Till now what I have tried is -
remove:function (item){
var data = ko.mapping.toJS(item);
ko.mapping.fromJS(data, groupDeleteViewModel.group);
$("#groupDelete").show();
}
But this just does not work. i really don't know why. It should have worked ideally.
Can someone tell what is the right way of using ko.mapping in such a case?
Thanks.
The mapping plugin is looking for mapping data already present in groupDeleteViewModel.group, but it doesn't find it, because you didn't initialize groupDeleteViewModel.group using the mapping plugin.
So instead of initializing group like you did:
group: { Id: ko.observable(), Name: ko.observable(), Members: ko.observableArray() }
initialize it using the mapping plugin:
group: ko.mapping.fromJS({ Id: undefined, Name: undefined, Members: [] })
And this is me fiddling around with your code: fiddle

MVC2 code conversion in Razor

I am using someones code for paging. His code is in MVC 2 and I want it in MVC3 Razor. Problem is with syntax.
Below is the code in mvc need someone to fix syntax for razor please.
Problem is in this line
IList<Customer> customers = (IList<Customer>)Model.Data;
//Can't use Model.Data directly. Doesn't pick up generic type.
IList<Customer> customers = (IList<Customer>)Model.Data;
foreach (Customer item in customers) { %>
<tr onclick="onRowClick(<%= item.ID %>)">
<td>
<%= Html.ActionLink("Edit", "Edit", new { id=item.ID}) %> |
<%= Html.ActionLink("Delete", "Delete", new { id=item.ID })%>
</td>
<td>
<%= Html.Encode(item.ID) %>
</td>
<td>
<%= Html.Encode(item.FirstName) %>
</td>
</tr>
<% } %>
The line could be translated like this:
# {
IList<Customer> customers = (IList<Customer>)Model.Data;
}
and then:
#foreach (Customer item in customers) {
<tr onclick="onRowClick(#item.ID)">
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.ID })
#:|
#Html.ActionLink("Delete", "Delete", new { id = item.ID })
</td>
<td>
#item.ID
</td>
<td>
#item.FirstName
</td>
</tr>
}
I would also benefit from this migration to improve this code. Currently you are using loops in your views which are ugly and could be replaced with display templates.
So, in your main view:
#Html.DisplayFor(x => x.Data)
and in ~/Views/Home/DisplayTemplates/Customer.cshtml:
#model YourApp.Models.Customer
<tr onclick="onRowClick(#Model.ID)">
<td>
#Html.ActionLink("Edit", "Edit", new { id = Model.ID })
#:|
#Html.ActionLink("Delete", "Delete", new { id = Model.ID })
</td>
<td>
#Model.ID
</td>
<td>
#Model.FirstName
</td>
</tr>

Prototype focusFirstElement() causes form to 'disappear' in IE

Strange bug I'm getting. I have a login form that is hidden by default, once a user clicks on an observed element, the element containing the form slides down (using Effect.BlidnDown in Scriptaculous)
Here is the function, which is part of the 'Interface' object:
revealLoginForm: function() {
$('a_login').blur();
if (!$('hform').visible()) {
Effect.BlindDown('hform', {
duration: 0.4,
afterFinish: function() {
$('f_login').focusFirstElement();
}
});
} else {
$('f_login').focusFirstElement();
}
},
The event observation:
Event.observe('a_login', 'click', Interface.revealLoginForm);
And the HTML:
<a id='a_login' href='javascript:void(0);'>Login to My Account</a>
....
<div id='hform' style='display:none;'>
<form id='f_login' action='...' method='post' name='sidelogin'>
<table cellspacing='0' class='login'>
<tr>
<th>Login ID:</th><td><input style='padding:2px;' type='text' size='18' name='enc_loginname' /></td>
</tr>
<tr>
<th>Password:</th><td><input style='padding:2px;' type='password' size='18' name='enc_password' /></td>
</tr>
<tr>
<th></th><td><input type='submit' class='submit' value='Login ยป' /></td>
</tr>
</table>
</form>
</div>
If I disable the $('f_login').focusFirstElement(); command in revealLoginForm(), the form does not disappear. What's strange is, the other call to this function does not adversely affect the element, it only seems to happen when called within the afterFinish callback to the Effect.BlindDown function.
Any ideas? It would be nice to have the first element of this form selected once the form has appeared. This works fine in Firefox.. it's just IE (Im using IE7) that's causing problems (go figure...)