Using $state.go to call ui-router child state - angular-ui-router

So I am trying to have a sub menu that changes the state of the child view, and I am failing.
So set up the following function to call $state.go
$scope.stateGo = function (state) {
console.log("Loadting state " + state)
$state.go(state);
}
And I can see on the console that the correct (or what I think is the correct state name) is called
Loadting state board.stat
However, nothing at all seems to be happening with the actual router. If I change it so a parent state. It does work. For example, if I set it to board it works.
The files that contains the ui-views looks as follows:
<div ui-view="topmenu">
</div>
</div>
<div id="mainView">
<div ui-view="mainView">
</div>
<div style="height: 100px;"> </div>
</div>
<div class="col-md-offset-3 footer navbar-fixed-bottom" id="adView">
<div ui-view="adView">
</div>
</div>
The state config:
.state('board', {
url: "/view/board",
views: {
topmenu: {templateUrl: "views/partials/menu-board"},
mainView: {templateUrl: "views/partials/welcome"},
adView: {templateUrl: "views/partials/amazon-banner"}
},
//controller: 'testCtrl'
})
.state('board.stat', {
url: "/stat",
views: {
topmenu: {templateUrl: "views/partials/menu-board"},
mainView: {templateUrl: "views/partials/stat"},
adView: {templateUrl: "views/partials/amazon-banner"}
}
})
Am I missing something, should a call to $state.go('board.stat') get ui-router to load stat into mainView? And if so, any idea why it isn't?
======================= EDIT ===================
OK, think I might be doing it wrong, but not certain how...
Changed the buttons to use ui-href
<a ui-sref="board.stat" ui-sref-active="active" class="btn btn-xlarge" ><button class="btn btn-primary btn-circle btn-xl"><i class="fa fa-bar-chart fa-1x"></i><br><h6>Stats</h6></button></a>
<a ui-sref="board.quickbet" ui-sref-active="active" class="btn btn-xlarge" ><button class="btn btn-primary btn-circle btn-xl"><i class="fa fa-plus fa-1x"></i><br><h6>Quick bet</h6></button></a>
So same layout as earlier, but it seems like both child states are loaded ONLY when I enter parent state.
So I added some debugging for the state using the following two functions:
$rootScope.$on('$stateChangeError',
function(event, toState, toParams, fromState, fromParams, error){
console.log("State error: " + error);
})
$rootScope.$on('$viewContentLoading',
function(event, viewConfig){
// Access to all the view config properties.
// and one special property 'targetView'
// viewConfig.targetView
console.log("State event: " + viewConfig)
});
But the only output I get is:
2 State event: mainView#
2 State event: adView#
But when I press the buttons nothing seems to happen

Think I solved it.
Well, I did solve it, but I'm surprised by how it works.
So the problems seems to be that I thought the child state would reload the hole set of ui-views, it does not, and trying to do so seems to do nothing. I have no clue if this is correct interpretation, or expected behaviour, but this is what worked for me.
Load parent state with all three views (named topmenu, mainView and adView) (happens automatically).
Add a new ui-view (in my case in stats.ejs loaded on mainView)
This is your stats and bets
<ui-view></ui-view>
Last thing is to ONLY update the parts of the screen you wan't, so not mainView, but targeting the new ui-view in stats.ejs
.state('board.stat', {
templateUrl: "views/partials/stat"
})
And it works, just not certain if this has to do with the DOM or something, but it worked in my case

Related

Browser-independent way to save text in a TextAreaFor

