BeginForm and AttributeRouting [duplicate] - asp.net-mvc-5

I'm creating a form for a DropDown like this:
#{
Html.BeginForm("View", "Stations", FormMethod.Get);
}
#Html.DropDownList("id", new SelectList(ViewBag.Stations, "Id", "Name"), new { onchange = "this.form.submit();" })
#{
Html.EndForm();
}
If I choose a value from my dropdown I get redirected to the correct controller but the URL is not as I would like to have it:
/Stations/View?id=f2cecc62-7c8c-498d-b6b6-60d48a862c1c
What I want is:
/Stations/View/f2cecc62-7c8c-498d-b6b6-60d48a862c1c
So how do I get the id= querystring parameter replaced by the more simple URL Scheme I want?

A form with FormMethod.Get will always post back the values of its form controls as query string values. A browser cannot generate a url based on your route configurations because they are server side code.
If you really wanted to generate /Stations/View/f2cecc62-7c8c-498d-b6b6-60d48a862c1c, then you could use javascript/jquery to build your own url and redirect
#using (Html.BeginForm("View", "Stations", FormMethod.Get))
{
#Html.DropDownList("id", new SelectList(ViewBag.Stations, "Id", "Name"))
}
var baseUrl = '#Url.Action("View", "Stations")';
$('#id').change(function() {
location.href = baseUrl + '/' $(this).val();
});
Side note: Submitting on the .change() event is not expected behavior and is confusing to a user. Recommend you add a button to let the user make their selection, check it and then submit the form (handle the button's .click() event rather that the dropdownlist's .change() event)

Remove "id"
from
#Html.DropDownList("id", new SelectList(ViewBag.Stations, "Id", "Name"), new { onchange = "this.form.submit();" })

Related

Changing the title of the header

I use the SAPUI5 Framework.
Within a page there are two possibilities for action, to make a new patient and to edit a patient. The new and edit, control/view pages are compiled into one, one control and one view for both new and edit.
Since they both are within one-page control/view, whenever I try to make a new patient or to edit a patient I get the same title for both of these Options.
My approach.
Get the URL of the page -> New or Edit. -> Split till I get, if it's new or edit.
If its new, change the title to New if edit that the title to Edit.
var completurl = window.location.href;
var split = completurl.split("/");
if(split[7] == 'new'){
this.byId("semantic:DetailPageID").setTitle("New");
}
else {
this.byId("semantic:DetailPageID").setTitle("Edit");
}
Expected: To change the title of the header.
Actuality: Doesn't do shit
First you need the different buttons in your main.view.xml.
main.view.xml:
<Button press="onPressNew" text="New"/>
<Button press="onPressEdit" text="Edit"/>
Now you could use a local model for saving the action
editNew.controller.js:
onPressEdit: function () {
this.myLocalModel.setProperty("/Action", "Edit");
//Navigate to editNew.view.xml
},
onPressNew: function () {
this.myLocalModel.setProperty("/Action", "New");
//Navigate to editNew.view.xml
}
In your editNew.view.xml, you could use expression binding
editNew.view.xml:
<Page id="pageEditNew" title="{= ${localModel>/Action} === 'Edit' ? ${i18n>title_edit} : ${i18n>title_new}}">

Yii2 CRUD and Pagination

