How to use React-Router in a Slider - hyperlink

First, show the UI.
When I touchMove the handler and touchEnd, I want to change the url, like before changing is .../component and after changing the url will became .../component?range=[0,1000]
----- more detail -----
var RangeSlider = React.createClass({
render: function() {
return (
<div className="range-slider-module">
<div className="range-slider-area">
<div ref="filledRange" className="range-slider-filled"></div> {/* This div show the target range selected*/}
<div onTouchStart={this.handleMouseDown}
onMouseDown={this.handleMouseDown}
onClick={this.handleClick}
ref="handlerLeft"
className="range-slider-handler-left">
</div> {/* Left handler */}
<div onTouchStart={this.handleMouseDown}
onMouseDown={this.handleMouseDown}
onClick={this.handleClick}
ref="handlerRight"
className="range-slider-handler-right">
</div> {/* Right handler */}
</div>
</div>
</div>
);
}
})

Related

ReactJS not binding via map to state values

I'm working with an MVC5 project and running into an issue with React not binding an array. I had this working in an MVC Core project, but had to "regress" back to the old structure. Biggest change seemed to be in the controller, changing from JsonResult (Core MVC) to Json (MVC5) for the return type on the ajax call.
Here's the output from Chrome Developer Tools:
(removed due to lack of reputation points)
And, my code for my .jsx file:
var LineItem = React.createClass({
render: function () {
return (
<div className="gridItem">
<div className="lessLineHeight smallFont">
<div className='section group'>
<div className="col span_1_of_2" id={this.props.ordHeaderId}>
<text>{this.props.code}</text>
</div>
<div className='col span_1_of_2 text-right'>
<i className={this.props.apptIconString} aria-hidden='true'></i>
<i className={this.props.highValueIconString}></i>
<i className={this.props.hazmatIconString}></i>
</div>
</div>
<div className='section group'>
<div className='col span_6_of_10'>
<text title='Trading Partner - Client'>{this.props.tradingPartnerName}</text>
</div>
<div className='col span_4_of_10 text-right'>
<text className='overflowElip' title='Account Manager'>{this.props.accountManager}</text>
</div>
</div>
<div className='section group'>
<div className='col span_1_of_2'>
<text title={"Origin: " + this.props.originAddress + "; " + this.props.origContact}>{this.props.originAddress}</text>
</div>
<div className='col span_1_of_2 text-right'>
<text title={"Destination:" + this.props.destinationAddress + "; " + this.props.destContact}>{this.props.destinationCity}</text>
</div>
</div>
<div className='section group'>
<div className='col span_1_of_3'>${this.props.freightValue}</div>
<div className='col span_1_of_3 text-center'>
<a title='Promote Order to Load'>To Load</a>
</div>
<div className='col span_1_of_3 text-right' id={'datePlanned' + this.props.ordHeaderId}>
<text title='Pickup Date'>{this.props.dateCreated}</text>
</div>
</div>
</div>
</div>
);
}
});
var ItemList = React.createClass({
getInitialState: function () {
return { items: [] };
},
loadData: function () {
$.ajax({
url: this.props.url,
dataType: 'json',
success: function (data) {
console.log(data);
this.setState({ items: data });
console.log(this.state.items);
$("#column1").find(".gridItem:odd").css({ "background-color": "#ddd" }).end().find(".gridItem:even").css({ "background-color": "#fff" });
}.bind(this),
error: function (xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
componentDidMount: function () {
this.loadData();
/*window.setInterval(this.loadData, this.props.pollInterval);*/
},
render: function () {
if (this.state.items) {
console.log("State has items.");
var itemNodes = this.state.items.map(function (foo) {
return (
<LineItem key={foo.ordHeaderId}
accountManager={foo.accountManager}
apptIconString={foo.apptIconString}
commodityDescription={foo.commodityDescription}
commodityId={foo.commodityId}
dateCreated={foo.dateCreated}
deliveryAppt={foo.deliveryAppt}
destContact={foo.destContact}
destinationAddress={foo.destinationAddress}
destinationAddressName={foo.destinationAddressName}
destinationCity={foo.destinationCity}
earlyDeliveryTime={foo.earlyDeliveryTime}
earlyPickupTime={foo.earlyPickupTime}
equipmentName={foo.equipmentName}
freightValue={foo.freightValue}
handlingUnits={foo.handlingUnits}
hazmatIconString={foo.hazmatIconString}
highValueIconString={foo.highValueIconString}
isHazmat={foo.isHazmat}
isHighValue={foo.isHighValue}
lateDeliveryTime={foo.lateDeliveryTime}
latePickupTime={foo.latePickupTime}
loadId={foo.loadId}
loadNum={foo.loadNum}
loadTmsStatus={foo.loadTmsStatus}
ordHeaderId={foo.ordHeaderId}
ordNum={foo.ordNum}
orderType={foo.orderType}
origContact={foo.originContact}
originAddress={foo.originAddress}
originAddressName={foo.originAddressName}
originationCity={foo.originationCity}
pickupAppt={foo.pickupAppt}
pieces={foo.pieces}
plannedEnd={foo.plannedEnd}
plannedStart={foo.plannedStart}
requiredTemp={foo.requiredTemp}
specialInstructions={foo.specialInstructions}
targetCost={foo.targetCost}
teamId={foo.teamId}
tempControlled={foo.tempControlled}
tradingPartnerNameCNum={foo.tradingPartnerNameCNum}
tradingPartnerName={foo.tradingPartnerNameClient}
transportMode={foo.transportMode}
user3gIdBookedBy={foo.user3gIdBookedBy}
user3gIdCreatedBy={foo.user3gIdCreatedBy}
weight={foo.weight} />
);
});
return (
<div className="itemList">
{itemNodes}
</div>
);
} else {
return null;
}
}
});
ReactDOM.render(
<ItemList url="/DispatchBoard/getColumn1Data" pollInterval={2000} />,
document.getElementById('column1')
);
As you can see from the image, the render: in the loadData function sees the items coming back from the ajax call, and then sets them to state, but when it comes time to map them, it does nothing.
Any ideas on what I'm not seeing?
EDIT
Here's a screen show showing the 'undefined' value(s) in one of the LineItems after failing to map properly. undefined values
EDIT #2
Here's a screenshot showing that the objects are hydrated and not being parsed. object present, not parsed
After seeing the screenshot you posted in EDIT #2
The issue is you're using different property name when accessing the data from foo while setting the properties on your component
So changing it from
<LineItem key={foo.ordHeaderId}
accountManager={foo.accountManager}
apptIconString={foo.apptIconString}
to
<LineItem key={foo.ordHeaderId}
accountManager={foo.AccountManager}
...
should do the trick
That is use the exact property name from your foo object instead of using camel cased or some other version of it.
The if condition in <ItemList> render is wrong. It should be like
if(this.state.items.length > 0)
Everything else looks fine. But, you forgot to add the key to the <LineItem> component
<LineItem key={foo.ordHeaderId}
accountManager={foo.accountManager}
... />
Here, you are passing key as a prop to the <LineItem> component but you forgot to set that key from the prop to the parent element.
var LineItem = React.createClass({
render: function () {
return (
<div className="gridItem" key={this.props.key}>
<div className="lessLineHeight smallFont">
....
)
}
})
This should remove the error/warning
From what I have experienced you can't pass key as a prop element. Remove this from you LineItem and see if it works. Let the warning persist. You can figure out a way to remove the warning later if this works.
<LineItem
accountManager={foo.accountManager}
apptIconString={foo.apptIconString}
commodityDescription={foo.commodityDescription}
commodityId={foo.commodityId}
dateCreated={foo.dateCreated}
deliveryAppt={foo.deliveryAppt}
destContact={foo.destContact}
destinationAddress={foo.destinationAddress}
destinationAddressName={foo.destinationAddressName}
destinationCity={foo.destinationCity}
earlyDeliveryTime={foo.earlyDeliveryTime}
earlyPickupTime={foo.earlyPickupTime}
equipmentName={foo.equipmentName}
freightValue={foo.freightValue}
handlingUnits={foo.handlingUnits}
hazmatIconString={foo.hazmatIconString}
highValueIconString={foo.highValueIconString}
isHazmat={foo.isHazmat}
isHighValue={foo.isHighValue}
lateDeliveryTime={foo.lateDeliveryTime}
latePickupTime={foo.latePickupTime}
loadId={foo.loadId}
loadNum={foo.loadNum}
loadTmsStatus={foo.loadTmsStatus}
ordHeaderId={foo.ordHeaderId}
ordNum={foo.ordNum}
orderType={foo.orderType}
origContact={foo.originContact}
originAddress={foo.originAddress}
originAddressName={foo.originAddressName}
originationCity={foo.originationCity}
pickupAppt={foo.pickupAppt}
pieces={foo.pieces}
plannedEnd={foo.plannedEnd}
plannedStart={foo.plannedStart}
requiredTemp={foo.requiredTemp}
specialInstructions={foo.specialInstructions}
targetCost={foo.targetCost}
teamId={foo.teamId}
tempControlled={foo.tempControlled}
tradingPartnerNameCNum={foo.tradingPartnerNameCNum}
tradingPartnerName={foo.tradingPartnerNameClient}
transportMode={foo.transportMode}
user3gIdBookedBy={foo.user3gIdBookedBy}
user3gIdCreatedBy={foo.user3gIdCreatedBy}
weight={foo.weight} />
Random User found the answer and it's contained in his comment.
The "key" to the problem was not capitalizing the properties that were to be mapped. Not sure why it worked the way it was in Core MVC, but, obviously, it doesn't work the same in MVC 4.

Content of <div> not updating

I've got a div element which I am using as a popup which does not update itself. I'll use the picture below to explain:
When I click on each row in the grid, the right hand side updates to show the details, part of which is a potentially lengthy Note field. The button View Note triggers a popup with the full text inside. Here, I have previously selected Donor 2000000, which displayed the correct note. However, when I select another Donor(2000002 as highlighted) the information in the popup retains the info for the first selected Donor. So, essentially it sets it once and then does not update.
The (partial) code for the main View is:
<div class="col-md-4 col-md-push-8">
<h4>
Donor Details
</h4>
<div id="donor-details">
<p class="muted">
Select donor to display detailed infomation
</p>
</div>
</div>
<div class="col-md-8 col-md-pull-4">
#Html.Action("DonorSummaryGrid") #* configure grid in a partial view *#
</div>
</div>
<script>
$(function () {
pageGrids.donorSummaryGrid.onRowSelect(function (e) {
$.post("/Donor/GetDonorDetails?donorId=" + e.row.DonorId, function (data) {
if (data.Status <= 0) {
alert(data.Message);
return;
}
$("#donor-details").html(data.Content);
});
});
});
</script>
The code for the partial view - which contains the details - is:
#if (!String.IsNullOrWhiteSpace(Model.CurrentNoteText)) {
<div id="note-dialog" title="Note for Donor #Model.DonorId">
<p>#Html.DisplayTextFor(model => model.CurrentNoteText)</p>
</div>
<br />
}
#Scripts.Render("~/Scripts/NoteDialogue.js")
When I debug, the value of Model.CurrentNoteText and #Model.DonorId do reflect the correct data.
NoteDialogue.js is:
$(function() {
$("#note-dialog").dialog({
autoOpen: false,
show: {
effect: "blind",
duration: 500
},
hide: {
effect: "blind",
duration: 200
}
});
$("#opener").click(function() {
$("#note-dialog").dialog("open");
});
});
I hope this is clear :)
Oh, there are no errors shown in the browser, and everthing functions as expected, except for updating the info in the popup.
I have tried
<script>
$("#note-dialog").html("#Model.CurrentNoteText");
</script>
with no success.
Got there in the end :)
Looking at the generated source, I noticed that the code for
<div id="note-dialog" title="Note for Donor #Model.DonorId">
<p>#Html.DisplayTextFor(model => model.CurrentNoteText)</p>
</div>
<br />
was being generated right at the bottom, outside all the other divs containing the grid and details. Looked something like this:
<div tabindex="-1" class="ui-dialog ui-widget ui-widget-content ui-corner-all ui-front ui-draggable ui-resizable" role="dialog" aria-describedby="note-dialog" aria-labelledby="ui-id-1"....>
As I clicked each row with a note in, an extra div was being generated, with the aria-labelledby attribute incrementing, e.g. "ui-id-2", "ui-id-3"...
The first generated div was being selected for the dialogue opening.
The solution was to remove the div on the row click event. Code now is:
$(function() {
pageGrids.donorSummaryGrid.onRowSelect(function (e) {
$("#note-dialog").remove();
$.post("/Donor/GetDonorDetails?donorId=" + e.row.DonorId, function(data) {
if (data.Status <= 0) {
alert(data.Message);
return;
}
$("#donor-details").html(data.Content);
});
});
});

Tap event on a ui-block is not firing - JQuery Mobile

I have a piece of code:
On HTML body:
<div data-role="content">
<section class="ui-grid-c">
<div class="ui-block-a">Column 1</div>
<div class="ui-block-b">Column 2</div>
<div class="ui-block-c">Column 3</div>
<div class="ui-block-d">Column 4</div>
<div class="ui-block-a">Column 1</div>
<div class="ui-block-b">Column 2</div>
<div class="ui-block-c">Column 3</div>
<div class="ui-block-d">Column 4</div>
<div class="ui-block-a">Column 1</div>
<div class="ui-block-b">Column 2</div>
<div class="ui-block-c">Column 3</div>
<div class="ui-block-d">Column 4</div>
<div class="ui-block-a">Column 1</div>
<div class="ui-block-b">Column 2</div>
<div class="ui-block-c">Column 3</div>
<div class="ui-block-d">Column 4</div>
</section>
<button id="show">Show</button>
</div>
and on JQM side:
var word = "";
$(document).on('tap', 'ui-block-a', function(e){
word = word + $(this).text();
});
$(document).on('click', '#show', function(e){
alert(word);
word = "";
});
This part:
$(document).on('tap', 'ui-block-a', function(e)
is not firing as expected.If I replace word = word + $(this).text(); with alert($(this).text()); no alert window is showing up.
Another question is if I want write a tap event handler on 'ui-block-b' a seperate event handler must be written to handle this event? I want to call the same function $(document).on('tap', 'ui-block-a', function(e) when a tap event occurs in any of ui-blocks.
It seems like an typo. In $(document).on('tap', 'ui-block-a', function(e){, it should be .ui-block-a instead of ui-block-a.
For the second question. I have two suggestions.
First is to use a common class for all these <div> and bind this event to this common class.
For example, add a class named word-add to all the <div>.
<div class="ui-block-a word-add">Column 1</div>
and then bind the tap event on word-add
$(document).on('tap', 'word-add', function(e){...})
The second is to define a function first and bind this function to tap event.
function addWord(e){
word = word + $(this).text();
}
$(document).on('tap', 'ui-block-a', addWord);
$(document).on('tap', 'ui-block-b', addWord);

jqm slider stop event not firing

I am trying to build a JQM page with a toggle/flip slider that shows/hides txt box based on slider position.
Please see JSfiddle test page.
HTML -
<div data-role="page">
<div data-role="header" data-theme="b">
<label>JQM Slider Toggle test</label>
</div>
<div data-role="container">
<div data-role="fieldcontain">
<label for="OnFront">Device Location:</label>
<select name="OnFront" id="OnFront" data-role="slider" data-theme="b">
<option value="true">Front</option>
<option value="false">Rear</option>
</select>
</div>
<div id="DeviceOnFront">
<div data-role="fieldcontain">
<label for="FrontPosId">Front Position</label>
<input type="text" id="FrontPosId" class="input_txt"></input>
</div>
</div>
<div id="DeviceOnRear" hidden="hidden">
<div data-role="fieldcontain">
<label for="RearPosId">Rear Position</label>
<input type="text" id="RearPosId" class="input_txt"></input>
</div>
</div>
</div>
<div data-role="footer" data-theme="b">
<label>Glyn Lewis</label>
</div>
JS -
$('div[data-role="page"]').bind('pageinit', function () {
// debug test to see if events are firing ???
$("#OnFront").on("start", function () {
alert("User has started sliding my-slider!");
});
$("#OnFront").on("stop", function (event) {
var value = event.target.value;
alert("User has finished sliding my slider, its value is: " + value);
});
// code for changing which txt box is shown
// based on toggle/flip switch
$("#OnFront").on("stop", function (event) {
var value = event.target.value;
if (value == true) {
$("#DeviceOnFront").show();
$("#DeviceOnRear").hide();
} else {
$("#DeviceOnFront").hide();
$("#DeviceOnRear").show();
};
});
};
I am unable to get the slider "stop" event to fire ??
Any pointers would be gratefully accepted.
Here's a working solution made from your example: http://jsfiddle.net/Gajotres/AWyXq/
You had few error's. Events sliderstop and sliderstart don't exist:
$("#OnFront").on("sliderstart", function () {
alert("User has started sliding my-slider!");
});
their correct names are slidestart and slidestop:
$('#OnFront').on('slidestart', function(){
console.log('Start');
});

Change position of input filed for jQuery Mobile Filter List

Im using the jQuery Mobile Filter List:
http://jquerymobile.com/test/docs/lists/lists-search-with-dividers.html
Is it possible to move the position of the input field so I can put it into a div already on my page?
Using jQuery's appendTo seems to work fine but its kind of a hacky solution. Thanks
this is what I found while searching for solution to a similar problem.
HTML code example:
<div data-role="page" id="page-id">
<div data-role="content">
<div data-role="fieldcontain">
<input type="search" name="password" id="search" value="" />
</div>
<div class="filter-div" data-filter="one">1</div>
<div class="filter-div" data-filter="two">2</div>
<div class="filter-div" data-filter="three">3</div>
<div class="filter-div" data-filter="four">4</div>
<div class="filter-div" data-filter="five">5</div>
</div>
</div>
JS code example:
$(document).delegate('#page-id', 'pageinit', function () {
var $filterDivs = $('.filter-div');
$('#search').bind('keyup change', function () {
if (this.value == '') {
$filterDivs.slideDown(500);
} else {
var regxp = new RegExp(this.value),
$show = $filterDivs.filter(function () {
return ($(this).attr('data-filter').search(regxp) > -1);
});
$filterDivs.not($show).slideUp(500);
$show.slideDown(500);
}
});
});
This way you can place your input text box anywhere on your page and it should properly filter a list of items you want.
JSFiddle DEMO: http://jsfiddle.net/cZW5r/30/

Resources