Using ASP.NET MVC, I have a View that contains a TextAreaFor, where I want users to be able to type in some notes and save them on-the-fly, see notes that were saved there before (whether by them or some other user), as well as modify existing notes (like to add additional notes). Here's what I have....
The divs in the View:
<div class="form-group">
<label for="InternalNotes" class="control-label">Internal Notes</label>
#Html.TextAreaFor(w => w.InternalNotes, new { #class = "form-control" , #id="notes" }) #*this is editable*#
</div>
<div class="form-group">
<div class="col-xs-6">
<button type="button" id="savenotes" class="btn btn-default btn-primary"><span class="glyphicon glyphicon-floppy-disk"></span> Save Request Notes</button>
<div style="color:green; display:none" id="notessuccess">Notes successfully saved</div>
<div style="color:red; display:none" id="noteserror">Notes unable to be saved</div>
</div>
<div class="col-xs-6 text-right">
<button type="submit" id="deletereq" class="btn btn-default btn-primary" value="delete" name="submit"><span class="glyphicon glyphicon-remove"></span> Delete Request</button>
</div>
</div>
So the user could type something into the TextAreaFor, then hit the "savenotes" button, which should save them via Ajax. This is the jQuery for that:
$(document).ready(function () {
$("#savenotes").click(function () {
$("#notessuccess").hide();
$("#noteserror").hide();
var id = #Model.AccessRequestId;
var notes = document.getElementById("notes").textContent; //innerText;
$.ajax({
data: { 'id': id, 'notes': notes },
type: 'POST',
//contentType: "application/json; charset=utf-8",
url: '/Administration/SaveRequestNotes',
success: function (data) {
if (data.success == "ok") {
$("#notessuccess").fadeIn();
} else {
$("#noteserror").fadeIn();
}
},
fail: function (data) {
$("#noteserror").fadeIn();
}
});
});
});
The "innerText" is commented out because that's what I was originally using, but it was only working in Internet Explorer - another user is using Chrome, where he could see the other user's notes that were already there, but when he'd try to save notes in addition to theirs, it would blow it all out so the notes would be empty!
So I changed it to "textContent". That still works in Internet Explorer, but now in both Chrome and Firefox while it won't empty out existing notes, it still won't save new notes added. What is a browser-independent way I can make this work so everyone's notes will get properly saved whatever they are using?
Thank you!
You can use the jQuery val() method get the text user entered to the textarea
var notes = $("#notes").val();
alert(notes);
You might also consider using the Url.Action helper method to generate the correct relative path to your action method.
url: '#Url.Action("SaveRequestNotes","Administration")',

How can I pass a data-id value to a ViewComponent

I want to use a ViewComponent in a Modal dialog to edit some data, I can get the ViewComponent to show on screen, when I click the button and if I hard code a value it will retrieve the correct data.
#await Component.InvokeAsync("Contact", 2);
or
#await Component.InvokeAsync("Contact", new { id=2 });
But what I can't see how to do is make the Id dependent upon which button I click. Ideally I'd like to just use data-id.
All the examples I've seen used fixed values.
Edit:
The ViewComponent is used in a ModalTagHelper, which is toggled on via an anchor tag, but I also have some jQuery that fires first.
$('.btnShow').on('click', function () {
$('#hdnContactId').val($(this).data('id'));
alert($('#hdnContactId').val());
});
Edit
<modal id="EditContact" title="Contact Details">
<modal-body>
#await Component.InvokeAsync("Contact", new { id=2 });
</modal-body>
<modal-footer>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</modal-footer>
</modal>
OK, so I finally figured a way to do it.
I removed the #await etc from the modal section, so by default it gets no data.
Then in the Controller I added:
public IActionResult ContactViewComponent(int Id) {
return ViewComponent("Contact", Id);
}
and changed my script to:
$('.btnShow').on('click', function (e) {
$('#hdnContactId').val($(this).data('id'));
var container = $(".modal-body");
$.get("/Contact/ContactViewComponent?Id=" + $(this).data('id'), function (data) { container.html(data); });
});
and it now works :)

How to use autoscroll in Angular UI-ROUTER

All:
I am pretty new to Angular UI-Router, when I come to ui-view, there is one attribute called "autoscroll" confused me so much, I thought it controll if the view page scroll(is my understanding correct, if not, please help with what this autoscroll does), but when I use it like:
<body ng-controller="main">
<div class="header">
<span>
<a ui-sref="home">HOME</a>
</span>
<span>
<a ui-sref="signup">SIGNUP</a>
</span>
</div>
<div class="body" ui-view autoscroll=false statename={{scroll}}></div>
</body>
And
app
.controller("main", function($scope){
$scope.scroll = true;
})
.config(function($urlRouterProvider, $stateProvider){
$urlRouterProvider.otherwise("/home");
$stateProvider
.state("signup", {
url: "/signup",
template: "<div class='signup'><span>This is a signup page. </span><p>And a long paragraph is follow</span></div>"
})
.state("home", {
url: "/home",
template: "<div class='home'><span>This is a home page. </span><span>And a long paragraph is follow</span></div>"
})
})
I have tried
autoscroll=false
autoscroll=true
autoscroll="false"
autoscroll="true"
//I set $scope.scroll to true and false
autoscroll={{scroll}}
autoscroll=scroll
autoscroll="scroll"
None of these works: when I scroll current view down and switch to another view, it always automatically scroll to Top, what I want is keep the view to current scroll position, any idea?
Thanks for help.

