Laravel Nova Hide view button from HasMany field - laravel-nova

i need to hide view button on HasMany field
In my Manager resource i have new panel with HasMany Relationship Field
new Panel('Orders History', [
HasMany::make('Orders')
]),
I was trying to use policies as described in docs: https://nova.laravel.com/docs/3.0/resources/authorization.html#relationships
in my ManagerPolicy class i create method
public function viewOrder($user)
{
return false;
}
but its not working...
Need some ideas what im doing wrong
P.S. Please keep in mind that i need to hide view button only on relation the orders page should have this functionality

Related

How get an parent id in HasMany field Laravel Nova

i have Category resource which have a nested Items resources via HasMany field
public function fields(Request $request)
{
return [
new Panel('Items', [
HasMany::make('Items', 'items')
]),
];
}
I need to perform specific validation with Items: the Category have integer field max_default_items so when creating a new Item inside the category i need to check, does max_default_items is greater than the actual count of items with is_default flag. The problem is that i have no idea how to get the Category id inside Item
Is it possible to pass params to HasMany field and get it inside Items resource?
Please help!

MVC5 - Dynamically choose which properties are displayed in an form

Let's say I have two users who are accessing a form. One is an admin user and one is a normal user. And only the admin can view and edit AdminOnlyField Then let's say I have the following class:
public class Car
{
public string Make {get;set;}
public string Model {get;set;}
public string AdminOnlyField {get;set;}
}
I'm not able to figure out how to conditionally make the AdminOnlyField visible and editable using #html.BeginForm(), I know you can use properties from ViewBag but in this case all the information I need is coming back from a database so I don't think I can utilize ViewBag.
Is this something MVC can accomplish or do I need to explore Angular?
The easiest way is to insert if(User.IsInRole(stringRole))
Yet if you want to hide this mechanism you can make an EditorTemplate.
The file has to be in location Views/Shared/EditorTemplates/EditFormTemplate.cshtml
For AdminOnlyField you can hide this functionality by template.
#if(User.IsInRole("Admin")
{
<div>
<label>AdminOnlyField: </label>
#Html.EditorFor(model => Model.AdminOnlyField)
</div>
}
Usage:
#Html.EditorForModel("YourCustomTemplateName")
If you need more information:
There is more information

ASP.NET MVC Using different controllers in single view

I'm new in ASP.NET MVC and I find troubles in some MVC patterns.
It's pretty clear the paradigm One controller -> One View but in a complex scenario where I have a wizard page where at every step I collect data for different models I can't find a straight and simple solution.
Example:
I have these 3 models: Student, Subject, Subscription
I want to make a jquery wizard page to create a subscription in this way:
Ask to select an existent student or create a new one
Ask to select an existent subject or create a new one
Ask to input some other data (date start, date end, payment etc)
This wizard is in view Subscription/Create and is using a Subscription model with some ViewBag data.
How can i achieve this?
It's better posting everything to a single controller action and call inserts in every models involved? Or is better post data at each step to the right Action?
If you're using jQuery for this, then in reality all you need is one viewmodel. That single viewmodel will contain the properties for eveything you intend to collect from the user e.g
public class SubscriptionCreateViewModel
{
// Fields from page 1 of the wizard.
public string Username { get; set;}
// Fields from page 2 of the wizard.
public string Foo { get; set;}
// etc.
}
When the user clicks Create (or whatever) on the last step of the wizard, the jQuery can make an Ajax POST call to the Subscriptions controller e.g
$.ajax({
type: 'POST',
url: 'url to controller',
data : { Username : 'UserName', Foo : 'foo' }
});
[HttpPost]
public ActionResult Create(SubscriptionCreateViewModel viewModel)
{
// Do whatever.
}
This implies that all the fields are shown in the same view though, by some JavaScript that changes what fields are shown to the user, based on the current wizard step.
If you are using separate views, then I suggest you use three controllers and three viewmodels, one for each controller (StudentController, StundentCreateViewModel, SubjectController, etc)

Grails relating values from two different domains in a custom view

