How to update a textfield based on other form elements - javascript

I'm writing a little database query app.
What i'm trying to do: Each time a checkbox is clicked, i'd like for a query that includes the selected fields to be generated and inserted into the textarea.
The problem: For some reason, with every click, its showing the query from the previous click event, not the current one.
Here's the markup:
<div class="application container" ng-controller="OQB_Controller">
<!-- top headr -->
<nav class="navbar navbar-default navbar-fixed-top navbar-inverse shadow" role="navigation">
<a class="navbar-brand">
Algebraix Database Client
</a>
<ul class="nav navbar-nav navbar-right">
<!--<li>Clear Queries</li>-->
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<span class="glyphicon glyphicon-import"></span> Load Data <b class="caret"></b></a>
<ul class="dropdown-menu">
<li>Default Data</li>
<li>Custom Import</li>
<!-- <li class="divider"></li> -->
</ul>
</li>
<li>
<a href="" class="queries-clear">
<span class="glyphicon glyphicon-remove"></span> Clear Queries
</a>
</li>
</ul>
</nav>
<!-- left column -->
<div class="col-md-4">
<div class="well form-group">
<ul>
<li ng-repeat="option in options">
<input type="checkbox" class="included-{{option.included}}" value="{{option.value}}" ng-click="buildQuery()" ng-model="option.included"> {{option.text}}
</li>
</ul>
</div>
</div>
<!-- right column -->
<div class="col-md-8">
<form role="form" id="sparqlForm" method="POST" action="" class="form howblock">
<div class="form-group">
<!--<label>Query</label>-->
<textarea type="text" name="query" class="form-control" rows="10" placeholder="Write your SPARQL query here">{{query}}</textarea>
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Submit Query" data-loading-text="Running Query..." />
</div>
</form>
</div>
</div>
And in my controller, i am doing the following:
var OQB_Controller = function($scope) {
console.log('OQB_CONTROLLER');
$scope.query = 0;
$scope.options = [
{ text: "checkbox1", value: "xyz123", included: false }
,{ text: "checkbox2", value: "abcRRR", included: false }
,{ text: "checkbox2", value: "abcRRR", included: false }
];
$scope.buildQuery = function() {
console.log('click');
var lines = [];
lines.push("SELECT *");
lines.push("WHERE {");
lines.push(" ?s ?p ?o .");
for(var i = 0; i<$scope.options.length; i++) {
var line = $scope.options[i];
console.log( line.value, line.included, i );
if( line.included ) {
lines.push(" OPTIONAL { ?s "+line.value+" ?o } .");
}
}
lines.push("}");
lines.push("LIMIT 10");
var _query = lines.join("\n");
$scope.query = _query;
};
};
To reiterate, every time the build query method is called, the state of the included booleans is from one click event prior. this has the symptoms of the classic javascript problem of the keyup vs keydown and the state of the event... however, i'm not sure if that is what is happening here.
is there a better way to do build the query (than what i'm currently doing) and populate the textarea based on the checked boxes?

use ng-change instead of ng-click because it is more appropriate for this particular desired behavior. See the ng-change documentation below:
The ngChange expression is only evaluated when a change in the input
value causes a new value to be committed to the model.
It will not be evaluated:
if the value returned from the $parsers transformation pipeline has
not changed if the input has continued to be invalid since the model
will stay null if the model is changed programmatically and not by a
change to the input value

Related

Multiselect Dropdown - Display Selected Data on Button

I have a multiselect dropdown that fetches data from the database. There are preselected data that I need to display on page load instead of displaying the "Please Select" word. I am using angularjs and javascript. How can I possibly do that. My code looks like this:
<div class="btn-group col-md-6 pull-right">
<button data-toggle="dropdown" class="col-xs-12 btn btn-primary dropdown-toggle" >---Please select---{{item.skin_type_name}}<span class="caret"></span></button>
<ul class="dropdown-menu">
<li ng-repeat="item in SkinType">
<input type="checkbox" id={{item.skin_type_id}} name="NAME2" value="{{item.skin_type_id}}" ng-checked="skintypeID[item.skin_type_id]==item.skin_type_id" ng-click="skntypclk(item.skin_type_id)" ng-disabled="currreadstypepro==1" ng-required="curstyp==1"><label>{{item.skin_type_name}}</label>
</li>
</ul>
I am using an API fetching data from the database and it looks like this one:
editorService.editSkintype(id)
.then(function(data){
$rootScope.loadercount--;
console.log($rootScope.loadercount);
skintypeIDArr = {};
angular.forEach(data.data, function(value) {
angular.forEach(value, function(value, key) {
if(key == "skin_type_id"){
skintype[value] = value;
skintypeIDArr[value] = value;
}
});
});
$scope.skintypeID = skintypeIDArr;
})
How can I display the preselected value on button instead of Please select? The data can only be displayed once I edit the values but what i need is to display the preselected value on page load. How can I do that?
Make sure to have the currently selected item in the scope. so the HTML would be:
<div class="btn-group col-md-6 pull-right">
<button data-toggle="dropdown" class="col-xs-12 btn btn-primary dropdown-toggle">{{selectedItem.skin_type_name}}<span class="caret"></span></button>
<ul class="dropdown-menu">
<li ng-repeat="item in SkinType">
<input type="checkbox" id={{item.skin_type_id}} name="NAME2" value="{{item.skin_type_id}}" ng-checked="skintypeID[item.skin_type_id]==item.skin_type_id" ng-click="skntypclk(item.skin_type_id)" ng-disabled="currreadstypepro==1" ng-required="curstyp==1"><label>{{item.skin_type_name}}</label>
</li>
</ul>
</div>
If so, then in your controller you could simply load the default value and then run the API call:
app.controller('ctrl', function($scope) {
$scope.selectedItem = {
skin_type_name: "Preselected Data"
};
// Now run the API call...
});
This way the preselected data will be set when the controller is loaded.
If you need it to be outside the controller, then declare the selectedItem in the $rootScope instead.

when i close the modal, checked inputs became unchecked

i use input with checkbox type to narrow my search result;
problem is i put the checkboxes in to the modal and when i checked many of them and close the modal the checked inputs become unchecked .
and i want every time that i open the modal input checked been checked.
var filterTemps = [
"partial/uicomponent/mdlFilters/mdl.estateType.filter.html",
];
$scope.showReleventMdl = function(num){
var filtersModal = $modal({
backdrop:true,
placement:'top',
templateUrl : filterTemps[num],
controller : 'filterCtrl',
show: false
});
filtersModal.$promise.then(filtersModal.show);
};
<!-- trigger the function for call modal -->
<ul class="nav navbar-nav">
<li>
</li>
...
</ul>
--------------------------------------------------
<!-- my Modal Template -->
<div class="modal-body">
<ul class="filterList">
<li class="filterListItem half" ng-repeat="item in string.pages.mainPage.estateTypes">
<input id="estateType{{$index}}" ng-click="checked(item)" type="checkbox" class="filterCheck">
<label for="estateType{{$index}}" ng-bind="item"></label>
</li>
</ul>
</div>
i want to know is there any way to store checked inputs and bring them back in checked state with modal ?
TNKS a lot
You are not setting any values to a $scope object. Try this...
<div class="modal-body">
<ul class="filterList">
<li class="filterListItem half" ng-repeat="item in string.pages.mainPage.estateTypes">
<input id="estateType{{$index}}" type="checkbox" ng-model="checkbox[$index].checked" class="filterCheck">
<label for="estateType{{$index}}" ng-bind="item"></label>
</li>
</ul>
</div>
Then, in your controller, you can set up the $scope object for your checkbox values.
$scope.checkbox = {};

Making visible and refreshing a DOM element : Angular JS

Not very familiar with Angular JS but here is what I have and what I want:
<div ng-app="MyApp" ng-controller="appController">
<div class="input-group">
<input class="form-control enableEnter" type="text" ng-model="action"/>
<div class="input-group-btn">
<button class="btn btn-primary" ng-click="search()">Search</button>
</div>
</div>
<ul class="dropdown-menu" id="list" ng-show = {{display}} >
<li> hello </li>
<li class="dropdown" ng-repeat="x in actions">
{{x.name}}
</li>
</ul>
</div>
My js file :
MyApp.controller('appController', ['$scope', function ($scope) {
$scope.actions = [];
$scope.display=false;
$scope.search = function () {
$.get("http://localhost:8080/get/something/" + $scope.action)
.success(function (response) {
console.log(response);
$scope.actions = response['RESPONSE'];
$scope.display=true;
}).error(function (jqXHR, textStatus, errorThrown) {
console.error("Error retrieving something list", textStatus, errorThrown);
});
}
}]);
The $scope.actions is empty initialized in the controller however on clicking the "Submit" button , we get a list of actions which are populated in actions. I want to show this list below the form. For this I am changing the value of ng-show when submit is clicked. Should this automatically update the <UL> element? Because I can't seem to see anything even after clicking.
You don't need to interpolate {{ }} inside an ng-show:
<ul class="dropdown-menu" id="list" ng-show="display" >
<li> hello </li>
<li class="dropdown" ng-repeat="x in actions">
{{x.name}}
</li>
</ul>
You might also want to look into an ng-if as well.
Problem is in below statement
<ul class="dropdown-menu" id="list" ng-show = {{display}} >
`change ng-show= {{display}} to ng-show='display'`
Check this working example - In this example, I have created submit button after clicking on ,I have change value of display and stored some dummy data.
https://jsfiddle.net/Shital_D/fc0L5pe3/2/

Angular JS - Need to apply different filter (for a table) depending upon different drop downs on page

I'm having three different sets of drop downs and also search box to apply filter for a table. My table should filter if someone enters text in textbox (or) depending on the value selected in one of the three drop downs (textbox searches and drop down searches are exclusive of each other).
This is my HTML:
<div ng-app="myModule" ng-controller="myController">
<nav class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<form class="navbar-form navbar-left form-horizontal" role="search">
<div class="form-group">
<label for="searchSeries" class="control-label">Find:</label>
<input type="text" id="searchSeries" ng-model="searchText" class="form-control" placeholder="Search TV Series" />
<div class="btn-group btn-input clearfix">
<button type="button" class="btn btn-default dropdown-toggle form-control" data-toggle="dropdown"> <span data-bind="label">Select One</span> <span class="caret"></span> </button>
<ul class="dropdown-menu" role="menu">
<li>Action</li>
<li>Animation</li>
<li>Comedy</li>
<li>Fantasy</li>
<li>Drama</li>
<li>Mystery</li>
<li>Romance</li>
<li>Science Fiction</li>
<li>Mini Series</li>
<li>Reality</li>
<li>Documentary</li>
<li>Crime</li>
<li>Game Show</li>
<li>Talk Show</li>
<li>Adventure</li>
<li>Home and Garden</li>
<li>Thriller</li>
<li>Sport</li>
<li>Family</li>
<li>Children</li>
<li>News</li>
<li>Horror</li>
</ul>
</div>
<select ng-model="properties.config" ng-options="prop.value as prop.name for prop in properties.configs">
</select>
<select ng-model="order.config" ng-options="template.value as template.name for template in order.configs">
</select>
</div>
</form>
</div>
<!-- /.navbar-collapse -->
</div>
<!-- /.container-fluid -->
</nav>
<div class="container-fluid">
<div class="table-responsive">
<table class="table table-bordered">
<tbody>
<tr ng-repeat="user in users[0].tvseries | filter: searchText | filter: order.config | filter:properties.config">
<td><img ng-src="{{user.thumbnail}}" alt="" /></td>
<td><div>{{user.tv_show_name}}</div>
<div>{{user.brief_description}}</div>
<div>{{user.rating}}</div></td>
<td><div>{{user.show_time}}</div>
<div>{{user.genre}}</div>
<div>{{user.current_season}}</div>
<div>{{user.current_episode}}</div></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
My controllers.js:
var myModule = angular.module('myModule', []);
myModule.controller('myController', function($scope, userRepository) {
userRepository.getAllUsers().success(function(users) {$scope.users = users;});
$scope.order = {};
$scope.properties = {};
//Configuration
$scope.order.configs = [
{'name': 'Ascending',
'value': 'tv_show_name'},
{'name': 'Descending',
'value': '-tv_show_name'}
];
$scope.properties.configs = [
{'name': 'Show Time',
'value': 'show_time'},
{'name': 'Rating',
'value': 'rating'}
];
//Setting first option as selected in configuration select
$scope.order.config = $scope.order.configs[0].value;
$scope.properties.config = $scope.properties.configs[0].value;
});
myModule.factory('userRepository', function($http) {
return {
getAllUsers: function() {
var url = "https://api.mongolab.com/api/1/databases/tvshowsdb/collections/tvshowsdbcollections?apiKey=e2SbmkVmLOQN-wH_ga84n9prYsgU8lQ5";
return $http.get(url);
}
};
});
Note that: when I apply "filter: searchText" in my html, it works fine and I face no issue. But when I try to apply two more filters "filter: order.config | filter:properties.config", my code doesn't execute. Please help me understand where I'm going wrong :(
Because you are adding and removing - before tv_show_name, I think that you are trying to sort the results by multiple fields? If that is the case, the syntax would be:
orderBy: [order.config, properties.config].
Here is a demo: http://plnkr.co/edit/yLYQGYGcGZMqoj6yfqoT?p=preview
Note: the demo is reading from a json file, instead of the mongolab api, because I needed to add duplicate names and start times, to show the effects of multi-level sorting. Also, notice that I changed the order of the selects to match the order in which you were applying the filters. I think it is intuitive that the first select take precedence over the next select.
Update
If you only want to sort by one of the options at a time, you can use a string variable, much like the orderBy api demo:
<div ng-click="predicate = 'tv_show_name'">Show Name ascending</div>
<div ng-click="predicate = '-tv_show_name'">Show Name descending</div>
<div ng-click="predicate = 'show_time'">Show Time</div>
<div ng-click="predicate = 'rating'">Rating</div>
...
<tr ng-repeat="user in users[0].tvseries | filter: searchText | orderBy:predicate">
Here is the updated Demo

How to do a foreach binding using KnockoutJS in Bootstrap-themed dropdown

I'm developing a small notifications-like module, where the user can see his 5 latest activities that are logged in the DB (MSSQL). The values that I need are all there, but for some reason knockout binding is not working. Here are code snippets:
<div class="dropdown-menu toolbar pull-right" data-bind="with: layoutLogsModel">
<h3 style="border: none;">Recent activities:</h3>
<!-- "mailbox-slimscroll-js" identifier is used with Slimscroll.js plugin -->
<ul id="mailbox-slimscroll-js" class="mailbox" data-bind="foreach: layoutLogsModel.notification">
<div class="alert inbox">
<a href="javascript:void(0)">
<i class="icon-book" style="color: orange;"></i>
Some text
</a>
<br>
Some text #2
</div>
</ul>
</div>
For now, I only want to display random text for every item that is in the observableArray.
ViewModel is the following:
var layoutLogsModel = {
notification: ko.observableArray()
};
function getLastFiveActivities() {
get(apiUrl + "Logs/GetLastFiveActivities", { ClientUserID: loggedUserID }, function (data) {
layoutLogsModel.notification(data);
});
}
And every time I call this function, the list is empty (IMAGE)
(the function is called on click, and absolutely no errors are shown in the console).
What is it that I am doing wrong?
EDIT:
The thing was, I forgot to execute ko.applyBindings for that viewModel. Then, I changed the HTML to look like this:
<ul id="mailbox-slimscroll-js" class="mailbox" data-bind="foreach: notification">
<div class="alert inbox">
<a href="javascript:void(0)">
<i class="icon-user" style="color: green;"></i>
<span data-bind="text: $data"></span>
</a>
</div>
</ul>
Aslo, I modified the get function slightly, like this:
function getLastFiveActivities() {
get(apiUrl + "Logs/GetLastFiveActivities", { ClientUserID: loggedUserID }, function (data) {
layoutLogsModel.notification(data.Notification);
});
}
(changed data to data.Notification based on the MVC model property that contains the array)
After all that, the data was available immediately.
try removing the layoutLogsModel from the foreach, you are already using it with the binding "with", so eveything in that div will be part of layoutLogsModel.
<div class="dropdown-menu toolbar pull-right" data-bind="with: layoutLogsModel">
<h3 style="border: none;">Recent activities:</h3>
<!-- "mailbox-slimscroll-js" identifier is used with Slimscroll.js plugin -->
<ul id="mailbox-slimscroll-js" class="mailbox" data-bind="foreach: notification">
<div class="alert inbox">
<a href="javascript:void(0)">
<i class="icon-book" style="color: orange;"></i>
Some text
</a>
<br>
Some text #2
</div>
</ul>
</div>

Categories

Resources