How to pass values from text area to table using AngularJS - javascript

C# MVC App using AngularJS
I am trying to display a list of values in a table that were originally entered in a text area.
Here is the workflow
User enters values in a text area as
A
B
C
When the user clicks on a button a modal window opens and should display A B C in a table .
I am trying to use angular to do this. I have tried the following:
<a class="btn btn-inverse pull-right" ng-click="arrangelist()">Arrange list</a>
<textarea id="letterlist" ng_model="letters"></textarea>
Also tried
#Html.TextAreaFor(model => model.letters, new { ng_model = "letters", #class = "width-100-percent", #rows = "7" })
And here is my modal window:
<div id=" arrangelist" class="modal hide fade" aria-hidden="true">
<table class="table">
<thead>
<tr>
<th>Letters</th>
</tr>
</thead>
<tbody>
<tr ng-animate="'table-anim'" ng-repeat="letter in letters">
<td>{{letter}}</td>
</tr>
</tbody>
</table>
<button type="button" class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
</div>
Here is the JavaScript that opens the window:
$scope. arrangelist = function() {
return $('#arrangevideos').modal('show');
}
So the modal window opens and displays the table but no values are inside the table.
How can I pass the values from the text area to the table in the modal window using Angular

Change ng_model = "letters" to ng-model = "letters".
And letters should be an array instead of string. You have to split the input to list of strings.
$scope.arrangelist = function() {
var letterplits;
letterplits = $('#letterlist').val().split('\n');
$scope.letters = letterplits;
return $('#arrangelist').modal('show');
}

you need to use ng-model, not ng_model. As long as your modal is in the same controller as your textarea, you should be able to pass it. Also, you have a space between $scope. and arrangelist. See this fiddle for a simple working example.

Related

AngularJS: Bind data returned from a modal to row it was clicked from

Using AngularJS here.
I am working on a UI which has a dropdown. Based on what the user selects I show 2 tabs to the user.
Each tab data is returned from a service which just returns an array of data (string).
Against each string value returned I show a button against it. When you click the button it opens a modal popup where the user can select some data.
When they close the modal I return the data back to the controller.
The normal flow of binding data to tab, opening modal and returning data from modal all works fine.
What I am not able to understand or design is how to bind the returned data against the button or row which it was clicked from
For example as below:
Tab1
String1 - Button1
String2 - Button2
String3 - Button3
If I open the modal by clicking button1, how do I find out button1 was pressed and bind back data that was returned from its modal.
Some of the relevant code as below:
<div id="params" ng-if="type.selected">
<tabset class="tabbable-line">
<tab heading="Sets" ng-if="sets" active="tab.set">
<div class="form-group m-grid-col-md-8 param" style="margin-top:5px"
ng-repeat="set in sets" >
<label class="control-label col-md-3 param-label">{{set}}
</label>
<button ng-click="openModal()" class="btn btn-info btn-sm">
Select
</button>
</div>
</tab>
<tab heading="Tables" ng-if="tables" active="tab.table">
<div class="form-group m-grid-col-md-8 param"
ng-repeat="table in tables">
<label class="control-label col-md-3 param-label">{{table}}
</label>
<button ng-click="openModal()" class="btn btn-info btn-sm">
Select
</button>
</div>
</tab>
</tabset>
</div>
Controller:
$scope.onChangeType = function (selectedValue) {
$scope.getData(selectedValue);
};
$scope.getData = function (selectedValue) {
//Commenting out the service part for now and hardcoding array
// service.getData(selectedValue).then(function (res) {
$scope.sets = ['Set1', 'Set2', 'Set3'];
$scope.tables = ['Table1', 'Table2'];
// });
};
$scope.openModal = function () {
myFactory.defineModal().then(function (response) {
//how to bind data from response
});
};
I have created a plnkr for this sample as:
http://plnkr.co/edit/vqtQsJP1dqGnRA6s?preview
--Edited--
<div class="form-group m-grid-col-md-8 param" ng-repeat="table in tables">
<label class="control-label col-md-3 param-label">{{table}}
</label>
<button ng-click="openModal(table)" class="btn btn-info btn-sm">
Select
</button>
<span>
{{table.utype}}
</span>
</div>
Pass the table object as an argument to the openModal function:
<button ng-click="openModal(table)">Select</button>
Use it in the openModal function:
$scope.openModal = function (table) {
myFactory.defineModal().then(function (result) {
table.utype = result.utype;
table.minvalue = result.minvalue;
});
};
Be sure to close the modal with the result:
$scope.ok = function () {
var result = {
utype: $scope.utype,
minvalue: $scope.minvalue,
};
$modalInstance.close(result);
};
Keep in mind that modals are considered disruptive and are despised by user.
Generally speaking, disruptions and distractions negatively affect human performance, a common finding in cognitive psychology. Many studies have shown that distraction greatly increases task time on a wide variety of tasks.
For more information, see
What research is there suggesting modal dialogs are disruptive?
While I dont get any error not but I dont get the text returned.
Be sure to furnish objects to the ng-repeat:
$scope.getData = function (selectedValue) {
//Commenting out the service part for now and hardcoding array
// service.getData(selectedValue).then(function (res) {
̶$̶s̶c̶o̶p̶e̶.̶t̶a̶b̶l̶e̶s̶ ̶=̶ ̶[̶'̶T̶a̶b̶l̶e̶1̶'̶,̶'̶T̶a̶b̶l̶e̶2̶'̶]̶;̶
$scope.tables = [
{name:'Table1',},
{name:'Table2',},
];
// });
};
The DEMO on PLNKR
Try to pass the table to openModal in your template
<button ng-click="openModal(table)"
Now you can use it as a reference in your openModal function
$scope.openModal = function (table) {
// table === the clicked table
}