I am using Yii2 with Pjax for index/gridview listing. using pjax pagination , search all working fine without postback to server.
My problem starts now,
suppose i am on page number 2, i have clicked on edit record of that 2nd page list, i reach to update view, i have done changes and saved, now i am redirected to view , now i clicked on index link from breadcrumbs.
i want to reach to page number 2 of index rather then 1st page.
Traditional process for this is get refereeing page params an append that in breadcrumbs.
But is there any simple approach to this problem where i can write few lines of code and its applied to every where in backend?
Thanks for reading.
For remembering grid filter, pages i use yii2-grid-view-state
If you need to store page only, isn't it quite easy to pass page param into your view url (<model/view>) like <model>/view?id=<id>&page=<page>?
in your index.php view, edit your ActionColumn as follow:
[
'class' => 'yii\grid\ActionColumn',
'urlCreator' => function ($action, $model, $key, $index) {
return \yii\helpers\Url::to([$action, 'id' => $model->id, 'page' => Yii::$app->request->getQueryParam('page', null)]);
},
],
As you can see, I'm getting page param from request url and pass it to models' action buttons (to all buttons, but in your question it would be enough for view button of course)
And when you click to view model, in our Controller we need to get that page value and pass it to our view.php view (in order to place it in breadcrumbs).
Our ModelController:
public function actionView($id, $page = null)
{
return $this->render('view', [
'model' => $this->findModel($id),
'page' => $page,
]);
}
And finally view.php view will get the page value, and populate the index url (if not null):
/* #var $page int */
$this->title = $model->name;
$this->params['breadcrumbs'][] = ['label' => 'Index', 'url' => ['index', 'page' => $page]];
So when you press the Index breadcrumb, it will open the page, where you entered from.
Some advantages againts session implementation (#user1764431 solution):
Each of your tab can return to it's own last page
Simple and stupid solution
Some disadvantages:
If you need to store some filter params, url could stretch very long
Just add following Code in every controller of actionIndex() rest all things will take care
$searchModel = new CentervideosSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
/*Code insertion block begin*/
$params = Yii::$app->request->queryParams;
if (count($params) <= 1)
{
$params = Yii::$app->session['customerparams'];
if(isset(Yii::$app->session['customerparams']['page']))
$_GET['page'] = Yii::$app->session['customerparams']['page'];
if(isset(Yii::$app->session['customerparams']['per-page']))
$_GET['per-page'] = Yii::$app->session['customerparams']['per-page'];
}
else
{
Yii::$app->session['customerparams'] = $params;
}
$dataProvider = $searchModel->search($params);
/*Code insertion block Ends*/

MVC 5 routing issue with new url for subcategories

In my productcontroller I have two actionresult returning methods:
[Route("Shop/{brand}/{category}/{subcategory?}/{page:int?}")]
public ActionResult Index(string brand, string category, string subcategory, int? page, SortOptions currentSort = SortOptions.SinceDesc)
{ //...
and
[HttpPost]
[Route("Shop/{brand}/{category}/{subcategory?}/{page:int?}")]
public ActionResult Index(ProductsViewModel pvm)
{ //...
And this is my razor view:
#using (#Html.BeginForm("Index", "Products", FormMethod.Post))
{
#Html.DropDownListFor(x => x.SubCatID, Model.SubCategoriesSelectList, new { #class = "multiselect" })
}
When I submit the page it hits the httppost method but the url is still: Shop/nike/shoes even when I selected the subcategory runningshoes from the dropdown.
I would like to have urls like:
shop/nike/shoes
shop/nike/shoes/runningshoes
Being more of a webform-guy I am having a hard time to navigate to new url's and using viewmodel properties as parameters.
edit posted my UI:
to explain my ui:
the first dropdown should get to a subcategory. for instance: shop/nike/shoes/runningshoes
The second should post 'back' to sort the products.
The price slider should post back because it should filter. (would filter client side if there was no paging)
The paging should get so you can deeplink to a certain page: shop/nike/shoes/runningshoes/page2 etc.
In your BeginForm(...) you end up having to pass a route values dictionary with Subcategory = "runningshoes"
This does mix values being passed by GET, aka in the querystring through the route values dictionary, and POST, which will be the values from the form, but will accomplish what you are trying to do. More can be read about the BeginForm(..) overload Here on MSDN
You should end up with:
#using (#Html.BeginForm("Index", "Products", new { subcategory = "runningshoes" }, FormMethod.Post))
{
#Html.DropDownListFor(x => x.SubCatID, Model.SubCategoriesSelectList, new { #class = "multiselect" })
}
EDIT
Just realized you want the value from the form post to be in the QueryString on the response. Instead of returning the view directly from your MVC method for the Form Post what you could possibly do is a return RedirectToAction("ActionName", "ControllerName", new { subcategory = request.SubCategory }); which you would have an action that would support this redirect specifically.
Additional information on redirect to action can be found here on MSDN

Want to fill WinJS.UI.ListView with my own data

I had got the data using
WinJS.xhr({ url: url, responseType: "json" }).then(
function(result){},
function(error){}
);
I make this stuff on the button click event.
I got the data properly but can not fill them in my ListView.
So now, how can I bind the JSON data in my WinJS.UI.ListView on every click of button with my new data...? please help me for this with some simple example. because I had already checked so many links. But still I could not understand where
it should go something like this:
WinJS.xhr({ .. }).then(function xhrcomplete(req)
{
var data; // assuming you already have code that parsed json text to an object.
var items = [];
// fill code here to get items out of the data
var list = new WinJS.Binding.List(items);
// binding code will depend on whether listview has groupHeaderTemplate or not
// if not - it should be like this
listView.winControl.itemDataSource = list.dataSource; // listView is the id of the your list view control in html
}).then(null, function onerror(error)
{
// handle error case
});

Sharepoint List redirect with new id

I have a list within Sharepoint, using a custom new form I have added a custom list form control ("New item form" for the list) and changed the SaveButton to a standard input HTML button, and added an 'onclick' event that is as follows:
onclick="javascript: {ddwrt:GenFireServerEvent('__commit;__redirect={NewFormWizard2.aspx?id=}')}"
This works as in saves the data and redirects to the NewFormWizard2.aspx?id= page.
How do I get the ID of the created item to be passed to the redirected page?
Thus once the form is completed it would redirect to NewFormWizard2.aspx?id=23
jtherkel was close, but was missing a '}' on the end of the redirect url. I used an extra concat below
<input type="button" value="Submit" name="btnSave" onclick="javascript: {ddwrt:GenFireServerEvent(concat('__commit;__redirect={lists/MyListName/DispForm.aspx?ID=',/dsQueryResponse/Rows/Row/#ID,'}'))}" />
I am not sure where the ID will exist on the page you host the Javascript from. Does it appear in the querystring or on a field on the page?
There is nothing in the request or response that will identify the item. I have had this issue when doing some web loadtesting.
I can only suggest that your create the item using the webservices as that at gives you some return xml.
This answer does not solve the "new form" issue, but it might help others with the syntax for screens that contain existing list items.
I tested this quickly in my SharePoint (MOSS 2007) environment.
onclick="javascript: {ddwrt:GenFireServerEvent(concat('__commit;__redirect={NewFormWizard2.aspx?id=',/dsQueryResponse/Rows/Row/#ID))}"
The concat syntax is an XSLT instruction that tells the processor to combine the values enclosed in single quotes. I adapted this answer from info I found here.
Loading Values in a Custom List Form
http://wssdevelopment.blogspot.com/2007_04_01_archive.html
I hope this would be helpfull:
1- In SharePoint Designer create new page, call it for example "LastItem.aspx" and place a dataview on it with a single form view for the destination list item.
2-Limit paging to just one record, set the sorting by ID and descending and filter the list to just show item which is created by [current user].
3-Now you do not need to pass any query string to this page. just replace the default "OK" button in NewForm.aspx of the list with a standard HTML input button and add this to its definition "onclick="javascript: {ddwrt:GenFireServerEvent(concat('__commit;__redirect={LastItem.aspx}". After submitting a new item to list you will be redirected to an edit view of the created item.
You can do the same for save button in LastItem.aspx to redirect to some other page after clicking on save button.
found an approach using pure javascript (JQuery) and the SPAPI code from http://darrenjohnstone.net/.
The list contains two fields, title and BodyCopy
I've thewn created a form that asks for a title and a question, both text fields, then the submit button calls the following function: (note that ServerAddress and LIST_question need to be updated to your own details).
The function then uploads the details using the SOAP service within LISTS.ASMX and using the response gets the ID of the new item and redirects the page.
var LIST_question = '{xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}';
var ServerAddress = 'http://xxx/';
function submitQuestion()
{
var title = new String($("#title").val());
var t = new String($("#question").val());
t=t.trim();
if(t=="")
return;
title=title.trim();
if(title=="")
return;
var lists = new SPAPI_Lists(ServerAddress) ;
//
var newItem = { Title : title, BodyCopy : t};
var items = lists.quickAddListItem(LIST_question, newItem);
var id=-1;
if (items.status == 200)
{
var rows = items.responseXML.getElementsByTagName('z:row');
if(rows.length ==1)
{
var r = rows[0];
var id = r.getAttribute('ows_ID');
window.location.href='DispForm.aspx?ID='+id;
}
else
{
alert("Error: No row added");
}
}
else
{
alert('There was an error: ' + items.statusText);
return;
}
}
You can achieve this using JavaScript http://www.sharepointdrive.com/blog/Lists/Posts/Post.aspx?ID=9

Resources