Based on cool StackOverflow code, I successfully created a series of dynamically-loaded <SELECT> drop-downs. However, when processing the form (e.g., if there's an error in the submitted information) I need to automatically select the appropriate <OPTION> in the dynamically loaded <SELECT> blocks. I tried a solution that works with static <SELECT> blocks, but it didn't work on my dynamically-loaded block. (I'm hiding/showing <SELECT> blocks as they are needed.) Here's the code:
<?php do things at the beginning of the page ?>
<script>
$(function() {
$('#container_A1').hide();
$"#category_A0").change(function() {
$("#category_A1").load("http://domain.com/loader/"+$("#category_A0").val());
$("#container_A1").show();
});
});
</script>
<?php create the HTML page... ?>
<script><?php
if( isset($_POST['category_A0']) && $_POST['category_A0'] != '' &&
isset($_POST['category_A1']) && $_POST['category_A1'] != ''){ ?>
$(function() {
$("#category_A1").load("http://domain.com/loader/"+$("#category_A0").val());
$("#container_A1").show();
$("#category_A1").val("<?php echo $_POST['category_A1']; ?>"); // NOT WORKING
});
<?php
}
?>
</script>
Everything works fine except the last JQuery line that tries to set the value of the category_A1 <SELECT> block to the option defined in $_POST['category_A1']. That doesn't work. Is the .load() function not complete when the subsequent .val() function is called?
Thanks!
.load is an asynchronous function. jQuery will continue on to the lines while .load is running, so the second $("#category_A1").val("<?php echo $_POST['category_A1']; ?>"); will always be overriden by the result of $("#category_A1").load("http://domain.com/loader/"+$("#category_A0").val());
Related
I'm using Bootstrap to do some form validation on my web app. With a normal select menu, it would be really easy to have an error message pop-up when the field is invalid:
<select class="someClass" required>
<option value="">Select an option</option>
<option>foo</option>
<option>bar</option>
</select>
<div class="invalid-feedback">Please make a selection.</div>
However, I'm using Bootstrap-Select's "selectpicker" class, and the "invalid-feedback" message in the div no longer works. Is there anyway to force Bootstrap-Select to recognize the "invalid-feedback" class or am I going to have to go about this a different way?
I figured out how to do this, and more generally this is an answer for anytime you have to "manually" force an error to work with Bootstrap's native validation system. It's really hacky, but I couldn't find anything else that works.
Say you have a "selectpicker" that looks like this:
<select id="mySelect" class="selectpicker" required>
<option value="">Select an option</option>
<option>foo</option>
<option>bar</option>
</select>
<div id="error" class="invalid-feedback">Please make a selection.</div>
The error message "Please make a selection" will not show, even if the select element is invalid; it will show, however, if it also has the "d-block" class:
<div id="error" class="invalid-feedback d-block">Please make a selection.</div>
So to manually force errors, you have to use JavaScript to check for the ":invalid" CSS pseudo-class; if it has this pseudo-class, then you add the "d-block" class to your div to show the error. You can use the matches() method and classList.add():
var selector = document.getElementById("mySelect");
var errorMsg = document.getElementById("error");
if(selector.matches(":invalid"))
{
errorMsg.classList.add("d-block");
}
You do this to add the message and you can remove it by checking for ":valid" and removing "d-block" from the classList.
I had multiple versions of the bootstrap-select elements in one of my forms and was having a really hard time getting this to work. The method below won't show the checkmark or x on the input, but it will show the invalid-feedback and valid-feedback boxes properly.
Using the advice from secretagentmango's answer, you can create a function that loops through all of your inputs with the "selectpicker" class, grab their parent form-group element, and then find the children "valid-feedback" and "invalid-feedback" elements
to add or remove the d-block class and hide/show them.
function bsSelectValidation() {
if ($("#myForm").hasClass('was-validated')) {
$(".selectpicker").each(function (i, el) {
if ($(el).is(":invalid")) {
$(el).closest(".form-group").find(".valid-feedback").removeClass("d-block");
$(el).closest(".form-group").find(".invalid-feedback").addClass("d-block");
}
else {
$(el).closest(".form-group").find(".invalid-feedback").removeClass("d-block");
$(el).closest(".form-group").find(".valid-feedback").addClass("d-block");
}
});
}
}
Now you need to run this function after form submit, and you can add it directly to the sample code from the Bootstrap Docs:
(function () {
'use strict';
window.addEventListener('load', function () {
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.getElementsByClassName('needs-validation');
// Loop over them and prevent submission
var validation = Array.prototype.filter.call(forms, function (form) {
form.addEventListener('submit', function (event) {
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
bsSelectValidation();
}, false);
});
}, false);
})();
The only thing different in the above code from bootstrap's sample is the call to our new function, "bsSelectValidation".
Now you need to listen for changes in the form to automatically update the d-block classes and fix the valid/invalid messages as people make changes to the form:
$('#myForm').change(bsSelectValidation);
Now your select menus should properly show the valid-feedback and invalid-feedback divs on form submit or change.
I found that if I simply remove the value="" part of the "option" element, then the validation message shows properly. That is, if I don't select anything from the dropdown, the my "invalid-feedback" message shows up. When I select something, it goes away and I can proceed further. It's worth a try if you haven't tried it.
My first "option" is simply this: <option>(select)</option> -- no 'value' clause is present.
Hope this helps.
I am creating a simple onclick event for a button. It's just not working. Below is what I wrote.
<script type='text/javascript'>
rec(){
<?php
$myfilename = "info.txt";
if(file_exists($myfilename)){
echo file_get_contents($myfilename);
}
?>
};
</script>
<button onclick="rec()">Click me</button>
Not sure, what wrong. I also commented entire php and just tried to echo hi, that also didn't work.
Kindly request your advice. Thanks.
Try printing out your javascript rather than putting PHP inside your javascript. For example you can try.
<?php
$myfilename = "info.txt";
if(file_exists($myfilename)){
$file = file_get_contents($myfilename);
echo "<script type='text/javascript'> function rec(){ console.log($file); console.log('This is JS being printed by PHP'); }</script>";
}
?>
Please keep in mind you should declare your function with the function keyword and there is no way for us to tell what $myfilename returns without more information, but if you're just trying to print html inside of PHP this should work for you.
Good day folks,
I am having an issue with Yii2, dunno whats goin on after searching online haven't found an answer.
Updated Question with more details
Here is a summary I am trying to change div content of my view via an ajax call to a controller action – the controller action I am calling does nothing but renders another view file which contains a Jui Tab.
The problem is it loads the home page + my Content at a lower part not processed.
If I visit the URL of the action that the ajax request calls, it displays properly with no issues – When I try to append it to my div on another view, this problem occurs.
Here are screenshots of my view
Page Displaying correctly on visiting URL
https://www.dropbox.com/s/77ovpl6fnznjs1p/Page%20displaying%20correctly%20on%20visiting%20URL.png?dl=0
Updating div with the rendered view displays content in a wrong manner
https://www.dropbox.com/s/6nld4wk1p9pkhz9/Screenshot%20of%20the%20update%20view.png?dl=0
A- Initial View Code
Here is my first view code – Contains a div that you click to fireup the ajax call and another div called content which gets the response
brense.PHP
<?php
use yii\helpers\Html;
use yii\jui\Tabs;
?> <div style="background: blue; cursor: pointer; width:100px;" id="brense">Click ME</div><div id="content">Content</div>
B- Ajax (JS File) `$('#brense').click(function(){
alert('click Received');
$.ajax({
url:'index.php?r=assignments/get-me2',
Type:'GET',
success:function(data){
alert("bombo");
$('#content').append('<div>Appended Content</div>');
$('#content').html(data);
}
});
});
`
C- Controller Action – Called by Ajax
public function actionGetMe2(){
return $this->renderAjax('tab');
}
D- Tab’s View that should be loaded inside the div content
<?php
use yii\helpers\Html;
use yii\jui\Tabs;
?>
<div>
<?php echo Tabs::widget(
['items'=>[
['label'=>'One','content'=>'Content 1'],
['label'=>'Two ','content'=>'Content 2'],
],
]
);
?>
</div>
Ok, here is the problem. Yii and Yii2 have an automatic numbering of elements. It has elements that are called w0, w1, w2. In a normal page you have w0 1 time, Yii takes care of that. Because you bring in code with Ajax, the page is actually a new page, so it has it's own w0 element. if you take a look at the code that it has it calls
$('#w0').tabs();
Now that works fine when you look at the page alone, but it will not work ok at all on your page because after inserting the content on the page you have 2 w0 elements. It basically calls the tab on the first one of them (in my test it was the nav bar) and that messes it up. The solution is to give the tabs an id.
So your tab.php file should be:
<?php
use yii\helpers\Html;
use yii\jui\Tabs;
?>
<div>
<?php echo Tabs::widget(
[
'id' => 'tabs',
'items'=>[
['label'=>'One','content'=>'Content 1'],
['label'=>'Two ','content'=>'Content 2'],
],
]
);
?>
</div>
This should solve your problem, but you migth have other problems too. Like loading jquery and jquery ui 2 times, 1 with the main page the other with your ajax. Now STOP using renderAjax you should use renderPartial.
Your code should be: in the main view file:
<?php
use yii\jui\JuiAsset;
JuiAsset::register($this);
?>
<div style="background: blue; cursor: pointer; width:100px;" id="brense">Click ME</div><div id="content">Content</div>
<?php
$script = <<<EOD
$('#brense').click(function(){
alert('click Received');
$.ajax({
url:'index.php?r=site/get-me2',
Type:'GET',
dataType: 'html',
success:function(data){
$('#content').html(data);
$('#tabs').tabs();
}
});
});
EOD;
$this->registerJs($script);
I am registering jquerui ui asset at the top, if you already have it loaded it will not load it again. I have a function that brings over the ajax, and that function also calls $('#tabs').tabs(); to actually create the jquery ui tabs.
Your controller
public function actionGetMe2(){
return $this->renderPartial('tab');
}
My first time to use Twig template with CodeIgniter. I'm used to the default form functionality of the framework, but I was asked to try to render the form using Twig. I find the template engine to be nice and confusing at the same time. So that means, my controller would be very fat with code. But the main issue here is to render the form using twig.
Below is what I used to do when I want to render a form. View: TableSample.php
<?php
echo form_open("", array("name"=>"form_reg", "method"=>"post", "id"=>"form_reg"));
echo form_input("type"=>"text", "name"=>"fname", "value"=>set_value("fname"));
echo form_input("type"=>"text", "name"=>"lname", "value"=>set_value("lname"));
echo form_input("type"=>"text", "name"=>"emailaddress", "value"=>set_value("emailaddress"));
echo form_input("type"=>"submit", "name"=>"submit", "value"=>"Submit");
echo form_close();
?>
Controller: register.php
public function register (){
$this->load->view("TableSample");
if($this->input->post("submit")) {
/** retrieve input details, pass them as array to model, then redirect if registration is successful**/
}
}
But since I have to use Twig, things have been a little bit different.
public function register () {
$detail["form_open"] = form_open("", array("name"=>"form_reg", "method"=>"post", "id"=>"form_reg"));
$detail["form_input_name"] = form_input("type"=>"text", "name"=>"fname");
$detail["form_input_lname"] = form_input("type"=>"text", "name"=>"lname");
$detail["form_input_eadd"] = form_input("type"=>"text", "name"=>"email");
$detail["form_input_submit"] = form_input("type"=>"submit", "name"=>"submit", "value"=>"Submit");
$detail["form_close"] = form_close();
//codes for saving here
//call twig view
$this->twig->display("tableSample.html.twig", $detail);
}
tableSample.html.twig would be like this:
<html>
<head></head>
<body>
{{ form_open }} //will display form as a **String** and not THE **HTML** like this:
<form method="post" name="form_reg" id="form_reg"></form>
{{ form_close }}
</body>
</html>
I know I'm missing something, please point me to the right way of rendering this. Thank You!
ok, I think I got it. raw made it possible. Twig Raw Filter
I've a problem only with chrome 25 and osx.
I get results with this line
console.log($$('.sort-box-slt-pl-opt'));
But with this lines
$$('.sort-box-slt-pl-opt').addEvent('click', function(event){
console.log('test');
});
the code inside the addEvent handler is never reached.
Did anyone have the same problem ?
I'm working with mootools 1.4, but the same problem happen when i try to use document.getElementsByClassName
thanks.
thank you for your comment but i still have the same trouble.
this is my html structure:
<span id="ead-sort-box-select-bloc">
<select id="ead-sort-box-select" class="divid-slt___cdc_" name="sort-box-ead">
<option class="sort-box-slt-pl-opt sort-box-slt-pl-opt-asc" value="functions/ead/mosaic-results.ajax-html?base=ead&champ1=fulltext&op1=AND&search_type=simple&query1=sdxall%3A1&ssearch-submit-npt.x=0&ssearch-submit-npt.y=0&form-display-only-media=&docs=true&&skippage=here&sf=&so=asc">pertinence</option>
<option class="sort-box-slt-pl-opt sort-box-slt-pl-opt-asc" value="functions/ead/mosaic-results.ajax-html?base=ead&champ1=fulltext&op1=AND&search_type=simple&query1=sdxall%3A1&ssearch-submit-npt.x=0&ssearch-submit-npt.y=0&form-display-only-media=&docs=true&&skippage=here&sf=fucomptitle&so=asc">titre croissant</option>
<option class="sort-box-slt-pl-opt sort-box-slt-pl-opt-desc" value="functions/ead/mosaic-results.ajax-html?base=ead&champ1=fulltext&op1=AND&search_type=simple&query1=sdxall%3A1&ssearch-submit-npt.x=0&ssearch-submit-npt.y=0&form-display-only-media=&docs=true&&skippage=here&sf=fucomptitle&so=desc">titre décroissant</option>
<option> .... </option>
</select>
<span>
I want to execute an ajax function when the user select an option but, the code inside the addEvent is never reached. This is the JS code:
...
if(Browser.chrome && Browser.Platform.mac){
if($('ead-sort-box-select') != null){
var elements = $$('.sort-box-slt-pl-opt');
elements.each( function( element ) {
element.addEvent('click', function(){
console.log('test');
});
});
}
}
...