Change a variable when a link is clicked

I have a page that loads the last 25 rows from a database and displays them in a table. I want to be able to click a link and have a modal popup that contains more information. I've got everything working except for knowing which row Id was clicked. Below is currently what I have. Model.ClickedId never changes from the default value so the popup has the same message everytime.
How can I make it so ClickedId on the backend is set to item.Id when the link is clicked?
Backend:
public int ClickedId { get; set; } = 0;
Front end:
#foreach (var item in Model.SFException)
{
<tr>
<td>
View <!-- Set ID to item.ID? -->
</td>
<td>
#Html.DisplayFor(modelItem => item.ObjectType)
</td>
<td>
#Html.DisplayFor(modelItem => item.ObjectKeyProperty)
</td>
<td>
#Html.DisplayFor(modelItem => item.ObjectKeyValue)
</td>
...
And the modal code where I am trying to display more information:
<div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalCenterTitle">Exception Details</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
#Html.DisplayFor(model => model.SFException[Model.ClickedId].StackTraceErrorMessage)
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
There are a couple of ways I've done this in the past. Either:
Get all the information that all rows need and dump it on the page (maybe in hidden elements), then when the user interacts with your rows show/hide the relevant extra information. Depending on how much extra info you need there can be a bit of overhead with this.
Put the 'StackTraceErrorMessage' on the page somewhere like
<td class="open-modal" data-itemId="#item.Id">
View
<input type="hidden" value="#item.StackTraceErrorMessage" />
</td>
Then in JS look for when the 'View' text is clicked, move the StackTraceErrorMessage from the hidden area to the modal html and display the modal html
$(document).ready(function() {
$(".open-modal").click(function() {
// get the item id from the clicked on element
var itemId = $(this).data("itemId");
// get the relevant StackTraceErrorMessage and put in the modal html
var message = $(this).find('input').val();
$('.modal-body').html(message);
// show the modal html (presumably this has styles associated to make it look like a dialog)
$('.modal).show();
});
)};
The second options is, put the basic information on the page and then when the user interacts with it go back to the server-side to request more details and then display that. There's a bit more back-and-forth and setup for this method.
The link in your row would look something like this:
<td data-itemId="#item.Id" class="show-row-details">View</td>
Where the item id is stored as an attribute in the element and a class is attached so we can watch for clicks.
In your js you would then look for any clicks like :
$(document).ready(function() {
$(".show-row-details").click(function() {
// get the item id from the clicked on element
var itemId = $(this).data("itemId");
// make a request to the backend for more info
$.ajax({
url: baseUrl + "YourController/YourAction",
data: { itemId : itemId },
success: function (data) {
// put the data returned into the popup element on our page and make it visible
$('#popup').html(data);
$('#popup').show();
}
})
});
)};
So to support this on your page you would need an elment ready to recieve data from the backend
<div id="popup" style="display:none"></div>
and also you would need a controller and action on your backend that is going to return the Html that you want to display in the popup div (pretty much just an action that loads a partial view (i.e. no layout) with your 'modal code' in it).
Note: I haven't actually tried the above code, so there may be some syntax errors etc

bootstrap modal displays twice

I have a users table with a button that shows a modal containing info about the user.
So I will have 10 rows, each with its own button, the first time I press a button, it will display a modal (let's call this modal A) containing the info for the user and work normally.
When I click on a button for another user it will display modal A then on top it will display the correct modal (modal B) when I close this modal, modal A is no longer on screen but the backdrop will still be visible.
I'm using laravel 5.5 with bootstrap 3 here is the code for the modal load.
Javascript
$(".btn").click(function(){
var button = $(this)
var employee_id = button.data('id')
var url = "/something/else/" + employee_id;
$('.modal-container').load(url,function(result){
$('#display').modal({show:true});
});
});
HTML
<a class="btn btn-primary" data-toggle="modal" data-id="{{ $simething->id }}" href="#display" id="modal_link">Show Modal</a>
This is the complete code
<table id="table" class="table" cellspacing="0" width="100%" role="grid">
<thead>
<th>ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>Events</th>
</thead>
<tbody>
#foreach ($empleados as $empleado)
<tr>
<td>{{ $simething->id }}</td>
<td>{{ $simething->fname }}</td>
<td>{{ $simething->lname }}</td>
<td>
<a class="btn btn-primary" data-toggle="modal" data-id="{{ $simething->id }}" href="#display" id="modal_link">Show Modal</a>
<div class="modal-container"></div>
</td>
</tr>
#endforeach
</tbody>
<script>
$(document).ready(function(){
$(".btn").on('click', function(e){
var button = $(this); // Button that triggered the modal
var employee_id = button.data('id'); // Extract info from data-* attributes
var url = "/somethin/else/" + employee_id;
$('.modal-container').load(url,function(){
$('#display').modal('show');
});
});
});
</script>
You are launching the modal twice every time, which after a few clicks is probably stacking up and causing the issues you're seeing. Try changing your html to not auto launch a modal, like so:
<a class="btn btn-primary modal-btn" data-id="{{ $simething->id }}" href="#/" id="modal_link">Show Modal</a>
Also, you shouldnt use the ".btn" as the way you select the button, as many buttons on your page may have that boostrap class. I would give it a unique class that you only want to target this modal with, or an ID if its for only one button per click event. Change your javascript to this:
$(".modal-btn").click(function(){
var button = $(this)
var employee_id = button.data('id')
var url = "/something/else/" + employee_id;
$('.modal-container').load(url,function(result){
$('#display').modal({show:true});
});
});

MVC - Html.Action to retrieve element using Javascript, then pass it as parameter to Controller, then return a PartialView

View - My view has a modal that has an #Html.Action that calls the PartialViewResult in Controller. Notice the #Html.Action("RetrieveItemPrice", new { item_Id = 1 }) still has predefined item_Id.
Q#1: How do I create a function that will get an element's value and put it in the item_Id parameter before sending it to the Controller? Could this be inserted in the #Html.Action?
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<div id="pvPrice" class="" style="border: 0px solid green; ">
#Html.Action("RetrieveItemPrice", new { item_Id = 1 })
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<table id="dbTable">
<thead>
<tr>
<th class="hidden">
#Html.DisplayNameFor(model => model.itemId)
</th>
<th>
#Html.DisplayNameFor(model => model.itemName)
</th>
</tr>
</thead>
<tbody id="dbBody">
#foreach (var item in Model.Items)
{
<tr>
<td class="hidden">
#Html.DisplayFor(modelItem => item.itemid)
</td>
<td>
#Html.DisplayFor(modelItem => item.itemname)
</td>
</tr>
}
</tbody>
</table>
Controller
public PartialViewResult RetrieveItemPrice(string item_Id)
{
var prices = from ip in _odb.ITEM_PRICE_MSTR
join i in _odb.ITEM_MSTR on i.ITM_ID equals i.ITM_ID
select new ItemModel
{
itemid = i.ITM_ID,
itemname = i.ITM_DESC,
itemprice = ip.ITM_PRICE,
defaultflag = ip.DEFAULT_FL,
startdate = DbFunctions.TruncateTime(ip.START_DT),
enddate = DbFunctions.TruncateTime(ip.END_DT),
createddt = i.CREA_DT
};
prices = prices.Where(i => i.itemid.ToLower().Contains(item_Id.ToLower()));
prices = prices.OrderByDescending(i => i.itemprice);
var vm = new ItemViewModel();
vm.Items = prices.ToPagedList(pageNumber, pageSize);
return PartialView("_ViewItemPrice", vm);
}
Q#2: When I return a PartialView in Controller using PartialViewResult, who's going to receive and display it in the View? I ran the code, but nothing is being displayed. I think I still lack codes in View to receive the returned PartialView in Controller
Assuming you have many items with different item_Id and you want to show the modal dialog when this item is clicked. You should be listen to the click event on the element, make an ajax call and get the response (partial view result) and use that to build your modal dialog content.
Assuming your main view has code like this
<table>
#foreach (var item in Model.Items)
{
<tr>
<td>#item.itemname</td>
<td><a href="#Url.Action("RetrieveItemPrice",new { item_Id = itemId})"
class="modal-link" >#item.itemname</a>
</td>
</tr>
}
</table>
<!-- The below code is for the modal dialog -->
<div id="modal-container" class="modal fade" tabindex="-1" role="dialog">
X
<div class="modal-content">
<div class="modal-body"></div>
</div>
This will generate links with css class modal-link for each item in the table. The href value of the links will be like YourControllerName/RetrieveItemPrice?item_id=123(123 will be replaced with actual itemid) Now listen to the click event on these, make an ajax call to the href attribute value of these links and use the response for populating the modal dialog content.
$(function () {
$('body').on('click', '.modal-link', function (e) {
e.preventDefault();
$("#modal-container").remove();
$.get($(this).attr("href"), function (data) {
$('<div id="modal-container" class="modal fade">
<div class="modal-content" id="modalbody">'
+ data + '</div></div>').modal();
});
});
});
This code will replace the entire content of the modal with the partial view result coming from the RetrieveItemPrice action method. That means you need to include the necessary markup needed for the modal header and footer(with buttons) in the _ViewItemPrice partial view.
A#1: the code calling #Html.Action is executed on server-side, at that phase the html document has not been sent to client-side so you don't have to look for a way to retrieve element value. You can pass it directly to the call, instead, because the model used for rendering the view (including the element) should be accessible to the code in the modal.
If you place the modal markups right inside the view, you definitely can get #Model.ItemId, for example.
If you place the modal in a partial view, you can pass item id via ViewBag:
#Html.Partial("Modal", null, new ViewDataDictionary{{"ItemId", Model.ItemId}})
then use it in the modal markups:
#Html.Action("RetrieveItemPrice", new { item_Id = ViewBag.ItemId })
A#2: you should try if [ChildActionOnly] makes the action RetrieveItemPrice works.

Populate angular ui bootstrap popover

How do you populate an angular ui bootstrap popover? I want to populate the popover with a list of actor names. Here is the code:
<div class="container" ng-if="radioModel=='Search for Actor'">
<p>Movies played in:</p>
<table class="table table-bordered">
<tr ng-repeat="name in listOfMovies">
<td>
<p>
<button uib-popover="populateWithListOfData" popover-trigger="mouseenter" type="button" class="btn btn-default"> {{ name }}</button>
</p>
</td>
</tr>
</table>
</div>
I want to be able to populate this popover for each name of the ng-repeat. So I will get a name of a movie and based on that name I want to populate the popover with a list of actors in that movie. Thanks guys.
This is definitely possible.
I have setup a data item called friends in JS
$scope.friends = [
{name:'John'},
{name:'Jessie'},
{name:'Johanna'},
{name:'Joy'}
];
Also , an array was created for the text in the popup
$scope.toolTip =['D','A','C','T'];
If you want to display a pop up for each row.
I've created the ng-repeat and the relevant popover.In order to display all the letters in the first popover.
<div ng-repeat="f in friends">
{{f.name}}
<button uib-tooltip="{{toolTip[$index]}}" type="button" class="btn btn-default">Tooltip {{placement.selected}}</button>
</div>
Here is a working demo
How does it works?
Your tool tip value is set as uib-tooltip="{{toolTip[$index]}}".it accesses each element according to the $index obtained from ng-repeat.
If you want to display all the data in the first pop up
I've created the ng-repeat and the relevant popover.In order to display all the letters in the first popover.
<div ng-repeat="f in friends">
<div ng-if="$index==0">
<button uib-tooltip="{{toolTip}}" type="button" class="btn btn-default">Tooltip {{placement.selected}}</button>
</div>
{{f.name}}
</div>
Here is a working demo
How does it works?
Your tool tip value is set as uib-tooltip="{{toolTip}}".It enters the ng-if , if the condition is met, and thus prints the array.
I couldn't test if it works, but this might give you the idea.
(function ()
{
function moviePopover($compile)
{
return {
restrict: "EA",
scope: true,
templateUrl: '<button uib-popover-template="dynamicPopover.templateUrl" popover-title="{{dynamicPopover.title}}" type="button" class="btn btn-default">Popover With Template</button>',
link: function (scope, element, attrs)
{
scope.dynamicPopover = {
content: "Movies",
templateUrl: "myPopoverTemplate.html",
title: "Title"
};
if (attrs.movieName !== undefined)
{
scope.movieList = getMoviesByName(attrs.movieName);
$compile(element)(scope);
//If 1st leads to infinit loop use this
// $compile(element.contents())(scope);
}
function getMoviesByName(movieName)
{
//return all moviews based on movieName
//here im just returning dummy array(you return your data)
return ["Movie1", "Movie2"];
}
}
}
}
angular.module("myApp").directive("moviePopover", ["$compile", moviePopover]);
}());
<script type="text/ng-template" id="myPopoverTemplate.html">
<ul>
<li ng-repeat="movie in movieList">{{movie}}</li>
</ul>
</script>
<div class="container" ng-if="radioModel=='Search for Actor'">
<p>Movies played in:</p>
<table class="table table-bordered">
<tr ng-repeat="name in listOfMovies">
<td>
<p>
<movie-popover movie-name="{{name}}"></movie-popover>
</p>
</td>
</tr>
</table>
</div>

Categories

Resources