I can't get <p/> or <br/> to create new lines when used after a custom ReactJS component that uses this Bootstrap CSS in the form <div className="col-sm-10"> i.e.
var MyChatClientView = React.createClass({
render: function() {
return (
<div>
<h2>Chat</h2>
<span>Type something</span>
<MyChatForm />
<p/>
<br/>
<div>
This text is on the same line as MyChatForm, I want it on a new line!
</div>
</div>
);
}
});
var MyChatForm = React.createClass({
handleSubmit: function(e) {
e.preventDefault();
var myChatTxt = this.refs.myChatTxt.getDOMNode().value.trim();
},
render: function() {
return (
<div>
<form role="form" onSubmit={this.handleSubmit}>
<div className="form-group">
<input type="textarea" className="form-control" id="post-chat" ref="myChatTxt" />
</div>
<div className="form-group">
<div className="col-sm-10">
<button type="submit" className="btn btn-primary btn-lg btn-block">Send</button>
</div>
</div>
</form>
</div>
);
}
});
To size form controls using Bootstrap, either (1) your form needs the form-horizontal class or (2) your columns need to be wrapped in an element with the row class.
This is covered in the control sizing section of the Bootstrap docs.
In your case it seems to make sense to replace the form-group with the needed row:
var MyChatForm = React.createClass({
handleSubmit: function(e) {
e.preventDefault();
var myChatTxt = this.refs.myChatTxt.getDOMNode().value.trim();
},
render: function() {
return (
<div>
<form role="form" onSubmit={this.handleSubmit}>
<div className="form-group">
<input type="textarea" className="form-control" id="post-chat" ref="myChatTxt" />
</div>
<div className="row">
<div className="col-sm-10">
<button type="submit" className="btn btn-primary btn-lg btn-block">Send</button>
</div>
</div>
</form>
</div>
);
}
});
Related
The code below shows a multi step form, the second page displays two buttons next and previous and for some reason the previous button doesn't work. I tried playing with code a lot but I couldn't figure it out. Please help.
<form class="form-wrapper">
<fieldset class="section is-active">
<h3>Details</h3>
<div class="inputlabel">
<label>Exchange</label>
</div>
<input type="text" placeholder="Exchange..">
<div class="button">Next</div>
</fieldset>
<fieldset class="section">
<h3>Title</h3>
<div class="inputlabel">
<label>Balance</label>
</div>
<input type="text" placeholder="Password" readonly>
<div class="btnpre" onclick="prvbtn()" id="btnprevious">Previous</div>
<input class="submit button" type="submit" value="Finish">
</fieldset>
<fieldset class="section">
<i class="fas fa-check-circle fa-7x"></i>
<h2>Saved</h2>
<p>Your Data has been saved</p>
<div class="button" id="button2">Close</div>
</fieldset>
</form>
This is the jQuery script
<script>
$(document).ready(function(){
$(".form-wrapper .button").click(function(){
var button = $(this);
var currentSection = button.parents(".section");
var currentSectionIndex = currentSection.index();
var headerSection = $('.steps li').eq(currentSectionIndex);
currentSection.removeClass("is-active").next().addClass("is-active");
headerSection.removeClass("is-active").next().addClass("is-active");
$(".form-wrapper").submit(function(e) {
e.preventDefault();
});
function prvbtn(){
if(currentSectionIndex === 1){
currentSectionIndex = 0;
}
if(currentSectionIndex === 2){
$(document).find(".form-wrapper .section").first().addClass("is-active");
$(document).find(".steps li").first().addClass("is-active");
}
});
});
</script>
Consider the following example.
$(function() {
// Define a Global Index
var sectionIndex = 0;
$(".form-wrapper .button").click(function() {
// Examine the button and determine which button was clicked
if ($(this).hasClass("next")) {
// Use the current Index and them increment it
$(".section").eq(sectionIndex++).toggleClass("is-active");
$(".section").eq(sectionIndex).toggleClass("is-active");
} else {
// Use the current Index and them decrement it
$(".section").eq(sectionIndex--).toggleClass("is-active");
$(".section").eq(sectionIndex).toggleClass("is-active");
}
});
$(".form-wrapper").submit(function(e) {
e.preventDefault();
});
});
.section {
display: none;
}
.section.is-active {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class="form-wrapper">
<fieldset class="section is-active">
<h3>Details</h3>
<div class="inputlabel">
<label>Exchange</label>
</div>
<input type="text" placeholder="Exchange..">
<div class="next button">Next</div>
</fieldset>
<fieldset class="section">
<h3>Title</h3>
<div class="inputlabel">
<label>Balance</label>
</div>
<input type="text" placeholder="Password" readonly>
<div class="previous button" id="btnprevious">Previous</div>
<input class="submit button" type="submit" value="Finish">
</fieldset>
<fieldset class="section">
<i class="fas fa-check-circle fa-7x"></i>
<h2>Saved</h2>
<p>Your Data has been saved</p>
<div class="button" id="button2">Close</div>
</fieldset>
</form>
This assigns one callback to all button elements. With an if statement, we can easily determine the direction.
I have a page and when I click on this page with "trigger" I can print the "#content" page. but I want it to return to the "home" I want with the "BACK" button on the page that comes up, but it just doesn't work. Where am I making the mistake?
index.php
<div class="app-content content" id="content">
<?php require 'home' ?></div>
home.php
<div id="kasaButton">
<a type="button" href="#" data-target="contact"> Contact</a>
<a type="button" href="#" data-target="gallery"> Gallery</a>
</div>
<div class="card">
<table class="datatables-basic table">
<thead>
<tr>
<th>İD</th>
<th>NAME</th>
</tr>
</thead>
<tbody>
<tr>
<td>İD</td>
<td>NAME</td>
</tr>
</tbody>
</table>
</div>
gallery
<div class="card-body">
<form action="" method="post">
<input type="text" class="form-control" placeholder="Cari Adı" value=""/>
<button id="save" type="submit">SAVE</button>
<button id="back" type="button">BACK</button>
</form>
</div>
$(document).ready(function () {
var trigger = $("#kasaButton a"),
container = $("#content");
trigger.on("click", function () {
var $this = $(this)
target = $this.data('target');
container.load(target);
return false;
});
});
$(document).ready(function () {
$("#back").on("click", function () {
$("#content").load('home');
});
})
Just add a div with the id of "content"
here is an example of gallery.php:
<div class="card-body">
<form action="" method="post">
<input type="text" class="form-control" placeholder="Cari Adı" value=""/>
<button id="save" type="submit">SAVE</button>
<button id="back" type="button">BACK</button>
</form>
</div>
<div id="content"></div>
<script>
$(document).ready(function () {
var trigger = $("#kasaButton a"),
container = $("#content");
trigger.on("click", function () {
var $this = $(this)
target = $this.data('target');
container.load(target);
return false;
});
});
$(document).ready(function () {
$("#back").on("click", function () {
$("#content").load('home.php');
});
})
</script>
I am making an react application with a simple CRUD functionality. In my environment I use a framework called react bootstrap 2.
Link: https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/getting-started.html
I have a form that the user can fill the information:
<form id="car-form" onSubmit={this.handleSubmit}>
<input type="hidden" name="carId" />
<div className="row">
<div className="form-group col-sm-3">
<label>Brand</label>
<input type="text" className="form-control" placeholder="Enter brand" value={this.state.brand} onChange={this.handleChange} />
</div>
</div>
<div className="row">
<div className="form-group col-sm-3">
<label>Model</label>
<input type="text" className="form-control" placeholder="Enter model" value={this.state.model} onChange={this.handleChange} />
</div>
</div>
<div className="row">
<div className="form-group col-sm-3">
<label>Color</label>
<input type="text" className="form-control" placeholder="Enter color" value={this.state.color} onChange={this.handleChange} />
</div>
</div>
<div className="row">
<div className="form-group col-sm-3">
<label>TopSpeed</label>
<input type="number" className="form-control" placeholder="Enter speed" value={this.state.topSpeed} onChange={this.handleChange} />
</div>
</div>
<div className="btn-group mr-2">
<button type="submit" className="btn btn-danger mr-1">Save changes</button>
<button type="reset" className="btn btn-danger mr-1">New record</button>
<button type="submit" className="btn btn-danger mr-1">Delete record</button>
</div>
</form>
The user can add a car and this working fine with the .NET core backend. I have a function from the official react bootstrap 2 documentation to select a row.
const rowEvents = {
onClick: (e, row, rowIndex) => {
console.log(`clicked on row with index: ${rowIndex}`);
}
};
When I click on a row I get the right index number. Now when I click on a row I want to fill the fields with data.
This is my handleChange method
handleChange(event) {
this.setState({
brand: event.target.brand,
model: event.target.model,
color: event.target.color,
topspeed: event.target.top
})
};
It still doesn't work when I click on a row.
How can I fill the fields when I click on a row?
Solution I used:
How do I programatically fill input field value with React?
assuming this.state.cars is where you storing the cars data . On clicking on the row change your function to
const rowEvents = {
onClick: (e, row, rowIndex) => {
this.setState({
brand: this.state.cars[rowIndex].brand,
model: this.state.cars[rowIndex].model,
color: this.state.cars[rowIndex].color,
topspeed: this.state.cars[rowIndex].top
})
}
};
and copy your rowEvents to render()
I am working on SPA (Single Page Application) for Online Team Collaboration service(OTC) ,and I include HTML pages by ng-include,in some included page there is a popover ,this one contains a possibility for creating a public group chat,and in order to create one ,the user must submit, now my question is : how can i display a "successfully created" message in the same popover instead of the main div for creating the group in the popover?
The external page (the page that include other pages):
<div ng-show="ctrChanneldiv" ng-contoller="ctrChannelCon" style="float: right;" class="col-md-3">
<div ng-include="'CreateChannel.html'" ></div>
</div>
The Controller ctrChannelCon:
appvar.controller('ctrChannelCon',['$scope','$http','$rootScope',function($scope, $http, $rootScope){
$scope.createBtn = function() {
$http.post("http://localhost:8080/ExampleServletv3/crtchannelservlet",this.crtchannel)
.success(function(response) {
setTimeout(function () {
$scope.$apply(function(){
//******* Here Display "Successfully Created" In the Popover *******//
});
});
});
};
}]);
In CreateChannel.html :
<div>
<div class="row">
<a href="#" class="popper" data-toggle="popover"
data-placement="bottom"><span class="glyphicon glyphicon-plus"></span>Create Channel</a>
<div class="popper-content hide">
<div class="form-group">
<!-- ng-controller="createChannelCon" -->
<div class="form-group">
<label>Channel name:</label>
</div>
<div class="form-group">
<input ng-model="crtchannel.Name" type="text" placeholder="enter channel's name" maxlength="30"
class="form-control input-md" required />
</div>
<div class="form-group">
<label>Description:</label>
</div>
<div class="form-group">
<textarea cols="15" ng-model="crtchannel.Description" type="text"
placeholder="enter channel's description" maxlength="500"
class="form-control input-md" required></textarea>
</div>
<div>
<input ng-model="crtchannel.Type" type="radio" name="chtype"
value="private" required /> Private<br> <input
ng-model="crtchannel.Type" type="radio" name="chtype"
value="public" /> Public<br>
</div>
<div class="form-group">
<button ng-click="createBtn()" class="btn btn primary">Apply</button>
</div>
</div>
</div>
<script>
$('.popper').popover({
container : 'body',
html : true,
content : function() {
return $(this).next('.popper-content').html();
}
});
</script>
</div>
</div>
Any suggestions?
Thanks
You may use ngClass directive to counter this problem. ngClass directive allows conditional application of classes. Create a div for successfully created in the popup and set up ng-class directive with a variable in the scope and assign it true and false as per your requirement.
JS
appvar.controller('ctrChannelCon',['$scope','$http','$rootScope',function($scope, $http, $rootScope){
$scope.createBtn = function() {
$http.post("http://localhost:8080/ExampleServletv3/crtchannelservlet",this.crtchannel)
.success(function(response) {
setTimeout(function () {
$scope.$apply(function(){
//******* Change value of a model *******//
$scope.hidden = false;
});
});
});
};
}]);
HTML
<span ng-class="{hide: hidden}">Successfully Created</span>
CSS
.hide { display: none; }
Set a flag in your controller on success and use this flag to show or hide the success message:
...
<div class="form-group">
<button ng-click="createBtn()" class="btn btn primary">Apply</button>
</div>
<div ng-show="isSuccess">Successfully Created</div>
Inside the controller:
$scope.isSuccess = false;
$scope.createBtn = function() {
$http.post("http://localhost:8080/ExampleServletv3/crtchannelservlet",this.crtchannel)
.success(function(response) {
setTimeout(function () {
$scope.$apply(function(){
//******* Here Display "Successfully Created" In the Popover *******//
$scope.isSuccess = true;
});
});
});
};
I have two buttons inside separate controllers.
<div ng-controller="aCtrl">
<button class="addButton" ng-click="toggle()"> Add </button>
<form ng-hide="myVar" ng-submit="submit()">
<input ......
<input ......
</form>
</div>
<div ng-controller="bCtrl">
<button class="EditButton" ng-click="toggle()"> Add </button>
<form ng-hide="myVar" ng-submit="submit()">
<input ......
<input ......
</form>
</div>
Note: Toggle just switches the hide/show bool in the back-end
As you can see when clicking the Addbutton it will show the form for aCtrl and EditButton for bCtrl. The result of the current layout is when Add Buttons form expands it pushes the EditButton down. I don't think this can be fixed with CSS as its the logical flow of the HTML.
I am looking for solutions that would allow me to have the buttons at the top in the flow of the page then the forms below.
for example I tried:
<button ng-controller="aCtrl" class="EditButton" ng-click="toggle()"> Add </button>
<button ng-controller="bCtrl" class="addButton" ng-click="toggle()"> Add </button>
<div ng-controller="aCtrl">
<form ng-hide="myVar" ng-submit="submit()">
<input ......
<input ......
</form>
</div>
<div ng-controller="bCtrl">
<form ng-hide="myVar" ng-submit="submit()">
<input ......
<input ......
</form>
</div>
Which doesn't seem to work.
The problem is that ng-hide hides the content with a display: none that causes the space occupied by the element to collapse.
You need visibility: hidden that also hides the element, but keeps the space.
Therefore, use ng-class instead of ng-hide:
<div ng-controller="aCtrl">
<button class="addButton" ng-click="toggle()"> Add </button>
<form ng-class="{ 'hidden' : myVar }" ng-submit="submit()">
<input ......
<input ......
</form>
</div>
<div ng-controller="bCtrl">
<button class="EditButton" ng-click="toggle()"> Add </button>
<form ng-class="{ 'hidden' : myVar }" ng-submit="submit()">
<input ......
<input ......
</form>
</div>
and the CSS
.hidden {
visibility: hidden;
}
Here is a live sample:
var myApp = angular.module('myApp',[]);
function aCtrl($scope) {
$scope.myVar = true;
$scope.toggle = function () {
$scope.myVar = !$scope.myVar;
}
}
function bCtrl($scope) {
$scope.myVar = true;
$scope.toggle = function () {
$scope.myVar = !$scope.myVar;
}
}
.hidden {
visibility: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<section ng-app="myApp">
<div ng-controller="aCtrl">
<button class="addButton" ng-click="toggle()"> aCtrl.Add </button>
<form ng-class="{ 'hidden' : myVar }" ng-submit="submit()">
<input type="text" value="aCtrl.form">
</form>
</div>
<div ng-controller="bCtrl">
<button class="EditButton" ng-click="toggle()"> bCtrl.Add </button>
<form ng-class="{ 'hidden' : myVar }" ng-submit="submit()">
<input type="text" value="bCtrl.form">
</form>
</div>
</section>
As you can see, the bCtrl.Add button remains in place, regardless whether aCtrl.form is visible or not.
It can be done via css only, just wrap the two in a div with position: relative and then add position:absolute to addButton and editButton together with top/left/right positioning values.
<div class="formContainer">
<div ng-controller="aCtrl">
<button class="addButton" ng-click="toggle()"> Add </button>
<form ng-hide="myVar" ng-submit="submit()">
<h1>Add form</h1>
<input type="text">
<input type="text">
</form>
</div>
<div ng-controller="bCtrl">
<button class="editButton" ng-click="toggle()"> Edit </button>
<form ng-hide="myVar" ng-submit="submit()">
<h1>Edit form</h1>
<input type="text">
<input type="text">
</form>
</div>
</div>
and css:
.formContainer {
position: relative;
width: 200px;
padding-top: 30px;
}
.addButton {
position: absolute;
top: 0;
right: 40px;
}
.editButton {
position: absolute;
top: 0;
right: 0;
}
Here's a working demo: Plunker CSS Only
There's another way, put them in a parent controller, which would hold the logic for toggling between the forms and then each form have their own controller for their respective functionalities.
Here's a working demo of the second version: Plunker with parent Controller
Here is example as u mentioned in your post. u can keep button outside of your controllers
var myApp = angular.module('myApp',[]);
myApp.controller('aCtrl', ['$scope', function ($scope) {
$scope.myVar = true
}]);
myApp.controller('bCtrl', ['$scope', function ($scope) {
$scope.myVar = true;
}]);
function getscope(ctrlName) {
var sel = 'div[ng-controller="' + ctrlName + '"]';
return angular.element(sel).scope();
}
function showForm(ctrlName) {
var $scope = getscope(ctrlName);
$scope.myVar = !$scope.myVar;
$scope.$apply();
}
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
<section ng-app="myApp">
<button class="addButton" onclick="showForm('aCtrl')"> aCtrl.Add </button>
<button class="EditButton" onclick="showForm('bCtrl')"> bCtrl.Add </button>
<div ng-controller="aCtrl">
<form ng-hide="myVar" ng-submit="submit()">
<input type="text" value="aCtrl.form">
</form>
</div>
<div ng-controller="bCtrl">
<form ng-hide="myVar" ng-submit="submit()">
<input type="text" value="bCtrl.form">
</form>
</div>
</section>
Is having two controllers is your requirement ?
You can have a separate controller of the button for eg. btnCtrl and toogle the value using a $rootscope variable. As follows.
<button ng-controller="btnCtrl" class="EditButton" ng-click="toggle()"> Add </button>
<button ng-controller="btnCtrl" class="addButton" ng-click="toggle()"> Add </button>
<div ng-controller="aCtrl">
<form ng-hide="$root.myVar" ng-submit="submit()">
<input ......
<input ......
</form>
</div>
<div ng-controller="bCtrl">
<form ng-hide="$root.myVar" ng-submit="submit()">
<input ......
<input ......
</form>
</div>