EmberJs {{ action }} helper in a view doesn't work

I'm trying to add bootstrap modals in my ember app. I'd like to be able to add modals, with a specified template and be able to handle actions. I can't get it works. The modal appears, my controller's properties are bound, but i can't handle actions. I don't understand why. I'd really like to be able to trigger modal from anywhere in my controllers and bind actions on them.
My view looks like this:
App.ModalView = Ember.View.extend({
classNames: ['modal fade'],
attributeBindings: ['role'],
role: 'dialog',
didInsertElement: function() {
this._super();
this.$().modal();
this.$().on('hidden.bs.modal', this.close.bind(this));
},
close: function(event) {
return this.destroy();
}
});
And i instanciate it like this in a random controller:
var modal = controller.container.lookup('view:modal');
modal.reopen({
controller: this,
targetObject: this,
templateName: 'mymodal'
});
return modal.appendTo('body');
My template looks like this:
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"></button>
<h4 class="modal-title">My Modal Title</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-12">
My modal content
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" data-dismiss="modal" class="btn default">Close</button>
<button type="button" class="btn green" {{ action "myaction"}}>My Button with an action</button>
</div>
</div>
</div>
If i try to display some controller properties, it works. But when i click on the button with the "myaction" action nothing happends. Maybe i'm completely wrong about the way to handle modals in my app (i'm pretty new in the Ember's World).
I'm using the last release of ember (1.1.1) and bootstrap 3.
Thanks,
Vinc
I figured it out. In fact, my app was running into a specific dom element (#app). As i was adding the view to the body, my modale was added "outside" my app ! So, the events bubbling chain was broken. Instead of adding my view to the body, i add it to my application root element and now everything works as expected !
There's a good chance that the modal method is disconnecting it from the body, which would break your actions.
See also: Ember.js and Foundation 4 modal window
You shouldn't access view like this
var modal = controller.container.lookup('view:modal');
See Wycats comment here.
Alternatively, This answer may help you in instantiating modals

Error on submiting form MVC3 .Net

Hi there I have an error when I submit the following form:
<div id="tabs">
<ul>
<li>Project Details</li>
<li>Project Attachments</li>
<li><a href="#Url.Action("Members", "ProjectNetwork", new { IsTab = true })">Project
Network</a></li>
<li>Bulleting Board</li>
<li>Bids Received</li>
</ul>
</div>
<div id="LowerButton">
#Html.Hidden("MainStatus", #Model.Status)
#using (#Html.BeginForm("Dashboard", "Dashboard"))
{
<button type="button" id="MakeComment">
Make a Comment
</button>
<input type="submit" id="GoDashBoard" value="Return to Project List" />
}
</div>
When I press the button "GoDashBoard", The method "Dashboard" in the controller "Dashboard" is not reached. Instead the following error appears:
It tells me that a model property is beign sent to the server. However, there are no model properties inside the dashboard form.. unless I'm sending many forms at the same time. But I dont think thats possible right? Do you guys have any idea of why is trying to set a model property when I'm not actually sending any?
Update:
this is the input of the dashboard action:
public ActionResult Dashboard(int page = 1)
{
var user = (User)Session["User"];
if (user != null)
{...
}}
the input is a default integer. However, I saw the trace of the calls and its submiting another form which is not related to the one im using:
That form is inside of one of the ajax tabs. I dont understand how one form submits another form and they are not nested. Anyone knows a good workaround? because im thinking of receiving both forms in both actions and make some validations.
I solved it by removing the form "Dashboard" and instead adding an invisible link. The button would reference the invisible link:
#*#using (#Html.BeginForm("Dashboard", "Dashboard"))
{ *#
<button type="button" id="MakeComment">
Make a Comment
</button>
<button name="button" type="button" onclick="document.location.href=$('#GoDashBoard').attr('href')">Return to Project List</button>
<a id="GoDashBoard" href="#Url.Action("Dashboard", "Dashboard")" style="display:none;"></a>
#*<input type="submit" id="GoDashBoard" value="Return to Project List" />*#
#* }*#

Resources