While I'm experienced with Java, I am a Grails newbie but I am trying to get into it. I set up a basic "School" application containing the following domains:
Student
Class
Attendance
Both the 'Student' and 'Class' domains are scaffolded. Now, I want to create the 'Attendance' domain, and I'm going to need a controller with a custom view. I can do that, I'm just looking to understand (at a high level) the best way to set up the view (let's call it 'attendance.gsp').
The view will contain a dropdown box to select a class. Once a class is selected, I want to populate a table. The first column will contain the list of students in the class, and the second column will contain "Attended?" checkboxes.
I think that I can at least get that far.
I am wondering how to go about relating the checkbox value to the student. Since this class is not scaffolded, no attendance column has been created in the database. Do I need to have anything defined in the Attendance domain? How might you go about doing this? Can anyone recommend a particular example online that is doing something similar?
Thanks!
Something like this:
class Class {
...
static hasMany = [sessionsAttendance: Attendance]
}
class Student {
....
}
class Attendance {
static hasMany = [studentsAttended: Student]
}

Adding child elements onto a domain object before the domain object is created

(Sorry if this is a noob question, I couldn't find the answers on the grails reference)
I have the following domain heirarchy :
User > (has many) Survey > (has many) SurveyQuestion > (has many) SurveyQuestionResponse
These are two of the above :
class Survey {
String surveyName
static hasMany = [questions: SurveyQuestion]
static belongsTo = [user:User]
static constraints = {
}
}
class SurveyQuestion {
String question
static hasMany = [responses : SurveyQuestionResponse]
static belongsTo = [survey:Survey]
static constraints = {
}
}
When I create a Survey, I first see a screen like this :
I fill in the survey name, then click add a survey question, and see the next screen :
But it requires a survey being set, which hasn't yet completed.
Question : Do I have to create and save the survey first, then edit it and add survey questions (each of which individually need to be created and saved before I can create responses), or is there a way to add child objects as I'm creating the parent objects?
I want to use dynamic scaffolding so I don't have to create controllers and views manually.
The questions and answers are entirely independent, and will not be re-used across the hierarchy.
You should use command objects. This way you can comfortably add child elements while creating the parent. E.g.
class CreateSurveyCommand {
String surveyName
List<SurveyQuestion> surveyQuestions =
org.apache.commons.collections.list.LazyList.decorate(
new ArrayList(),
new org.apache.commons.collections.functors.InstantiateFactory(SurveyQuestion.class))
}
In the view (assuming index.gsp) you have something like:
<g:textField name="surveyName" value="${cmd?.question}" />
<g:each in="${cmd.surveyQuestions}" var="surveyQuestion" status="i">
<g:textField
name="surveyQuestions[i].question"
value="${cmd?.surveyQuestions[i].question}" />
</g:each>
<g:actionSubmit action="addQuestion"/>
Having an addQuestion action within your controller:
def addAction(CreateSurveyCommand cmd) {
cmd.surveyQuestions.add(new SurveyQuestion())
render(view:"index", model: [cmd: cmd])
}
Editing is another topic, but works the same way.
Have a look at this blog post:
http://blog.andresteingress.com/2012/06/29/groovy-2-0-love-for-grails-command-objects
Using that user interface you should create, save and add. A better approach is to create a master/detail user interface. You can see that approach here:
https://github.com/leadVisionary/Grails-Survey-Module
http://programmingitch.blogspot.com/2009/10/data-binding-for-one-to-many.html
http://omarello.com/2010/08/grails-one-to-many-dynamic-forms/
http://java.dzone.com/articles/creating-master-detail-forms
http://kapilpandit.wordpress.com/2009/02/25/complex_form_grails/
If you declare questions as a List in the Survey class then your views will be able to access them by index.
List questions
static hasMany = [questions: SurveyQuestion]
In your form GSP you can use something like this:
<g:textField
name="questions[0].question"
value="${surveyInstance?.questions?.size() > 0 ? surveyInstance?.questions[0]?.question : ''}"/>
The ternary for the value is a little crude but could easily be tucked away in your own tag.
If you really need to use dynamic scaffolding you can override individual views or the templates used to generate the view. Alternatively you could use the fields plugin to render the inputs for the questions property.
I've created a simple app & at that point everything appears to just work. I was expecting to have to write a PropertyEditor implementation to grow the list but it seems that Grails 2.1 will do this for you.
Reordering or removing questions would need more experimentation but updating the questions works, i.e. the question text is changed rather than a new SurveyQuestion instance being created.
If you are going to reuse the questions... maybe you shouldn't use a belongsTo =[survey:Survey]
Then if you don't have this relationship, you can create a template for creating the questions and add them to the question collection in survey object before saving it!

Resources